RefactoringRope/Refactoring.py

changeset 11
562f9758d2e1
parent 10
0fdfae822ca7
child 12
75fff1da56b6
diff -r 0fdfae822ca7 -r 562f9758d2e1 RefactoringRope/Refactoring.py
--- a/RefactoringRope/Refactoring.py	Sun Jan 30 14:49:37 2011 +0100
+++ b/RefactoringRope/Refactoring.py	Sun Jan 30 17:02:15 2011 +0100
@@ -21,20 +21,20 @@
 import rope.refactor.usefunction
 import rope.refactor.inline
 import rope.refactor.move
-##import rope.refactor.change_signature
+import rope.refactor.change_signature
 import rope.refactor.introduce_factory
 import rope.refactor.introduce_parameter
 ##import rope.refactor.method_object
 ##import rope.refactor.encapsulate_field
 ##import rope.refactor.localtofield
 ##import rope.refactor.topackage
-##from rope.refactor.importutils import ImportOrganizer
+from rope.refactor.importutils import ImportOrganizer
 
 import rope.contrib.findit
 ##import rope.contrib.finderrors
 
 from PyQt4.QtCore import QObject, SIGNAL
-from PyQt4.QtGui import QMenu, QApplication, QMessageBox
+from PyQt4.QtGui import QMenu, QApplication, QMessageBox, QDialog
 
 from E5Gui.E5Application import e5App
 
@@ -57,6 +57,10 @@
 from UseFunctionDialog import UseFunctionDialog
 from IntroduceFactoryDialog import IntroduceFactoryDialog
 from IntroduceParameterDialog import IntroduceParameterDialog
+from ConfirmationDialog import ConfirmationDialog
+from RestructureDialog import RestructureDialog
+from ChangeSignatureDialog import ChangeSignatureDialog
+from InlineArgumentDefaultDialog import InlineArgumentDefaultDialog
 
 import Utilities
 
@@ -300,6 +304,143 @@
         self.actions.append(self.refactoringIntroduceParameterAct)
         
         #####################################################
