예제 #1
0
def show():
    """Show all the issues in a dialog.  The list of issues will be
    automatically cleared.  If there are no issues to report, nothing
    is done."""

    global allIssues

    if len(allIssues) == 0:
        # Nothing to report.
        return

    import sb.util.dialog
    dialog, area = sb.util.dialog.createButtonDialog(
        'issue-dialog',
        ['ok'], 'ok')

    message = area.createFormattedText()
    message.setMinSize(500, 300)

    msg = ''

    bgColor = ['#90E090', '#FFFF80', '#E05050']
    fgColor = ['black', 'black', 'white']
    severeName = ['Note', 'Warning', 'Error']

    isFirst = True

    # Compose a HTML formatted version of each issue.
    for severe in [HIGH, MEDIUM, LOW]:
        # Show the important issues first.
        for issue in allIssues:
            if issue[0] != severe:
                continue

            if not isFirst:
                msg += '<hr>'
            isFirst = False

            msg += '<table width="100%" border=0 cellspacing=3 cellpadding=4>'
            msg += '<tr><td bgcolor="%s" width="20%%" align=center>' % \
                   bgColor[issue[0]]
            msg += '<font color="%s"><b>' % fgColor[issue[0]] + \
                   severeName[issue[0]] + '</b></font>'
            msg += '<td width="80%"><h3>' + language.expand(
                language.translate(issue[1]), *issue[2])
            msg += '</h3>' + language.expand(
                language.translate(issue[1] + '-text'), *issue[2])
            msg += '</table>'

    message.setText(msg)
    dialog.run()
        
    # Only show each issue once.
    allIssues = []
예제 #2
0
def show():
    """Show all the issues in a dialog.  The list of issues will be
    automatically cleared.  If there are no issues to report, nothing
    is done."""

    global allIssues

    if len(allIssues) == 0:
        # Nothing to report.
        return

    import sb.util.dialog
    dialog, area = sb.util.dialog.createButtonDialog('issue-dialog', ['ok'],
                                                     'ok')

    message = area.createFormattedText()
    message.setMinSize(500, 300)

    msg = ''

    bgColor = ['#90E090', '#FFFF80', '#E05050']
    fgColor = ['black', 'black', 'white']
    severeName = ['Note', 'Warning', 'Error']

    isFirst = True

    # Compose a HTML formatted version of each issue.
    for severe in [HIGH, MEDIUM, LOW]:
        # Show the important issues first.
        for issue in allIssues:
            if issue[0] != severe:
                continue

            if not isFirst:
                msg += '<hr>'
            isFirst = False

            msg += '<table width="100%" border=0 cellspacing=3 cellpadding=4>'
            msg += '<tr><td bgcolor="%s" width="20%%" align=center>' % \
                   bgColor[issue[0]]
            msg += '<font color="%s"><b>' % fgColor[issue[0]] + \
                   severeName[issue[0]] + '</b></font>'
            msg += '<td width="80%"><h3>' + language.expand(
                language.translate(issue[1]), *issue[2])
            msg += '</h3>' + language.expand(
                language.translate(issue[1] + '-text'), *issue[2])
            msg += '</table>'

    message.setText(msg)
    dialog.run()

    # Only show each issue once.
    allIssues = []
예제 #3
0
 def createConflictButtons(self, addonName):
     self.area.setWeight(0)
     self.choices = []
     self.choices.append(
         resolving.area.createRadioButton('', True, True))
     self.choices.append(
         resolving.area.createRadioButton('', False))
         
     self.choices[0].setText(language.expand(
         language.translate('conflict-choice1'), addonName))
         
     self.choices[1].setText(language.expand(
         language.translate('conflict-choice2'), addonName))
예제 #4
0
    def getShortContentAnalysis(self):
        """Forms a short single line of text that describes the contents
        of the WAD."""

        # The directory must already be read by this time.
        analysis = []              
        mapCount = 0
        hasCustomTextures = False
        
        for lump in self.lumps:
            # Count the number of maps.
            if len(lump) == 4 and lump[0] == 'E' and lump[2] == 'M' and \
               lump[1] in string.digits and lump[3] in string.digits:
                mapCount += 1
            elif len(lump) == 5 and lump[:3] == 'MAP' and \
               lump[3] in string.digits and lump[4] in string.digits:
                mapCount += 1
            # Any custom textures?
            elif lump == 'PNAMES' or lump == 'TEXTURE1' or lump == 'TEXTURE2':
                hasCustomTextures = True
        
        if mapCount > 0:
            analysis.append( language.expand(
                language.translate('wad-analysis-maps'), str(mapCount)) )
        if hasCustomTextures:
            analysis.append(language.translate('wad-analysis-custom-textures'))
        
        return string.join(analysis, ', ').capitalize()
