Example #1
0
    def updateList():
        # Update the found addons list.
        foundList.clear()
        dialog.disableWidget(actionButton)
        extensions = ao.getAddonExtensions() + ['manifest']

        # This should be done in addons.py.
        fileNames = os.listdir(pathField.getText())
        for name in fileNames:
            type = ''
            for ext in extensions:
                if paths.hasExtension(ext, name):
                    type = ext
                    break

            if not type:
                # Unknown files are skipped.
                continue

            # Manifests don't appear in the list if the corresponding
            # addon is in the same directory.
            if paths.hasExtension('manifest', name):
                foundSame = False

                # Identifier of the addon the manifest belongs to.
                manifestId = paths.getBase(name)

                # See if the addon is in the list.
                for other in fileNames:
                    if other == name:
                        continue
                    if manifestId == ao.formIdentifier(other)[0]:
                        foundSame = True
                        break                    
                if foundSame:
                    # Don't add it.
                    continue
            
            foundList.addItemWithColumns(
                name, name, language.translate('addon-dialog-type-' + type))
    def updateList():
        # Update the found addons list.
        foundList.clear()
        dialog.disableWidget(actionButton)
        extensions = ao.getAddonExtensions() + ['manifest']

        # This should be done in addons.py.
        fileNames = os.listdir(pathField.getText())
        for name in fileNames:
            type = ''
            for ext in extensions:
                if paths.hasExtension(ext, name):
                    type = ext
                    break

            if not type:
                # Unknown files are skipped.
                continue

            # Manifests don't appear in the list if the corresponding
            # addon is in the same directory.
            if paths.hasExtension('manifest', name):
                foundSame = False

                # Identifier of the addon the manifest belongs to.
                manifestId = paths.getBase(name)

                # See if the addon is in the list.
                for other in fileNames:
                    if other == name:
                        continue
                    if manifestId == ao.formIdentifier(other)[0]:
                        foundSame = True
                        break
                if foundSame:
                    # Don't add it.
                    continue

            foundList.addItemWithColumns(
                name, name, language.translate('addon-dialog-type-' + type))