+        ## Import refactorings actions
+        #####################################################
+        
+        self.refactoringImportsOrganizeAct = E5Action(
+                self.trUtf8('Organize Imports'),
+                self.trUtf8('&Organize Imports'),
+                0, 0,
+                self,'refactoring_organize_imports')
+        self.refactoringImportsOrganizeAct.setStatusTip(self.trUtf8(
+            'Sort imports according to PEP-8'))
+        self.refactoringImportsOrganizeAct.setWhatsThis(self.trUtf8(
+            """<b>Organize Imports</b>"""
+            """<p>Sort imports according to PEP-8.</p>"""
+        ))
+        self.refactoringImportsOrganizeAct.triggered[()].connect(
+            self.__importsOrganize)
+        self.actions.append(self.refactoringImportsOrganizeAct)
+        
+        self.refactoringImportsStarExpandAct = E5Action(
+                self.trUtf8('Expand Star Imports'),
+                self.trUtf8('E&xpand Star Imports'),
+                0, 0,
+                self,'refactoring_expand_star_imports')
+        self.refactoringImportsStarExpandAct.setStatusTip(self.trUtf8(
+            'Expand imports like "from xxx import *"'))
+        self.refactoringImportsStarExpandAct.setWhatsThis(self.trUtf8(
+            """<b>Expand Star Imports</b>"""
+            """<p>Expand imports like "from xxx import *".</p>"""
+            """<p>Select the import to act on or none to do all."""
+            """ Unused imports are deleted.</p>"""
+        ))
+        self.refactoringImportsStarExpandAct.triggered[()].connect(
+            self.__importsExpandStar)
+        self.actions.append(self.refactoringImportsStarExpandAct)
+        
+        self.refactoringImportsRelativeToAbsoluteAct = E5Action(
+                self.trUtf8('Relative to Absolute'),
+                self.trUtf8('Relative to &Absolute'),
+                0, 0,
+                self,'refactoring_relative_to_absolute_imports')
+        self.refactoringImportsRelativeToAbsoluteAct.setStatusTip(self.trUtf8(
+            'Transform relative imports to absolute ones'))
+        self.refactoringImportsRelativeToAbsoluteAct.setWhatsThis(self.trUtf8(
+            """<b>Relative to Absolute</b>"""
+            """<p>Transform relative imports to absolute ones.</p>"""
+            """<p>Select the import to act on or none to do all."""
+            """ Unused imports are deleted.</p>"""
+        ))
+        self.refactoringImportsRelativeToAbsoluteAct.triggered[()].connect(
+            self.__importsRelativeToAbsolute)
+        self.actions.append(self.refactoringImportsRelativeToAbsoluteAct)
+        
+        self.refactoringImportsFromsToImportsAct = E5Action(
+                self.trUtf8('Froms to Imports'),
+                self.trUtf8('Froms to &Imports'),
+                0, 0,
+                self,'refactoring_froms_to_imports')
+        self.refactoringImportsFromsToImportsAct.setStatusTip(self.trUtf8(
+            'Transform From imports to plain imports'))
+        self.refactoringImportsFromsToImportsAct.setWhatsThis(self.trUtf8(
+            """<b>Froms to Imports</b>"""
+            """<p>Transform From imports to plain imports.</p>"""
+            """<p>Select the import to act on or none to do all."""
+            """ Unused imports are deleted.</p>"""
+        ))
+        self.refactoringImportsFromsToImportsAct.triggered[()].connect(
+            self.__importsFromToImport)
+        self.actions.append(self.refactoringImportsFromsToImportsAct)
+        
+        self.refactoringImportsHandleLongAct = E5Action(
+                self.trUtf8('Handle Long Imports'),
+                self.trUtf8('Handle &Long Imports'),
+                0, 0,
+                self,'refactoring_organize_imports')
+        self.refactoringImportsHandleLongAct.setStatusTip(self.trUtf8(
+            'Transform long import statements to look better'))
+        self.refactoringImportsHandleLongAct.setWhatsThis(self.trUtf8(
+            """<b>Handle Long Imports</b>"""
+            """<p>Transform long import statements to look better.</p>"""
+            """<p>Select the import to act on or none to do all."""
+            """ Unused imports are deleted.</p>"""
+        ))
+        self.refactoringImportsHandleLongAct.triggered[()].connect(
+            self.__importsHandleLong)
+        self.actions.append(self.refactoringImportsHandleLongAct)
+        
+        #####################################################
+        ## Various refactorings actions
+        #####################################################
+        
+        self.refactoringRestructureAct = E5Action(
+                self.trUtf8('Restructure'),
+                self.trUtf8('Res&tructure'),
+                0, 0,
+                self,'refactoring_restructure')
+        self.refactoringRestructureAct.setStatusTip(self.trUtf8(
+            'Restructure code'))
+        self.refactoringRestructureAct.setWhatsThis(self.trUtf8(
+            """<b>Restructure</b>"""
+            """<p>Restructure code. See "Rope Help" for examples.</p>"""
+        ))
+        self.refactoringRestructureAct.triggered[()].connect(
+            self.__restructure)
+        self.actions.append(self.refactoringRestructureAct)
+        
+        self.refactoringChangeSignatureAct = E5Action(
+                self.trUtf8('Change Method Signature'),
+                self.trUtf8('&Change Method Signature'),
+                0, 0,
+                self,'refactoring_change_method_signature')
+        self.refactoringChangeSignatureAct.setStatusTip(self.trUtf8(
+            'Change the signature of the selected method or function'))
+        self.refactoringChangeSignatureAct.setWhatsThis(self.trUtf8(
+            """<b>Change Method Signature</b>"""
+            """<p>Change the signature of the selected method"""
+            """ or function.</p>"""
+        ))
+        self.refactoringChangeSignatureAct.triggered[()].connect(
+            self.__changeSignature)
+        self.actions.append(self.refactoringChangeSignatureAct)
+        
+        self.refactoringInlineArgumentDefaultAct = E5Action(
+                self.trUtf8('Inline Argument Default'),
+                self.trUtf8('Inline &Argument Default'),
+                0, 0,
+                self,'refactoring_inline_argument_default')
+        self.refactoringInlineArgumentDefaultAct.setStatusTip(self.trUtf8(
+            'Inline a parameters default value'))
+        self.refactoringInlineArgumentDefaultAct.setWhatsThis(self.trUtf8(
+            """<b>Inline Argument Default</b>"""
+            """<p>Inline a parameters default value.</p>"""
+        ))
+        self.refactoringInlineArgumentDefaultAct.triggered[()].connect(
+            self.__inlineArgumentDefault)
+        self.actions.append(self.refactoringInlineArgumentDefaultAct)
+        
+        #####################################################
         ## Undo/Redo actions
         #####################################################
         
