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 #####################################################