Example #3
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]))
Example #4
0
def chooseAddons(dialogId, title, actionButton):
    """Opens an addon selection dialog.

    @param title Title of the dialog.

    @param actionButton The button that will perform the affirmative
    action of the dialog.
    """
    dialog, area = sb.util.dialog.createButtonDialog(dialogId, 
        ['cancel', actionButton], 
        actionButton)

    dialog.addEndCommand('addon-dialog-add-to-custom-folders')

    # The action button is disabled until a valid selection has been
    # made.
    dialog.disableWidget(actionButton)

    area.setWeight(0)
    folderArea = area.createArea(alignment=ui.ALIGN_HORIZONTAL)
    folderArea.setExpanding(False)
    folderArea.setBorder(2, ui.BORDER_NOT_LEFT)
    folderArea.setWeight(0)
    folderArea.createText('addon-dialog-folder').resizeToBestSize()
    folderArea.setBorderDirs(ui.BORDER_ALL)
    folderArea.setWeight(1)
    pathField = folderArea.createTextField('')
    pathField.setText(os.getcwd())
    pathField.select()
    pathField.focus()
    folderArea.setWeight(0)
    folderArea.setBorderDirs(ui.BORDER_NOT_RIGHT)
    browseButton = folderArea.createButton('addon-dialog-folder-browse',
                                           style=wg.Button.STYLE_MINI)
    #folderArea.addSpacer()
    #folderArea.setBorderDirs(ui.BORDER_NOT_RIGHT)
    
    folderCmdArea = area.createArea(alignment=ui.ALIGN_HORIZONTAL)
    folderCmdArea.setExpanding(False)
    folderCmdArea.setBorder(6, ui.BORDER_NOT_TOP)
    folderCmdArea.setWeight(1)
    folderCmdArea.addSpacer()
    folderCmdArea.setWeight(0)
        
    uninstButton = folderCmdArea.createButton('addon-dialog-folder-uninstalled')
   
    # Add to Custom Folders button.
    folderCmdArea.setBorder(6, ui.BORDER_LEFT | ui.BORDER_BOTTOM)
    addToMyButton = folderCmdArea.createButton('addon-dialog-add-to-custom-folders')

    def goToUninstalled():
        pathField.setText(paths.getUserPath(paths.UNINSTALLED))
        pathField.select()
        addToMyButton.disable()

    uninstButton.addReaction(goToUninstalled)

    area.createText('addon-dialog-found')
    area.setWeight(1)
    foundList = area.createList('', style=sb.widget.list.List.STYLE_COLUMNS)
    foundList.setMinSize(500, 300)

    area.setWeight(0)
    area.createText('addon-dialog-addons-copied', maxLineLength=70).resizeToBestSize()

    def selectAction():
        dialog.enableWidget(actionButton)

    foundList.addReaction(selectAction)

    for col, width in [('name', None), ('type', 180)]:
        foundList.addColumn('addon-dialog-' + col, width)

    def updateList():
        # Update the found addons list.
        foundList.clear()
        dialog.disableWidget(actionButton)
        extensions = ao.getAddonExtensions() + ['manifest']

        # This should be done in addons.py.
        fileNames = os.listdir(pathField.getText())
        for name in fileNames:
            type = ''
            for ext in extensions:
                if paths.hasExtension(ext, name):
                    type = ext
                    break

            if not type:
                # Unknown files are skipped.
                continue

            # Manifests don't appear in the list if the corresponding
            # addon is in the same directory.
            if paths.hasExtension('manifest', name):
                foundSame = False

                # Identifier of the addon the manifest belongs to.
                manifestId = paths.getBase(name)

                # See if the addon is in the list.
                for other in fileNames:
                    if other == name:
                        continue
                    if manifestId == ao.formIdentifier(other)[0]:
                        foundSame = True
                        break                    
                if foundSame:
                    # Don't add it.
                    continue
            
            foundList.addItemWithColumns(
                name, name, language.translate('addon-dialog-type-' + type))

    # Update reactions.
    def pathChanged():
        if os.path.exists(pathField.getText()):
            updateList()
            if pathField.getText() != paths.getUserPath(paths.UNINSTALLED):
                addToMyButton.enable()
        else:
            addToMyButton.disable()

    def browseAction():
        # Show a directory browser.
        selection = sb.util.dialog.chooseFolder('addon-dialog-browse-prompt',
                                                pathField.getText())
        if len(selection):
            pathField.setText(selection)
            pathField.select()

    # The initial contents of the list.
    updateList()

    pathField.addReaction(pathChanged)
    browseButton.addReaction(browseAction)

    dialog.addEndCommand(actionButton)
    result = dialog.run()
    if result == actionButton:
        addonFiles = map(lambda name: os.path.join(pathField.getText(), name),
                         foundList.getSelectedItems())

        # Include any associated manifests.
        for name in addonFiles:
            manifest = ao.formIdentifier(name)[0] + '.manifest'
            manifestFile = os.path.join(pathField.getText(), manifest)
            if manifest not in addonFiles and os.path.exists(manifestFile):
                addonFiles.append(manifestFile)
                #print 'including ' + manifestFile + ' due to ' + name

        return addonFiles

    elif result == 'addon-dialog-add-to-custom-folders':
        paths.addAddonPath(pathField.getText())
        events.send(events.Notify('addon-paths-changed'))
        ao.refresh()
        return []

    # The dialog was canceled.
    return []
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 chooseAddons(dialogId, title, actionButton):
    """Opens an addon selection dialog.

    @param title Title of the dialog.

    @param actionButton The button that will perform the affirmative
    action of the dialog.
    """
    dialog, area = sb.util.dialog.createButtonDialog(dialogId,
                                                     ['cancel', actionButton],
                                                     actionButton)

    dialog.addEndCommand('addon-dialog-add-to-custom-folders')

    # The action button is disabled until a valid selection has been
    # made.
    dialog.disableWidget(actionButton)

    area.setWeight(0)
    folderArea = area.createArea(alignment=ui.ALIGN_HORIZONTAL)
    folderArea.setExpanding(False)
    folderArea.setBorder(2, ui.BORDER_NOT_LEFT)
    folderArea.setWeight(0)
    folderArea.createText('addon-dialog-folder').resizeToBestSize()
    folderArea.setBorderDirs(ui.BORDER_ALL)
    folderArea.setWeight(1)
    pathField = folderArea.createTextField('')
    pathField.setText(os.getcwd())
    pathField.select()
    pathField.focus()
    folderArea.setWeight(0)
    folderArea.setBorderDirs(ui.BORDER_NOT_RIGHT)
    browseButton = folderArea.createButton('addon-dialog-folder-browse',
                                           style=wg.Button.STYLE_MINI)
    #folderArea.addSpacer()
    #folderArea.setBorderDirs(ui.BORDER_NOT_RIGHT)

    folderCmdArea = area.createArea(alignment=ui.ALIGN_HORIZONTAL)
    folderCmdArea.setExpanding(False)
    folderCmdArea.setBorder(6, ui.BORDER_NOT_TOP)
    folderCmdArea.setWeight(1)
    folderCmdArea.addSpacer()
    folderCmdArea.setWeight(0)

    uninstButton = folderCmdArea.createButton(
        'addon-dialog-folder-uninstalled')

    # Add to Custom Folders button.
    folderCmdArea.setBorder(6, ui.BORDER_LEFT | ui.BORDER_BOTTOM)
    addToMyButton = folderCmdArea.createButton(
        'addon-dialog-add-to-custom-folders')

    def goToUninstalled():
        pathField.setText(paths.getUserPath(paths.UNINSTALLED))
        pathField.select()
        addToMyButton.disable()

    uninstButton.addReaction(goToUninstalled)

    area.createText('addon-dialog-found')
    area.setWeight(1)
    foundList = area.createList('', style=sb.widget.list.List.STYLE_COLUMNS)
    foundList.setMinSize(500, 300)

    area.setWeight(0)
    area.createText('addon-dialog-addons-copied',
                    maxLineLength=70).resizeToBestSize()

    def selectAction():
        dialog.enableWidget(actionButton)

    foundList.addReaction(selectAction)

    for col, width in [('name', None), ('type', 180)]:
        foundList.addColumn('addon-dialog-' + col, width)

    def updateList():
        # Update the found addons list.
        foundList.clear()
        dialog.disableWidget(actionButton)
        extensions = ao.getAddonExtensions() + ['manifest']

        # This should be done in addons.py.
        fileNames = os.listdir(pathField.getText())
        for name in fileNames:
            type = ''
            for ext in extensions:
                if paths.hasExtension(ext, name):
                    type = ext
                    break

            if not type:
                # Unknown files are skipped.
                continue

            # Manifests don't appear in the list if the corresponding
            # addon is in the same directory.
            if paths.hasExtension('manifest', name):
                foundSame = False

                # Identifier of the addon the manifest belongs to.
                manifestId = paths.getBase(name)

                # See if the addon is in the list.
                for other in fileNames:
                    if other == name:
                        continue
                    if manifestId == ao.formIdentifier(other)[0]:
                        foundSame = True
                        break
                if foundSame:
                    # Don't add it.
                    continue

            foundList.addItemWithColumns(
                name, name, language.translate('addon-dialog-type-' + type))

    # Update reactions.
    def pathChanged():
        if os.path.exists(pathField.getText()):
            updateList()
            if pathField.getText() != paths.getUserPath(paths.UNINSTALLED):
                addToMyButton.enable()
        else:
            addToMyButton.disable()

    def browseAction():
        # Show a directory browser.
        selection = sb.util.dialog.chooseFolder('addon-dialog-browse-prompt',
                                                pathField.getText())
        if len(selection):
            pathField.setText(selection)
            pathField.select()

    # The initial contents of the list.
    updateList()

    pathField.addReaction(pathChanged)
    browseButton.addReaction(browseAction)

    dialog.addEndCommand(actionButton)
    result = dialog.run()
    if result == actionButton:
        addonFiles = map(lambda name: os.path.join(pathField.getText(), name),
                         foundList.getSelectedItems())

        # Include any associated manifests.
        for name in addonFiles:
            manifest = ao.formIdentifier(name)[0] + '.manifest'
            manifestFile = os.path.join(pathField.getText(), manifest)
            if manifest not in addonFiles and os.path.exists(manifestFile):
                addonFiles.append(manifestFile)
                #print 'including ' + manifestFile + ' due to ' + name

        return addonFiles

    elif result == 'addon-dialog-add-to-custom-folders':
        paths.addAddonPath(pathField.getText())
        events.send(events.Notify('addon-paths-changed'))
        ao.refresh()
        return []

    # The dialog was canceled.
    return []