예제 #5
0
    def getShortContentAnalysis(self):
        """Forms a short single line of text that describes the contents
        of the WAD."""

        # The directory must already be read by this time.
        analysis = []
        mapCount = 0
        hasCustomTextures = False

        for lump in self.lumps:
            # Count the number of maps.
            if len(lump) == 4 and lump[0] == 'E' and lump[2] == 'M' and \
               lump[1] in string.digits and lump[3] in string.digits:
                mapCount += 1
            elif len(lump) == 5 and lump[:3] == 'MAP' and \
               lump[3] in string.digits and lump[4] in string.digits:
                mapCount += 1
            # Any custom textures?
            elif lump == 'PNAMES' or lump == 'TEXTURE1' or lump == 'TEXTURE2':
                hasCustomTextures = True

        if mapCount > 0:
            analysis.append(
                language.expand(language.translate('wad-analysis-maps'),
                                str(mapCount)))
        if hasCustomTextures:
            analysis.append(language.translate('wad-analysis-custom-textures'))

        return string.join(analysis, ', ').capitalize()
예제 #6
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
예제 #7
0
def showAddonInfo(addon):
    """Display a summary of an addon in the help panel.

    @param addon An addons.Addon object.
    """
    global currentAddon, currentSetting

    # No longer showing a setting.
    currentSetting = None

    # The current addon that is displayed in the help.
    currentAddon = addon

    oneLiners = (detailedAddonMode == False)
    ident = addon.getId()

    # Begin the page with a table that contains the basic info.
    msg = '<html>'

    def optLink(id, isLink):
        if isLink:
            return '<a href="%s">%s</a>' % (id, language.translate(id))
        else:
            return language.translate(id)

    # The detail selection links.
    msg += '<center><font size="-1">'
    msg += optLink('help-addon-mode-brief', detailedAddonMode) + ' | '
    msg += optLink('help-addon-mode-detailed', not detailedAddonMode)
    msg += '</font></center><br>'

    # Summary table.
    msg += tableBegin

    msg += '<tr><td colspan="2"><b><font size="+1">' + \
           language.translate(ident) + \
           '</font></b>'

    def makeField(msg, fieldId, oneLiner=True):
        title = language.translate('help-addon-' + fieldId)
        contentId = ident + '-' + fieldId

        text = ''
        if language.isDefined(contentId):
            # This information has been defined.
            text = language.translate(contentId)
        elif detailedAddonMode:
            # Force all fields to show.
            text = '-'

        if text:
            if oneLiner:
                msg += tableRow + entryHeader(title) + entryContent(text)
            else:
                msg += tableRow + entryHeader(title, 2) + \
                       tableRow + entryContent(text, 2)

        return msg

    msg = makeField(msg, 'version')

    if detailedAddonMode:
        # Get the last modification time from the addon.
        modTime = time.localtime(addon.getLastModified())
        msg += tableRow + entryHeader(language.translate('help-addon-date')) \
               + entryContent(time.strftime("%d %b %Y", modTime))

    msg = makeField(msg, 'summary', oneLiners)

    if detailedAddonMode:
        msg = makeField(msg, 'contact', oneLiners)
        msg = makeField(msg, 'author', oneLiners)
        msg = makeField(msg, 'copyright', oneLiners)
        msg = makeField(msg, 'license', oneLiners)

    # Dependencies.
    deps = []

    exCats = addon.getExcludedCategories()
    if len(exCats):
        deps.append((language.translate('help-addon-excluded-categories'),
                     map(lambda c: language.translate(c.getLongId()), exCats)))

    for type, label in [(sb.addon.EXCLUDES, 'help-addon-excludes'),
                        (sb.addon.REQUIRES, 'help-addon-requires'),
                        (sb.addon.PROVIDES, 'help-addon-provides'),
                        (sb.addon.OFFERS, 'help-addon-offers')]:
        # Make a copy of the list so we can modify it.
        keywords = [kw for kw in addon.getKeywords(type)]

        # In the Brief mode, hide the identifier of the addon in the
        # Provides field.
        if not detailedAddonMode and type == sb.addon.PROVIDES:
            keywords.remove(addon.getId())

        if len(keywords) > 0:
            # Include this in the info.
            def xlate(key):
                if ao.exists(key):
                    return '<a href="%s">%s</a>' % \
                           (key, language.translate(key))
                else:
                    return key

            deps.append((language.translate(label), map(xlate, keywords)))

    if len(deps):
        # Print a dependencies table.
        msg += tableRow + entryHeader(
            language.translate('help-addon-dependencies'), 2)

        content = ""

        for dep in deps:
            if dep is not deps[0]:
                content += '<br>'
            content += "<b>" + dep[0] + ":</b><ul><li>"
            content += string.join(dep[1], '<li>')
            content += '</ul>'

        msg += tableRow + entryContent(content, 2)

    msg += tableEnd

    # Inside a box?
    if addon.getBox():
        box = addon.getBox()
        msg += language.expand(language.translate('help-addon-part-of-box'),
                               box.getId(), language.translate(
                                   box.getId())) + '<p>'

    # The overview.
    if language.isDefined(ident + '-readme'):
        msg += language.translate(ident + '-readme')

    msg += '</html>'

    helpText.setText(msg)
    showLogo(False)
