コード例 #1
0
class PluginsDialog( QDialog ):
    " Codimension plugins dialog "

    def __init__( self, pluginManager, parent = None ):
        QDialog.__init__( self, parent )
        self.setWindowTitle( "Plugin Manager" )

        self.__pluginManager = pluginManager
        self.__configFuncs = {} # int -> callable

        self.__createLayout()
        self.__populate()

        self.__pluginsView.setFocus()
        self.__inItemChange = False
        return

    def __createLayout( self ):
        " Creates the dialog layout "
        self.resize( 640, 480 )
        self.setSizeGripEnabled( True )

        layout = QVBoxLayout()

        # Plugins list
        self.__pluginsView = QTreeWidget()
        self.__pluginsView.setAlternatingRowColors( True )
        self.__pluginsView.setRootIsDecorated( False )
        self.__pluginsView.setItemsExpandable( False )
        self.__pluginsView.setSortingEnabled( True )
        self.__pluginsView.setItemDelegate( NoOutlineHeightDelegate( 4 ) )
        self.__pluginsView.setUniformRowHeights( True )

        # Alert | system/user | Enable | Name | Version
        self.__pluginsHeader = QTreeWidgetItem( [ "", "", "", "Name", "Version", "" ] )
        self.__pluginsView.setHeaderItem( self.__pluginsHeader )
        self.__pluginsView.header().setSortIndicator( NAME_COL, Qt.AscendingOrder )
        self.connect( self.__pluginsView,
                      SIGNAL( "itemSelectionChanged()" ),
                      self.__pluginSelectionChanged )
        self.connect( self.__pluginsView,
                      SIGNAL( "itemChanged(QTreeWidgetItem*,int)" ),
                      self.__onItemChanged )

        layout.addWidget( self.__pluginsView )

        # Detailed information
        detailsLabel = QLabel( "Detailed information" )
        layout.addWidget( detailsLabel )
        self.__details = QTreeWidget()
        self.__details.setAlternatingRowColors( False )
        self.__details.setRootIsDecorated( False )
        self.__details.setItemsExpandable( False )
        self.__details.setSortingEnabled( False )
        self.__details.setItemDelegate( NoOutlineHeightDelegate( 4 ) )
        self.__details.setUniformRowHeights( True )

        detailsHeader = QTreeWidgetItem( [ "", "" ] )
        self.__details.setHeaderItem( detailsHeader )
        self.__details.setHeaderHidden( True )

        metrics = QFontMetrics( self.__details.font() )
        rect = metrics.boundingRect( "X" )
        self.__details.setFixedHeight( rect.height() * 6 + 5 )
        layout.addWidget( self.__details )

        # Errors/warnings
        errorsLabel = QLabel( "Errors / warnings" )
        layout.addWidget( errorsLabel )
        self.__errorsText = QTextEdit()
        self.__errorsText.setReadOnly( True )
        self.__errorsText.setAcceptRichText( False )
        metrics = QFontMetrics( self.__errorsText.font() )
        rect = metrics.boundingRect( "X" )
        self.__errorsText.setFixedHeight( rect.height() * 4 + 5 )
        layout.addWidget( self.__errorsText )

        # Buttons box
        buttonBox = QDialogButtonBox( self )
        buttonBox.setOrientation( Qt.Horizontal )
        buttonBox.setStandardButtons( QDialogButtonBox.Ok )
        self.__OKButton = buttonBox.button( QDialogButtonBox.Ok )
        self.__OKButton.setDefault( True )
        self.connect( buttonBox, SIGNAL( "accepted()" ), self.close )
        self.connect( buttonBox, SIGNAL( "rejected()" ), self.close )
        layout.addWidget( buttonBox )

        self.setLayout( layout )
        return

    def __createConfigButton( self ):
        " Creates a configure button for a plugin "
        button = SettingsButton()
        self.connect( button, SIGNAL( 'CustomClick' ), self.onPluginSettings )
        return button

    def __populate( self ):
        " Populates the list with the plugins "
        index = 0

        for category in self.__pluginManager.activePlugins:
            for cdmPlugin in self.__pluginManager.activePlugins[ category ]:
                newItem = PluginItem( self.__pluginManager, cdmPlugin, True, category )
                self.__pluginsView.addTopLevelItem( newItem )
                settingsButton = self.__createConfigButton()

                try:
                    configFunction = cdmPlugin.getObject().getConfigFunction()
                    if configFunction is None:
                        settingsButton.setToolTip( "Plugin does not need configuring" )
                        settingsButton.setEnabled( False )
                    else:
                        settingsButton.setToolTip( "Click to configure" )
                        settingsButton.setEnabled( True )
                        self.__configFuncs[ index ] = configFunction
                        settingsButton.index = index
                        index += 1
                except Exception:
                    settingsButton.setToolTip( "Bad plugin interface. No "
                                               "configuration function received." )
                    settingsButton.setEnabled( False )

                self.__pluginsView.setItemWidget( newItem, SETTINGS_COL, settingsButton )

        for category in self.__pluginManager.inactivePlugins:
            for cdmPlugin in self.__pluginManager.inactivePlugins[ category ]:
                newItem = PluginItem( self.__pluginManager, cdmPlugin, False, category )
                self.__pluginsView.addTopLevelItem( newItem )
                settingsButton = self.__createConfigButton()

                try:
                    configFunction = cdmPlugin.getObject().getConfigFunction()
                    if configFunction is None:
                        settingsButton.setToolTip( "Plugin does not need configuring" )
                        settingsButton.setEnabled( False )
                    else:
                        settingsButton.setToolTip( "Enable plugin and then click to configure" )
                        settingsButton.setEnabled( False )
                        self.__configFuncs[ index ] = configFunction
                        settingsButton.index = index
                        index += 1
                except:
                    settingsButton.setToolTip( "Bad plugin interface. No "
                                               "configuration function received." )
                    settingsButton.setEnabled( False )

                self.__pluginsView.setItemWidget( newItem, SETTINGS_COL, settingsButton )

        for cdmPlugin in self.__pluginManager.unknownPlugins:
            newItem = PluginItem( self.__pluginManager, cdmPlugin, False, None )
            self.__pluginsView.addTopLevelItem( newItem )
            settingsButton = self.__createConfigButton()
            settingsButton.setToolTip( "Unknown plugins are not configurable" )
            settingsButton.setEnabled( False )
            self.__pluginsView.setItemWidget( newItem, SETTINGS_COL, settingsButton )

        self.__sortPlugins()
        self.__resizePlugins()
        return


    def __sortPlugins( self ):
        " Sorts the plugins table "
        self.__pluginsView.sortItems(
                    self.__pluginsView.sortColumn(),
                    self.__pluginsView.header().sortIndicatorOrder() )
        return

    def __resizePlugins( self ):
        " Resizes the plugins table "
        self.__pluginsView.header().setStretchLastSection( False )
        self.__pluginsView.header().resizeSections(
                                        QHeaderView.ResizeToContents )
        self.__pluginsView.header().resizeSection( STATE_COL, 28 )
        self.__pluginsView.header().setResizeMode( STATE_COL, QHeaderView.Fixed )
        self.__pluginsView.header().resizeSection( CONFLICT_COL, 28 )
        self.__pluginsView.header().setResizeMode( CONFLICT_COL, QHeaderView.Fixed )
        self.__pluginsView.header().resizeSection( TYPE_COL, 28 )
        self.__pluginsView.header().setResizeMode( TYPE_COL, QHeaderView.Fixed )

        self.__pluginsView.header().setResizeMode( VERSION_COL, QHeaderView.Stretch )
        self.__pluginsView.header().resizeSection( SETTINGS_COL, 24 )
        self.__pluginsView.header().setResizeMode( SETTINGS_COL, QHeaderView.Fixed )
        return

    def __pluginSelectionChanged( self ):
        " Triggered when an item is selected "
        selected = list( self.__pluginsView.selectedItems() )
        if selected:
            self.__updateDetails( selected[ 0 ] )
        else:
            self.__updateDetails( None )
        return

    def __updateDetails( self, item ):
        " Updates the content of the details and the error boxes "
        self.__details.clear()
        self.__errorsText.setText( "" )

        if item is None:
            return

        self.__details.addTopLevelItem(
                    QTreeWidgetItem( [ "Author", item.plugin.getAuthor() ] ) )
        self.__details.addTopLevelItem(
                    QTreeWidgetItem( [ "Path", os.path.normpath( item.plugin.getPath() ) ] ) )
        self.__details.addTopLevelItem(
                    QTreeWidgetItem( [ "Description", item.plugin.getDescription() ] ) )
        self.__details.addTopLevelItem(
                    QTreeWidgetItem( [ "Web site", item.plugin.getWebsite() ] ) )

        copyright = item.plugin.getCopyright()
        if copyright is not None:
            if copyright.lower() != "unknown":
                self.__details.addTopLevelItem(
                    QTreeWidgetItem( [ "Copyright", copyright ] ) )

        for name in item.plugin.getDetails():
            value = item.plugin.getDetails()[ name ]
            self.__details.addTopLevelItem( QTreeWidgetItem( [ name, value ] ) )

        self.__errorsText.setText( item.plugin.conflictMessage )
        return

    def __onItemChanged( self, item, column ):
        " Triggered when an item is changed "

        if self.__inItemChange:
            return

        if item.active:
            self.__inItemChange = True
            item.plugin.disable()
            item.active = False

            settingsButton = self.__pluginsView.itemWidget( item, SETTINGS_COL )
            settingsButton.setEnabled( False )
            if settingsButton.index != -1:
                settingsButton.setToolTip( "Enable plugin and then click to configure" )

            if item.category in self.__pluginManager.inactivePlugins:
                self.__pluginManager.inactivePlugins[ item.category ].append( item.plugin )
            else:
                self.__pluginManager.inactivePlugins[ item.category ] = [ item.plugin ]
            self.__pluginManager.activePlugins[ item.category ].remove( item.plugin )
            self.__pluginManager.saveDisabledPlugins()
            self.__inItemChange = False
            self.__pluginManager.sendPluginDeactivated( item.plugin )
            return

        self.__inItemChange = True
        message = self.__pluginManager.checkConflict( item.plugin )
        if message is not None:
            item.setCheckState( STATE_COL, Qt.Unchecked )
            self.__errorsText.setText( message )
            self.__inItemChange = False
            return

        try:
            item.plugin.enable()
            item.active = True
            if item.category in self.__pluginManager.activePlugins:
                self.__pluginManager.activePlugins[ item.category ].append( item.plugin )
            else:
                self.__pluginManager.activePlugins[ item.category ] = [ item.plugin ]
            self.__pluginManager.inactivePlugins[ item.category ].remove( item.plugin )
            self.__pluginManager.saveDisabledPlugins()
            self.__errorsText.setText( "" )
            item.setIcon( CONFLICT_COL, PixmapCache().getIcon( 'empty.png' ) )
            item.setToolTip( CONFLICT_COL, "" )

            settingsButton = self.__pluginsView.itemWidget( item, SETTINGS_COL )
            if settingsButton.index != -1:
                settingsButton.setToolTip( "Click to configure" )
                settingsButton.setEnabled( True )
            self.__pluginManager.sendPluginActivated( item.plugin )
        except:
            item.setCheckState( STATE_COL, Qt.Unchecked )
            self.__errorsText.setText( "Error activating the plugin - exception is generated" )

        self.__inItemChange = False
        return

    def onPluginSettings( self, index ):
        " Triggered when a configuring function is called "
        if index not in self.__configFuncs:
            return

        try:
            self.__configFuncs[ index ]()
        except Exception, exc:
            logging.error( "Error calling the plugin configuration function. "
                           "Message: " + str( exc ) )
        return