@@ -529,10 +670,10 @@
         smenu.addSeparator()
         smenu.addAction(self.refactoringUseFunctionAct)
         smenu.addSeparator()
-##        smenu.addAction(self.refactoringChangeSignatureAct)
-##        smenu.addAction(self.refactoringInlineArgumentDefaultAct)
+        smenu.addAction(self.refactoringChangeSignatureAct)
+        smenu.addAction(self.refactoringInlineArgumentDefaultAct)
         smenu.addSeparator()
-##        smenu.addAction(self.refactoringRestructureAct)
+        smenu.addAction(self.refactoringRestructureAct)
         smenu.addSeparator()
         smenu.addAction(self.refactoringIntroduceFactoryAct)
         smenu.addAction(self.refactoringIntroduceParameterAct)
@@ -546,6 +687,13 @@
 ##        smenu.addAction(self.refactoringTransformModuleAct)
         smenu.addSeparator()
         
+        imenu = smenu.addMenu(self.trUtf8("Im&ports"))
+        imenu.addAction(self.refactoringImportsOrganizeAct)
+        imenu.addAction(self.refactoringImportsStarExpandAct)
+        imenu.addAction(self.refactoringImportsRelativeToAbsoluteAct)
+        imenu.addAction(self.refactoringImportsFromsToImportsAct)
+        imenu.addAction(self.refactoringImportsHandleLongAct)
+        
         smenu.addSeparator()
         smenu.addAction(self.refactoringUndoAct)
         smenu.addAction(self.refactoringRedoAct)
@@ -1112,6 +1260,170 @@
         self.dlg.show()
     
     #####################################################