예제 #8
0
def createResolver(problem, addons):
    """Create the necessary widgets in the area to resolve the problem.

    @param area An ui.Area object.  Will be cleared.

    @param problem The problem description as returned by
    addons.findConflicts.

    @param addons Set of Addon objects.  This should be modified
    according to the user's selections.
    """
    global resolving

    # Set the general parameters of the resolver.
    resolving.problem = problem
    resolving.addons = addons
    
    resolving.area.clear()
    resolving.area.setWeight(2)

    message = resolving.area.createFormattedText()
    message.setMinSize(250, 250)

    resolving.area.setWeight(1)

    # Enter this problem into the log.
    log(problem)
    
    # The name of the problem.
    problemName = problem[0]

    if problemName == 'exclusion-by-category':
        # The list of excluded addons. 
        names = map(lambda a: language.translate(a.getId()), problem[2])
        names.sort()

        msg = "<ul><li>" + string.join(names, '<li>') + "</ul>"
    
        message.setText(language.expand(
            language.translate('category-conflict-message'),
            language.translate(problem[1].getId()), msg))

        # Create the radio buttons.
        resolving.createConflictButtons(language.translate(problem[1].getId()))

    elif problemName == 'exclusion-by-keyword':
        msg = '<ul>'

        for addon, key in problem[2]:
            msg += '<li>'
            if addon.getId() != key:
                msg += key + " in "
            msg += language.translate(addon.getId())

        msg += '</ul>'

        message.setText(language.expand(
            language.translate('keyword-conflict-message'),
            language.translate(problem[1].getId()), msg))

        # Create the radio buttons.
        resolving.createConflictButtons(language.translate(problem[1].getId()))

    elif problemName == 'exclusion-by-value':
        # The list of excluded values.
        names = []
        for v in problem[2]:
            if language.isDefined(v):
                names.append(language.translate(v))
            else:
                names.append(v)
        msg = "<ul><li>" + string.join(names, '<li>') + "</ul>"
        message.setText(language.expand(
            language.translate('value-conflict-message'),
            language.translate(problem[1].getId()), msg))            

    elif problemName == 'provide-conflict':
        # Collect the conflicting addons into a list.
        resolving.conflicted = []
        keys = []
        for a, b, key in problem[1]:

            if a not in resolving.conflicted:
                resolving.conflicted.append(a)
                
            if b not in resolving.conflicted:
                resolving.conflicted.append(b)
                
            if key not in keys:
                keys.append(key)

        #ao.sortIdentifiersByName(conflicting)

        message.setText(language.expand(
            language.translate('provide-conflict-message'),
            "<ul><li>" + string.join(keys, '<li>') + "</ul>"))

        resolving.list = resolving.area.createList('')
        for a in resolving.conflicted:
            resolving.list.addItem(a.getId())

    elif problemName == 'missing-requirements':

        resolving.conflicted = problem[1]

        res = "<p><ul>"
        res += "<li>" + string.join(problem[2], '<li>') + "</ul>"

        msg = language.expand(
            language.translate('missing-requirements-message'),
            language.translate(problem[1].getId()))
        
        message.setText(msg + res)

        resolving.list = None
        
    resolving.area.updateLayout()