コード例 #2
0
class PluginsDialog(QDialog):
    " Codimension plugins dialog "

    def __init__(self, pluginManager, parent=None):
        QDialog.__init__(self, parent)
        self.setWindowTitle("Plugin Manager")

        self.__pluginManager = pluginManager
        self.__configFuncs = {}  # int -> callable

        self.__createLayout()
        self.__populate()

        self.__pluginsView.setFocus()
        self.__inItemChange = False
        return

    def __createLayout(self):
        " Creates the dialog layout "
        self.resize(640, 480)
        self.setSizeGripEnabled(True)

        layout = QVBoxLayout()

        # Plugins list
        self.__pluginsView = QTreeWidget()
        self.__pluginsView.setAlternatingRowColors(True)
        self.__pluginsView.setRootIsDecorated(False)
        self.__pluginsView.setItemsExpandable(False)
        self.__pluginsView.setSortingEnabled(True)
        self.__pluginsView.setItemDelegate(NoOutlineHeightDelegate(4))
        self.__pluginsView.setUniformRowHeights(True)

        # Alert | system/user | Enable | Name | Version
        self.__pluginsHeader = QTreeWidgetItem(
            ["", "", "", "Name", "Version", ""])
        self.__pluginsView.setHeaderItem(self.__pluginsHeader)
        self.__pluginsView.header().setSortIndicator(NAME_COL,
                                                     Qt.AscendingOrder)
        self.connect(self.__pluginsView, SIGNAL("itemSelectionChanged()"),
                     self.__pluginSelectionChanged)
        self.connect(self.__pluginsView,
                     SIGNAL("itemChanged(QTreeWidgetItem*,int)"),
                     self.__onItemChanged)

        layout.addWidget(self.__pluginsView)

        # Detailed information
        detailsLabel = QLabel("Detailed information")
        layout.addWidget(detailsLabel)
        self.__details = QTreeWidget()
        self.__details.setAlternatingRowColors(False)
        self.__details.setRootIsDecorated(False)
        self.__details.setItemsExpandable(False)
        self.__details.setSortingEnabled(False)
        self.__details.setItemDelegate(NoOutlineHeightDelegate(4))
        self.__details.setUniformRowHeights(True)

        detailsHeader = QTreeWidgetItem(["", ""])
        self.__details.setHeaderItem(detailsHeader)
        self.__details.setHeaderHidden(True)

        metrics = QFontMetrics(self.__details.font())
        rect = metrics.boundingRect("X")
        self.__details.setFixedHeight(rect.height() * 6 + 5)
        layout.addWidget(self.__details)

        # Errors/warnings
        errorsLabel = QLabel("Errors / warnings")
        layout.addWidget(errorsLabel)
        self.__errorsText = QTextEdit()
        self.__errorsText.setReadOnly(True)
        self.__errorsText.setAcceptRichText(False)
        metrics = QFontMetrics(self.__errorsText.font())
        rect = metrics.boundingRect("X")
        self.__errorsText.setFixedHeight(rect.height() * 4 + 5)
        layout.addWidget(self.__errorsText)

        # Buttons box
        buttonBox = QDialogButtonBox(self)
        buttonBox.setOrientation(Qt.Horizontal)
        buttonBox.setStandardButtons(QDialogButtonBox.Ok)
        self.__OKButton = buttonBox.button(QDialogButtonBox.Ok)
        self.__OKButton.setDefault(True)
        self.connect(buttonBox, SIGNAL("accepted()"), self.close)
        self.connect(buttonBox, SIGNAL("rejected()"), self.close)
        layout.addWidget(buttonBox)

        self.setLayout(layout)
        return

    def __createConfigButton(self):
        " Creates a configure button for a plugin "
        button = SettingsButton()
        self.connect(button, SIGNAL('CustomClick'), self.onPluginSettings)
        return button

    def __populate(self):
        " Populates the list with the plugins "
        index = 0

        for category in self.__pluginManager.activePlugins:
            for cdmPlugin in self.__pluginManager.activePlugins[category]:
                newItem = PluginItem(self.__pluginManager, cdmPlugin, True,
                                     category)
                self.__pluginsView.addTopLevelItem(newItem)
                settingsButton = self.__createConfigButton()

                try:
                    configFunction = cdmPlugin.getObject().getConfigFunction()
                    if configFunction is None:
                        settingsButton.setToolTip(
                            "Plugin does not need configuring")
                        settingsButton.setEnabled(False)
                    else:
                        settingsButton.setToolTip("Click to configure")
                        settingsButton.setEnabled(True)
                        self.__configFuncs[index] = configFunction
                        settingsButton.index = index
                        index += 1
                except Exception:
                    settingsButton.setToolTip(
                        "Bad plugin interface. No "
                        "configuration function received.")
                    settingsButton.setEnabled(False)

                self.__pluginsView.setItemWidget(newItem, SETTINGS_COL,
                                                 settingsButton)

        for category in self.__pluginManager.inactivePlugins:
            for cdmPlugin in self.__pluginManager.inactivePlugins[category]:
                newItem = PluginItem(self.__pluginManager, cdmPlugin, False,
                                     category)
                self.__pluginsView.addTopLevelItem(newItem)
                settingsButton = self.__createConfigButton()

                try:
                    configFunction = cdmPlugin.getObject().getConfigFunction()
                    if configFunction is None:
                        settingsButton.setToolTip(
                            "Plugin does not need configuring")
                        settingsButton.setEnabled(False)
                    else:
                        settingsButton.setToolTip(
                            "Enable plugin and then click to configure")
                        settingsButton.setEnabled(False)
                        self.__configFuncs[index] = configFunction
                        settingsButton.index = index
                        index += 1
                except:
                    settingsButton.setToolTip(
                        "Bad plugin interface. No "
                        "configuration function received.")
                    settingsButton.setEnabled(False)

                self.__pluginsView.setItemWidget(newItem, SETTINGS_COL,
                                                 settingsButton)

        for cdmPlugin in self.__pluginManager.unknownPlugins:
            newItem = PluginItem(self.__pluginManager, cdmPlugin, False, None)
            self.__pluginsView.addTopLevelItem(newItem)
            settingsButton = self.__createConfigButton()
            settingsButton.setToolTip("Unknown plugins are not configurable")
            settingsButton.setEnabled(False)
            self.__pluginsView.setItemWidget(newItem, SETTINGS_COL,
                                             settingsButton)

        self.__sortPlugins()
        self.__resizePlugins()
        return

    def __sortPlugins(self):
        " Sorts the plugins table "
        self.__pluginsView.sortItems(
            self.__pluginsView.sortColumn(),
            self.__pluginsView.header().sortIndicatorOrder())
        return

    def __resizePlugins(self):
        " Resizes the plugins table "
        self.__pluginsView.header().setStretchLastSection(False)
        self.__pluginsView.header().resizeSections(
            QHeaderView.ResizeToContents)
        self.__pluginsView.header().resizeSection(STATE_COL, 28)
        self.__pluginsView.header().setResizeMode(STATE_COL, QHeaderView.Fixed)
        self.__pluginsView.header().resizeSection(CONFLICT_COL, 28)
        self.__pluginsView.header().setResizeMode(CONFLICT_COL,
                                                  QHeaderView.Fixed)
        self.__pluginsView.header().resizeSection(TYPE_COL, 28)
        self.__pluginsView.header().setResizeMode(TYPE_COL, QHeaderView.Fixed)

        self.__pluginsView.header().setResizeMode(VERSION_COL,
                                                  QHeaderView.Stretch)
        self.__pluginsView.header().resizeSection(SETTINGS_COL, 24)
        self.__pluginsView.header().setResizeMode(SETTINGS_COL,
                                                  QHeaderView.Fixed)
        return

    def __pluginSelectionChanged(self):
        " Triggered when an item is selected "
        selected = list(self.__pluginsView.selectedItems())
        if selected:
            self.__updateDetails(selected[0])
        else:
            self.__updateDetails(None)
        return

    def __updateDetails(self, item):
        " Updates the content of the details and the error boxes "
        self.__details.clear()
        self.__errorsText.setText("")

        if item is None:
            return

        self.__details.addTopLevelItem(
            QTreeWidgetItem(["Author", item.plugin.getAuthor()]))
        self.__details.addTopLevelItem(
            QTreeWidgetItem(["Path",
                             os.path.normpath(item.plugin.getPath())]))
        self.__details.addTopLevelItem(
            QTreeWidgetItem(["Description",
                             item.plugin.getDescription()]))
        self.__details.addTopLevelItem(
            QTreeWidgetItem(["Web site", item.plugin.getWebsite()]))

        copyright = item.plugin.getCopyright()
        if copyright is not None:
            if copyright.lower() != "unknown":
                self.__details.addTopLevelItem(
                    QTreeWidgetItem(["Copyright", copyright]))

        for name in item.plugin.getDetails():
            value = item.plugin.getDetails()[name]
            self.__details.addTopLevelItem(QTreeWidgetItem([name, value]))

        self.__errorsText.setText(item.plugin.conflictMessage)
        return

    def __onItemChanged(self, item, column):
        " Triggered when an item is changed "

        if self.__inItemChange:
            return

        if item.active:
            self.__inItemChange = True
            item.plugin.disable()
            item.active = False

            settingsButton = self.__pluginsView.itemWidget(item, SETTINGS_COL)
            settingsButton.setEnabled(False)
            if settingsButton.index != -1:
                settingsButton.setToolTip(
                    "Enable plugin and then click to configure")

            if item.category in self.__pluginManager.inactivePlugins:
                self.__pluginManager.inactivePlugins[item.category].append(
                    item.plugin)
            else:
                self.__pluginManager.inactivePlugins[item.category] = [
                    item.plugin
                ]
            self.__pluginManager.activePlugins[item.category].remove(
                item.plugin)
            self.__pluginManager.saveDisabledPlugins()
            self.__inItemChange = False
            self.__pluginManager.sendPluginDeactivated(item.plugin)
            return

        self.__inItemChange = True
        message = self.__pluginManager.checkConflict(item.plugin)
        if message is not None:
            item.setCheckState(STATE_COL, Qt.Unchecked)
            self.__errorsText.setText(message)
            self.__inItemChange = False
            return

        try:
            item.plugin.enable()
            item.active = True
            if item.category in self.__pluginManager.activePlugins:
                self.__pluginManager.activePlugins[item.category].append(
                    item.plugin)
            else:
                self.__pluginManager.activePlugins[item.category] = [
                    item.plugin
                ]
            self.__pluginManager.inactivePlugins[item.category].remove(
                item.plugin)
            self.__pluginManager.saveDisabledPlugins()
            self.__errorsText.setText("")
            item.setIcon(CONFLICT_COL, PixmapCache().getIcon('empty.png'))
            item.setToolTip(CONFLICT_COL, "")

            settingsButton = self.__pluginsView.itemWidget(item, SETTINGS_COL)
            if settingsButton.index != -1:
                settingsButton.setToolTip("Click to configure")
                settingsButton.setEnabled(True)
            self.__pluginManager.sendPluginActivated(item.plugin)
        except:
            item.setCheckState(STATE_COL, Qt.Unchecked)
            self.__errorsText.setText(
                "Error activating the plugin - exception is generated")

        self.__inItemChange = False
        return

    def onPluginSettings(self, index):
        " Triggered when a configuring function is called "
        if index not in self.__configFuncs:
            return

        try:
            self.__configFuncs[index]()
        except Exception, exc:
            logging.error("Error calling the plugin configuration function. "
                          "Message: " + str(exc))
        return