487 self.refactoringMethodToMethodObjectAct.triggered.connect( |
490 self.refactoringMethodToMethodObjectAct.triggered.connect( |
488 self.__methodToMethodObject) |
491 self.__methodToMethodObject) |
489 self.actions.append(self.refactoringMethodToMethodObjectAct) |
492 self.actions.append(self.refactoringMethodToMethodObjectAct) |
490 |
493 |
491 ##################################################### |
494 ##################################################### |
492 ## Undo/Redo actions |
495 ## History actions |
493 ##################################################### |
496 ##################################################### |
494 |
497 |
495 self.refactoringUndoAct = E5Action( |
498 self.refactoringProjectHistoryAct = E5Action( |
496 self.tr('Undo'), |
499 self.tr('Show Project History'), |
497 self.tr('&Undo'), |
500 self.tr('Show Project History...'), |
498 0, 0, |
501 0, 0, |
499 self, 'refactoring_undo') |
502 self, 'refactoring_show_project_history') |
500 self.refactoringUndoAct.setStatusTip(self.tr( |
503 self.refactoringProjectHistoryAct.setStatusTip(self.tr( |
501 'Undo the last refactoring')) |
504 'Show the refactoring history of the project')) |
502 self.refactoringUndoAct.setWhatsThis(self.tr( |
505 self.refactoringProjectHistoryAct.setWhatsThis(self.tr( |
503 """<b>Undo</b>""" |
506 """<b>Show Project History</b>""" |
504 """<p>Undo the last refactoring.</p>""" |
507 """<p>This opens a dialog to show the refactoring history of""" |
505 )) |
|
506 self.refactoringUndoAct.triggered.connect( |
|
507 self.__undo) |
|
508 self.actions.append(self.refactoringUndoAct) |
|
509 |
|
510 self.refactoringRedoAct = E5Action( |
|
511 self.tr('Redo'), |
|
512 self.tr('Re&do'), |
|
513 0, 0, |
|
514 self, 'refactoring_redo') |
|
515 self.refactoringRedoAct.setStatusTip(self.tr( |
|
516 'Redo the last refactoring')) |
|
517 self.refactoringRedoAct.setWhatsThis(self.tr( |
|
518 """<b>Redo</b>""" |
|
519 """<p>Redo the last refactoring.</p>""" |
|
520 )) |
|
521 self.refactoringRedoAct.triggered.connect( |
|
522 self.__redo) |
|
523 self.actions.append(self.refactoringRedoAct) |
|
524 |
|
525 self.refactoringUndoHistoryAct = E5Action( |
|
526 self.tr('Show Project Undo History'), |
|
527 self.tr('Show Project Undo History'), |
|
528 0, 0, |
|
529 self, 'refactoring_show_project_undo_history') |
|
530 self.refactoringUndoHistoryAct.setStatusTip(self.tr( |
|
531 'Show the undo history of the project')) |
|
532 self.refactoringUndoHistoryAct.setWhatsThis(self.tr( |
|
533 """<b>Show Project Undo History</b>""" |
|
534 """<p>Opens a dialog to show the undo history list of""" |
|
535 """ the project.</p>""" |
508 """ the project.</p>""" |
536 )) |
509 )) |
537 self.refactoringUndoHistoryAct.triggered.connect( |
510 self.refactoringProjectHistoryAct.triggered.connect( |
538 self.__showProjectUndoHistory) |
511 self.__showProjectHistory) |
539 self.actions.append(self.refactoringUndoHistoryAct) |
512 self.actions.append(self.refactoringProjectHistoryAct) |
540 |
513 |
541 self.refactoringRedoHistoryAct = E5Action( |
514 self.refactoringFileHistoryAct = E5Action( |
542 self.tr('Show Project Redo History'), |
515 self.tr('Show Current File History'), |
543 self.tr('Show Project Redo History'), |
516 self.tr('Show Current File History...'), |
544 0, 0, |
517 0, 0, |
545 self, 'refactoring_show_project_redo_history') |
518 self, 'refactoring_show_file_history') |
546 self.refactoringRedoHistoryAct.setStatusTip(self.tr( |
519 self.refactoringFileHistoryAct.setStatusTip(self.tr( |
547 'Show the redo history of the project')) |
520 'Show the refactoring history of the current file')) |
548 self.refactoringRedoHistoryAct.setWhatsThis(self.tr( |
521 self.refactoringFileHistoryAct.setWhatsThis(self.tr( |
549 """<b>Show Project Redo History</b>""" |
522 """<b>Show Current File History</b>""" |
550 """<p>Opens a dialog to show the redo history list of""" |
523 """<p>This opens a dialog to show the refactoring history of""" |
551 """ the project.</p>""" |
|
552 )) |
|
553 self.refactoringRedoHistoryAct.triggered.connect( |
|
554 self.__showProjectRedoHistory) |
|
555 self.actions.append(self.refactoringRedoHistoryAct) |
|
556 |
|
557 self.refactoringUndoFileHistoryAct = E5Action( |
|
558 self.tr('Show Current File Undo History'), |
|
559 self.tr('Show Current File Undo History'), |
|
560 0, 0, |
|
561 self, 'refactoring_show_file_undo_history') |
|
562 self.refactoringUndoFileHistoryAct.setStatusTip(self.tr( |
|
563 'Show the undo history of the current file')) |
|
564 self.refactoringUndoFileHistoryAct.setWhatsThis(self.tr( |
|
565 """<b>Show Current File Undo History</b>""" |
|
566 """<p>Opens a dialog to show the undo history list of""" |
|
567 """ the current file.</p>""" |
524 """ the current file.</p>""" |
568 )) |
525 )) |
569 self.refactoringUndoFileHistoryAct.triggered.connect( |
526 self.refactoringFileHistoryAct.triggered.connect( |
570 self.__showFileUndoHistory) |
527 self.__showFileHistory) |
571 self.actions.append(self.refactoringUndoFileHistoryAct) |
528 self.actions.append(self.refactoringFileHistoryAct) |
572 |
|
573 self.refactoringRedoFileHistoryAct = E5Action( |
|
574 self.tr('Show Current File Redo History'), |
|
575 self.tr('Show Current File Redo History'), |
|
576 0, 0, |
|
577 self, 'refactoring_show_file_redo_history') |
|
578 self.refactoringRedoFileHistoryAct.setStatusTip(self.tr( |
|
579 'Show the redo history of the current file')) |
|
580 self.refactoringRedoFileHistoryAct.setWhatsThis(self.tr( |
|
581 """<b>Show Current File Redo History</b>""" |
|
582 """<p>Opens a dialog to show the redo history list of""" |
|
583 """ the current file.</p>""" |
|
584 )) |
|
585 self.refactoringRedoFileHistoryAct.triggered.connect( |
|
586 self.__showFileRedoHistory) |
|
587 self.actions.append(self.refactoringRedoFileHistoryAct) |
|
588 |
529 |
589 self.refactoringClearHistoryAct = E5Action( |
530 self.refactoringClearHistoryAct = E5Action( |
590 self.tr('Clear History'), |
531 self.tr('Clear History'), |
591 self.tr('Clear History'), |
532 self.tr('Clear History'), |
592 0, 0, |
533 0, 0, |
826 self.tr("{0}\nVersion {1}\n\n{2}".format( |
760 self.tr("{0}\nVersion {1}\n\n{2}".format( |
827 self.__ropeConfig["RopeInfo"], |
761 self.__ropeConfig["RopeInfo"], |
828 self.__ropeConfig["RopeVersion"], |
762 self.__ropeConfig["RopeVersion"], |
829 self.__ropeConfig["RopeCopyright"]))) |
763 self.__ropeConfig["RopeCopyright"]))) |
830 |
764 |
831 def __canUndo(self): |
|
832 """ |
|
833 Private slot to check, if there are changes to be undone. |
|
834 |
|
835 @return flag indicating, that undoable changes are available (boolean) |
|
836 """ |
|
837 return False |
|
838 return self.__project is not None and \ |
|
839 len(self.__project.history.undo_list) > 0 |
|
840 |
|
841 def __canRedo(self): |
|
842 """ |
|
843 Private slot to check, if there are changes to be redone. |
|
844 |
|
845 @return flag indicating, that redoable changes are available (boolean) |
|
846 """ |
|
847 return False |
|
848 return self.__project is not None and \ |
|
849 len(self.__project.history.redo_list) > 0 |
|
850 |
|
851 def __getFileUndoList(self, resource): |
|
852 """ |
|
853 Private slot to get a list of undoable changes. |
|
854 |
|
855 @param resource file resource to filter against |
|
856 (rope.base.resources.File) |
|
857 @return list of change objects (list of rope.base.change.Change) |
|
858 """ |
|
859 undoList = [] |
|
860 for change in self.__project.history.undo_list: |
|
861 if resource in change.get_changed_resources(): |
|
862 undoList.append(change) |
|
863 return undoList |
|
864 |
|
865 def __getFileRedoList(self, resource): |
|
866 """ |
|
867 Private slot to get a list of redoable changes. |
|
868 |
|
869 @param resource file resource to filter against |
|
870 (rope.base.resources.File) |
|
871 @return list of change objects (list of rope.base.change.Change) |
|
872 """ |
|
873 redoList = [] |
|
874 for change in self.__project.history.redo_list: |
|
875 if resource in change.get_changed_resources(): |
|
876 redoList.append(change) |
|
877 return redoList |
|
878 |
|
879 def __canUndoFile(self, resource): |
|
880 """ |
|
881 Private slot to check, if there are undoable changes for a resource. |
|
882 |
|
883 @param resource file resource to check against |
|
884 (rope.base.resources.File) |
|
885 @return flag indicating, that undoable changes are available (boolean) |
|
886 """ |
|
887 return self.__canUndo() and len(self.__getFileUndoList(resource)) > 0 |
|
888 |
|
889 def __canRedoFile(self, resource): |
|
890 """ |
|
891 Private slot to check, if there are redoable changes for a resource. |
|
892 |
|
893 @param resource file resource to check against |
|
894 (rope.base.resources.File) |
|
895 @return flag indicating, that redoable changes are available (boolean) |
|
896 """ |
|
897 return self.__canRedo() and len(self.__getFileRedoList(resource)) > 0 |
|
898 |
|
899 def __showRefactoringMenu(self): |
|
900 """ |
|
901 Private slot called before the refactoring menu is shown. |
|
902 """ |
|
903 self.refactoringUndoAct.setEnabled(self.__canUndo()) |
|
904 self.refactoringRedoAct.setEnabled(self.__canRedo()) |
|
905 |
|
906 def __showRefactoringHistoryMenu(self): |
765 def __showRefactoringHistoryMenu(self): |
907 """ |
766 """ |
908 Private slot called before the refactoring history menu is shown. |
767 Private slot called before the refactoring history menu is shown. |
909 """ |
768 """ |
910 aw = e5App().getObject("ViewManager").activeWindow() |
769 aw = e5App().getObject("ViewManager").activeWindow() |
911 resource = None |
770 enable = aw is not None and bool(aw.getFileName()) |
912 if aw is not None and self.__project is not None: |
771 |
913 filename = aw.getFileName() |
772 self.refactoringFileHistoryAct.setEnabled(enable) |
914 if filename is not None: |
773 |
915 resource = rope.base.libutils.path_to_resource( |
774 def handleRopeError(self, result): |
916 self.__project, filename) |
775 """ |
917 |
776 Public method to handle a rope error. |
918 self.refactoringUndoHistoryAct.setEnabled(self.__canUndo()) |
|
919 self.refactoringUndoFileHistoryAct.setEnabled( |
|
920 resource is not None and self.__canUndoFile(resource)) |
|
921 self.refactoringRedoHistoryAct.setEnabled(self.__canRedo()) |
|
922 self.refactoringRedoFileHistoryAct.setEnabled( |
|
923 resource is not None and self.__canRedoFile(resource)) |
|
924 |
|
925 def __handleRopeError(self, result): |
|
926 """ |
|
927 Private method to handle a rope error. |
|
928 |
777 |
929 @param result dictionary containing the error information |
778 @param result dictionary containing the error information |
930 @type dict |
779 @type dict |
931 @return flag indicating, that the error is to be ignored |
780 @return flag indicating, that the error is to be ignored |
932 @rtype bool |
781 @rtype bool |
1777 self.dlg = MethodToMethodObjectDialog(self, title, converter, |
1626 self.dlg = MethodToMethodObjectDialog(self, title, converter, |
1778 parent=self.__ui) |
1627 parent=self.__ui) |
1779 self.dlg.show() |
1628 self.dlg.show() |
1780 |
1629 |
1781 ##################################################### |
1630 ##################################################### |
1782 ## Undo/Redo refactorings |
1631 ## Refactoring History |
1783 ##################################################### |
1632 ##################################################### |
1784 |
1633 |
1785 def __undo(self): |
1634 def __showProjectHistory(self): |
1786 """ |
1635 """ |
1787 Private slot to undo the last refactoring. |
1636 Private method to show the project refactoring history. |
1788 """ |
1637 """ |
1789 title = self.tr("Undo refactoring") |
1638 if self.__historyDialog is not None: |
1790 history = self.__project.history |
1639 self.__historyDialog.close() |
1791 res = E5MessageBox.yesNo( |
1640 |
1792 None, |
|
1793 title, |
|
1794 self.tr("""Shall the refactoring <b>{0}</b> be undone?""") |
|
1795 .format(Utilities.html_encode( |
|
1796 history.undo_list[-1].description))) |
|
1797 if res: |
|
1798 if not self.confirmAllBuffersSaved(): |
|
1799 return |
|
1800 |
|
1801 from ProgressHandle import ProgressHandle |
|
1802 changes = history.undo_list[-1] |
|
1803 handle = ProgressHandle(self.tr("Undo"), False, self.__ui) |
|
1804 handle.show() |
|
1805 QApplication.processEvents() |
|
1806 try: |
|
1807 history.undo(task_handle=handle) |
|
1808 except Exception as err: |
|
1809 self.handleRopeError(err, title, handle) |
|
1810 handle.reset() |
|
1811 self.refreshEditors(changes) |
|
1812 if self.__e5project.isDirty(): |
|
1813 self.__e5project.saveProject() |
|
1814 |
|
1815 def __redo(self): |
|
1816 """ |
|
1817 Private slot to redo the last refactoring. |
|
1818 """ |
|
1819 title = self.tr("Redo refactoring") |
|
1820 history = self.__project.history |
|
1821 res = E5MessageBox.yesNo( |
|
1822 None, |
|
1823 title, |
|
1824 self.tr("""Shall the refactoring <b>{0}</b> be redone?""") |
|
1825 .format(Utilities.html_encode( |
|
1826 history.redo_list[-1].description))) |
|
1827 if res: |
|
1828 if not self.confirmAllBuffersSaved(): |
|
1829 return |
|
1830 |
|
1831 from ProgressHandle import ProgressHandle |
|
1832 changes = history.redo_list[-1] |
|
1833 handle = ProgressHandle(self.tr("Redo"), False, self.__ui) |
|
1834 handle.show() |
|
1835 QApplication.processEvents() |
|
1836 try: |
|
1837 history.redo(task_handle=handle) |
|
1838 except Exception as err: |
|
1839 self.handleRopeError(err, title, handle) |
|
1840 handle.reset() |
|
1841 self.refreshEditors(changes) |
|
1842 if self.__e5project.isDirty(): |
|
1843 self.__e5project.saveProject() |
|
1844 |
|
1845 def __showProjectUndoHistory(self): |
|
1846 """ |
|
1847 Private method to show list of changes available for an undo operation. |
|
1848 """ |
|
1849 from HistoryDialog import HistoryDialog |
1641 from HistoryDialog import HistoryDialog |
1850 undoList = list(reversed(self.__project.history.undo_list)) |
1642 self.__historyDialog = HistoryDialog(self, parent=self.__ui) |
1851 self.dlg = HistoryDialog(self, undoList, True, self.__ui) |
1643 self.__historyDialog.finished.connect(self.__historyDialogClosed) |
1852 self.dlg.show() |
1644 self.__historyDialog.show() |
1853 |
1645 |
1854 def __showProjectRedoHistory(self): |
1646 def __showFileHistory(self): |
1855 """ |
1647 """ |
1856 Private method to show list of changes available for a redo operation. |
1648 Private method to show the refactoring history of the current file. |
1857 """ |
|
1858 from HistoryDialog import HistoryDialog |
|
1859 redoList = self.__project.history.redo_list |
|
1860 self.dlg = HistoryDialog(self, redoList, False, self.__ui) |
|
1861 self.dlg.show() |
|
1862 |
|
1863 def __showFileUndoHistory(self): |
|
1864 """ |
|
1865 Private method to show list of changes related to the current file |
|
1866 available for an undo operation. |
|
1867 """ |
1649 """ |
1868 aw = e5App().getObject("ViewManager").activeWindow() |
1650 aw = e5App().getObject("ViewManager").activeWindow() |
1869 |
1651 |
1870 if aw is None: |
1652 if aw is None: |
1871 return |
1653 return |
|
1654 |
|
1655 if self.__historyDialog is not None: |
|
1656 self.__historyDialog.close() |
1872 |
1657 |
1873 from HistoryDialog import HistoryDialog |
1658 from HistoryDialog import HistoryDialog |
1874 filename = aw.getFileName() |
1659 filename = aw.getFileName() |
1875 resource = rope.base.libutils.path_to_resource( |
1660 if filename: |
1876 self.__project, filename) |
1661 self.__historyDialog = HistoryDialog( |
1877 undoList = list(reversed(self.__getFileUndoList(resource))) |
1662 self, filename=filename, parent=self.__ui) |
1878 self.dlg = HistoryDialog(self, undoList, True, self.__ui) |
1663 self.__historyDialog.show() |
1879 self.dlg.show() |
|
1880 |
|
1881 def __showFileRedoHistory(self): |
|
1882 """ |
|
1883 Private method to show list of changes related to the current file |
|
1884 available for a redo operation. |
|
1885 """ |
|
1886 aw = e5App().getObject("ViewManager").activeWindow() |
|
1887 |
|
1888 if aw is None: |
|
1889 return |
|
1890 |
|
1891 from HistoryDialog import HistoryDialog |
|
1892 filename = aw.getFileName() |
|
1893 resource = rope.base.libutils.path_to_resource( |
|
1894 self.__project, filename) |
|
1895 redoList = self.__getFileRedoList(resource) |
|
1896 self.dlg = HistoryDialog(self, redoList, False, self.__ui) |
|
1897 self.dlg.show() |
|
1898 |
1664 |
1899 def __clearHistory(self): |
1665 def __clearHistory(self): |
1900 """ |
1666 """ |
1901 Private slot to clear the redo and undo lists. |
1667 Private slot to clear the redo and undo lists. |
1902 """ |
1668 """ |
1903 res = E5MessageBox.yesNo( |
1669 res = E5MessageBox.yesNo( |
1904 None, |
1670 None, |
1905 self.tr("Clear History"), |
1671 self.tr("Clear History"), |
1906 self.tr("""Do you really want to clear the undo""" |
1672 self.tr("Do you really want to clear the refactoring history?")) |
1907 """ and redo history?""")) |
|
1908 if res: |
1673 if res: |
1909 self.__project.history.clear() |
1674 self.sendJson("History", { |
|
1675 "Subcommand": "Clear", |
|
1676 }) |
|
1677 |
|
1678 if self.__historyDialog is not None: |
|
1679 self.__historyDialog.historyCleared() |
|
1680 |
|
1681 def __processHistoryResult(self, result): |
|
1682 """ |
|
1683 Private method to process the history data sent by the refactoring |
|
1684 client. |
|
1685 |
|
1686 @param result dictionary containing the history data |
|
1687 @type dict |
|
1688 """ |
|
1689 if self.handleRopeError(result) and self.__historyDialog is not None: |
|
1690 self.__historyDialog.processHistoryCommand(result) |
|
1691 |
|
1692 def __historyDialogClosed(self): |
|
1693 """ |
|
1694 Private slot handling the closing of the history dialog. |
|
1695 """ |
|
1696 self.__historyDialog = None |
1910 |
1697 |
1911 ##################################################### |
1698 ##################################################### |
1912 ## Find actions including mouse click handler |
1699 ## Find actions including mouse click handler |
1913 ##################################################### |
1700 ##################################################### |
1914 |
1701 |
2331 """ |
2118 """ |
2332 for act in self.actions: |
2119 for act in self.actions: |
2333 act.setEnabled(False) |
2120 act.setEnabled(False) |
2334 self.__mainMenu.menuAction().setEnabled(False) |
2121 self.__mainMenu.menuAction().setEnabled(False) |
2335 |
2122 |
2336 self.stopClient() |
2123 if self.__helpDialog is not None: |
|
2124 self.__helpDialog.close() |
|
2125 self.__helpDialog = None |
|
2126 if self.__historyDialog is not None: |
|
2127 self.__historyDialog.close() |
|
2128 self.__historyDialog = None |
|
2129 |
|
2130 self.sendJson("CloseProject", {}, flush=True) |
2337 |
2131 |
2338 self.__projectopen = False |
2132 self.__projectopen = False |
2339 self.__projectpath = '' |
2133 self.__projectpath = '' |
2340 self.__projectLanguage = "" |
2134 self.__projectLanguage = "" |
2341 self.__ropeConfig = {} |
2135 self.__ropeConfig = {} |
2342 |
2136 |
2343 # TODO: delete this or move to client |
2137 self.stopClient() |
2344 ## def getProject(self): |
2138 |
2345 ## """ |
|
2346 ## Public method to get a reference to the rope project object. |
|
2347 ## |
|
2348 ## @return reference to the rope project object (RopeProject) |
|
2349 ## """ |
|
2350 ## return self.__project |
|
2351 ## |
|
2352 def confirmBufferIsSaved(self, editor): |
2139 def confirmBufferIsSaved(self, editor): |
2353 """ |
2140 """ |
2354 Public method to check, if an editor has unsaved changes. |
2141 Public method to check, if an editor has unsaved changes. |
2355 |
2142 |
2356 @param editor reference to the editor to be checked |
2143 @param editor reference to the editor to be checked |
2370 """ |
2157 """ |
2371 res = e5App().getObject("ViewManager").checkAllDirty() |
2158 res = e5App().getObject("ViewManager").checkAllDirty() |
2372 self.sendJson("Validate", {}) |
2159 self.sendJson("Validate", {}) |
2373 return res |
2160 return res |
2374 |
2161 |
2375 # TODO: port this |
2162 def refreshEditors(self, changedFiles): |
2376 def refreshEditors(self, changes): |
|
2377 """ |
2163 """ |
2378 Public method to refresh modified editors. |
2164 Public method to refresh modified editors. |
2379 |
2165 |
2380 @param changes reference to the ChangeSet object |
2166 @param changedFiles list of changed files |
2381 (rope.base.change.ChangeSet) |
2167 @type list of str |
2382 """ |
2168 """ |
2383 vm = e5App().getObject("ViewManager") |
2169 vm = e5App().getObject("ViewManager") |
2384 |
|
2385 changedFiles = [] |
|
2386 # for resource in changes.get_changed_resources(): |
|
2387 # if not resource.is_folder(): |
|
2388 # changedFiles.append(resource.real_path) |
|
2389 |
|
2390 openFiles = [Utilities.normcasepath(f) for f in vm.getOpenFilenames()] |
2170 openFiles = [Utilities.normcasepath(f) for f in vm.getOpenFilenames()] |
2391 |
2171 |
2392 for file in changedFiles: |
2172 for fileName in changedFiles: |
2393 normfile = Utilities.normcasepath(file) |
2173 normfile = Utilities.normcasepath(fileName) |
2394 if normfile in openFiles: |
2174 if normfile in openFiles: |
2395 editor = vm.getEditor(normfile)[1] |
2175 editor = vm.getEditor(normfile)[1] |
2396 editor.refresh() |
2176 editor.refresh() |
2397 |
2177 |
2398 aw = vm.activeWindow() |
2178 aw = vm.activeWindow() |