예제 #9
0
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]))
예제 #10
0
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
예제 #11
0
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
예제 #12
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
예제 #13
0
def showAddonInfo(addon):
    """Display a summary of an addon in the help panel.

    @param addon An addons.Addon object.
    """
    global currentAddon, currentSetting

    # No longer showing a setting.
    currentSetting = None

    # The current addon that is displayed in the help.
    currentAddon = addon

    oneLiners = (detailedAddonMode == False)
    ident = addon.getId()
    
    # Begin the page with a table that contains the basic info.
    msg = '<html>'

    def optLink(id, isLink):
        if isLink:
            return '<a href="%s">%s</a>' % (id, language.translate(id))
        else:
            return language.translate(id)

    # The detail selection links.
    msg += '<center><font size="-1">'
    msg += optLink('help-addon-mode-brief', detailedAddonMode) + ' | '
    msg += optLink('help-addon-mode-detailed', not detailedAddonMode)
    msg += '</font></center><br>'

    # Summary table.
    msg += tableBegin

    msg += '<tr><td colspan="2"><b><font size="+1">' + \
           language.translate(ident) + \
           '</font></b>'

    def makeField(msg, fieldId, oneLiner=True):
        title = language.translate('help-addon-' + fieldId)
        contentId = ident + '-' + fieldId

        text = ''
        if language.isDefined(contentId):
            # This information has been defined.
            text = language.translate(contentId)
        elif detailedAddonMode:
            # Force all fields to show.
            text = '-'

        if text:
            if oneLiner:
                msg += tableRow + entryHeader(title) + entryContent(text)
            else:
                msg += tableRow + entryHeader(title, 2) + \
                       tableRow + entryContent(text, 2)

        return msg

    msg = makeField(msg, 'version')

    if detailedAddonMode:
        # Get the last modification time from the addon.
        modTime = time.localtime(addon.getLastModified())
        msg += tableRow + entryHeader(language.translate('help-addon-date')) \
               + entryContent(time.strftime("%d %b %Y", modTime))
    
    msg = makeField(msg, 'summary', oneLiners)

    if detailedAddonMode:
        msg = makeField(msg, 'contact', oneLiners)
        msg = makeField(msg, 'author', oneLiners)
        msg = makeField(msg, 'copyright', oneLiners)
        msg = makeField(msg, 'license', oneLiners)

    # Dependencies.
    deps = []
    
    exCats = addon.getExcludedCategories()
    if len(exCats):
        deps.append((language.translate('help-addon-excluded-categories'),
                     map(lambda c: language.translate(c.getLongId()), exCats)))

    for type, label in [(sb.addon.EXCLUDES, 'help-addon-excludes'),
                        (sb.addon.REQUIRES, 'help-addon-requires'),
                        (sb.addon.PROVIDES, 'help-addon-provides'),
                        (sb.addon.OFFERS, 'help-addon-offers')]:
        # Make a copy of the list so we can modify it.
        keywords = [kw for kw in addon.getKeywords(type)]

        # In the Brief mode, hide the identifier of the addon in the
        # Provides field.
        if not detailedAddonMode and type == sb.addon.PROVIDES:
            keywords.remove(addon.getId())            
        
        if len(keywords) > 0:
            # Include this in the info.
            def xlate(key):
                if ao.exists(key):
                    return '<a href="%s">%s</a>' % \
                           (key, language.translate(key))
                else:
                    return key
            deps.append((language.translate(label), map(xlate, keywords)))

    if len(deps):
        # Print a dependencies table.
        msg += tableRow + entryHeader(
            language.translate('help-addon-dependencies'), 2)

        content = ""

        for dep in deps:
            if dep is not deps[0]:
                content += '<br>'
            content += "<b>" + dep[0] + ":</b><ul><li>"
            content += string.join(dep[1], '<li>')
            content += '</ul>'

        msg += tableRow + entryContent(content, 2)            

    msg += tableEnd

    # Inside a box?
    if addon.getBox():
        box = addon.getBox()
        msg += language.expand(
            language.translate('help-addon-part-of-box'),
            box.getId(), language.translate(box.getId())) + '<p>'

    # The overview.
    if language.isDefined(ident + '-readme'):
        msg += language.translate(ident + '-readme')

    msg += '</html>'

    helpText.setText(msg)
    showLogo(False)
예제 #14
0
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]))
예제 #15
0
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
예제 #16
0
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