+    ## Import refactorings
+    #####################################################
+    
+    def __importsOrganize(self):
+        """
+        Private slot to organize imports.
+        """
+        self.__doImports(self.trUtf8("Organize Imports"), 
+            ImportOrganizer.organize_imports)
+    
+    def __importsExpandStar(self):
+        """
+        Private slot to expand star imports.
+        """
+        self.__doImports(self.trUtf8("Expand Star Imports"), 
+            ImportOrganizer.expand_star_imports)
+    
+    def __importsRelativeToAbsolute(self):
+        """
+        Private slot to transform relative to absolute imports.
+        """
+        self.__doImports(self.trUtf8("Relative to Absolute"), 
+            ImportOrganizer.relatives_to_absolutes)
+    
+    def __importsFromToImport(self):
+        """
+        Private slot to transform from imports to plain imports.
+        """
+        self.__doImports(self.trUtf8("Froms to Imports"), 
+            ImportOrganizer.froms_to_imports)
+    
+    def __importsHandleLong(self):
+        """
+        Private slot to handle long imports.
+        """
+        self.__doImports(self.trUtf8("Handle Long Imports"), 
+            ImportOrganizer.handle_long_imports)
+    
+    def __doImports(self, title, method):
+        """
+        Private method to perform the various imports refactorings.
+        """
+        aw = e5App().getObject("ViewManager").activeWindow()
+        
+        if aw is None:
+            return
+        
+        if not self.confirmBufferIsSaved(aw):
+            return
+        
+        filename = aw.getFileName()
+        if aw.hasSelectedText():
+            line, index, line1, index1 = aw.getSelection()
+            offset = aw.positionFromLineIndex(line, index)
+        else:
+            offset = None
+        
+        importOrganizer = ImportOrganizer(self.__project)
+        resource = rope.base.libutils.path_to_resource(
+            self.__project, filename)
+        try:
+            changes = method(importOrganizer, resource, offset=offset)
+            if changes is not None:
+                dlg = ConfirmationDialog(changes, self.__ui)
+                if dlg.exec_() == QDialog.Accepted:
+                    self.__project.do(changes)
+                    self.refreshEditors(changes)
+                    if self.__e5project.isDirty():
+                        self.__e5project.saveProject()
+            else:
+                E5MessageBox.information(self.__ui, title,
+                    self.trUtf8("The selected refactoring did not produce"
+                                " any change."))
+        except Exception as err:
+            self.handleRopeError(err, title)
+    
+    #####################################################
+    ## Various refactorings
+    #####################################################
+    
+    def __restructure(self):
+        """
+        Private slot to restructure code.
+        """
+        title = self.trUtf8("Restructure")
+        self.dlg = RestructureDialog(self, title, parent=self.__ui)
+        self.dlg.show()
+    
+    def __changeSignature(self):
+        """
+        Private slot to change the signature of a method or function.
+        """
+        aw = e5App().getObject("ViewManager").activeWindow()
+        
+        if aw is None:
+            return
+        
+        title = self.trUtf8("Change Method Signature")
+        if not aw.hasSelectedText():
+            # no selection available
+            E5MessageBox.warning(self.__ui, title,
+                self.trUtf8("Highlight the method or function to change"
+                    " and try again."))
+            return 
+        
+        if not self.confirmAllBuffersSaved():
+            return
+        
+        filename = aw.getFileName()
+        line, index, line1, index1 = aw.getSelection()
+        offset = aw.positionFromLineIndex(line, index)
+        
+        resource = rope.base.libutils.path_to_resource(
+            self.__project, filename)
+        try:
+            changer = rope.refactor.change_signature.ChangeSignature(
+                self.__project, resource, offset)
+        except Exception as err:
+            self.handleRopeError(err, title)
+            return 
+        
+        self.dlg = ChangeSignatureDialog(self, title, changer, 
+                                         parent=self.__ui)
+        self.dlg.show()
+    
+    def __inlineArgumentDefault(self):
+        """
+        Private slot to inline the default value of a parameter of a
+        method or function.
+        """
+        aw = e5App().getObject("ViewManager").activeWindow()
+        
+        if aw is None:
+            return
+        
+        title = self.trUtf8("Inline Argument Default")
+        if not aw.hasSelectedText():
+            # no selection available
+            E5MessageBox.warning(self.__ui, title,
+                self.trUtf8("Highlight the method or function to inline"
+                    " a parameter's default and try again."))
+            return 
+        
+        if not self.confirmAllBuffersSaved():
+            return
+        
+        filename = aw.getFileName()
+        line, index, line1, index1 = aw.getSelection()
+        offset = aw.positionFromLineIndex(line, index)
+        
+        resource = rope.base.libutils.path_to_resource(
+            self.__project, filename)
+        try:
+            changer = rope.refactor.change_signature.ChangeSignature(
+                self.__project, resource, offset)
+        except Exception as err:
+            self.handleRopeError(err, title)
+            return 
+        
+        self.dlg = InlineArgumentDefaultDialog(self, title, changer, 
+                                               parent=self.__ui)
+        self.dlg.show()
+    
+    #####################################################
     ## Undo/Redo refactorings
     #####################################################
     

eric ide

mercurial