PluginManager/PluginUninstallDialog.py

changeset 0
de9c2efb9d02
child 7
c679fb30c8f3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PluginManager/PluginUninstallDialog.py	Mon Dec 28 16:03:33 2009 +0000
@@ -0,0 +1,206 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2007 - 2009 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a dialog for plugin deinstallation.
+"""
+
+import sys
+import os
+import imp
+import shutil
+
+from PyQt4.QtGui import *
+from PyQt4.QtCore import *
+
+from PluginManager import PluginManager
+from Ui_PluginUninstallDialog import Ui_PluginUninstallDialog
+
+class PluginUninstallWidget(QWidget, Ui_PluginUninstallDialog):
+    """
+    Class implementing a dialog for plugin deinstallation.
+    """
+    def __init__(self, pluginManager, parent = None):
+        """
+        Constructor
+        
+        @param pluginManager reference to the plugin manager object
+        @param parent parent of this dialog (QWidget)
+        """
+        QWidget.__init__(self, parent)
+        self.setupUi(self)
+        
+        if pluginManager is None:
+            # started as external plugin deinstaller
+            self.__pluginManager = PluginManager(doLoadPlugins = False)
+            self.__external = True
+        else:
+            self.__pluginManager = pluginManager
+            self.__external = False
+        
+        self.pluginDirectoryCombo.addItem(self.trUtf8("User plugins directory"), 
+            QVariant(self.__pluginManager.getPluginDir("user")))
+        
+        globalDir = self.__pluginManager.getPluginDir("global")
+        if globalDir is not None and os.access(globalDir, os.W_OK):
+            self.pluginDirectoryCombo.addItem(self.trUtf8("Global plugins directory"), 
+                QVariant(globalDir))
+    
+    @pyqtSlot(int)
+    def on_pluginDirectoryCombo_currentIndexChanged(self, index):
+        """
+        Private slot to populate the plugin name combo upon a change of the
+        plugin area.
+        
+        @param index index of the selected item (integer)
+        """
+        pluginDirectory = self.pluginDirectoryCombo\
+                .itemData(index).toString()
+        pluginNames = self.__pluginManager.getPluginModules(pluginDirectory)
+        pluginNames.sort()
+        self.pluginNameCombo.clear()
+        for pluginName in pluginNames:
+            fname = "%s.py" % os.path.join(pluginDirectory, pluginName)
+            self.pluginNameCombo.addItem(pluginName, QVariant(fname))
+        self.buttonBox.button(QDialogButtonBox.Ok)\
+            .setEnabled(self.pluginNameCombo.currentText() != "")
+    
+    @pyqtSlot()
+    def on_buttonBox_accepted(self):
+        """
+        Private slot to handle the accepted signal of the button box.
+        """
+        if self.__uninstallPlugin():
+            self.emit(SIGNAL("accepted()"))
+    
+    def __uninstallPlugin(self):
+        """
+        Private slot to uninstall the selected plugin.
+        
+        @return flag indicating success (boolean)
+        """
+        pluginDirectory = self.pluginDirectoryCombo\
+                .itemData(self.pluginDirectoryCombo.currentIndex())\
+                .toString()
+        pluginName = self.pluginNameCombo.currentText()
+        pluginFile = self.pluginNameCombo\
+                .itemData(self.pluginNameCombo.currentIndex())\
+                .toString()
+        
+        if not self.__pluginManager.unloadPlugin(pluginName, pluginDirectory):
+            QMessageBox.critical(None,
+                self.trUtf8("Plugin Uninstallation"),
+                self.trUtf8("""<p>The plugin <b>{0}</b> could not be unloaded."""
+                            """ Aborting...</p>""").format(pluginName),
+                QMessageBox.StandardButtons(\
+                    QMessageBox.Ok))
+            return False
+        
+        if not pluginDirectory in sys.path:
+            sys.path.insert(2, pluginDirectory)
+        module = imp.load_source(pluginName, pluginFile)
+        if not hasattr(module, "packageName"):
+            QMessageBox.critical(None,
+                self.trUtf8("Plugin Uninstallation"),
+                self.trUtf8("""<p>The plugin <b>{0}</b> has no 'packageName' attribute."""
+                            """ Aborting...</p>""").format(pluginName),
+                QMessageBox.StandardButtons(\
+                    QMessageBox.Ok))
+            return False
+        
+        package = getattr(module, "packageName")
+        if package is None:
+            package = "None"
+            packageDir = ""
+        else:
+            packageDir = os.path.join(pluginDirectory, package)
+        if hasattr(module, "prepareUninstall"):
+            module.prepareUninstall()
+        internalPackages = []
+        if hasattr(module, "internalPackages"):
+            # it is a comma separated string
+            internalPackages = [p.strip() for p in module.internalPackages.split(",")]
+        del module
+        
+        # clean sys.modules
+        self.__pluginManager.removePluginFromSysModules(
+            pluginName, package, internalPackages)
+        
+        try:
+            if packageDir and os.path.exists(packageDir):
+                shutil.rmtree(packageDir)
+            
+            fnameo = "%so" % pluginFile
+            if os.path.exists(fnameo):
+                os.remove(fnameo)
+            
+            fnamec = "%sc" % pluginFile
+            if os.path.exists(fnamec):
+                os.remove(fnamec)
+            
+            os.remove(pluginFile)
+        except OSError, err:
+            QMessageBox.critical(None,
+                self.trUtf8("Plugin Uninstallation"),
+                self.trUtf8("""<p>The plugin package <b>{0}</b> could not be"""
+                            """ removed. Aborting...</p>"""
+                            """<p>Reason: {1}</p>""").format(packageDir, unicode(err)),
+                QMessageBox.StandardButtons(\
+                    QMessageBox.Ok))
+            return False
+        
+        QMessageBox.information(None,
+            self.trUtf8("Plugin Uninstallation"),
+            self.trUtf8("""<p>The plugin <b>{0}</b> was uninstalled successfully"""
+                        """ from {1}.</p>""")\
+                .format(pluginName, pluginDirectory),
+            QMessageBox.StandardButtons(\
+                QMessageBox.Ok))
+        return True
+
+class PluginUninstallDialog(QDialog):
+    """
+    Class for the dialog variant.
+    """
+    def __init__(self, pluginManager, parent = None):
+        """
+        Constructor
+        
+        @param pluginManager reference to the plugin manager object
+        @param parent reference to the parent widget (QWidget)
+        """
+        QDialog.__init__(self, parent)
+        self.setSizeGripEnabled(True)
+        
+        self.__layout = QVBoxLayout(self)
+        self.__layout.setMargin(0)
+        self.setLayout(self.__layout)
+        
+        self.cw = PluginUninstallWidget(pluginManager, self)
+        size = self.cw.size()
+        self.__layout.addWidget(self.cw)
+        self.resize(size)
+        
+        self.connect(self.cw, SIGNAL("accepted()"), self.accept)
+        self.connect(self.cw.buttonBox, SIGNAL("rejected()"), self.reject)
+
+class PluginUninstallWindow(QMainWindow):
+    """
+    Main window class for the standalone dialog.
+    """
+    def __init__(self, parent = None):
+        """
+        Constructor
+        
+        @param parent reference to the parent widget (QWidget)
+        """
+        QMainWindow.__init__(self, parent)
+        self.cw = PluginUninstallWidget(None, self)
+        size = self.cw.size()
+        self.setCentralWidget(self.cw)
+        self.resize(size)
+        
+        self.connect(self.cw, SIGNAL("accepted()"), self.close)
+        self.connect(self.cw.buttonBox, SIGNAL("rejected()"), self.close)

eric ide

mercurial