def onCommand(self, event): """Handle the slider reset command.""" base.Widget.onCommand(self, event) if self.widgetId and event.hasId(self.resetCommand): pr.getActive().removeValue(self.widgetId)
def __getPresentation(self, tabId): """Compose the HTML presentation for a tab identifier. @return HTML content as a string. """ # Kludge for the game-options icon. There should be a way to # map the icon more flexibly so this hardcoding wouldn't be # needed. if tabId == "game-options": game = "game-jdoom" if pr.getActive(): for c in pr.getActive().getComponents(): if c[:5] == "game-": game = c break imageName = language.translate(game + "-icon") else: imageName = language.translate(tabId + "-icon") return ( '<table width="100%" border=0 cellspacing=3 cellpadding=1>' + "<tr><td width=35><img width=32 height=32 " + 'src="%s"></td><td align="left" valign="center">%s</td>' % (paths.findBitmap(imageName), language.translate(tabId)) + "</tr></table>" )
def handleNotify(event): """Handle a notification event.""" global listenSelections if event.hasId('active-profile-changed'): refreshList() if event.hasId('maps-list-selected') and listenSelections: pr.getActive().useAddon(event.getSelection()) if event.hasId('maps-list-deselected'): pr.getActive().dontUseAddon(event.getDeselection()) if event.hasId('addon-attached'): listenSelections = False mapListBox.selectItem(event.getAddon()) mapListBox.setItemImage(event.getAddon(), 1) listenSelections = True if event.hasId('addon-detached'): listenSelections = False mapListBox.deselectItem(event.getAddon()) mapListBox.setItemImage(event.getAddon(), 0) listenSelections = True if event.hasId('addon-database-reloaded'): refreshList() if event.hasId('language-changed'): mapListBox.retranslateColumns()
def onThumbTrack(self, ev): if self.widgetId: newValue = self.getValue() if newValue != self.oldValue: pr.getActive().setValue(self.widgetId, str(newValue)) # Send a notification. events.send(events.EditNotify(self.widgetId, newValue)) self.oldValue = newValue
def refreshItemInList(item): addon = ao.get(item) defaultAddons = pr.getDefaults().getAddons() if pr.getActive() is not pr.getDefaults(): profileAddons = pr.getActive().getAddons() else: profileAddons = None # Update the image of the item. addonList.setItemImage(item, determineIcon(addon, pr.getActive(), defaultAddons, profileAddons))
def refreshItemInList(item): addon = ao.get(item) defaultAddons = pr.getDefaults().getAddons() if pr.getActive() is not pr.getDefaults(): profileAddons = pr.getActive().getAddons() else: profileAddons = None # Update the image of the item. addonList.setItemImage( item, determineIcon(addon, pr.getActive(), defaultAddons, profileAddons))
def folderBrowseAction(): # Open a folder browser for selecting the value for a file # setting. settingId = setting.getId() value = pr.getActive().getValue(settingId) if not value: currentValue = '' else: currentValue = value.getValue() selection = sb.util.dialog.chooseFolder(settingId + '-selection-title', currentValue) if len(selection) > 0: pr.getActive().setValue(settingId, selection)
def onNotify(self, event): base.Widget.onNotify(self, event) if self.widgetId and sb.confdb.isSettingDefined(self.widgetId): if event.hasId('active-profile-changed'): # Get the value for the setting as it has been defined # in the currently active profile. self.getFromProfile(pr.getActive())
def onClick(self, event): """Swap through the three states when the check box is clicked.""" if self.widgetId: w = self.getWxWidget() state = w.Get3StateValue() if (state == wx.CHK_UNDETERMINED and pr.getActive() is pr.getDefaults()): state = wx.CHK_UNCHECKED w.Set3StateValue(state) if state == wx.CHK_CHECKED: pr.getActive().setValue(self.widgetId, 'yes') newValue = 'yes' elif state == wx.CHK_UNCHECKED: pr.getActive().setValue(self.widgetId, 'no') newValue = 'no' else: pr.getActive().removeValue(self.widgetId) newValue = 'default' self.updateState() events.send(events.EditNotify(self.widgetId, newValue)) # Let wxWidgets process the event, too. event.Skip()
def handleCommand(event): if pr.getActive() is pr.getDefaults(): return if event.hasId('play'): # Launch the game with the active profile. startGame(pr.getActive()) elif event.hasId('continue') and resolving: continueResolving() elif event.hasId('view-command-line'): # Generate a command line and display it in a dialog. options = generateOptions(pr.getActive()) if options == None: return # Escape any angle brackets. options = options.replace('<', '<') options = options.replace('>', '>') options = options.replace(' -', '<br>-') # Highlight all the options with a bold font. pos = 0 while pos < len(options): if options[pos:pos + 5] == '<br>-' or \ pos == 0 and options[pos] == '-': options = options[:pos] + '<b>' + options[pos:] pos += 5 while pos < len(options) and \ options[pos] not in string.whitespace: pos += 1 options = options[:pos] + '</b>' + options[pos:] pos += 1 dialog, area = sb.util.dialog.createButtonDialog( 'view-command-line-dialog', ['ok'], 'ok') msg = area.createFormattedText() msg.setMinSize(500, 400) msg.setText('<tt>' + options + '</tt>') dialog.run()
def handleNotify(event): """This is called when somebody sends a notification. @param event A events.Notify object. """ if event.hasId('show-help-text-now'): helpText.unfreeze() return if helpDisabled: return if event.hasId('init-done'): setField(FIELD_MAIN, language.translate('help-welcome')) setField(FIELD_COMMAND, language.translate('help-command-defaults')) updateHelpText() elif event.hasId('show-help-text-now'): helpText.unfreeze() elif event.hasId('active-profile-changed'): if pr.getActive() is pr.getDefaults(): setField(FIELD_COMMAND, language.translate('help-command-defaults')) else: setField(FIELD_COMMAND, language.translate('help-command')) elif event.hasId('tab-selected'): setField(FIELD_MAIN, '') setField(FIELD_CURRENT_TAB, language.translate('help-' + event.getSelection())) elif event.hasId('addon-list-selected') or \ event.hasId('maps-list-selected'): # Display information about the selected addon in the panel. try: showAddonInfo(ao.get(event.getSelection())) except KeyError: # It wasn't an addon. pass elif event.hasId('focus-changed'): try: setting = st.getSetting(event.getFocus()) showSettingInfo(setting) except KeyError: # It was likely not a setting id. pass elif event.hasId('value-changed'): if currentSetting and event.getSetting() == currentSetting.getId(): showSettingInfo(currentSetting) elif event.hasId('language-changed'): pass
def handleNotify(event): if event.hasId('active-profile-changed'): # Disable or enable controls based on which profile is selected. if pr.getActive() is pr.getDefaults(): playButton.disable() ui.disableMenuCommand('play') ui.disableMenuCommand('view-command-line') else: playButton.enable() ui.enableMenuCommand('play') ui.enableMenuCommand('view-command-line')
def onItemSelected(self, ev): """Handle the wxWidgets event that is sent when the current selection changes in the list box. @param ev A wxWidgets event. """ if self.widgetId: newSelection = self.items[ev.GetSelection()] if sb.confdb.isSettingDefined(self.widgetId): # This is a setting. if newSelection == 'default': pr.getActive().removeValue(self.widgetId) else: pr.getActive().setValue(self.widgetId, newSelection) # Notify everyone of the change. events.send(events.EditNotify(self.widgetId, newSelection)) else: # Normal list. events.send(events.SelectNotify(self.widgetId, newSelection))
def browseAction(): # Open a file browser for selecting the value for a file # setting. settingId = setting.getId() value = pr.getActive().getValue(settingId) if not value: currentValue = '' else: currentValue = value.getValue() selection = sb.util.dialog.chooseFile( settingId + '-selection-title', currentValue, setting.hasToExist(), setting.getAllowedTypes()) if len(selection) > 0: pr.getActive().setValue(settingId, selection) if events.isMuted(): # Update manually. text.getFromProfile(pr.getActive())
def onNotify(self, event): """Notification listener. @param event An events.Notify object. """ base.Widget.onNotify(self, event) if self.reactToNotify and event.hasId(self.widgetId + '-value-changed'): # This is our value. self.setText(event.getValue()) if self.widgetId and event.hasId('active-profile-changed'): self.getFromProfile(pr.getActive())
def handleNotify(event): """This is called when someone sends a notification event.""" #if event.hasId('init-done'): if (event.hasId('value-changed') or event.hasId('active-profile-changed')): # Update any settings with value dependencies. enableByRequirements(pr.getActive()) showCompatibleAddons(pr.getActive()) # Only the defaults profile has the General category. if pr.getActive() is pr.getDefaults(): wasIt = (categoryArea.getSelectedTab() == 'game-options') categoryArea.showTab('general-options') categoryArea.showTab('game-options', False) if wasIt: categoryArea.selectTab('general-options') else: wasIt = (categoryArea.getSelectedTab() == 'general-options') categoryArea.showTab('game-options') categoryArea.showTab('general-options', False) if wasIt: categoryArea.selectTab('game-options') categoryArea.updateIcon('game-options') elif event.hasId('addon-database-reloaded'): # Since the new addon will most likely introduce new settings, # we'll need to recreate the all the settings tabs. createWidgets() # The newly-created widgets don't have any data in them. Make # them refresh their values. pr.refresh()
def onChange(self, ev): """Handle the wxWidgets event that is sent when the contents of the field changes.""" if self.widgetId: if self.getWxWidget().IsInBounds(): v = ev.GetValue() if v is not None: newValue = str(v) else: newValue = '' else: newValue = None self.reactToNotify = False if newValue == None: pr.getActive().removeValue(self.widgetId) else: pr.getActive().setValue(self.widgetId, newValue) self.reactToNotify = True # Notification about the change. events.sendAfter(events.EditNotify(self.widgetId, newValue))
def notifyHandler(event): if summaryDisabled: return if event.hasId('active-profile-changed'): p = pr.getActive() titleLabel.setText(p.getName()) # Update the summary entries. updateSummary(p) # Change to the Summary tab automatically. if event.hasId('active-profile-changed') and \ st.getSystemBoolean('summary-profile-change-autoselect'): if event.wasChanged(): # The profile did actually change. ui.selectTab(SUMMARY) elif event.hasId('value-changed') or \ event.hasId('addon-attached') or \ event.hasId('addon-detached'): # Resummarize due to a changed value of a setting. updateSummary(pr.getActive())
def refreshList(): """Fill the maps list with addons.""" # Clear the list. mapListBox.clear() wads = [a for a in ao.getAvailableAddons(pr.getActive()) if a.getType() == 'addon-type-wad' and a.isPWAD()] # Translate addon names. wads.sort(lambda a, b: cmp(a.getId(), b.getId())) for wad in wads: # TODO: More information titles. if not language.isDefined(wad.getId()): visibleName = language.translate(wad.getId()) else: visibleName = os.path.basename(wad.getContentPath()) mapListBox.addItemWithColumns(wad.getId(), 0, visibleName, wad.getShortContentAnalysis()) prof = pr.getActive() usedAddons = prof.getUsedAddons() theFirst = True # Select the addons currently attached to the profile. # Also make sure the first one is visible. for addonId in usedAddons: mapListBox.selectItem(addonId) mapListBox.setItemImage(addonId, 1) if theFirst: # Make sure it's visible. mapListBox.ensureVisible(addonId) theFirst = False
def __getPresentation(self, tabId): """Compose the HTML presentation for a tab identifier. @return HTML content as a string. """ # Kludge for the game-options icon. There should be a way to # map the icon more flexibly so this hardcoding wouldn't be # needed. if tabId == 'game-options': game = 'game-jdoom' if pr.getActive(): for c in pr.getActive().getComponents(): if c[:5] == 'game-': game = c break imageName = language.translate(game + '-icon') else: imageName = language.translate(tabId + '-icon') return ('<table width="100%" border=0 cellspacing=3 cellpadding=1>' + '<tr><td width=35><img width=32 height=32 ' + 'src="%s"></td><td align="left" valign="center">%s</td>' % (paths.findBitmap(imageName), language.translate(tabId)) + '</tr></table>')
def onTextChange(self, ev): """Handle the wxWidgets event that occurs when the contents of the field are updated (for any reason). @param ev wxWidgets event. """ if self.willNotify and self.widgetId: newText = self.getWxWidget().GetValue() if not self.validator(newText): # The new text is not valid. Nothing will be done. return self.reactToNotify = False if not len(newText): pr.getActive().removeValue(self.widgetId) else: pr.getActive().setValue(self.widgetId, newText) self.reactToNotify = True # Send a notification. events.sendAfter(events.EditNotify(self.widgetId, newText)) self.react()
def refreshList(): """Fill the maps list with addons.""" # Clear the list. mapListBox.clear() wads = [ a for a in ao.getAvailableAddons(pr.getActive()) if a.getType() == 'addon-type-wad' and a.isPWAD() ] # Translate addon names. wads.sort(lambda a, b: cmp(a.getId(), b.getId())) for wad in wads: # TODO: More information titles. if not language.isDefined(wad.getId()): visibleName = language.translate(wad.getId()) else: visibleName = os.path.basename(wad.getContentPath()) mapListBox.addItemWithColumns(wad.getId(), 0, visibleName, wad.getShortContentAnalysis()) prof = pr.getActive() usedAddons = prof.getUsedAddons() theFirst = True # Select the addons currently attached to the profile. # Also make sure the first one is visible. for addonId in usedAddons: mapListBox.selectItem(addonId) mapListBox.setItemImage(addonId, 1) if theFirst: # Make sure it's visible. mapListBox.ensureVisible(addonId) theFirst = False
def onNotify(self, event): base.Widget.onNotify(self, event) if self.widgetId: if self.reactToNotify and event.hasId(self.widgetId + '-value-changed'): # This is our value. if event.getValue() != None: self.setValue(int(event.getValue())) else: self.setValue(None) elif event.hasId('active-profile-changed'): # Get the value for the setting as it has been defined # in the currently active profile. value = pr.getActive().getValue(self.widgetId, False) if value and value.getValue() != '': self.setValue(int(value.getValue())) else: self.setValue(None)
def onNotify(self, event): """Handle notifications. When the active profile changes, the check box's state is updated.""" base.Widget.onNotify(self, event) if self.widgetId: w = self.getWxWidget() if event.hasId('active-profile-changed'): self.getFromProfile(pr.getActive()) elif event.hasId(self.widgetId + '-value-changed'): if event.getValue() == 'yes': w.Set3StateValue(wx.CHK_CHECKED) elif event.getValue() == 'no': w.Set3StateValue(wx.CHK_UNCHECKED) elif event.getValue() is None: w.Set3StateValue(wx.CHK_UNDETERMINED) self.updateState()
def retranslate(self): """Update all the items in the tree.""" if pr.getActive(): pass
def runWizard(): """Run the wizard dialog.""" # Make sure the help panel isn't updated during the wizard. #events.send(events.Command('freeze')) suggested = { 'doom1': 'DOOM.WAD', 'doom1-share': 'DOOM1.WAD', 'doom1-ultimate': 'DOOM.WAD', 'doom2': 'DOOM2.WAD', 'doom2-tnt': 'TNT.WAD', 'doom2-plut': 'PLUTONIA.WAD', 'heretic-ext': 'HERETIC.WAD', 'heretic-share': 'HERETIC.WAD', 'heretic': 'HERETIC.WAD', 'hexen': 'HEXEN.WAD', 'hexen-demo': 'HEXEN.WAD', 'hexen-dk': 'HEXEN.WAD', 'hacx': 'HACX.WAD', 'chex': 'CHEX.WAD' } events.mute() # Make the Defaults profile active. pr.setActive(pr.getDefaults()) wiz = WizardDialog(language.translate('setup-wizard'), paths.findBitmap('wizard')) # Language selection page. langPage = WizardPage(wiz, 'wizard-language') area = langPage.getArea() area.createText('wizard-language-explanation', maxLineLength=65).resizeToBestSize() sar, languageCheckBox = area.createSetting(st.getSetting('language')) languageCheckBox.getFromProfile(pr.getActive()) # Game selection. gamePage = ProfileWizardPage(wiz, 'wizard-games', None) gamePage.follows(langPage) area = gamePage.getArea() area.createText('wizard-select-games', maxLineLength=65).resizeToBestSize() area.setBorderDirs(ui.BORDER_NOT_BOTTOM) games = area.createList('', style=sb.widget.list.List.STYLE_CHECKBOX) area.setBorderDirs(ui.BORDER_NOT_TOP) games.setMinSize(50, 180) gamePage.setGameList(games) def allGames(): # Check the entire list. for item in games.getItems(): games.checkItem(item, True) def clearGames(): # Uncheck the entire list. for item in games.getItems(): games.checkItem(item, False) controls = area.createArea(alignment=ui.ALIGN_HORIZONTAL, border=2) controls.setWeight(0) button = controls.createButton('wizard-games-all', wb.Button.STYLE_MINI) button.addReaction(allGames) button.resizeToBestSize() button = controls.createButton('wizard-games-clear', wb.Button.STYLE_MINI) button.addReaction(clearGames) button.resizeToBestSize() # The pages will be linked together. previousPage = gamePage deathKingsWad = None # We'll do this dynamically. checkedProfiles = ['doom1', 'doom2', 'heretic', 'hexen'] # Only display the system profiles in the wizard (not any user # profiles). profiles = pr.getProfiles(lambda p: p.isSystemProfile()) for p in profiles: if p is not pr.getDefaults(): games.addItem(p.getId(), p.getId() in checkedProfiles) # Create a page for the profile. page = ProfileWizardPage(wiz, p.getId(), games) # Link the pages together. page.follows(previousPage) previousPage = page area = page.getArea() area.createText('wizard-locate-iwad', maxLineLength=65).resizeToBestSize() # The suggestion. if suggested.has_key(p.getId()): sugArea = area.createArea(alignment=ui.ALIGN_HORIZONTAL, border=2) sugArea.setExpanding(False) sugArea.setWeight(1) sugArea.createText('wizard-suggested-iwad', ':', align=wt.Text.RIGHT) sugArea.setWeight(2) sug = sugArea.createText('') sug.setText(suggested[p.getId()]) sar, page.iwadText = area.createSetting(st.getSetting('iwad')) if p.getId() == 'hexen-dk': area.setBorder(12, ui.BORDER_ALL) area.createLine() area.setBorder(6, ui.BORDER_ALL) area.createText('deathkings-selection-title').setHeadingStyle() # Death Kings is an extension to Hexen. It uses the # same Hexen IWAD, but also an addon IWAD. area.createText('wizard-locate-iwad-deathkings', maxLineLength=65).resizeToBestSize() entry = area.createArea(alignment=ui.ALIGN_HORIZONTAL, border=4) entry.setExpanding(False) entry.setWeight(1) entry.setBorderDirs(ui.BORDER_NOT_LEFT) deathKingsWad = entry.createTextField('') entry.setWeight(0) entry.setBorderDirs(ui.BORDER_TOP_BOTTOM) browseButton = entry.createButton('browse-button', wb.Button.STYLE_MINI) def browseDeathKings(): # Open a file browser. selection = sb.util.dialog.chooseFile('deathkings-selection-title', '', True, [('file-type-wad', 'wad')]) if len(selection) > 0: deathKingsWad.setText(selection) browseButton.addReaction(browseDeathKings) # Addon paths. pathsPage = ProfileWizardPage(wiz, 'wizard-addon-paths', games) pathsPage.follows(previousPage) area = pathsPage.getArea() area.createText('wizard-addon-paths-explanation', maxLineLength=65).resizeToBestSize() area.setBorderDirs(ui.BORDER_NOT_BOTTOM) pathList = area.createList('addon-paths-list') pathList.setMinSize(100, 120) # Insert the current custom paths into the list. for p in paths.getAddonPaths(): pathList.addItem(p) def addAddonPath(): selection = sb.util.dialog.chooseFolder('addon-paths-add-prompt', '') if selection: pathList.addItem(selection) pathList.selectItem(selection) def removeAddonPath(): selection = pathList.getSelectedItem() if selection: pathList.removeItem(selection) area.setWeight(0) area.setBorderDirs(ui.BORDER_NOT_TOP) commands = area.createArea(alignment=ui.ALIGN_HORIZONTAL, border=2) commands.setWeight(0) # Button for adding new paths. button = commands.createButton('new-addon-path', wb.Button.STYLE_MINI) button.addReaction(addAddonPath) # Button for removing a path. button = commands.createButton('delete-addon-path', wb.Button.STYLE_MINI) button.addReaction(removeAddonPath) # Launch options. quitPage = WizardPage(wiz, 'wizard-launching') quitPage.follows(pathsPage) area = quitPage.getArea() area.createText('wizard-launching-explanation').resizeToBestSize() sar, quitCheckBox = area.createSetting(st.getSetting('quit-on-launch')) quitCheckBox.getFromProfile(pr.getActive()) # List of unusable profiles, due to a missing IWAD. unusableProfiles = [] # When the page changes in the wizard, change the active profile. def changeActiveProfile(page): prof = pr.get(page.getId()) if prof: pr.setActive(prof) else: pr.setActive(pr.getDefaults()) # Update page with values from the current profile. page.update() wiz.setPageReaction(changeActiveProfile) if wiz.run(langPage) == 'ok': events.unmute() # Show the profiles that now have an IWAD. for prof in profiles: if prof.getValue('iwad', False) != None: pr.show(prof.getId()) if prof.getId() in unusableProfiles: unusableProfiles.remove(prof.getId()) else: pr.hide(prof.getId()) if prof.getId() not in unusableProfiles and \ prof.getId() in games.getSelectedItems(): unusableProfiles.append(prof.getId()) # Install the Death Kings WAD? if deathKingsWad: try: ident = ao.install(deathKingsWad.getText()) # Attach the WAD as an addon. kingsProfile = pr.get('hexen-dk') kingsProfile.useAddon(ident) except: # TODO: Handle error. pass # Update custom addon paths. currentAddonPaths = paths.getAddonPaths() wasModified = False for path in pathList.getItems(): if path not in currentAddonPaths: paths.addAddonPath(path) wasModified = True for path in currentAddonPaths: if path not in pathList.getItems(): paths.removeAddonPath(path) wasModified = True if wasModified: # Load addons from new paths. ao.refresh() events.send(events.Notify('addon-paths-changed')) # The wizard will only be shown once automatically. pr.getDefaults().setValue(HAS_BEEN_RUN, 'yes', False) else: # Wizard was canceled. events.unmute() pr.refresh() # This'll destroy all the pages of the wizard as well. wiz.destroy() # Enable help panel updates again. #events.send(events.Command('unfreeze')) # Tell the user about unusable profiles. if len(unusableProfiles) > 0: dialog, area = sb.util.dialog.createButtonDialog( 'wizard-unlaunchable-profiles', ['ok'], 'ok', resizable=False) # Compose a list of the unlaunchable profiles. profList = '' unusableProfiles.sort(lambda a, b: cmp(language.translate(a), language.translate(b))) for p in unusableProfiles: profList += "\n" + language.translate(p) msg = area.createText() msg.setText(language.translate('wizard-unlaunchable-profiles-listed') + "\n" + profList) msg.resizeToBestSize() dialog.run()
def notifyHandler(event): "This is called when a Notify event is broadcasted." # We are interested in notifications that concern profiles. if event.hasId('quit'): # Save the current profile configuration. pr.save() elif event.hasId('language-changed'): # Just update the Defaults, because it's the only profile whose name # is translated. addListItem(pr.getDefaults()) elif event.hasId('profile-updated'): # A profile has been loaded or updated. Make sure it's in the # list. p = event.getProfile() # The Defaults profile should be first in the list. if p is pr.getDefaults(): destIndex = 0 else: # The new profile will be added to wherever the widget # wants to put it. destIndex = None if profileList.hasItem(p.getId()): # This already exists in the list. if p.isHidden(): # Remove it completely. profileList.removeItem(p.getId()) # Update the selected item since the active one is now # hidden. pr.setActive(pr.get(profileList.getSelectedItem())) else: # Just update the item. addListItem(p) elif not p.isHidden(): # The item does not yet exist in the list. addListItem(p, toIndex=destIndex) elif event.hasId('active-profile-changed') and not profileListDisabled: # Highlight the correct profile in the list. profileList.selectItem(pr.getActive().getId()) if pr.getActive() is pr.getDefaults(): if deleteButton: deleteButton.disable() if dupeButton: dupeButton.disable() ui.disableMenuCommand('rename-profile') ui.disableMenuCommand('delete-profile') ui.disableMenuCommand('hide-profile') ui.disableMenuCommand('duplicate-profile') profileList.setPopupMenu(defaultsMenu) else: isSystem = pr.getActive().isSystemProfile() if deleteButton: deleteButton.enable(not isSystem) if dupeButton: dupeButton.enable() ui.enableMenuCommand('rename-profile') ui.enableMenuCommand('delete-profile', not isSystem) ui.enableMenuCommand('hide-profile') ui.enableMenuCommand('duplicate-profile') if isSystem: menu = systemMenu else: menu = normalMenu profileList.setPopupMenu(menu) # Update the banner image. if bannerImage: bannerImage.setImage(pr.getActive().getBanner()) elif event.hasId('profile-list-selected'): # Change the currently active profile. p = pr.get(event.getSelection()) pr.setActive(p) # Double-clicking causes a Play command. if event.isDoubleClick() and p is not pr.getDefaults(): events.sendAfter(events.Command('play'))
def handleCommand(event): """This is called when someone sends a command event. @param event An events.Command object.""" # Figure out which addon has been currently selected in the addons # tree. The action will target this addon. selected = '' if event.hasId('refresh-addon-database'): ao.refresh() elif event.hasId('install-addon'): tab30.installer.run() elif event.hasId('uninstall-addon'): selectedItems = addonList.getSelectedItems() # Only take the uninstallable addons. addons = filter(lambda i: ao.isUninstallable(i), selectedItems) if len(addons) == 0: return # Make sure the user wants to uninstall. dialog, area = sb.util.dialog.createButtonDialog( 'uninstall-addon-dialog', ['no', 'yes'], 'no', resizable=False) if len(addons) == 1: text = language.translate('uninstall-addon-query') area.setExpanding(True) area.createRichText(language.expand(text, language.translate(addons[0]))) else: area.setWeight(0) area.createText('uninstall-addon-query-several') msg = '<html><ul>' for addon in addons: msg += '<li>' + language.translate(addon) + '</li>' msg += '</ul></html>' ft = area.createFormattedText() ft.setText(msg) ft.setMinSize(400, 150) if dialog.run() == 'yes': for addon in addons: ao.uninstall(addon) ao.refresh() elif event.hasId('addon-info'): sel = addonList.getSelectedItems() if len(sel) > 0: # Show the Addon Inspector. tab30.inspector.run(ao.get(sel[0])) elif event.hasId('addon-settings'): sel = addonList.getSelectedItems() if len(sel) > 0: command = events.Command('show-addon-settings') command.addon = sel[0] events.send(command) elif event.hasId('load-order'): # Open the Load Order dialog. tab30.loadorder.run(pr.getActive()) elif event.hasId('addon-list-check-selected'): for addon in addonList.getSelectedItems(): pr.getActive().useAddon(addon) elif event.hasId('addon-list-uncheck-selected'): for addon in addonList.getSelectedItems(): pr.getActive().dontUseAddon(addon) elif event.hasId('addon-list-check-all'): for addon in addonList.getItems(): pr.getActive().useAddon(addon) elif event.hasId('addon-list-uncheck-all'): for addon in addonList.getItems(): pr.getActive().dontUseAddon(addon) elif event.hasId('addon-show-parent-box'): for addon in addonList.getSelectedItems(): a = ao.get(addon) if a.getBox(): showInAddonList(a.getBox().getId()) break elif event.hasId('addon-show-box-category'): for addon in addonList.getSelectedItems(): a = ao.get(addon) if a.getType() == 'addon-type-box': addonList.deselectAllItems() tree.selectItem(a.getContentCategoryLongId()) refreshListIfVisible() break
def showSettingInfo(setting): """Display information about the focused setting in the help panel. @param setting A settings.Setting object. """ # Values will be taken from the active profile. prof = pr.getActive() # The identifier of the setting. ident = setting.getId() msg = '<html>' # The name of the setting. msg += '<b><font size="+1">' + language.translate(ident) + \ '</font></b>' # The command line option. msg += '<br><table bgcolor="' + bgColor + '" width="100%"><tr><td>' + \ '<font size="-1"><tt>' + \ setting.getCommandLine(prof) + '</tt></font></table><p>' fromDefaults = False if prof.getValue(ident, False) == None: fromDefaults = True # The value comes from the default profile. msg += language.expand(language.translate('help-value-from-defaults'), pr.getDefaults().getName()) + '<p>' def valueToText(v): if language.isDefined(v): return language.translate(v) else: return v msg += tableBegin # The current value of the setting. value = prof.getValue(ident) if value: #msg += '<b>%s:</b><br>' % language.translate('help-value-current') #msg += valueToText(value.getValue()) #msg += '<p>' msg += tableRow + \ entryHeader(language.translate('help-value-current')) + \ entryContent(valueToText(value.getValue())) # Min and max for the range and slider settings. if setting.getType() == 'slider' or setting.getType() == 'range': #msg += '<b>' + language.translate('help-value-min') + ':</b><br>' + \ # str(setting.getMinimum()) #msg += '<p><b>' + language.translate('help-value-max') + \ # ':</b><br>' + str(setting.getMaximum()) #msg += '<p>' msg += tableRow + entryHeader(language.translate('help-value-min')) + \ entryContent(str(setting.getMinimum())) + \ tableRow + entryHeader(language.translate('help-value-max')) + \ entryContent(str(setting.getMaximum())) # The default. if prof.getValue(ident, False) != None and prof is pr.getDefaults(): if setting.getDefault() != None: #msg += '<b>%s:</b><br>' % language.translate('help-value-default') #msg += valueToText(str(setting.getDefault())) #msg += '<p>' msg += tableRow + \ entryHeader(language.translate('help-value-default')) + \ entryContent(valueToText(str(setting.getDefault()))) elif not fromDefaults and prof is not pr.getDefaults(): defValue = pr.getDefaults().getValue(ident) if defValue: #msg += '<b>%s:</b><br>' % language.translate('help-value-default') #msg += valueToText(defValue.getValue()) #msg += '<p>' msg += tableRow + \ entryHeader(language.translate('help-value-default')) + \ entryContent(valueToText(defValue.getValue())) msg += tableEnd # The help text of this setting. helpId = ident + '-help' if language.isDefined(helpId): msg += language.translate(helpId) msg += '</html>' # Display the setting information in the help panel. helpText.setText(msg) showLogo(False) # The info will be automatically updated in case it changes while # displayed. global currentSetting currentSetting = setting
def doCreateSetting(self, setting, leftWeight=SETTING_WEIGHT_LEFT, rightWeight=SETTING_WEIGHT_RIGHT): """Create one or more widgets that can be used to edit the value of the specified setting. Automatically creates a subarea that contains all the widgets of the setting. @param setting A Setting object. @return Tuple (area, widget). The area which contains all the widgets of the setting, and the main widget of the setting. """ if setting.getType() == 'implicit': # No widgets for implicit settings. return (None, None) # This is the returned main widget of the setting. mainWidget = None # Create a subarea for all the widgets of the setting. area = self.createArea(alignment=ui.ALIGN_HORIZONTAL) area.setExpanding(False) # All settings have a similarly positioned label on the left # side. area.setWeight(leftWeight) if setting.getType() != 'toggle': area.createText(setting.getId(), ':', 16, sb.widget.text.Text.RIGHT) else: # Check boxes use a secondary indicator label. label = area.createText('toggle-use-default-value', align=sb.widget.text.Text.RIGHT) area.setWeight(0) area.setBorder(2) # Space between label and setting. area.addSpacer() area.setBorder(0) # Create the actual widget(s) for the setting. area.setWeight(rightWeight) if setting.getType() == 'toggle': # Toggle settings have just a checkbox. isChecked = False if pr.getActive(): isChecked = (pr.getActive().getValue(setting.getId()). getValue() == 'yes') check = area.createCheckBox(setting.getId(), isChecked) check.setDefaultIndicator(label) mainWidget = check elif setting.getType() == 'range': nf = area.createNumberField(setting.getId()) nf.setRange(setting.getMinimum(), setting.getMaximum()) mainWidget = nf elif setting.getType() == 'slider': slider = area.createSlider(setting.getId()) slider.setRange(setting.getMinimum(), setting.getMaximum(), setting.getStep()) mainWidget = slider elif setting.getType() == 'choice': # Create a label and a drop-down list. drop = area.createDropList(setting.getId()) mainWidget = drop # Insert the choices into the list. drop.addItem('default') for a in setting.getAlternatives(): drop.addItem(a) # Sort if necessary. if setting.isSorted(): drop.sortItems() # The selection will be updated soon afterwards. drop.selectItem('default') elif setting.getType() == 'text': text = area.createTextField(setting.getId()) mainWidget = text elif setting.getType() == 'file': # Create a text field and a button. sub = area.createArea(alignment=ui.ALIGN_HORIZONTAL, border=0) sub.setWeight(1) text = sub.createTextField(setting.getId()) mainWidget = text sub.setWeight(0) sub.setBorder(4, ui.BORDER_LEFT) browseButton = sub.createButton('browse-button', style=sb.widget.button.Button.STYLE_MINI) def browseAction(): # Open a file browser for selecting the value for a file # setting. settingId = setting.getId() value = pr.getActive().getValue(settingId) if not value: currentValue = '' else: currentValue = value.getValue() selection = sb.util.dialog.chooseFile( settingId + '-selection-title', currentValue, setting.hasToExist(), setting.getAllowedTypes()) if len(selection) > 0: pr.getActive().setValue(settingId, selection) if events.isMuted(): # Update manually. text.getFromProfile(pr.getActive()) browseButton.addReaction(browseAction) # If the file must exist, don't accept nonexistent files. if setting.hasToExist(): text.setValidator(lambda fileName: os.path.exists(fileName)) elif setting.getType() == 'folder': # Create a text field and a button, like with a file setting. sub = area.createArea(alignment=ui.ALIGN_HORIZONTAL, border=0) sub.setWeight(1) text = sub.createTextField(setting.getId()) mainWidget = text sub.setWeight(0) browseButton = sub.createButton('browse-button', style=sb.widget.button.Button.STYLE_MINI) def folderBrowseAction(): # Open a folder browser for selecting the value for a file # setting. settingId = setting.getId() value = pr.getActive().getValue(settingId) if not value: currentValue = '' else: currentValue = value.getValue() selection = sb.util.dialog.chooseFolder(settingId + '-selection-title', currentValue) if len(selection) > 0: pr.getActive().setValue(settingId, selection) browseButton.addReaction(folderBrowseAction) # If the file must exist, don't accept nonexistent files. if setting.hasToExist(): text.setValidator(lambda fileName: os.path.exists(fileName)) return (area, mainWidget)
def handleNotification(event): """This is called when someone sends a notification event. @param event An events.Notify object. """ global tabVisible global mustRefreshList if event.hasId('addon-list-icon-click'): # Clicking on the list icon will attach/detach the addon. profile = pr.getActive() if event.item in profile.getUsedAddons(): profile.dontUseAddon(event.item) else: profile.useAddon(event.item) elif event.hasId('addon-attached') or event.hasId('addon-detached'): refreshItemInList(event.getAddon()) elif event.hasId('addon-list-filter-mode-selected'): refreshListIfVisible() elif event.hasId('addon-list-check-column-click') or \ event.hasId('addon-list-name-column-click') or \ event.hasId('addon-list-version-column-click'): global listSortMode if 'check' in event.getId(): listSortMode = 'check' elif 'version' in event.getId(): listSortMode = 'version' else: listSortMode = 'name' sortList() elif event.hasId('tab-selected'): # If there is a refresh pending, do it now that the tab has # been selected. if event.getSelection() == ADDONS: tabVisible = True if mustRefreshList: refreshList() else: tabVisible = False elif event.hasId('active-profile-changed'): refreshListIfVisible() # Fill the tree with an updated listing of addons. #tree.populateWithAddons(pr.getActive()) #settingsButton.disable() elif event.hasId('addon-list-popup-update-request'): # The addon list is requesting an updated popup menu. # Menu items depend on which items are selected. items = addonList.getSelectedItems() menu = [] if len(items) == 1: # One addon is selected. if ao.get(items[0]).getBox(): menu += ['addon-show-parent-box'] if ao.get(items[0]).getType() == 'addon-type-box': menu += ['addon-show-box-category'] # Info is always available for all addons. menu += ['addon-info'] if st.haveSettingsForAddon(items[0]): menu += ['addon-settings'] elif len(items) > 1: # Multiple addons selected. menu += [ 'addon-list-check-selected', 'addon-list-uncheck-selected' ] if len(items) > 0: menu += ['uninstall-addon'] # Append the common items. if len(menu) > 0: menu.append('-') menu += ['install-addon'] menu += ['load-order'] menu += ['-', 'addon-list-check-all', 'addon-list-uncheck-all'] addonList.setPopupMenu(menu) elif event.hasId('category-tree-selected'): refreshListIfVisible() # Enable the settings button if there are settings for this # addon. #if st.haveSettingsForAddon(event.getSelection()): # settingsButton.enable() #else: # settingsButton.disable() # Can this be uninstalled? #uninstallButton.enable(ao.exists(event.getSelection()) and # ao.get(event.getSelection()).getBox() == None) elif event.hasId('addon-list-selected') or event.hasId( 'addon-list-deselected'): updateButtons() elif event.hasId('addon-installed'): refreshCategories() refreshListIfVisible() #tree.selectAddon(event.addon) elif event.hasId('addon-database-reloaded'): refreshCategories() refreshListIfVisible()
def commandHandler(event): """This is called when a Command event is broadcasted.""" global profileListDisabled if event.hasId('freeze'): profileListDisabled = True elif event.hasId('unfreeze'): profileListDisabled = False #notifyHandler(events.Notify('active-profile-changed')) pr.refresh() elif event.hasId('new-profile'): dialog, area = sb.util.dialog.createButtonDialog('new-profile-dialog', ['cancel', 'ok'], 'ok', resizable=False) dialog.disableWidget('ok') entry = area.createArea(alignment=ALIGN_HORIZONTAL) entry.setExpanding(False) # The name of the profile. entry.setWeight(1) entry.setBorder(4, ui.BORDER_RIGHT) entry.createText('new-profile-name', ':', align=wt.Text.RIGHT) entry.setBorder(0) entry.setWeight(2) nameField = entry.createTextField('') nameField.focus() # Only enable the OK button if there is something in the name field. def buttonEnabler(): dialog.enableWidget('ok', len(nameField.getText()) > 0) nameField.addReaction(buttonEnabler) # The game component. entry = area.createArea(alignment=ALIGN_HORIZONTAL) entry.setExpanding(False) entry.setWeight(1) entry.setBorder(4, ui.BORDER_RIGHT) entry.createText('new-profile-game', ':', align=wt.Text.RIGHT) entry.setBorder(0) entry.setWeight(2) gameDrop = entry.createDropList('') for game in st.getGameComponents(): gameDrop.addItem(game.getId()) gameDrop.sortItems() # Select the first one. gameDrop.selectItem(gameDrop.getItems()[0]) if dialog.run() == 'ok': # Get the values from the controls. pr.create(nameField.getText(), gameDrop.getSelectedItem()) elif event.hasId('rename-profile'): dialog, area = sb.util.dialog.createButtonDialog( 'rename-profile-dialog', ['cancel', 'ok'], 'ok', resizable=False) prof = pr.getActive() # A text field of the new name. entry = area.createArea(alignment=ALIGN_HORIZONTAL) entry.setExpanding(False) # The name of the profile. entry.setWeight(1) entry.setBorder(4, ui.BORDER_RIGHT) entry.createText('rename-profile-name', ':', align=wt.Text.RIGHT) entry.setBorder(0) entry.setWeight(2) nameField = entry.createTextField('') nameField.setText(prof.getName()) nameField.focus() # Only enable the OK button if there is something in the name # field. def buttonEnabler(): dialog.enableWidget('ok', len(nameField.getText()) > 0) nameField.addReaction(buttonEnabler) if dialog.run() == 'ok': prof.setName(nameField.getText()) # The profile list needs to be updated, too. events.send(events.ProfileNotify(prof)) pr.refresh() elif event.hasId('reset-profile'): dialog, area = sb.util.dialog.createButtonDialog( 'reset-profile-dialog', [ 'cancel', 'reset-profile-values', 'reset-profile-addons', 'reset-profile-everything' ], 'cancel', resizable=False) text = language.translate('reset-profile-query') message = area.createRichText( language.expand(text, pr.getActive().getName())) # Accept these as dialog-closing commands. dialog.addEndCommand('reset-profile-values') dialog.addEndCommand('reset-profile-addons') dialog.addEndCommand('reset-profile-everything') result = dialog.run() if result == 'cancel': return resetValues = True resetAddons = True if result == 'reset-profile-values': resetAddons = False elif result == 'reset-profile-addons': resetValues = False pr.reset(pr.getActive().getId(), resetValues, resetAddons) pr.refresh() elif event.hasId('delete-profile'): # If this is a system profile, just hide it. if pr.getActive().isSystemProfile(): pr.hide(pr.getActive().getId()) return dialog, area = sb.util.dialog.createButtonDialog( 'delete-profile-dialog', ['no', 'yes'], 'no', resizable=False) text = language.translate('delete-profile-query') area.createRichText(language.expand(text, pr.getActive().getName())) if dialog.run() == 'yes': # Get the values from the controls. pr.remove(pr.getActive().getId()) elif event.hasId('duplicate-profile'): dialog, area = sb.util.dialog.createButtonDialog( 'duplicate-profile-dialog', ['cancel', 'ok'], 'ok', resizable=False) text = language.translate('duplicating-profile') area.setWeight(1) area.createRichText(language.expand(text, pr.getActive().getName())) area.setWeight(1) entry = area.createArea(alignment=ALIGN_HORIZONTAL) entry.setExpanding(False) # The name of the profile. entry.setWeight(1) entry.setBorder(4, ui.BORDER_RIGHT) entry.createText('new-profile-name', ':', align=wt.Text.RIGHT) entry.setBorder(0) entry.setWeight(3) nameField = entry.createTextField('') nameField.setText(pr.getActive().getName()) nameField.focus() # Only enable the OK button if there is something in the name field. def buttonEnabler(): dialog.enableWidget('ok', len(nameField.getText()) > 0) nameField.addReaction(buttonEnabler) if dialog.run() == 'ok': pr.duplicate(pr.getActive().getId(), nameField.getText()) elif event.hasId('hide-profile'): pr.hide(pr.getActive().getId()) elif event.hasId('unhide-profiles'): # Display a dialog bog for unhiding hidden profiles. hiddenProfiles = pr.getProfiles(lambda p: p.isHidden()) dialog, area = sb.util.dialog.createButtonDialog( 'unhide-profile-dialog', ['cancel', 'ok'], 'ok', resizable=False) area.setWeight(0) area.createText('unhiding-profiles') area.setWeight(3) area.setBorder(0) profList = area.createList('', sb.widget.list.List.STYLE_CHECKBOX) profList.setMinSize(50, 150) def selectAll(): # Check the entire list. for item in profList.getItems(): profList.checkItem(item, True) def clearAll(): # Uncheck the entire list. for item in profList.getItems(): profList.checkItem(item, False) area.setWeight(0) controls = area.createArea(alignment=ALIGN_HORIZONTAL, border=2) controls.setWeight(0) button = controls.createButton( 'unhide-select-all', style=sb.widget.button.Button.STYLE_MINI) button.addReaction(selectAll) button.resizeToBestSize() button = controls.createButton( 'unhide-clear-all', style=sb.widget.button.Button.STYLE_MINI) button.addReaction(clearAll) button.resizeToBestSize() for prof in hiddenProfiles: profList.addItem(prof.getId()) if dialog.run() == 'ok': # Unhide all the selected items. selected = profList.getSelectedItems() for sel in selected: pr.show(sel) if len(selected): # Select the first one that was shown. pr.setActive(pr.get(selected[0]))
def showSettingInfo(setting): """Display information about the focused setting in the help panel. @param setting A settings.Setting object. """ # Values will be taken from the active profile. prof = pr.getActive() # The identifier of the setting. ident = setting.getId() msg = '<html>' # The name of the setting. msg += '<b><font size="+1">' + language.translate(ident) + \ '</font></b>' # The command line option. msg += '<br><table bgcolor="' + bgColor + '" width="100%"><tr><td>' + \ '<font size="-1"><tt>' + \ setting.getCommandLine(prof) + '</tt></font></table><p>' fromDefaults = False if prof.getValue(ident, False) == None: fromDefaults = True # The value comes from the default profile. msg += language.expand( language.translate('help-value-from-defaults'), pr.getDefaults().getName()) + '<p>' def valueToText(v): if language.isDefined(v): return language.translate(v) else: return v msg += tableBegin # The current value of the setting. value = prof.getValue(ident) if value: #msg += '<b>%s:</b><br>' % language.translate('help-value-current') #msg += valueToText(value.getValue()) #msg += '<p>' msg += tableRow + \ entryHeader(language.translate('help-value-current')) + \ entryContent(valueToText(value.getValue())) # Min and max for the range and slider settings. if setting.getType() == 'slider' or setting.getType() == 'range': #msg += '<b>' + language.translate('help-value-min') + ':</b><br>' + \ # str(setting.getMinimum()) #msg += '<p><b>' + language.translate('help-value-max') + \ # ':</b><br>' + str(setting.getMaximum()) #msg += '<p>' msg += tableRow + entryHeader(language.translate('help-value-min')) + \ entryContent(str(setting.getMinimum())) + \ tableRow + entryHeader(language.translate('help-value-max')) + \ entryContent(str(setting.getMaximum())) # The default. if prof.getValue(ident, False) != None and prof is pr.getDefaults(): if setting.getDefault() != None: #msg += '<b>%s:</b><br>' % language.translate('help-value-default') #msg += valueToText(str(setting.getDefault())) #msg += '<p>' msg += tableRow + \ entryHeader(language.translate('help-value-default')) + \ entryContent(valueToText(str(setting.getDefault()))) elif not fromDefaults and prof is not pr.getDefaults(): defValue = pr.getDefaults().getValue(ident) if defValue: #msg += '<b>%s:</b><br>' % language.translate('help-value-default') #msg += valueToText(defValue.getValue()) #msg += '<p>' msg += tableRow + \ entryHeader(language.translate('help-value-default')) + \ entryContent(valueToText(defValue.getValue())) msg += tableEnd # The help text of this setting. helpId = ident + '-help' if language.isDefined(helpId): msg += language.translate(helpId) msg += '</html>' # Display the setting information in the help panel. helpText.setText(msg) showLogo(False) # The info will be automatically updated in case it changes while # displayed. global currentSetting currentSetting = setting
def __getValueFromProfile(self): # Get the value for the setting as it has been defined # in the currently active profile. value = pr.getActive().getValue(self.widgetId) if value: self.setValue(int(value.getValue()))
def handleCommand(event): """This is called when someone sends a command event. @param event An events.Command object.""" # Figure out which addon has been currently selected in the addons # tree. The action will target this addon. selected = '' if event.hasId('refresh-addon-database'): ao.refresh() elif event.hasId('install-addon'): tab30.installer.run() elif event.hasId('uninstall-addon'): selectedItems = addonList.getSelectedItems() # Only take the uninstallable addons. addons = filter(lambda i: ao.isUninstallable(i), selectedItems) if len(addons) == 0: return # Make sure the user wants to uninstall. dialog, area = sb.util.dialog.createButtonDialog( 'uninstall-addon-dialog', ['no', 'yes'], 'no', resizable=False) if len(addons) == 1: text = language.translate('uninstall-addon-query') area.setExpanding(True) area.createRichText( language.expand(text, language.translate(addons[0]))) else: area.setWeight(0) area.createText('uninstall-addon-query-several') msg = '<html><ul>' for addon in addons: msg += '<li>' + language.translate(addon) + '</li>' msg += '</ul></html>' ft = area.createFormattedText() ft.setText(msg) ft.setMinSize(400, 150) if dialog.run() == 'yes': for addon in addons: ao.uninstall(addon) ao.refresh() elif event.hasId('addon-info'): sel = addonList.getSelectedItems() if len(sel) > 0: # Show the Addon Inspector. tab30.inspector.run(ao.get(sel[0])) elif event.hasId('addon-settings'): sel = addonList.getSelectedItems() if len(sel) > 0: command = events.Command('show-addon-settings') command.addon = sel[0] events.send(command) elif event.hasId('load-order'): # Open the Load Order dialog. tab30.loadorder.run(pr.getActive()) elif event.hasId('addon-list-check-selected'): for addon in addonList.getSelectedItems(): pr.getActive().useAddon(addon) elif event.hasId('addon-list-uncheck-selected'): for addon in addonList.getSelectedItems(): pr.getActive().dontUseAddon(addon) elif event.hasId('addon-list-check-all'): for addon in addonList.getItems(): pr.getActive().useAddon(addon) elif event.hasId('addon-list-uncheck-all'): for addon in addonList.getItems(): pr.getActive().dontUseAddon(addon) elif event.hasId('addon-show-parent-box'): for addon in addonList.getSelectedItems(): a = ao.get(addon) if a.getBox(): showInAddonList(a.getBox().getId()) break elif event.hasId('addon-show-box-category'): for addon in addonList.getSelectedItems(): a = ao.get(addon) if a.getType() == 'addon-type-box': addonList.deselectAllItems() tree.selectItem(a.getContentCategoryLongId()) refreshListIfVisible() break
def commandHandler(event): """This is called when a Command event is broadcasted.""" global profileListDisabled if event.hasId("freeze"): profileListDisabled = True elif event.hasId("unfreeze"): profileListDisabled = False # notifyHandler(events.Notify('active-profile-changed')) pr.refresh() elif event.hasId("new-profile"): dialog, area = sb.util.dialog.createButtonDialog("new-profile-dialog", ["cancel", "ok"], "ok", resizable=False) dialog.disableWidget("ok") entry = area.createArea(alignment=ALIGN_HORIZONTAL) entry.setExpanding(False) # The name of the profile. entry.setWeight(1) entry.setBorder(4, ui.BORDER_RIGHT) entry.createText("new-profile-name", ":", align=wt.Text.RIGHT) entry.setBorder(0) entry.setWeight(2) nameField = entry.createTextField("") nameField.focus() # Only enable the OK button if there is something in the name field. def buttonEnabler(): dialog.enableWidget("ok", len(nameField.getText()) > 0) nameField.addReaction(buttonEnabler) # The game component. entry = area.createArea(alignment=ALIGN_HORIZONTAL) entry.setExpanding(False) entry.setWeight(1) entry.setBorder(4, ui.BORDER_RIGHT) entry.createText("new-profile-game", ":", align=wt.Text.RIGHT) entry.setBorder(0) entry.setWeight(2) gameDrop = entry.createDropList("") for game in st.getGameComponents(): gameDrop.addItem(game.getId()) gameDrop.sortItems() # Select the first one. gameDrop.selectItem(gameDrop.getItems()[0]) if dialog.run() == "ok": # Get the values from the controls. pr.create(nameField.getText(), gameDrop.getSelectedItem()) elif event.hasId("rename-profile"): dialog, area = sb.util.dialog.createButtonDialog( "rename-profile-dialog", ["cancel", "ok"], "ok", resizable=False ) prof = pr.getActive() # A text field of the new name. entry = area.createArea(alignment=ALIGN_HORIZONTAL) entry.setExpanding(False) # The name of the profile. entry.setWeight(1) entry.setBorder(4, ui.BORDER_RIGHT) entry.createText("rename-profile-name", ":", align=wt.Text.RIGHT) entry.setBorder(0) entry.setWeight(2) nameField = entry.createTextField("") nameField.setText(prof.getName()) nameField.focus() # Only enable the OK button if there is something in the name # field. def buttonEnabler(): dialog.enableWidget("ok", len(nameField.getText()) > 0) nameField.addReaction(buttonEnabler) if dialog.run() == "ok": prof.setName(nameField.getText()) # The profile list needs to be updated, too. events.send(events.ProfileNotify(prof)) pr.refresh() elif event.hasId("reset-profile"): dialog, area = sb.util.dialog.createButtonDialog( "reset-profile-dialog", ["cancel", "reset-profile-values", "reset-profile-addons", "reset-profile-everything"], "cancel", resizable=False, ) text = language.translate("reset-profile-query") message = area.createRichText(language.expand(text, pr.getActive().getName())) # Accept these as dialog-closing commands. dialog.addEndCommand("reset-profile-values") dialog.addEndCommand("reset-profile-addons") dialog.addEndCommand("reset-profile-everything") result = dialog.run() if result == "cancel": return resetValues = True resetAddons = True if result == "reset-profile-values": resetAddons = False elif result == "reset-profile-addons": resetValues = False pr.reset(pr.getActive().getId(), resetValues, resetAddons) pr.refresh() elif event.hasId("delete-profile"): # If this is a system profile, just hide it. if pr.getActive().isSystemProfile(): pr.hide(pr.getActive().getId()) return dialog, area = sb.util.dialog.createButtonDialog("delete-profile-dialog", ["no", "yes"], "no", resizable=False) text = language.translate("delete-profile-query") area.createRichText(language.expand(text, pr.getActive().getName())) if dialog.run() == "yes": # Get the values from the controls. pr.remove(pr.getActive().getId()) elif event.hasId("duplicate-profile"): dialog, area = sb.util.dialog.createButtonDialog( "duplicate-profile-dialog", ["cancel", "ok"], "ok", resizable=False ) text = language.translate("duplicating-profile") area.setWeight(1) area.createRichText(language.expand(text, pr.getActive().getName())) area.setWeight(1) entry = area.createArea(alignment=ALIGN_HORIZONTAL) entry.setExpanding(False) # The name of the profile. entry.setWeight(1) entry.setBorder(4, ui.BORDER_RIGHT) entry.createText("new-profile-name", ":", align=wt.Text.RIGHT) entry.setBorder(0) entry.setWeight(3) nameField = entry.createTextField("") nameField.setText(pr.getActive().getName()) nameField.focus() # Only enable the OK button if there is something in the name field. def buttonEnabler(): dialog.enableWidget("ok", len(nameField.getText()) > 0) nameField.addReaction(buttonEnabler) if dialog.run() == "ok": pr.duplicate(pr.getActive().getId(), nameField.getText()) elif event.hasId("hide-profile"): pr.hide(pr.getActive().getId()) elif event.hasId("unhide-profiles"): # Display a dialog bog for unhiding hidden profiles. hiddenProfiles = pr.getProfiles(lambda p: p.isHidden()) dialog, area = sb.util.dialog.createButtonDialog( "unhide-profile-dialog", ["cancel", "ok"], "ok", resizable=False ) area.setWeight(0) area.createText("unhiding-profiles") area.setWeight(3) area.setBorder(0) profList = area.createList("", sb.widget.list.List.STYLE_CHECKBOX) profList.setMinSize(50, 150) def selectAll(): # Check the entire list. for item in profList.getItems(): profList.checkItem(item, True) def clearAll(): # Uncheck the entire list. for item in profList.getItems(): profList.checkItem(item, False) area.setWeight(0) controls = area.createArea(alignment=ALIGN_HORIZONTAL, border=2) controls.setWeight(0) button = controls.createButton("unhide-select-all", style=sb.widget.button.Button.STYLE_MINI) button.addReaction(selectAll) button.resizeToBestSize() button = controls.createButton("unhide-clear-all", style=sb.widget.button.Button.STYLE_MINI) button.addReaction(clearAll) button.resizeToBestSize() for prof in hiddenProfiles: profList.addItem(prof.getId()) if dialog.run() == "ok": # Unhide all the selected items. selected = profList.getSelectedItems() for sel in selected: pr.show(sel) if len(selected): # Select the first one that was shown. pr.setActive(pr.get(selected[0]))
def notifyHandler(event): "This is called when a Notify event is broadcasted." # We are interested in notifications that concern profiles. if event.hasId("quit"): # Save the current profile configuration. pr.save() elif event.hasId("language-changed"): # Just update the Defaults, because it's the only profile whose name # is translated. addListItem(pr.getDefaults()) elif event.hasId("profile-updated"): # A profile has been loaded or updated. Make sure it's in the # list. p = event.getProfile() # The Defaults profile should be first in the list. if p is pr.getDefaults(): destIndex = 0 else: # The new profile will be added to wherever the widget # wants to put it. destIndex = None if profileList.hasItem(p.getId()): # This already exists in the list. if p.isHidden(): # Remove it completely. profileList.removeItem(p.getId()) # Update the selected item since the active one is now # hidden. pr.setActive(pr.get(profileList.getSelectedItem())) else: # Just update the item. addListItem(p) elif not p.isHidden(): # The item does not yet exist in the list. addListItem(p, toIndex=destIndex) elif event.hasId("active-profile-changed") and not profileListDisabled: # Highlight the correct profile in the list. profileList.selectItem(pr.getActive().getId()) if pr.getActive() is pr.getDefaults(): if deleteButton: deleteButton.disable() if dupeButton: dupeButton.disable() ui.disableMenuCommand("rename-profile") ui.disableMenuCommand("delete-profile") ui.disableMenuCommand("hide-profile") ui.disableMenuCommand("duplicate-profile") profileList.setPopupMenu(defaultsMenu) else: isSystem = pr.getActive().isSystemProfile() if deleteButton: deleteButton.enable(not isSystem) if dupeButton: dupeButton.enable() ui.enableMenuCommand("rename-profile") ui.enableMenuCommand("delete-profile", not isSystem) ui.enableMenuCommand("hide-profile") ui.enableMenuCommand("duplicate-profile") if isSystem: menu = systemMenu else: menu = normalMenu profileList.setPopupMenu(menu) # Update the banner image. if bannerImage: bannerImage.setImage(pr.getActive().getBanner()) elif event.hasId("profile-list-selected"): # Change the currently active profile. p = pr.get(event.getSelection()) pr.setActive(p) # Double-clicking causes a Play command. if event.isDoubleClick() and p is not pr.getDefaults(): events.sendAfter(events.Command("play"))
def update(self): if self.iwadText: self.iwadText.getFromProfile(pr.getActive()) self.iwadText.select()
def refreshList(): """Refreshes the list of addons.""" addonList.freeze() # Try to keep the old selection, if there is one. oldSelections = addonList.getSelectedItems() addonList.clear() # Filtering parameters. profile = pr.getActive() isDefaults = profile is pr.getDefaults() if tree.getSelectedItem(): filterCategory = ao.getCategory(tree.getSelectedItem()) else: filterCategory = None # Which addons are currently attached? defaultAddons = pr.getDefaults().getAddons() if not isDefaults: profileAddons = pr.getActive().getAddons() else: profileAddons = None # Categories that will be in bold font in category-tree. boldCategories = [] # Determine filtering options. mode = listFilter.getSelectedItem() onlyCompatible = False onlyPWAD = False alsoBoxes = False if 'compatible' in mode: onlyCompatible = True if 'pwad' in mode: onlyPWAD = True if 'with-boxes' in mode: alsoBoxes = True for addon in ao.getAddons(): # Does this addon pass the filter? if not isDefaults and onlyCompatible: if not addon.isCompatibleWith(pr.getActive()): # Cannot be listed. continue if onlyPWAD and (addon.getType() != 'addon-type-wad' or not addon.isPWAD()): continue # Has a category been selected? if filterCategory and not filterCategory.isAncestorOf( addon.getCategory()): # Not in the category. continue # Addons in boxes are not listed unless the correct category is selected. if not alsoBoxes and addon.getBox(): # Addons in boxes are only visible if the selected category is a box category. boxCateg = addon.getBox().getContentCategoryLongId() if not filterCategory: continue if filterCategory.getLongId().find(boxCateg) != 0: # Not the right category. continue # Passed the filter! id = addon.getId() versionStr = '' icon = determineIcon(addon, profile, defaultAddons, profileAddons) if language.isDefined(id + '-version'): versionStr = language.translate(id + '-version') name = language.translate(id) if addon.getBox() and alsoBoxes: name += ' ' + language.translate('addon-list-in-box') addonList.addItemWithColumns(id, icon, name, versionStr) # Reselect old items. oldSelections.reverse() for sel in oldSelections: addonList.selectItem(sel) addonList.ensureVisible(sel) sortList() updateButtons() addonList.unfreeze() # Update the counter text. countText.setText( language.expand(language.translate('addon-counter'), str(len(addonList.getItems())), str(ao.getAddonCount()))) # Update boldings in category-tree. # --TODO!-- global mustRefreshList mustRefreshList = False