10278:e26fa3b06f4f | 10279:e6e270b705c2 |
---|---|
29 Qt, | 29 Qt, |
30 QTimer, | 30 QTimer, |
31 pyqtSignal, | 31 pyqtSignal, |
32 pyqtSlot, | 32 pyqtSlot, |
33 ) | 33 ) |
34 from PyQt6.QtGui import QActionGroup, QFont, QPainter, QPalette, QPixmap | 34 from PyQt6.QtGui import QAction, QActionGroup, QFont, QPainter, QPalette, QPixmap |
35 from PyQt6.QtPrintSupport import ( | 35 from PyQt6.QtPrintSupport import ( |
36 QAbstractPrintDialog, | 36 QAbstractPrintDialog, |
37 QPrintDialog, | 37 QPrintDialog, |
38 QPrinter, | 38 QPrinter, |
39 QPrintPreviewDialog, | 39 QPrintPreviewDialog, |
147 mouseDoubleClick = pyqtSignal(QPoint, Qt.MouseButton) | 147 mouseDoubleClick = pyqtSignal(QPoint, Qt.MouseButton) |
148 | 148 |
149 WarningCode = 1 | 149 WarningCode = 1 |
150 WarningPython = 2 | 150 WarningPython = 2 |
151 WarningStyle = 3 | 151 WarningStyle = 3 |
152 WarningInfo = 4 | |
152 | 153 |
153 # Autocompletion icon definitions | 154 # Autocompletion icon definitions |
154 ClassID = 1 | 155 ClassID = 1 |
155 ClassProtectedID = 2 | 156 ClassProtectedID = 2 |
156 ClassPrivateID = 3 | 157 ClassPrivateID = 3 |
249 # bookmarks are just a list of handles to the | 250 # bookmarks are just a list of handles to the |
250 # bookmark markers | 251 # bookmark markers |
251 self.syntaxerrors = {} | 252 self.syntaxerrors = {} |
252 # key: marker handle | 253 # key: marker handle |
253 # value: list of (error message, error index) | 254 # value: list of (error message, error index) |
254 self.warnings = {} | 255 self._warnings = {} |
255 # key: marker handle | 256 # key: marker handle |
256 # value: list of (warning message, warning type) | 257 # value: list of (warning message, warning type) |
257 self.notcoveredMarkers = [] # just a list of marker handles | 258 self.notcoveredMarkers = [] # just a list of marker handles |
258 self.showingNotcoveredMarkers = False | 259 self.showingNotcoveredMarkers = False |
259 | 260 |
569 # it's a clone | 570 # it's a clone |
570 self.__languageChanged(editor.apiLanguage, propagate=False) | 571 self.__languageChanged(editor.apiLanguage, propagate=False) |
571 self.__encodingChanged(editor.encoding, propagate=False) | 572 self.__encodingChanged(editor.encoding, propagate=False) |
572 self.__spellLanguageChanged(editor.getSpellingLanguage(), propagate=False) | 573 self.__spellLanguageChanged(editor.getSpellingLanguage(), propagate=False) |
573 # link the warnings to the original editor | 574 # link the warnings to the original editor |
574 self.warnings = editor.warnings | 575 self._warnings = editor._warnings |
575 | 576 |
576 self.setAcceptDrops(True) | 577 self.setAcceptDrops(True) |
577 | 578 |
578 # breakpoint handling | 579 # breakpoint handling |
579 self.breakpointModel = self.dbs.getBreakPointModel() | 580 self.breakpointModel = self.dbs.getBreakPointModel() |
1537 self, | 1538 self, |
1538 self.tr("Export source"), | 1539 self.tr("Export source"), |
1539 self.tr("""No export format given. Aborting..."""), | 1540 self.tr("""No export format given. Aborting..."""), |
1540 ) | 1541 ) |
1541 | 1542 |
1543 @pyqtSlot() | |
1542 def __showContextMenuLanguages(self): | 1544 def __showContextMenuLanguages(self): |
1543 """ | 1545 """ |
1544 Private slot handling the aboutToShow signal of the languages context | 1546 Private slot handling the aboutToShow signal of the languages context |
1545 menu. | 1547 menu. |
1546 """ | 1548 """ |
1603 | 1605 |
1604 self.__docstringGenerator = None | 1606 self.__docstringGenerator = None |
1605 | 1607 |
1606 def __languageChanged(self, language, propagate=True): | 1608 def __languageChanged(self, language, propagate=True): |
1607 """ | 1609 """ |
1608 Private slot handling a change of a connected editor's language. | 1610 Private method handling a change of a connected editor's language. |
1609 | 1611 |
1610 @param language language to be set (string) | 1612 @param language language to be set (string) |
1611 @param propagate flag indicating to propagate the change (boolean) | 1613 @param propagate flag indicating to propagate the change (boolean) |
1612 """ | 1614 """ |
1613 if language == "": | 1615 if language == "": |
1708 if act: | 1710 if act: |
1709 act.setChecked(False) | 1711 act.setChecked(False) |
1710 else: | 1712 else: |
1711 self.supportedLanguages[self.apiLanguage][2].setChecked(True) | 1713 self.supportedLanguages[self.apiLanguage][2].setChecked(True) |
1712 | 1714 |
1715 @pyqtSlot() | |
1713 def projectLexerAssociationsChanged(self): | 1716 def projectLexerAssociationsChanged(self): |
1714 """ | 1717 """ |
1715 Public slot to handle changes of the project lexer associations. | 1718 Public slot to handle changes of the project lexer associations. |
1716 """ | 1719 """ |
1717 self.setLanguage(self.fileName) | 1720 self.setLanguage(self.fileName) |
1718 | 1721 |
1722 @pyqtSlot() | |
1719 def __showContextMenuEncodings(self): | 1723 def __showContextMenuEncodings(self): |
1720 """ | 1724 """ |
1721 Private slot handling the aboutToShow signal of the encodings context | 1725 Private slot handling the aboutToShow signal of the encodings context |
1722 menu. | 1726 menu. |
1723 """ | 1727 """ |
1738 Private method to check the selected encoding of the encodings submenu. | 1742 Private method to check the selected encoding of the encodings submenu. |
1739 """ | 1743 """ |
1740 with contextlib.suppress(AttributeError, KeyError): | 1744 with contextlib.suppress(AttributeError, KeyError): |
1741 (self.supportedEncodings[self.__normalizedEncoding()].setChecked(True)) | 1745 (self.supportedEncodings[self.__normalizedEncoding()].setChecked(True)) |
1742 | 1746 |
1747 @pyqtSlot(str) | |
1743 def __encodingChanged(self, encoding, propagate=True): | 1748 def __encodingChanged(self, encoding, propagate=True): |
1744 """ | 1749 """ |
1745 Private slot to handle a change of the encoding. | 1750 Private slot to handle a change of the encoding. |
1746 | 1751 |
1747 @param encoding changed encoding (string) | 1752 @param encoding changed encoding |
1748 @param propagate flag indicating to propagate the change (boolean) | 1753 @type str |
1754 @param propagate flag indicating to propagate the change | |
1755 @type bool | |
1749 """ | 1756 """ |
1750 self.encoding = encoding | 1757 self.encoding = encoding |
1751 self.__checkEncoding() | 1758 self.__checkEncoding() |
1752 | 1759 |
1753 if not self.inEncodingChanged and propagate: | 1760 if not self.inEncodingChanged and propagate: |
1768 encoding.replace("-default", "") | 1775 encoding.replace("-default", "") |
1769 .replace("-guessed", "") | 1776 .replace("-guessed", "") |
1770 .replace("-selected", "") | 1777 .replace("-selected", "") |
1771 ) | 1778 ) |
1772 | 1779 |
1780 @pyqtSlot() | |
1773 def __showContextMenuEol(self): | 1781 def __showContextMenuEol(self): |
1774 """ | 1782 """ |
1775 Private slot handling the aboutToShow signal of the eol context menu. | 1783 Private slot handling the aboutToShow signal of the eol context menu. |
1776 """ | 1784 """ |
1777 self.showMenu.emit("Eol", self.eolMenu, self) | 1785 self.showMenu.emit("Eol", self.eolMenu, self) |
1791 Private method to check the selected eol type of the eol submenu. | 1799 Private method to check the selected eol type of the eol submenu. |
1792 """ | 1800 """ |
1793 with contextlib.suppress(AttributeError, TypeError): | 1801 with contextlib.suppress(AttributeError, TypeError): |
1794 self.supportedEols[self.getLineSeparator()].setChecked(True) | 1802 self.supportedEols[self.getLineSeparator()].setChecked(True) |
1795 | 1803 |
1804 @pyqtSlot() | |
1796 def __eolChanged(self): | 1805 def __eolChanged(self): |
1797 """ | 1806 """ |
1798 Private slot to handle a change of the eol mode. | 1807 Private slot to handle a change of the eol mode. |
1799 """ | 1808 """ |
1800 self.__checkEol() | 1809 self.__checkEol() |
1803 self.inEolChanged = True | 1812 self.inEolChanged = True |
1804 eol = self.getLineSeparator() | 1813 eol = self.getLineSeparator() |
1805 self.eolChanged.emit(eol) | 1814 self.eolChanged.emit(eol) |
1806 self.inEolChanged = False | 1815 self.inEolChanged = False |
1807 | 1816 |
1817 @pyqtSlot() | |
1808 def __showContextMenuSpellCheck(self): | 1818 def __showContextMenuSpellCheck(self): |
1809 """ | 1819 """ |
1810 Private slot handling the aboutToShow signal of the spell check | 1820 Private slot handling the aboutToShow signal of the spell check |
1811 context menu. | 1821 context menu. |
1812 """ | 1822 """ |
1820 ) | 1830 ) |
1821 self.menuActs["SpellCheckLanguages"].setEnabled(spellingAvailable) | 1831 self.menuActs["SpellCheckLanguages"].setEnabled(spellingAvailable) |
1822 | 1832 |
1823 self.showMenu.emit("SpellCheck", self.spellCheckMenu, self) | 1833 self.showMenu.emit("SpellCheck", self.spellCheckMenu, self) |
1824 | 1834 |
1835 @pyqtSlot() | |
1825 def __showContextMenuSpellLanguages(self): | 1836 def __showContextMenuSpellLanguages(self): |
1826 """ | 1837 """ |
1827 Private slot handling the aboutToShow signal of the spell check | 1838 Private slot handling the aboutToShow signal of the spell check |
1828 languages context menu. | 1839 languages context menu. |
1829 """ | 1840 """ |
1838 """ | 1849 """ |
1839 language = act.data() | 1850 language = act.data() |
1840 self.__setSpellingLanguage(language) | 1851 self.__setSpellingLanguage(language) |
1841 self.spellLanguageChanged.emit(language) | 1852 self.spellLanguageChanged.emit(language) |
1842 | 1853 |
1854 @pyqtSlot() | |
1843 def __checkSpellLanguage(self): | 1855 def __checkSpellLanguage(self): |
1844 """ | 1856 """ |
1845 Private slot to check the selected spell check language action. | 1857 Private slot to check the selected spell check language action. |
1846 """ | 1858 """ |
1847 language = self.getSpellingLanguage() | 1859 language = self.getSpellingLanguage() |
1848 with contextlib.suppress(AttributeError, KeyError): | 1860 with contextlib.suppress(AttributeError, KeyError): |
1849 self.supportedSpellLanguages[language].setChecked(True) | 1861 self.supportedSpellLanguages[language].setChecked(True) |
1850 | 1862 |
1863 @pyqtSlot(str) | |
1851 def __spellLanguageChanged(self, language, propagate=True): | 1864 def __spellLanguageChanged(self, language, propagate=True): |
1852 """ | 1865 """ |
1853 Private slot to handle a change of the spell check language. | 1866 Private slot to handle a change of the spell check language. |
1854 | 1867 |
1855 @param language new spell check language | 1868 @param language new spell check language |
1865 self.spellLanguageChanged.emit(language) | 1878 self.spellLanguageChanged.emit(language) |
1866 self.__inSpellLanguageChanged = False | 1879 self.__inSpellLanguageChanged = False |
1867 | 1880 |
1868 def __bindLexer(self, filename, pyname=""): | 1881 def __bindLexer(self, filename, pyname=""): |
1869 """ | 1882 """ |
1870 Private slot to set the correct lexer depending on language. | 1883 Private method to set the correct lexer depending on language. |
1871 | 1884 |
1872 @param filename filename used to determine the associated lexer | 1885 @param filename filename used to determine the associated lexer |
1873 language (string) | 1886 language |
1874 @param pyname name of the pygments lexer to use (string) | 1887 @type str |
1888 @param pyname name of the pygments lexer to use | |
1889 @type str | |
1875 """ | 1890 """ |
1876 if self.lexer_ is not None and ( | 1891 if self.lexer_ is not None and ( |
1877 self.lexer_.lexer() == "container" or self.lexer_.lexer() is None | 1892 self.lexer_.lexer() == "container" or self.lexer_.lexer() is None |
1878 ): | 1893 ): |
1879 self.SCN_STYLENEEDED.disconnect(self.__styleNeeded) | 1894 self.SCN_STYLENEEDED.disconnect(self.__styleNeeded) |
1981 self.__setAnnotationStyles() | 1996 self.__setAnnotationStyles() |
1982 | 1997 |
1983 self.lexer_.setDefaultColor(self.lexer_.color(0)) | 1998 self.lexer_.setDefaultColor(self.lexer_.color(0)) |
1984 self.lexer_.setDefaultPaper(self.lexer_.paper(0)) | 1999 self.lexer_.setDefaultPaper(self.lexer_.paper(0)) |
1985 | 2000 |
2001 @pyqtSlot(int) | |
1986 def __styleNeeded(self, position): | 2002 def __styleNeeded(self, position): |
1987 """ | 2003 """ |
1988 Private slot to handle the need for more styling. | 2004 Private slot to handle the need for more styling. |
1989 | 2005 |
1990 @param position end position, that needs styling (integer) | 2006 @param position end position, that needs styling |
2007 @type int | |
1991 """ | 2008 """ |
1992 self.lexer_.styleText(self.getEndStyled(), position) | 2009 self.lexer_.styleText(self.getEndStyled(), position) |
1993 | 2010 |
1994 def getLexer(self): | 2011 def getLexer(self): |
1995 """ | 2012 """ |
2031 """ | 2048 """ |
2032 return self.apiLanguage | 2049 return self.apiLanguage |
2033 | 2050 |
2034 def __bindCompleter(self, filename): | 2051 def __bindCompleter(self, filename): |
2035 """ | 2052 """ |
2036 Private slot to set the correct typing completer depending on language. | 2053 Private method to set the correct typing completer depending on language. |
2037 | 2054 |
2038 @param filename filename used to determine the associated typing | 2055 @param filename filename used to determine the associated typing |
2039 completer language (string) | 2056 completer language |
2057 @type str | |
2040 """ | 2058 """ |
2041 if self.completer is not None: | 2059 if self.completer is not None: |
2042 self.completer.setEnabled(False) | 2060 self.completer.setEnabled(False) |
2043 self.completer = None | 2061 self.completer = None |
2044 | 2062 |
2059 | 2077 |
2060 @return the completer object (CompleterBase) | 2078 @return the completer object (CompleterBase) |
2061 """ | 2079 """ |
2062 return self.completer | 2080 return self.completer |
2063 | 2081 |
2082 @pyqtSlot(bool) | |
2064 def __modificationChanged(self, m): | 2083 def __modificationChanged(self, m): |
2065 """ | 2084 """ |
2066 Private slot to handle the modificationChanged signal. | 2085 Private slot to handle the modificationChanged signal. |
2067 | 2086 |
2068 It emits the signal modificationStatusChanged with parameters | 2087 It emits the signal modificationStatusChanged with parameters |
2069 m and self. | 2088 m and self. |
2070 | 2089 |
2071 @param m modification status | 2090 @param m modification status |
2091 @type bool | |
2072 """ | 2092 """ |
2073 if not m and bool(self.fileName) and pathlib.Path(self.fileName).exists(): | 2093 if not m and bool(self.fileName) and pathlib.Path(self.fileName).exists(): |
2074 self.lastModified = pathlib.Path(self.fileName).stat().st_mtime | 2094 self.lastModified = pathlib.Path(self.fileName).stat().st_mtime |
2075 self.modificationStatusChanged.emit(m, self) | 2095 self.modificationStatusChanged.emit(m, self) |
2076 self.undoAvailable.emit(self.isUndoAvailable()) | 2096 self.undoAvailable.emit(self.isUndoAvailable()) |
2077 self.redoAvailable.emit(self.isRedoAvailable()) | 2097 self.redoAvailable.emit(self.isRedoAvailable()) |
2078 | 2098 |
2099 @pyqtSlot(int, int) | |
2079 def __cursorPositionChanged(self, line, index): | 2100 def __cursorPositionChanged(self, line, index): |
2080 """ | 2101 """ |
2081 Private slot to handle the cursorPositionChanged signal. | 2102 Private slot to handle the cursorPositionChanged signal. |
2082 | 2103 |
2083 It emits the signal cursorChanged with parameters fileName, | 2104 It emits the signal cursorChanged with parameters fileName, |
2084 line and pos. | 2105 line and pos. |
2085 | 2106 |
2086 @param line line number of the cursor | 2107 @param line line number of the cursor |
2108 @type int | |
2087 @param index position in line of the cursor | 2109 @param index position in line of the cursor |
2110 @type int | |
2088 """ | 2111 """ |
2089 self.cursorChanged.emit(self.fileName, line + 1, index) | 2112 self.cursorChanged.emit(self.fileName, line + 1, index) |
2090 | 2113 |
2091 if Preferences.getEditor("MarkOccurrencesEnabled"): | 2114 if Preferences.getEditor("MarkOccurrencesEnabled"): |
2092 self.__markOccurrencesTimer.stop() | 2115 self.__markOccurrencesTimer.stop() |
2110 self.__markerMap.update() | 2133 self.__markerMap.update() |
2111 | 2134 |
2112 self.lastLine = line | 2135 self.lastLine = line |
2113 self.lastIndex = index | 2136 self.lastIndex = index |
2114 | 2137 |
2138 @pyqtSlot() | |
2115 def __modificationReadOnly(self): | 2139 def __modificationReadOnly(self): |
2116 """ | 2140 """ |
2117 Private slot to handle the modificationAttempted signal. | 2141 Private slot to handle the modificationAttempted signal. |
2118 """ | 2142 """ |
2119 EricMessageBox.warning( | 2143 EricMessageBox.warning( |
2402 | 2426 |
2403 def __restoreBreakpoints(self): | 2427 def __restoreBreakpoints(self): |
2404 """ | 2428 """ |
2405 Private method to restore the breakpoints. | 2429 Private method to restore the breakpoints. |
2406 """ | 2430 """ |
2407 for handle in list(self.breaks.keys()): | 2431 for handle in self.breaks: |
2408 self.markerDeleteHandle(handle) | 2432 self.markerDeleteHandle(handle) |
2409 self.__addBreakPoints(QModelIndex(), 0, self.breakpointModel.rowCount() - 1) | 2433 self.__addBreakPoints(QModelIndex(), 0, self.breakpointModel.rowCount() - 1) |
2410 self.__markerMap.update() | 2434 self.__markerMap.update() |
2411 | 2435 |
2436 @pyqtSlot(QModelIndex, int, int) | |
2412 def __deleteBreakPoints(self, parentIndex, start, end): | 2437 def __deleteBreakPoints(self, parentIndex, start, end): |
2413 """ | 2438 """ |
2414 Private slot to delete breakpoints. | 2439 Private slot to delete breakpoints. |
2415 | 2440 |
2416 @param parentIndex index of parent item (QModelIndex) | 2441 @param parentIndex index of parent item |
2417 @param start start row (integer) | 2442 @type QModelIndex |
2418 @param end end row (integer) | 2443 @param start start row |
2444 @type int | |
2445 @param end end row | |
2446 @type int | |
2419 """ | 2447 """ |
2420 for row in range(start, end + 1): | 2448 for row in range(start, end + 1): |
2421 index = self.breakpointModel.index(row, 0, parentIndex) | 2449 index = self.breakpointModel.index(row, 0, parentIndex) |
2422 fn, lineno = self.breakpointModel.getBreakPointByIndex(index)[0:2] | 2450 fn, lineno = self.breakpointModel.getBreakPointByIndex(index)[0:2] |
2423 if fn == self.fileName: | 2451 if fn == self.fileName: |
2424 self.clearBreakpoint(lineno) | 2452 self.clearBreakpoint(lineno) |
2425 | 2453 |
2454 @pyqtSlot(QModelIndex, QModelIndex) | |
2426 def __changeBreakPoints(self, startIndex, endIndex): | 2455 def __changeBreakPoints(self, startIndex, endIndex): |
2427 """ | 2456 """ |
2428 Private slot to set changed breakpoints. | 2457 Private slot to set changed breakpoints. |
2429 | 2458 |
2430 @param startIndex start index of the breakpoints being changed | 2459 @param startIndex start index of the breakpoints being changed |
2431 (QModelIndex) | 2460 @type QModelIndex |
2432 @param endIndex end index of the breakpoints being changed | 2461 @param endIndex end index of the breakpoints being changed |
2433 (QModelIndex) | 2462 @type QModelIndex |
2434 """ | 2463 """ |
2435 if not self.inLinesChanged: | 2464 if not self.inLinesChanged: |
2436 self.__addBreakPoints(QModelIndex(), startIndex.row(), endIndex.row()) | 2465 self.__addBreakPoints(QModelIndex(), startIndex.row(), endIndex.row()) |
2437 | 2466 |
2467 @pyqtSlot(QModelIndex, QModelIndex) | |
2438 def __breakPointDataAboutToBeChanged(self, startIndex, endIndex): | 2468 def __breakPointDataAboutToBeChanged(self, startIndex, endIndex): |
2439 """ | 2469 """ |
2440 Private slot to handle the dataAboutToBeChanged signal of the | 2470 Private slot to handle the dataAboutToBeChanged signal of the |
2441 breakpoint model. | 2471 breakpoint model. |
2442 | 2472 |
2443 @param startIndex start index of the rows to be changed (QModelIndex) | 2473 @param startIndex start index of the rows to be changed |
2444 @param endIndex end index of the rows to be changed (QModelIndex) | 2474 @type QModelIndex |
2475 @param endIndex end index of the rows to be changed | |
2476 @type QModelIndex | |
2445 """ | 2477 """ |
2446 self.__deleteBreakPoints(QModelIndex(), startIndex.row(), endIndex.row()) | 2478 self.__deleteBreakPoints(QModelIndex(), startIndex.row(), endIndex.row()) |
2447 | 2479 |
2480 @pyqtSlot(QModelIndex, int, int) | |
2448 def __addBreakPoints(self, parentIndex, start, end): | 2481 def __addBreakPoints(self, parentIndex, start, end): |
2449 """ | 2482 """ |
2450 Private slot to add breakpoints. | 2483 Private slot to add breakpoints. |
2451 | 2484 |
2452 @param parentIndex index of parent item (QModelIndex) | 2485 @param parentIndex index of parent item |
2453 @param start start row (integer) | 2486 @type QModelIndex |
2454 @param end end row (integer) | 2487 @param start start row |
2488 @type int | |
2489 @param end end row | |
2490 @type int | |
2455 """ | 2491 """ |
2456 for row in range(start, end + 1): | 2492 for row in range(start, end + 1): |
2457 index = self.breakpointModel.index(row, 0, parentIndex) | 2493 index = self.breakpointModel.index(row, 0, parentIndex) |
2458 ( | 2494 ( |
2459 fn, | 2495 fn, |
2613 | 2649 |
2614 @return flag indicating the presence of breakpoints (boolean) | 2650 @return flag indicating the presence of breakpoints (boolean) |
2615 """ | 2651 """ |
2616 return len(self.breaks) > 0 | 2652 return len(self.breaks) > 0 |
2617 | 2653 |
2654 @pyqtSlot() | |
2618 def __menuToggleTemporaryBreakpoint(self): | 2655 def __menuToggleTemporaryBreakpoint(self): |
2619 """ | 2656 """ |
2620 Private slot to handle the 'Toggle temporary breakpoint' context menu | 2657 Private slot to handle the 'Toggle temporary breakpoint' context menu |
2621 action. | 2658 action. |
2622 """ | 2659 """ |
2624 self.line, index = self.getCursorPosition() | 2661 self.line, index = self.getCursorPosition() |
2625 self.line += 1 | 2662 self.line += 1 |
2626 self.__toggleBreakpoint(self.line, 1) | 2663 self.__toggleBreakpoint(self.line, 1) |
2627 self.line = -1 | 2664 self.line = -1 |
2628 | 2665 |
2666 @pyqtSlot() | |
2629 def menuToggleBreakpoint(self): | 2667 def menuToggleBreakpoint(self): |
2630 """ | 2668 """ |
2631 Public slot to handle the 'Toggle breakpoint' context menu action. | 2669 Public slot to handle the 'Toggle breakpoint' context menu action. |
2632 """ | 2670 """ |
2633 if self.line < 0: | 2671 if self.line < 0: |
2634 self.line, index = self.getCursorPosition() | 2672 self.line, index = self.getCursorPosition() |
2635 self.line += 1 | 2673 self.line += 1 |
2636 self.__toggleBreakpoint(self.line) | 2674 self.__toggleBreakpoint(self.line) |
2637 self.line = -1 | 2675 self.line = -1 |
2638 | 2676 |
2677 @pyqtSlot() | |
2639 def __menuToggleBreakpointEnabled(self): | 2678 def __menuToggleBreakpointEnabled(self): |
2640 """ | 2679 """ |
2641 Private slot to handle the 'Enable/Disable breakpoint' context menu | 2680 Private slot to handle the 'Enable/Disable breakpoint' context menu |
2642 action. | 2681 action. |
2643 """ | 2682 """ |
2645 self.line, index = self.getCursorPosition() | 2684 self.line, index = self.getCursorPosition() |
2646 self.line += 1 | 2685 self.line += 1 |
2647 self.__toggleBreakpointEnabled(self.line) | 2686 self.__toggleBreakpointEnabled(self.line) |
2648 self.line = -1 | 2687 self.line = -1 |
2649 | 2688 |
2689 @pyqtSlot() | |
2650 def menuEditBreakpoint(self, line=None): | 2690 def menuEditBreakpoint(self, line=None): |
2651 """ | 2691 """ |
2652 Public slot to handle the 'Edit breakpoint' context menu action. | 2692 Public slot to handle the 'Edit breakpoint' context menu action. |
2653 | 2693 |
2654 @param line linenumber of the breakpoint to edit | 2694 @param line line number of the breakpoint to edit |
2695 @type int | |
2655 """ | 2696 """ |
2656 from eric7.Debugger.EditBreakpointDialog import EditBreakpointDialog | 2697 from eric7.Debugger.EditBreakpointDialog import EditBreakpointDialog |
2657 | 2698 |
2658 if line is not None: | 2699 if line is not None: |
2659 self.line = line - 1 | 2700 self.line = line - 1 |
2700 | 2741 |
2701 break | 2742 break |
2702 | 2743 |
2703 self.line = -1 | 2744 self.line = -1 |
2704 | 2745 |
2746 @pyqtSlot() | |
2705 def menuNextBreakpoint(self): | 2747 def menuNextBreakpoint(self): |
2706 """ | 2748 """ |
2707 Public slot to handle the 'Next breakpoint' context menu action. | 2749 Public slot to handle the 'Next breakpoint' context menu action. |
2708 """ | 2750 """ |
2709 line, index = self.getCursorPosition() | 2751 line, index = self.getCursorPosition() |
2717 bpline = self.markerFindNext(0, self.breakpointMask) | 2759 bpline = self.markerFindNext(0, self.breakpointMask) |
2718 if bpline >= 0: | 2760 if bpline >= 0: |
2719 self.setCursorPosition(bpline, 0) | 2761 self.setCursorPosition(bpline, 0) |
2720 self.ensureLineVisible(bpline) | 2762 self.ensureLineVisible(bpline) |
2721 | 2763 |
2764 @pyqtSlot() | |
2722 def menuPreviousBreakpoint(self): | 2765 def menuPreviousBreakpoint(self): |
2723 """ | 2766 """ |
2724 Public slot to handle the 'Previous breakpoint' context menu action. | 2767 Public slot to handle the 'Previous breakpoint' context menu action. |
2725 """ | 2768 """ |
2726 line, index = self.getCursorPosition() | 2769 line, index = self.getCursorPosition() |
2734 bpline = self.markerFindPrevious(self.lines() - 1, self.breakpointMask) | 2777 bpline = self.markerFindPrevious(self.lines() - 1, self.breakpointMask) |
2735 if bpline >= 0: | 2778 if bpline >= 0: |
2736 self.setCursorPosition(bpline, 0) | 2779 self.setCursorPosition(bpline, 0) |
2737 self.ensureLineVisible(bpline) | 2780 self.ensureLineVisible(bpline) |
2738 | 2781 |
2782 @pyqtSlot() | |
2739 def __menuClearBreakpoints(self): | 2783 def __menuClearBreakpoints(self): |
2740 """ | 2784 """ |
2741 Private slot to handle the 'Clear all breakpoints' context menu action. | 2785 Private slot to handle the 'Clear all breakpoints' context menu action. |
2742 """ | 2786 """ |
2743 self.__clearBreakpoints(self.fileName) | 2787 self.__clearBreakpoints(self.fileName) |
2744 | 2788 |
2745 def __clearBreakpoints(self, fileName): | 2789 def __clearBreakpoints(self, fileName): |
2746 """ | 2790 """ |
2747 Private slot to clear all breakpoints. | 2791 Private method to clear all breakpoints. |
2748 | 2792 |
2749 @param fileName name of the file (string) | 2793 @param fileName name of the file |
2794 @type str | |
2750 """ | 2795 """ |
2751 idxList = [] | 2796 idxList = [] |
2752 for ln, _, _, _, _ in self.breaks.values(): | 2797 for ln, _, _, _, _ in self.breaks.values(): |
2753 index = self.breakpointModel.getBreakPointIndex(fileName, ln) | 2798 index = self.breakpointModel.getBreakPointIndex(fileName, ln) |
2754 if index.isValid(): | 2799 if index.isValid(): |
2814 | 2859 |
2815 @return flag indicating the presence of bookmarks (boolean) | 2860 @return flag indicating the presence of bookmarks (boolean) |
2816 """ | 2861 """ |
2817 return len(self.bookmarks) > 0 | 2862 return len(self.bookmarks) > 0 |
2818 | 2863 |
2864 @pyqtSlot() | |
2819 def menuToggleBookmark(self): | 2865 def menuToggleBookmark(self): |
2820 """ | 2866 """ |
2821 Public slot to handle the 'Toggle bookmark' context menu action. | 2867 Public slot to handle the 'Toggle bookmark' context menu action. |
2822 """ | 2868 """ |
2823 if self.line < 0: | 2869 if self.line < 0: |
2824 self.line, index = self.getCursorPosition() | 2870 self.line, index = self.getCursorPosition() |
2825 self.line += 1 | 2871 self.line += 1 |
2826 self.toggleBookmark(self.line) | 2872 self.toggleBookmark(self.line) |
2827 self.line = -1 | 2873 self.line = -1 |
2828 | 2874 |
2875 @pyqtSlot() | |
2829 def nextBookmark(self): | 2876 def nextBookmark(self): |
2830 """ | 2877 """ |
2831 Public slot to handle the 'Next bookmark' context menu action. | 2878 Public slot to handle the 'Next bookmark' context menu action. |
2832 """ | 2879 """ |
2833 line, index = self.getCursorPosition() | 2880 line, index = self.getCursorPosition() |
2841 bmline = self.markerFindNext(0, 1 << self.bookmark) | 2888 bmline = self.markerFindNext(0, 1 << self.bookmark) |
2842 if bmline >= 0: | 2889 if bmline >= 0: |
2843 self.setCursorPosition(bmline, 0) | 2890 self.setCursorPosition(bmline, 0) |
2844 self.ensureLineVisible(bmline) | 2891 self.ensureLineVisible(bmline) |
2845 | 2892 |
2893 @pyqtSlot() | |
2846 def previousBookmark(self): | 2894 def previousBookmark(self): |
2847 """ | 2895 """ |
2848 Public slot to handle the 'Previous bookmark' context menu action. | 2896 Public slot to handle the 'Previous bookmark' context menu action. |
2849 """ | 2897 """ |
2850 line, index = self.getCursorPosition() | 2898 line, index = self.getCursorPosition() |
2858 bmline = self.markerFindPrevious(self.lines() - 1, 1 << self.bookmark) | 2906 bmline = self.markerFindPrevious(self.lines() - 1, 1 << self.bookmark) |
2859 if bmline >= 0: | 2907 if bmline >= 0: |
2860 self.setCursorPosition(bmline, 0) | 2908 self.setCursorPosition(bmline, 0) |
2861 self.ensureLineVisible(bmline) | 2909 self.ensureLineVisible(bmline) |
2862 | 2910 |
2911 @pyqtSlot() | |
2863 def clearBookmarks(self): | 2912 def clearBookmarks(self): |
2864 """ | 2913 """ |
2865 Public slot to handle the 'Clear all bookmarks' context menu action. | 2914 Public slot to handle the 'Clear all bookmarks' context menu action. |
2866 """ | 2915 """ |
2867 for handle in self.bookmarks: | 2916 for handle in self.bookmarks: |
2872 | 2921 |
2873 ########################################################################### | 2922 ########################################################################### |
2874 ## Printing methods below | 2923 ## Printing methods below |
2875 ########################################################################### | 2924 ########################################################################### |
2876 | 2925 |
2926 @pyqtSlot() | |
2877 def printFile(self): | 2927 def printFile(self): |
2878 """ | 2928 """ |
2879 Public slot to print the text. | 2929 Public slot to print the text. |
2880 """ | 2930 """ |
2881 from .Printer import Printer | 2931 from .Printer import Printer |
2911 QApplication.processEvents() | 2961 QApplication.processEvents() |
2912 else: | 2962 else: |
2913 sb.showMessage(self.tr("Printing aborted"), 2000) | 2963 sb.showMessage(self.tr("Printing aborted"), 2000) |
2914 QApplication.processEvents() | 2964 QApplication.processEvents() |
2915 | 2965 |
2966 @pyqtSlot() | |
2916 def printPreviewFile(self): | 2967 def printPreviewFile(self): |
2917 """ | 2968 """ |
2918 Public slot to show a print preview of the text. | 2969 Public slot to show a print preview of the text. |
2919 """ | 2970 """ |
2920 from .Printer import Printer | 2971 from .Printer import Printer |
2964 | 3015 |
2965 @return flag indicating the presence of task markers (boolean) | 3016 @return flag indicating the presence of task markers (boolean) |
2966 """ | 3017 """ |
2967 return self.__hasTaskMarkers | 3018 return self.__hasTaskMarkers |
2968 | 3019 |
3020 @pyqtSlot() | |
2969 def nextTask(self): | 3021 def nextTask(self): |
2970 """ | 3022 """ |
2971 Public slot to handle the 'Next task' context menu action. | 3023 Public slot to handle the 'Next task' context menu action. |
2972 """ | 3024 """ |
2973 line, index = self.getCursorPosition() | 3025 line, index = self.getCursorPosition() |
2981 taskline = self.markerFindNext(0, 1 << self.taskmarker) | 3033 taskline = self.markerFindNext(0, 1 << self.taskmarker) |
2982 if taskline >= 0: | 3034 if taskline >= 0: |
2983 self.setCursorPosition(taskline, 0) | 3035 self.setCursorPosition(taskline, 0) |
2984 self.ensureLineVisible(taskline) | 3036 self.ensureLineVisible(taskline) |
2985 | 3037 |
3038 @pyqtSlot() | |
2986 def previousTask(self): | 3039 def previousTask(self): |
2987 """ | 3040 """ |
2988 Public slot to handle the 'Previous task' context menu action. | 3041 Public slot to handle the 'Previous task' context menu action. |
2989 """ | 3042 """ |
2990 line, index = self.getCursorPosition() | 3043 line, index = self.getCursorPosition() |
2998 taskline = self.markerFindPrevious(self.lines() - 1, 1 << self.taskmarker) | 3051 taskline = self.markerFindPrevious(self.lines() - 1, 1 << self.taskmarker) |
2999 if taskline >= 0: | 3052 if taskline >= 0: |
3000 self.setCursorPosition(taskline, 0) | 3053 self.setCursorPosition(taskline, 0) |
3001 self.ensureLineVisible(taskline) | 3054 self.ensureLineVisible(taskline) |
3002 | 3055 |
3056 @pyqtSlot() | |
3003 def extractTasks(self): | 3057 def extractTasks(self): |
3004 """ | 3058 """ |
3005 Public slot to extract all tasks. | 3059 Public slot to extract all tasks. |
3006 """ | 3060 """ |
3007 from eric7.Tasks.Task import Task | 3061 from eric7.Tasks.Task import Task |
3059 painter = QPainter(pixmap) | 3113 painter = QPainter(pixmap) |
3060 painter.fillRect(size - 4, 0, 4, size, Preferences.getEditorColour(key)) | 3114 painter.fillRect(size - 4, 0, 4, size, Preferences.getEditorColour(key)) |
3061 painter.end() | 3115 painter.end() |
3062 return pixmap | 3116 return pixmap |
3063 | 3117 |
3118 @pyqtSlot() | |
3064 def __initOnlineChangeTrace(self): | 3119 def __initOnlineChangeTrace(self): |
3065 """ | 3120 """ |
3066 Private slot to initialize the online change trace. | 3121 Private slot to initialize the online change trace. |
3067 """ | 3122 """ |
3068 self.__hasChangeMarkers = False | 3123 self.__hasChangeMarkers = False |
3076 self.__onlineChangeTraceTimer.timeout.connect( | 3131 self.__onlineChangeTraceTimer.timeout.connect( |
3077 self.__onlineChangeTraceTimerTimeout | 3132 self.__onlineChangeTraceTimerTimeout |
3078 ) | 3133 ) |
3079 self.textChanged.connect(self.__resetOnlineChangeTraceTimer) | 3134 self.textChanged.connect(self.__resetOnlineChangeTraceTimer) |
3080 | 3135 |
3136 @pyqtSlot() | |
3081 def __reinitOnlineChangeTrace(self): | 3137 def __reinitOnlineChangeTrace(self): |
3082 """ | 3138 """ |
3083 Private slot to re-initialize the online change trace. | 3139 Private slot to re-initialize the online change trace. |
3084 """ | 3140 """ |
3085 self.__oldText = self.text() | 3141 self.__oldText = self.text() |
3092 """ | 3148 """ |
3093 if Preferences.getEditor("OnlineChangeTrace"): | 3149 if Preferences.getEditor("OnlineChangeTrace"): |
3094 self.__onlineChangeTraceTimer.stop() | 3150 self.__onlineChangeTraceTimer.stop() |
3095 self.__onlineChangeTraceTimer.start() | 3151 self.__onlineChangeTraceTimer.start() |
3096 | 3152 |
3153 @pyqtSlot() | |
3097 def __onlineChangeTraceTimerTimeout(self): | 3154 def __onlineChangeTraceTimerTimeout(self): |
3098 """ | 3155 """ |
3099 Private slot to mark added and changed lines. | 3156 Private slot to mark added and changed lines. |
3100 """ | 3157 """ |
3101 self.__deleteAllChangeMarkers() | 3158 self.__deleteAllChangeMarkers() |
3124 | 3181 |
3125 if self.__hasChangeMarkers: | 3182 if self.__hasChangeMarkers: |
3126 self.changeMarkersUpdated.emit(self) | 3183 self.changeMarkersUpdated.emit(self) |
3127 self.__markerMap.update() | 3184 self.__markerMap.update() |
3128 | 3185 |
3186 @pyqtSlot() | |
3129 def resetOnlineChangeTraceInfo(self): | 3187 def resetOnlineChangeTraceInfo(self): |
3130 """ | 3188 """ |
3131 Public slot to reset the online change trace info. | 3189 Public slot to reset the online change trace info. |
3132 """ | 3190 """ |
3133 self.__lastSavedText = self.text() | 3191 self.__lastSavedText = self.text() |
3146 | 3204 |
3147 if self.__hasChangeMarkers: | 3205 if self.__hasChangeMarkers: |
3148 self.changeMarkersUpdated.emit(self) | 3206 self.changeMarkersUpdated.emit(self) |
3149 self.__markerMap.update() | 3207 self.__markerMap.update() |
3150 | 3208 |
3209 @pyqtSlot() | |
3151 def __deleteAllChangeMarkers(self): | 3210 def __deleteAllChangeMarkers(self): |
3152 """ | 3211 """ |
3153 Private slot to delete all change markers. | 3212 Private slot to delete all change markers. |
3154 """ | 3213 """ |
3155 self.markerDeleteAll(self.__changeMarkerUnsaved) | 3214 self.markerDeleteAll(self.__changeMarkerUnsaved) |
3186 | 3245 |
3187 @return flag indicating the presence of change markers (boolean) | 3246 @return flag indicating the presence of change markers (boolean) |
3188 """ | 3247 """ |
3189 return self.__hasChangeMarkers | 3248 return self.__hasChangeMarkers |
3190 | 3249 |
3250 @pyqtSlot() | |
3191 def nextChange(self): | 3251 def nextChange(self): |
3192 """ | 3252 """ |
3193 Public slot to handle the 'Next change' context menu action. | 3253 Public slot to handle the 'Next change' context menu action. |
3194 """ | 3254 """ |
3195 line, index = self.getCursorPosition() | 3255 line, index = self.getCursorPosition() |
3203 changeline = self.markerFindNext(0, self.changeMarkersMask) | 3263 changeline = self.markerFindNext(0, self.changeMarkersMask) |
3204 if changeline >= 0: | 3264 if changeline >= 0: |
3205 self.setCursorPosition(changeline, 0) | 3265 self.setCursorPosition(changeline, 0) |
3206 self.ensureLineVisible(changeline) | 3266 self.ensureLineVisible(changeline) |
3207 | 3267 |
3268 @pyqtSlot() | |
3208 def previousChange(self): | 3269 def previousChange(self): |
3209 """ | 3270 """ |
3210 Public slot to handle the 'Previous change' context menu action. | 3271 Public slot to handle the 'Previous change' context menu action. |
3211 """ | 3272 """ |
3212 line, index = self.getCursorPosition() | 3273 line, index = self.getCursorPosition() |
3302 break | 3363 break |
3303 # Couldn't find the unmodified state | 3364 # Couldn't find the unmodified state |
3304 | 3365 |
3305 def readFile(self, fn, createIt=False, encoding=""): | 3366 def readFile(self, fn, createIt=False, encoding=""): |
3306 """ | 3367 """ |
3307 Public slot to read the text from a file. | 3368 Public method to read the text from a file. |
3308 | 3369 |
3309 @param fn filename to read from (string) | 3370 @param fn filename to read from (string) |
3310 @param createIt flag indicating the creation of a new file, if the | 3371 @param createIt flag indicating the creation of a new file, if the |
3311 given one doesn't exist (boolean) | 3372 given one doesn't exist (boolean) |
3312 @param encoding encoding to be used to read the file (string) | 3373 @param encoding encoding to be used to read the file (string) |
3358 self.extractTasks() | 3419 self.extractTasks() |
3359 | 3420 |
3360 self.setModified(modified) | 3421 self.setModified(modified) |
3361 self.lastModified = pathlib.Path(fn).stat().st_mtime | 3422 self.lastModified = pathlib.Path(fn).stat().st_mtime |
3362 | 3423 |
3424 @pyqtSlot() | |
3363 def __convertTabs(self): | 3425 def __convertTabs(self): |
3364 """ | 3426 """ |
3365 Private slot to convert tabulators to spaces. | 3427 Private slot to convert tabulators to spaces. |
3366 """ | 3428 """ |
3367 if ( | 3429 if ( |
3391 ok = self.findNextTarget() | 3453 ok = self.findNextTarget() |
3392 self.endUndoAction() | 3454 self.endUndoAction() |
3393 | 3455 |
3394 def writeFile(self, fn, backup=True): | 3456 def writeFile(self, fn, backup=True): |
3395 """ | 3457 """ |
3396 Public slot to write the text to a file. | 3458 Public method to write the text to a file. |
3397 | 3459 |
3398 @param fn filename to write to (string) | 3460 @param fn filename to write to |
3399 @param backup flag indicating to save a backup (boolean) | 3461 @type str |
3400 @return flag indicating success (boolean) | 3462 @param backup flag indicating to save a backup |
3463 @type bool | |
3464 @return flag indicating success | |
3465 @rtype bool | |
3401 """ | 3466 """ |
3402 config = self.__loadEditorConfigObject(fn) | 3467 config = self.__loadEditorConfigObject(fn) |
3403 | 3468 |
3404 eol = self.__getEditorConfig("EOLMode", nodefault=True, config=config) | 3469 eol = self.__getEditorConfig("EOLMode", nodefault=True, config=config) |
3405 if eol is not None: | 3470 if eol is not None: |
3617 ) | 3682 ) |
3618 return False | 3683 return False |
3619 | 3684 |
3620 def saveFileAs(self, path=None): | 3685 def saveFileAs(self, path=None): |
3621 """ | 3686 """ |
3622 Public slot to save a file with a new name. | 3687 Public method to save a file with a new name. |
3623 | 3688 |
3624 @param path directory to save the file in (string) | 3689 @param path directory to save the file in |
3625 @return tuple of two values (boolean, string) giving a success | 3690 @type str |
3626 indicator and the name of the saved file | 3691 @return tuple containing a success indicator and the name of the saved file |
3692 @rtype tuple of (bool, str) | |
3627 """ | 3693 """ |
3628 return self.saveFile(True, path) | 3694 return self.saveFile(True, path) |
3629 | 3695 |
3630 def __saveDeviceFile(self, saveas=False): | 3696 def __saveDeviceFile(self, saveas=False): |
3631 """ | 3697 """ |
3667 | 3733 |
3668 return False | 3734 return False |
3669 | 3735 |
3670 def handleRenamed(self, fn): | 3736 def handleRenamed(self, fn): |
3671 """ | 3737 """ |
3672 Public slot to handle the editorRenamed signal. | 3738 Public method to handle the editorRenamed signal. |
3673 | 3739 |
3674 @param fn filename to be set for the editor (string). | 3740 @param fn filename to be set for the editor (string). |
3675 """ | 3741 """ |
3676 self.__clearBreakpoints(fn) | 3742 self.__clearBreakpoints(fn) |
3677 | 3743 |
3685 | 3751 |
3686 self.lastModified = pathlib.Path(fn).stat().st_mtime | 3752 self.lastModified = pathlib.Path(fn).stat().st_mtime |
3687 self.vm.setEditorName(self, self.fileName) | 3753 self.vm.setEditorName(self, self.fileName) |
3688 self.__updateReadOnly(True) | 3754 self.__updateReadOnly(True) |
3689 | 3755 |
3756 @pyqtSlot(str) | |
3690 def fileRenamed(self, fn): | 3757 def fileRenamed(self, fn): |
3691 """ | 3758 """ |
3692 Public slot to handle the editorRenamed signal. | 3759 Public slot to handle the editorRenamed signal. |
3693 | 3760 |
3694 @param fn filename to be set for the editor (string). | 3761 @param fn filename to be set for the editor |
3762 @type str. | |
3695 """ | 3763 """ |
3696 self.handleRenamed(fn) | 3764 self.handleRenamed(fn) |
3697 if not self.inFileRenamed: | 3765 if not self.inFileRenamed: |
3698 self.inFileRenamed = True | 3766 self.inFileRenamed = True |
3699 self.editorRenamed.emit(self.fileName) | 3767 self.editorRenamed.emit(self.fileName) |
3703 ## Utility methods below | 3771 ## Utility methods below |
3704 ########################################################################### | 3772 ########################################################################### |
3705 | 3773 |
3706 def ensureVisible(self, line, expand=False): | 3774 def ensureVisible(self, line, expand=False): |
3707 """ | 3775 """ |
3708 Public slot to ensure, that the specified line is visible. | 3776 Public method to ensure, that the specified line is visible. |
3709 | 3777 |
3710 @param line line number to make visible | 3778 @param line line number to make visible |
3711 @type int | 3779 @type int |
3712 @param expand flag indicating to expand all folds | 3780 @param expand flag indicating to expand all folds |
3713 @type bool | 3781 @type bool |
3720 QsciScintilla.SC_FOLDACTION_EXPAND, | 3788 QsciScintilla.SC_FOLDACTION_EXPAND, |
3721 ) | 3789 ) |
3722 | 3790 |
3723 def ensureVisibleTop(self, line, expand=False): | 3791 def ensureVisibleTop(self, line, expand=False): |
3724 """ | 3792 """ |
3725 Public slot to ensure, that the specified line is visible at the top | 3793 Public method to ensure, that the specified line is visible at the top |
3726 of the editor. | 3794 of the editor. |
3727 | 3795 |
3728 @param line line number to make visible | 3796 @param line line number to make visible |
3729 @type int | 3797 @type int |
3730 @param expand flag indicating to expand all folds | 3798 @param expand flag indicating to expand all folds |
3742 | 3810 |
3743 def __marginClicked(self, margin, line, modifiers): # noqa: U100 | 3811 def __marginClicked(self, margin, line, modifiers): # noqa: U100 |
3744 """ | 3812 """ |
3745 Private slot to handle the marginClicked signal. | 3813 Private slot to handle the marginClicked signal. |
3746 | 3814 |
3747 @param margin id of the clicked margin (integer) | 3815 @param margin id of the clicked margin |
3748 @param line line number of the click (integer) | 3816 @type int |
3749 @param modifiers keyboard modifiers (Qt.KeyboardModifiers) | 3817 @param line line number of the click |
3818 @type int | |
3819 @param modifiers keyboard modifiers | |
3820 @type Qt.KeyboardModifiers | |
3750 """ | 3821 """ |
3751 if margin == self.__bmMargin: | 3822 if margin == self.__bmMargin: |
3752 self.toggleBookmark(line + 1) | 3823 self.toggleBookmark(line + 1) |
3753 elif margin == self.__bpMargin: | 3824 elif margin == self.__bpMargin: |
3754 self.__toggleBreakpoint(line + 1) | 3825 self.__toggleBreakpoint(line + 1) |
3756 if self.markersAtLine(line) & (1 << self.syntaxerror): | 3827 if self.markersAtLine(line) & (1 << self.syntaxerror): |
3757 self.__showSyntaxError(line) | 3828 self.__showSyntaxError(line) |
3758 elif self.markersAtLine(line) & (1 << self.warning): | 3829 elif self.markersAtLine(line) & (1 << self.warning): |
3759 self.__showWarning(line) | 3830 self.__showWarning(line) |
3760 | 3831 |
3832 @pyqtSlot() | |
3761 def handleMonospacedEnable(self): | 3833 def handleMonospacedEnable(self): |
3762 """ | 3834 """ |
3763 Public slot to handle the Use Monospaced Font context menu entry. | 3835 Public slot to handle the Use Monospaced Font context menu entry. |
3764 """ | 3836 """ |
3765 if self.menuActs["MonospacedFont"].isChecked(): | 3837 if self.menuActs["MonospacedFont"].isChecked(): |
4078 if Preferences.getEditor("CommentColumn0"): | 4150 if Preferences.getEditor("CommentColumn0"): |
4079 return line.startswith(commentStr) | 4151 return line.startswith(commentStr) |
4080 else: | 4152 else: |
4081 return line.strip().startswith(commentStr) | 4153 return line.strip().startswith(commentStr) |
4082 | 4154 |
4155 @pyqtSlot() | |
4083 def toggleCommentBlock(self): | 4156 def toggleCommentBlock(self): |
4084 """ | 4157 """ |
4085 Public slot to toggle the comment of a block. | 4158 Public slot to toggle the comment of a block. |
4086 | 4159 |
4087 If the editor contains selected text and the start line is not commented, it | 4160 If the editor contains selected text and the start line is not commented, it |
4125 # 3. uncomment the determined block and reset the cursor position | 4198 # 3. uncomment the determined block and reset the cursor position |
4126 self.setSelection(begline, 0, endline, self.lineLength(endline)) | 4199 self.setSelection(begline, 0, endline, self.lineLength(endline)) |
4127 self.uncommentLineOrSelection() | 4200 self.uncommentLineOrSelection() |
4128 self.setCursorPosition(line, index - len(commentStr)) | 4201 self.setCursorPosition(line, index - len(commentStr)) |
4129 | 4202 |
4203 @pyqtSlot() | |
4130 def commentLine(self): | 4204 def commentLine(self): |
4131 """ | 4205 """ |
4132 Public slot to comment the current line. | 4206 Public slot to comment the current line. |
4133 """ | 4207 """ |
4134 if self.lexer_ is None or not self.lexer_.canBlockComment(): | 4208 if self.lexer_ is None or not self.lexer_.canBlockComment(): |
4142 lineText = self.text(line) | 4216 lineText = self.text(line) |
4143 pos = len(lineText.replace(lineText.lstrip(" \t"), "")) | 4217 pos = len(lineText.replace(lineText.lstrip(" \t"), "")) |
4144 self.insertAt(self.lexer_.commentStr(), line, pos) | 4218 self.insertAt(self.lexer_.commentStr(), line, pos) |
4145 self.endUndoAction() | 4219 self.endUndoAction() |
4146 | 4220 |
4221 @pyqtSlot() | |
4147 def uncommentLine(self): | 4222 def uncommentLine(self): |
4148 """ | 4223 """ |
4149 Public slot to uncomment the current line. | 4224 Public slot to uncomment the current line. |
4150 """ | 4225 """ |
4151 if self.lexer_ is None or not self.lexer_.canBlockComment(): | 4226 if self.lexer_ is None or not self.lexer_.canBlockComment(): |
4168 pos = len(lineText.replace(lineText.lstrip(" \t"), "")) | 4243 pos = len(lineText.replace(lineText.lstrip(" \t"), "")) |
4169 self.setSelection(line, pos, line, pos + len(commentStr)) | 4244 self.setSelection(line, pos, line, pos + len(commentStr)) |
4170 self.removeSelectedText() | 4245 self.removeSelectedText() |
4171 self.endUndoAction() | 4246 self.endUndoAction() |
4172 | 4247 |
4248 @pyqtSlot() | |
4173 def commentSelection(self): | 4249 def commentSelection(self): |
4174 """ | 4250 """ |
4175 Public slot to comment the current selection. | 4251 Public slot to comment the current selection. |
4176 """ | 4252 """ |
4177 if self.lexer_ is None or not self.lexer_.canBlockComment(): | 4253 if self.lexer_ is None or not self.lexer_.canBlockComment(): |
4198 | 4274 |
4199 # change the selection accordingly | 4275 # change the selection accordingly |
4200 self.setSelection(lineFrom, 0, endLine + 1, 0) | 4276 self.setSelection(lineFrom, 0, endLine + 1, 0) |
4201 self.endUndoAction() | 4277 self.endUndoAction() |
4202 | 4278 |
4279 @pyqtSlot() | |
4203 def uncommentSelection(self): | 4280 def uncommentSelection(self): |
4204 """ | 4281 """ |
4205 Public slot to uncomment the current selection. | 4282 Public slot to uncomment the current selection. |
4206 """ | 4283 """ |
4207 if self.lexer_ is None or not self.lexer_.canBlockComment(): | 4284 if self.lexer_ is None or not self.lexer_.canBlockComment(): |
4246 | 4323 |
4247 # change the selection accordingly | 4324 # change the selection accordingly |
4248 self.setSelection(lineFrom, indexFrom, lineTo, indexTo) | 4325 self.setSelection(lineFrom, indexFrom, lineTo, indexTo) |
4249 self.endUndoAction() | 4326 self.endUndoAction() |
4250 | 4327 |
4328 @pyqtSlot() | |
4251 def commentLineOrSelection(self): | 4329 def commentLineOrSelection(self): |
4252 """ | 4330 """ |
4253 Public slot to comment the current line or current selection. | 4331 Public slot to comment the current line or current selection. |
4254 """ | 4332 """ |
4255 if self.hasSelectedText(): | 4333 if self.hasSelectedText(): |
4256 self.commentSelection() | 4334 self.commentSelection() |
4257 else: | 4335 else: |
4258 self.commentLine() | 4336 self.commentLine() |
4259 | 4337 |
4338 @pyqtSlot() | |
4260 def uncommentLineOrSelection(self): | 4339 def uncommentLineOrSelection(self): |
4261 """ | 4340 """ |
4262 Public slot to uncomment the current line or current selection. | 4341 Public slot to uncomment the current line or current selection. |
4263 """ | 4342 """ |
4264 if self.hasSelectedText(): | 4343 if self.hasSelectedText(): |
4265 self.uncommentSelection() | 4344 self.uncommentSelection() |
4266 else: | 4345 else: |
4267 self.uncommentLine() | 4346 self.uncommentLine() |
4268 | 4347 |
4348 @pyqtSlot() | |
4269 def streamCommentLine(self): | 4349 def streamCommentLine(self): |
4270 """ | 4350 """ |
4271 Public slot to stream comment the current line. | 4351 Public slot to stream comment the current line. |
4272 """ | 4352 """ |
4273 if self.lexer_ is None or not self.lexer_.canStreamComment(): | 4353 if self.lexer_ is None or not self.lexer_.canStreamComment(): |
4279 self.beginUndoAction() | 4359 self.beginUndoAction() |
4280 self.insertAt(commentStr["end"], line, self.lineLength(line)) | 4360 self.insertAt(commentStr["end"], line, self.lineLength(line)) |
4281 self.insertAt(commentStr["start"], line, 0) | 4361 self.insertAt(commentStr["start"], line, 0) |
4282 self.endUndoAction() | 4362 self.endUndoAction() |
4283 | 4363 |
4364 @pyqtSlot() | |
4284 def streamCommentSelection(self): | 4365 def streamCommentSelection(self): |
4285 """ | 4366 """ |
4286 Public slot to comment the current selection. | 4367 Public slot to comment the current selection. |
4287 """ | 4368 """ |
4288 if self.lexer_ is None or not self.lexer_.canStreamComment(): | 4369 if self.lexer_ is None or not self.lexer_.canStreamComment(): |
4312 if lineFrom == endLine: | 4393 if lineFrom == endLine: |
4313 indexTo += len(commentStr["start"]) | 4394 indexTo += len(commentStr["start"]) |
4314 self.setSelection(lineFrom, indexFrom, lineTo, indexTo) | 4395 self.setSelection(lineFrom, indexFrom, lineTo, indexTo) |
4315 self.endUndoAction() | 4396 self.endUndoAction() |
4316 | 4397 |
4398 @pyqtSlot() | |
4317 def streamCommentLineOrSelection(self): | 4399 def streamCommentLineOrSelection(self): |
4318 """ | 4400 """ |
4319 Public slot to stream comment the current line or current selection. | 4401 Public slot to stream comment the current line or current selection. |
4320 """ | 4402 """ |
4321 if self.hasSelectedText(): | 4403 if self.hasSelectedText(): |
4322 self.streamCommentSelection() | 4404 self.streamCommentSelection() |
4323 else: | 4405 else: |
4324 self.streamCommentLine() | 4406 self.streamCommentLine() |
4325 | 4407 |
4408 @pyqtSlot() | |
4326 def boxCommentLine(self): | 4409 def boxCommentLine(self): |
4327 """ | 4410 """ |
4328 Public slot to box comment the current line. | 4411 Public slot to box comment the current line. |
4329 """ | 4412 """ |
4330 if self.lexer_ is None or not self.lexer_.canBoxComment(): | 4413 if self.lexer_ is None or not self.lexer_.canBoxComment(): |
4340 self.insertAt(commentStr["middle"], line, 0) | 4423 self.insertAt(commentStr["middle"], line, 0) |
4341 self.insertAt(eol, line, 0) | 4424 self.insertAt(eol, line, 0) |
4342 self.insertAt(commentStr["start"], line, 0) | 4425 self.insertAt(commentStr["start"], line, 0) |
4343 self.endUndoAction() | 4426 self.endUndoAction() |
4344 | 4427 |
4428 @pyqtSlot() | |
4345 def boxCommentSelection(self): | 4429 def boxCommentSelection(self): |
4346 """ | 4430 """ |
4347 Public slot to box comment the current selection. | 4431 Public slot to box comment the current selection. |
4348 """ | 4432 """ |
4349 if self.lexer_ is None or not self.lexer_.canBoxComment(): | 4433 if self.lexer_ is None or not self.lexer_.canBoxComment(): |
4372 | 4456 |
4373 # change the selection accordingly | 4457 # change the selection accordingly |
4374 self.setSelection(lineFrom, 0, endLine + 3, 0) | 4458 self.setSelection(lineFrom, 0, endLine + 3, 0) |
4375 self.endUndoAction() | 4459 self.endUndoAction() |
4376 | 4460 |
4461 @pyqtSlot() | |
4377 def boxCommentLineOrSelection(self): | 4462 def boxCommentLineOrSelection(self): |
4378 """ | 4463 """ |
4379 Public slot to box comment the current line or current selection. | 4464 Public slot to box comment the current line or current selection. |
4380 """ | 4465 """ |
4381 if self.hasSelectedText(): | 4466 if self.hasSelectedText(): |
4449 indexEnd = indexTo - self.indentationWidth() | 4534 indexEnd = indexTo - self.indentationWidth() |
4450 if indexEnd < 0: | 4535 if indexEnd < 0: |
4451 indexEnd = 0 | 4536 indexEnd = 0 |
4452 self.setSelection(lineFrom, indexStart, lineTo, indexEnd) | 4537 self.setSelection(lineFrom, indexStart, lineTo, indexEnd) |
4453 | 4538 |
4539 @pyqtSlot() | |
4454 def indentLineOrSelection(self): | 4540 def indentLineOrSelection(self): |
4455 """ | 4541 """ |
4456 Public slot to indent the current line or current selection. | 4542 Public slot to indent the current line or current selection. |
4457 """ | 4543 """ |
4458 if self.hasSelectedText(): | 4544 if self.hasSelectedText(): |
4459 self.__indentSelection(True) | 4545 self.__indentSelection(True) |
4460 else: | 4546 else: |
4461 self.__indentLine(True) | 4547 self.__indentLine(True) |
4462 | 4548 |
4549 @pyqtSlot() | |
4463 def unindentLineOrSelection(self): | 4550 def unindentLineOrSelection(self): |
4464 """ | 4551 """ |
4465 Public slot to unindent the current line or current selection. | 4552 Public slot to unindent the current line or current selection. |
4466 """ | 4553 """ |
4467 if self.hasSelectedText(): | 4554 if self.hasSelectedText(): |
4468 self.__indentSelection(False) | 4555 self.__indentSelection(False) |
4469 else: | 4556 else: |
4470 self.__indentLine(False) | 4557 self.__indentLine(False) |
4471 | 4558 |
4559 @pyqtSlot() | |
4472 def smartIndentLineOrSelection(self): | 4560 def smartIndentLineOrSelection(self): |
4473 """ | 4561 """ |
4474 Public slot to indent current line smartly. | 4562 Public slot to indent current line smartly. |
4475 """ | 4563 """ |
4476 if self.hasSelectedText(): | 4564 if self.hasSelectedText(): |
4484 else: | 4572 else: |
4485 self.__indentLine(True) | 4573 self.__indentLine(True) |
4486 | 4574 |
4487 def gotoLine(self, line, pos=1, firstVisible=False, expand=False): | 4575 def gotoLine(self, line, pos=1, firstVisible=False, expand=False): |
4488 """ | 4576 """ |
4489 Public slot to jump to the beginning of a line. | 4577 Public method to jump to the beginning of a line. |
4490 | 4578 |
4491 @param line line number to go to | 4579 @param line line number to go to |
4492 @type int | 4580 @type int |
4493 @param pos position in line to go to | 4581 @param pos position in line to go to |
4494 @type int | 4582 @type int |
4502 if firstVisible: | 4590 if firstVisible: |
4503 self.ensureVisibleTop(line, expand) | 4591 self.ensureVisibleTop(line, expand) |
4504 else: | 4592 else: |
4505 self.ensureVisible(line, expand) | 4593 self.ensureVisible(line, expand) |
4506 | 4594 |
4595 @pyqtSlot() | |
4507 def __textChanged(self): | 4596 def __textChanged(self): |
4508 """ | 4597 """ |
4509 Private slot to handle a change of the editor text. | 4598 Private slot to handle a change of the editor text. |
4510 | 4599 |
4511 This slot defers the handling to the next time the event loop | 4600 This slot defers the handling to the next time the event loop |
4512 is run in order to ensure, that cursor position has been updated | 4601 is run in order to ensure, that cursor position has been updated |
4513 by the underlying Scintilla editor. | 4602 by the underlying Scintilla editor. |
4514 """ | 4603 """ |
4515 QTimer.singleShot(0, self.__saveLastEditPosition) | 4604 QTimer.singleShot(0, self.__saveLastEditPosition) |
4516 | 4605 |
4606 @pyqtSlot() | |
4517 def __saveLastEditPosition(self): | 4607 def __saveLastEditPosition(self): |
4518 """ | 4608 """ |
4519 Private slot to record the last edit position. | 4609 Private slot to record the last edit position. |
4520 """ | 4610 """ |
4521 self.__lastEditPosition = self.getCursorPosition() | 4611 self.__lastEditPosition = self.getCursorPosition() |
4589 | 4679 |
4590 ########################################################################### | 4680 ########################################################################### |
4591 ## Setup methods below | 4681 ## Setup methods below |
4592 ########################################################################### | 4682 ########################################################################### |
4593 | 4683 |
4684 @pyqtSlot() | |
4594 def readSettings(self): | 4685 def readSettings(self): |
4595 """ | 4686 """ |
4596 Public slot to read the settings into our lexer. | 4687 Public slot to read the settings into our lexer. |
4597 """ | 4688 """ |
4598 # read the lexer settings and reinit the properties | 4689 # read the lexer settings and reinit the properties |
4800 self.setMarginWidth(self.__foldMargin, 0) | 4891 self.setMarginWidth(self.__foldMargin, 0) |
4801 self.setFolding( | 4892 self.setFolding( |
4802 QsciScintilla.FoldStyle.NoFoldStyle.value, self.__foldMargin | 4893 QsciScintilla.FoldStyle.NoFoldStyle.value, self.__foldMargin |
4803 ) | 4894 ) |
4804 | 4895 |
4896 @pyqtSlot() | |
4805 def __resizeLinenoMargin(self): | 4897 def __resizeLinenoMargin(self): |
4806 """ | 4898 """ |
4807 Private slot to resize the line numbers margin. | 4899 Private slot to resize the line numbers margin. |
4808 """ | 4900 """ |
4809 linenoMargin = Preferences.getEditor("LinenoMargin") | 4901 linenoMargin = Preferences.getEditor("LinenoMargin") |
5128 elif autoCompletionSource == QsciScintilla.AutoCompletionSource.AcsAPIs: | 5220 elif autoCompletionSource == QsciScintilla.AutoCompletionSource.AcsAPIs: |
5129 self.setAutoCompletionSource(QsciScintilla.AutoCompletionSource.AcsAPIs) | 5221 self.setAutoCompletionSource(QsciScintilla.AutoCompletionSource.AcsAPIs) |
5130 else: | 5222 else: |
5131 self.setAutoCompletionSource(QsciScintilla.AutoCompletionSource.AcsAll) | 5223 self.setAutoCompletionSource(QsciScintilla.AutoCompletionSource.AcsAll) |
5132 | 5224 |
5225 @pyqtSlot() | |
5133 def __toggleAutoCompletionEnable(self): | 5226 def __toggleAutoCompletionEnable(self): |
5134 """ | 5227 """ |
5135 Private slot to handle the Enable Autocompletion context menu entry. | 5228 Private slot to handle the Enable Autocompletion context menu entry. |
5136 """ | 5229 """ |
5137 if self.menuActs["AutoCompletionEnable"].isChecked(): | 5230 if self.menuActs["AutoCompletionEnable"].isChecked(): |
5141 | 5234 |
5142 ################################################################# | 5235 ################################################################# |
5143 ## Support for autocompletion hook methods | 5236 ## Support for autocompletion hook methods |
5144 ################################################################# | 5237 ################################################################# |
5145 | 5238 |
5239 @pyqtSlot(int) | |
5146 def __charAdded(self, charNumber): | 5240 def __charAdded(self, charNumber): |
5147 """ | 5241 """ |
5148 Private slot called to handle the user entering a character. | 5242 Private slot called to handle the user entering a character. |
5149 | 5243 |
5150 @param charNumber value of the character entered (integer) | 5244 @param charNumber value of the character entered |
5245 @type int | |
5151 """ | 5246 """ |
5152 char = chr(charNumber) | 5247 char = chr(charNumber) |
5153 # update code documentation viewer | 5248 # update code documentation viewer |
5154 if char == "(" and Preferences.getDocuViewer("ShowInfoOnOpenParenthesis"): | 5249 if char == "(" and Preferences.getDocuViewer("ShowInfoOnOpenParenthesis"): |
5155 self.vm.showEditorInfo(self) | 5250 self.vm.showEditorInfo(self) |
5197 return False | 5292 return False |
5198 | 5293 |
5199 wseps = self.lexer_.autoCompletionWordSeparators() | 5294 wseps = self.lexer_.autoCompletionWordSeparators() |
5200 return any(wsep.endswith(ch) for wsep in wseps) | 5295 return any(wsep.endswith(ch) for wsep in wseps) |
5201 | 5296 |
5297 @pyqtSlot() | |
5202 def __autocompletionCancelled(self): | 5298 def __autocompletionCancelled(self): |
5203 """ | 5299 """ |
5204 Private slot to handle the cancellation of an auto-completion list. | 5300 Private slot to handle the cancellation of an auto-completion list. |
5205 """ | 5301 """ |
5206 self.__acWatchdog.stop() | 5302 self.__acWatchdog.stop() |
5445 """ | 5541 """ |
5446 Private method to clear the auto-completions cache. | 5542 Private method to clear the auto-completions cache. |
5447 """ | 5543 """ |
5448 self.__acCache.clear() | 5544 self.__acCache.clear() |
5449 | 5545 |
5546 @pyqtSlot(int, str) | |
5450 def __completionListSelected(self, listId, txt): | 5547 def __completionListSelected(self, listId, txt): |
5451 """ | 5548 """ |
5452 Private slot to handle the selection from the completion list. | 5549 Private slot to handle the selection from the completion list. |
5453 | 5550 |
5454 @param listId the ID of the user list (should be 1 or 2) (integer) | 5551 @param listId the ID of the user list (should be 1 or 2) |
5455 @param txt the selected text (string) | 5552 @type int |
5553 @param txt the selected text | |
5554 @type str | |
5456 """ | 5555 """ |
5457 # custom completions via plug-ins | 5556 # custom completions via plug-ins |
5458 if listId == EditorAutoCompletionListID: | 5557 if listId == EditorAutoCompletionListID: |
5459 lst = txt.split() | 5558 lst = txt.split() |
5460 if len(lst) > 1: | 5559 if len(lst) > 1: |
5709 | 5808 |
5710 ################################################################# | 5809 ################################################################# |
5711 ## Methods needed by the code documentation viewer | 5810 ## Methods needed by the code documentation viewer |
5712 ################################################################# | 5811 ################################################################# |
5713 | 5812 |
5813 @pyqtSlot() | |
5714 def __showCodeInfo(self): | 5814 def __showCodeInfo(self): |
5715 """ | 5815 """ |
5716 Private slot to handle the context menu action to show code info. | 5816 Private slot to handle the context menu action to show code info. |
5717 """ | 5817 """ |
5718 self.vm.showEditorInfo(self) | 5818 self.vm.showEditorInfo(self) |
5762 elif self.__marginNumber(pos.x()) == self.__indicMargin: | 5862 elif self.__marginNumber(pos.x()) == self.__indicMargin: |
5763 self.indicMarginMenu.popup(self.mapToGlobal(pos)) | 5863 self.indicMarginMenu.popup(self.mapToGlobal(pos)) |
5764 elif self.__marginNumber(pos.x()) == self.__foldMargin: | 5864 elif self.__marginNumber(pos.x()) == self.__foldMargin: |
5765 self.foldMarginMenu.popup(self.mapToGlobal(pos)) | 5865 self.foldMarginMenu.popup(self.mapToGlobal(pos)) |
5766 | 5866 |
5867 @pyqtSlot() | |
5767 def __aboutToShowContextMenu(self): | 5868 def __aboutToShowContextMenu(self): |
5768 """ | 5869 """ |
5769 Private slot handling the aboutToShow signal of the context menu. | 5870 Private slot handling the aboutToShow signal of the context menu. |
5770 """ | 5871 """ |
5771 self.menuActs["Reopen"].setEnabled( | 5872 self.menuActs["Reopen"].setEnabled( |
5826 | 5927 |
5827 self.menuActs["Tools"].setEnabled(not self.toolsMenu.isEmpty()) | 5928 self.menuActs["Tools"].setEnabled(not self.toolsMenu.isEmpty()) |
5828 | 5929 |
5829 self.showMenu.emit("Main", self.menu, self) | 5930 self.showMenu.emit("Main", self.menu, self) |
5830 | 5931 |
5932 @pyqtSlot() | |
5831 def __showContextMenuAutocompletion(self): | 5933 def __showContextMenuAutocompletion(self): |
5832 """ | 5934 """ |
5833 Private slot called before the autocompletion menu is shown. | 5935 Private slot called before the autocompletion menu is shown. |
5834 """ | 5936 """ |
5835 self.menuActs["acDynamic"].setEnabled(self.canProvideDynamicAutoCompletion()) | 5937 self.menuActs["acDynamic"].setEnabled(self.canProvideDynamicAutoCompletion()) |
5837 self.menuActs["acAPI"].setEnabled(self.acAPI) | 5939 self.menuActs["acAPI"].setEnabled(self.acAPI) |
5838 self.menuActs["acAPIDocument"].setEnabled(self.acAPI) | 5940 self.menuActs["acAPIDocument"].setEnabled(self.acAPI) |
5839 | 5941 |
5840 self.showMenu.emit("Autocompletion", self.autocompletionMenu, self) | 5942 self.showMenu.emit("Autocompletion", self.autocompletionMenu, self) |
5841 | 5943 |
5944 @pyqtSlot() | |
5842 def __showContextMenuShow(self): | 5945 def __showContextMenuShow(self): |
5843 """ | 5946 """ |
5844 Private slot called before the show menu is shown. | 5947 Private slot called before the show menu is shown. |
5845 """ | 5948 """ |
5846 prEnable = False | 5949 prEnable = False |
5882 ) | 5985 ) |
5883 self.coverageHideAnnotationMenuAct.setEnabled(len(self.notcoveredMarkers) > 0) | 5986 self.coverageHideAnnotationMenuAct.setEnabled(len(self.notcoveredMarkers) > 0) |
5884 | 5987 |
5885 self.showMenu.emit("Show", self.menuShow, self) | 5988 self.showMenu.emit("Show", self.menuShow, self) |
5886 | 5989 |
5990 @pyqtSlot() | |
5887 def __showContextMenuGraphics(self): | 5991 def __showContextMenuGraphics(self): |
5888 """ | 5992 """ |
5889 Private slot handling the aboutToShow signal of the diagrams context | 5993 Private slot handling the aboutToShow signal of the diagrams context |
5890 menu. | 5994 menu. |
5891 """ | 5995 """ |
5896 else: | 6000 else: |
5897 self.applicationDiagramMenuAct.setEnabled(False) | 6001 self.applicationDiagramMenuAct.setEnabled(False) |
5898 | 6002 |
5899 self.showMenu.emit("Graphics", self.graphicsMenu, self) | 6003 self.showMenu.emit("Graphics", self.graphicsMenu, self) |
5900 | 6004 |
6005 @pyqtSlot(QMenu) | |
5901 def __showContextMenuMargin(self, menu): | 6006 def __showContextMenuMargin(self, menu): |
5902 """ | 6007 """ |
5903 Private slot handling the aboutToShow signal of the margins context | 6008 Private slot handling the aboutToShow signal of the margins context |
5904 menu. | 6009 menu. |
5905 | 6010 |
5954 self.marginMenuActs["ExpandChildren"].setEnabled(isFoldHeader) | 6059 self.marginMenuActs["ExpandChildren"].setEnabled(isFoldHeader) |
5955 self.marginMenuActs["CollapseChildren"].setEnabled(isFoldHeader) | 6060 self.marginMenuActs["CollapseChildren"].setEnabled(isFoldHeader) |
5956 | 6061 |
5957 if menu is self.indicMarginMenu: | 6062 if menu is self.indicMarginMenu: |
5958 hasSyntaxErrors = bool(self.syntaxerrors) | 6063 hasSyntaxErrors = bool(self.syntaxerrors) |
5959 hasWarnings = bool(self.warnings) | 6064 hasWarnings = bool(self._warnings) |
5960 hasNotCoveredMarkers = bool(self.notcoveredMarkers) | 6065 hasNotCoveredMarkers = bool(self.notcoveredMarkers) |
5961 | 6066 |
5962 self.marginMenuActs["GotoSyntaxError"].setEnabled(hasSyntaxErrors) | 6067 self.marginMenuActs["GotoSyntaxError"].setEnabled(hasSyntaxErrors) |
5963 self.marginMenuActs["ClearSyntaxError"].setEnabled(hasSyntaxErrors) | 6068 self.marginMenuActs["ClearSyntaxError"].setEnabled(hasSyntaxErrors) |
5964 if hasSyntaxErrors and self.markersAtLine(self.line) & ( | 6069 if hasSyntaxErrors and self.markersAtLine(self.line) & ( |
5992 self.__hasChangeMarkers | 6097 self.__hasChangeMarkers |
5993 ) | 6098 ) |
5994 | 6099 |
5995 self.showMenu.emit("Margin", menu, self) | 6100 self.showMenu.emit("Margin", menu, self) |
5996 | 6101 |
6102 @pyqtSlot() | |
5997 def __showContextMenuChecks(self): | 6103 def __showContextMenuChecks(self): |
5998 """ | 6104 """ |
5999 Private slot handling the aboutToShow signal of the checks context | 6105 Private slot handling the aboutToShow signal of the checks context |
6000 menu. | 6106 menu. |
6001 """ | 6107 """ |
6002 self.showMenu.emit("Checks", self.checksMenu, self) | 6108 self.showMenu.emit("Checks", self.checksMenu, self) |
6003 | 6109 |
6110 @pyqtSlot() | |
6004 def __showContextMenuTools(self): | 6111 def __showContextMenuTools(self): |
6005 """ | 6112 """ |
6006 Private slot handling the aboutToShow signal of the tools context | 6113 Private slot handling the aboutToShow signal of the tools context |
6007 menu. | 6114 menu. |
6008 """ | 6115 """ |
6009 self.showMenu.emit("Tools", self.toolsMenu, self) | 6116 self.showMenu.emit("Tools", self.toolsMenu, self) |
6010 | 6117 |
6118 @pyqtSlot() | |
6011 def __showContextMenuFormatting(self): | 6119 def __showContextMenuFormatting(self): |
6012 """ | 6120 """ |
6013 Private slot handling the aboutToShow signal of the code formatting context | 6121 Private slot handling the aboutToShow signal of the code formatting context |
6014 menu. | 6122 menu. |
6015 """ | 6123 """ |
6025 encoding = act.data() | 6133 encoding = act.data() |
6026 self.readFile(self.fileName, encoding=encoding) | 6134 self.readFile(self.fileName, encoding=encoding) |
6027 self.__convertTabs() | 6135 self.__convertTabs() |
6028 self.__checkEncoding() | 6136 self.__checkEncoding() |
6029 | 6137 |
6138 @pyqtSlot() | |
6030 def __contextSave(self): | 6139 def __contextSave(self): |
6031 """ | 6140 """ |
6032 Private slot handling the save context menu entry. | 6141 Private slot handling the save context menu entry. |
6033 """ | 6142 """ |
6034 ok = self.saveFile() | 6143 ok = self.saveFile() |
6035 if ok: | 6144 if ok: |
6036 self.vm.setEditorName(self, self.fileName) | 6145 self.vm.setEditorName(self, self.fileName) |
6037 | 6146 |
6147 @pyqtSlot() | |
6038 def __contextSaveAs(self): | 6148 def __contextSaveAs(self): |
6039 """ | 6149 """ |
6040 Private slot handling the save as context menu entry. | 6150 Private slot handling the save as context menu entry. |
6041 """ | 6151 """ |
6042 ok = self.saveFileAs() | 6152 ok = self.saveFileAs() |
6043 if ok: | 6153 if ok: |
6044 self.vm.setEditorName(self, self.fileName) | 6154 self.vm.setEditorName(self, self.fileName) |
6045 | 6155 |
6156 @pyqtSlot() | |
6046 def __contextSaveCopy(self): | 6157 def __contextSaveCopy(self): |
6047 """ | 6158 """ |
6048 Private slot handling the save copy context menu entry. | 6159 Private slot handling the save copy context menu entry. |
6049 """ | 6160 """ |
6050 self.saveFileCopy() | 6161 self.saveFileCopy() |
6051 | 6162 |
6163 @pyqtSlot() | |
6052 def __contextClose(self): | 6164 def __contextClose(self): |
6053 """ | 6165 """ |
6054 Private slot handling the close context menu entry. | 6166 Private slot handling the close context menu entry. |
6055 """ | 6167 """ |
6056 self.vm.closeEditor(self) | 6168 self.vm.closeEditor(self) |
6057 | 6169 |
6170 @pyqtSlot() | |
6058 def __newView(self): | 6171 def __newView(self): |
6059 """ | 6172 """ |
6060 Private slot to create a new view to an open document. | 6173 Private slot to create a new view to an open document. |
6061 """ | 6174 """ |
6062 self.vm.newEditorView(self.fileName, self, self.filetype) | 6175 self.vm.newEditorView(self.fileName, self, self.filetype) |
6063 | 6176 |
6177 @pyqtSlot() | |
6064 def __newViewNewSplit(self): | 6178 def __newViewNewSplit(self): |
6065 """ | 6179 """ |
6066 Private slot to create a new view to an open document. | 6180 Private slot to create a new view to an open document. |
6067 """ | 6181 """ |
6068 self.vm.addSplit() | 6182 self.vm.addSplit() |
6069 self.vm.newEditorView(self.fileName, self, self.filetype) | 6183 self.vm.newEditorView(self.fileName, self, self.filetype) |
6070 | 6184 |
6185 @pyqtSlot() | |
6071 def __selectAll(self): | 6186 def __selectAll(self): |
6072 """ | 6187 """ |
6073 Private slot handling the select all context menu action. | 6188 Private slot handling the select all context menu action. |
6074 """ | 6189 """ |
6075 self.selectAll(True) | 6190 self.selectAll(True) |
6076 | 6191 |
6192 @pyqtSlot() | |
6077 def __deselectAll(self): | 6193 def __deselectAll(self): |
6078 """ | 6194 """ |
6079 Private slot handling the deselect all context menu action. | 6195 Private slot handling the deselect all context menu action. |
6080 """ | 6196 """ |
6081 self.selectAll(False) | 6197 self.selectAll(False) |
6082 | 6198 |
6199 @pyqtSlot() | |
6083 def joinLines(self): | 6200 def joinLines(self): |
6084 """ | 6201 """ |
6085 Public slot to join the current line with the next one. | 6202 Public slot to join the current line with the next one. |
6086 """ | 6203 """ |
6087 curLine = self.getCursorPosition()[0] | 6204 curLine = self.getCursorPosition()[0] |
6119 self.beginUndoAction() | 6236 self.beginUndoAction() |
6120 self.removeSelectedText() | 6237 self.removeSelectedText() |
6121 self.insertAt(" ", curLine, startIndex) | 6238 self.insertAt(" ", curLine, startIndex) |
6122 self.endUndoAction() | 6239 self.endUndoAction() |
6123 | 6240 |
6241 @pyqtSlot() | |
6124 def shortenEmptyLines(self): | 6242 def shortenEmptyLines(self): |
6125 """ | 6243 """ |
6126 Public slot to compress lines consisting solely of whitespace | 6244 Public slot to compress lines consisting solely of whitespace |
6127 characters. | 6245 characters. |
6128 """ | 6246 """ |
6133 while ok: | 6251 while ok: |
6134 self.replaceTarget("") | 6252 self.replaceTarget("") |
6135 ok = self.findNextTarget() | 6253 ok = self.findNextTarget() |
6136 self.endUndoAction() | 6254 self.endUndoAction() |
6137 | 6255 |
6256 @pyqtSlot() | |
6138 def __autosaveEnable(self): | 6257 def __autosaveEnable(self): |
6139 """ | 6258 """ |
6140 Private slot handling the autosave enable context menu action. | 6259 Private slot handling the autosave enable context menu action. |
6141 """ | 6260 """ |
6142 if self.menuActs["AutosaveEnable"].isChecked(): | 6261 if self.menuActs["AutosaveEnable"].isChecked(): |
6144 else: | 6263 else: |
6145 self.autosaveManuallyDisabled = True | 6264 self.autosaveManuallyDisabled = True |
6146 | 6265 |
6147 def shouldAutosave(self): | 6266 def shouldAutosave(self): |
6148 """ | 6267 """ |
6149 Public slot to check the autosave flags. | 6268 Public method to check the autosave flags. |
6150 | 6269 |
6151 @return flag indicating this editor should be saved (boolean) | 6270 @return flag indicating this editor should be saved (boolean) |
6152 """ | 6271 """ |
6153 return ( | 6272 return ( |
6154 bool(self.fileName) | 6273 bool(self.fileName) |
6195 fileType, | 6314 fileType, |
6196 self.fileName or "(Unnamed)", | 6315 self.fileName or "(Unnamed)", |
6197 self.text(), | 6316 self.text(), |
6198 ) | 6317 ) |
6199 | 6318 |
6319 @pyqtSlot(str, str) | |
6200 def __processSyntaxCheckError(self, fn, msg): | 6320 def __processSyntaxCheckError(self, fn, msg): |
6201 """ | 6321 """ |
6202 Private slot to report an error message of a syntax check. | 6322 Private slot to report an error message of a syntax check. |
6203 | 6323 |
6204 @param fn filename of the file | 6324 @param fn filename of the file |
6214 | 6334 |
6215 self.toggleWarning(0, 0, True, msg) | 6335 self.toggleWarning(0, 0, True, msg) |
6216 | 6336 |
6217 self.updateVerticalScrollBar() | 6337 self.updateVerticalScrollBar() |
6218 | 6338 |
6339 @pyqtSlot(str, dict) | |
6219 def __processSyntaxCheckResult(self, fn, problems): | 6340 def __processSyntaxCheckResult(self, fn, problems): |
6220 """ | 6341 """ |
6221 Private slot to report the resulting messages of a syntax check. | 6342 Private slot to report the resulting messages of a syntax check. |
6222 | 6343 |
6223 @param fn filename of the checked file (str) | 6344 @param fn filename of the checked file |
6345 @type str | |
6224 @param problems dictionary with the keys 'error' and 'warnings' which | 6346 @param problems dictionary with the keys 'error' and 'warnings' which |
6225 hold a list containing details about the error/ warnings | 6347 hold a list containing details about the error/ warnings |
6226 (file name, line number, column, codestring (only at syntax | 6348 (file name, line number, column, codestring (only at syntax |
6227 errors), the message) (dict) | 6349 errors), the message) |
6350 @type dict | |
6228 """ | 6351 """ |
6229 # Check if it's the requested file, otherwise ignore signal | 6352 # Check if it's the requested file, otherwise ignore signal |
6230 if fn != self.fileName and (bool(self.fileName) or fn != "(Unnamed)"): | 6353 if fn != self.fileName and (bool(self.fileName) or fn != "(Unnamed)"): |
6231 return | 6354 return |
6232 | 6355 |
6236 error = problems.get("error") | 6359 error = problems.get("error") |
6237 if error: | 6360 if error: |
6238 _fn, lineno, col, code, msg = error | 6361 _fn, lineno, col, code, msg = error |
6239 self.toggleSyntaxError(lineno, col, True, msg) | 6362 self.toggleSyntaxError(lineno, col, True, msg) |
6240 | 6363 |
6241 warnings = problems.get("py_warnings", []) | 6364 for _fn, lineno, col, _code, msg in problems.get("py_warnings", []): |
6242 for _fn, lineno, col, _code, msg in warnings: | |
6243 self.toggleWarning(lineno, col, True, msg, warningType=Editor.WarningPython) | 6365 self.toggleWarning(lineno, col, True, msg, warningType=Editor.WarningPython) |
6244 | 6366 |
6245 warnings = problems.get("warnings", []) | 6367 for _fn, lineno, col, _code, msg in problems.get("warnings", []): |
6246 for _fn, lineno, col, _code, msg in warnings: | |
6247 self.toggleWarning(lineno, col, True, msg, warningType=Editor.WarningCode) | 6368 self.toggleWarning(lineno, col, True, msg, warningType=Editor.WarningCode) |
6248 | 6369 |
6249 self.updateVerticalScrollBar() | 6370 self.updateVerticalScrollBar() |
6250 | 6371 |
6372 @pyqtSlot() | |
6251 def __initOnlineSyntaxCheck(self): | 6373 def __initOnlineSyntaxCheck(self): |
6252 """ | 6374 """ |
6253 Private slot to initialize the online syntax check. | 6375 Private slot to initialize the online syntax check. |
6254 """ | 6376 """ |
6255 self.__onlineSyntaxCheckTimer = QTimer(self) | 6377 self.__onlineSyntaxCheckTimer = QTimer(self) |
6432 | 6554 |
6433 @return flag indicating the presence of coverage markers (boolean) | 6555 @return flag indicating the presence of coverage markers (boolean) |
6434 """ | 6556 """ |
6435 return len(self.notcoveredMarkers) > 0 | 6557 return len(self.notcoveredMarkers) > 0 |
6436 | 6558 |
6559 @pyqtSlot() | |
6437 def nextUncovered(self): | 6560 def nextUncovered(self): |
6438 """ | 6561 """ |
6439 Public slot to handle the 'Next uncovered' context menu action. | 6562 Public slot to handle the 'Next uncovered' context menu action. |
6440 """ | 6563 """ |
6441 line, index = self.getCursorPosition() | 6564 line, index = self.getCursorPosition() |
6449 ucline = self.markerFindNext(0, 1 << self.notcovered) | 6572 ucline = self.markerFindNext(0, 1 << self.notcovered) |
6450 if ucline >= 0: | 6573 if ucline >= 0: |
6451 self.setCursorPosition(ucline, 0) | 6574 self.setCursorPosition(ucline, 0) |
6452 self.ensureLineVisible(ucline) | 6575 self.ensureLineVisible(ucline) |
6453 | 6576 |
6577 @pyqtSlot() | |
6454 def previousUncovered(self): | 6578 def previousUncovered(self): |
6455 """ | 6579 """ |
6456 Public slot to handle the 'Previous uncovered' context menu action. | 6580 Public slot to handle the 'Previous uncovered' context menu action. |
6457 """ | 6581 """ |
6458 line, index = self.getCursorPosition() | 6582 line, index = self.getCursorPosition() |
6558 if not (markers & (1 << self.syntaxerror)): | 6682 if not (markers & (1 << self.syntaxerror)): |
6559 handle = self.markerAdd(line - 1, self.syntaxerror) | 6683 handle = self.markerAdd(line - 1, self.syntaxerror) |
6560 self.syntaxerrors[handle] = [(msg, index)] | 6684 self.syntaxerrors[handle] = [(msg, index)] |
6561 self.syntaxerrorToggled.emit(self) | 6685 self.syntaxerrorToggled.emit(self) |
6562 else: | 6686 else: |
6563 for handle in list(self.syntaxerrors.keys()): | 6687 for handle in self.syntaxerrors: |
6564 if ( | 6688 if ( |
6565 self.markerLine(handle) == line - 1 | 6689 self.markerLine(handle) == line - 1 |
6566 and (msg, index) not in self.syntaxerrors[handle] | 6690 and (msg, index) not in self.syntaxerrors[handle] |
6567 ): | 6691 ): |
6568 self.syntaxerrors[handle].append((msg, index)) | 6692 self.syntaxerrors[handle].append((msg, index)) |
6569 if show: | 6693 if show: |
6570 self.setCursorPosition(line - 1, index) | 6694 self.setCursorPosition(line - 1, index) |
6571 self.ensureLineVisible(line - 1) | 6695 self.ensureLineVisible(line - 1) |
6572 else: | 6696 else: |
6573 for handle in list(self.syntaxerrors.keys()): | 6697 for handle in self.syntaxerrors: |
6574 if self.markerLine(handle) == line - 1: | 6698 if self.markerLine(handle) == line - 1: |
6575 del self.syntaxerrors[handle] | 6699 del self.syntaxerrors[handle] |
6576 self.markerDeleteHandle(handle) | 6700 self.markerDeleteHandle(handle) |
6577 self.syntaxerrorToggled.emit(self) | 6701 self.syntaxerrorToggled.emit(self) |
6578 | 6702 |
6579 self.__setAnnotation(line - 1) | 6703 self.__setAnnotation(line - 1) |
6580 self.__markerMap.update() | 6704 self.__markerMap.update() |
6581 | |
6582 def getSyntaxErrors(self): | |
6583 """ | |
6584 Public method to retrieve the syntax error markers. | |
6585 | |
6586 @return sorted list of all lines containing a syntax error | |
6587 (list of integer) | |
6588 """ | |
6589 selist = [] | |
6590 for handle in list(self.syntaxerrors.keys()): | |
6591 selist.append(self.markerLine(handle) + 1) | |
6592 | |
6593 selist.sort() | |
6594 return selist | |
6595 | 6705 |
6596 def getSyntaxErrorLines(self): | 6706 def getSyntaxErrorLines(self): |
6597 """ | 6707 """ |
6598 Public method to get the lines containing a syntax error. | 6708 Public method to get the lines containing a syntax error. |
6599 | 6709 |
6615 | 6725 |
6616 @return flag indicating the presence of syntax errors (boolean) | 6726 @return flag indicating the presence of syntax errors (boolean) |
6617 """ | 6727 """ |
6618 return len(self.syntaxerrors) > 0 | 6728 return len(self.syntaxerrors) > 0 |
6619 | 6729 |
6730 @pyqtSlot() | |
6620 def gotoSyntaxError(self): | 6731 def gotoSyntaxError(self): |
6621 """ | 6732 """ |
6622 Public slot to handle the 'Goto syntax error' context menu action. | 6733 Public slot to handle the 'Goto syntax error' context menu action. |
6623 """ | 6734 """ |
6624 seline = self.markerFindNext(0, 1 << self.syntaxerror) | 6735 seline = self.markerFindNext(0, 1 << self.syntaxerror) |
6628 if self.markerLine(handle) == seline: | 6739 if self.markerLine(handle) == seline: |
6629 index = self.syntaxerrors[handle][0][1] | 6740 index = self.syntaxerrors[handle][0][1] |
6630 self.setCursorPosition(seline, index) | 6741 self.setCursorPosition(seline, index) |
6631 self.ensureLineVisible(seline) | 6742 self.ensureLineVisible(seline) |
6632 | 6743 |
6744 @pyqtSlot() | |
6633 def clearSyntaxError(self): | 6745 def clearSyntaxError(self): |
6634 """ | 6746 """ |
6635 Public slot to handle the 'Clear all syntax error' context menu action. | 6747 Public slot to handle the 'Clear all syntax error' context menu action. |
6636 """ | 6748 """ |
6637 for handle in list(self.syntaxerrors.keys()): | 6749 for handle in self.syntaxerrors: |
6638 line = self.markerLine(handle) + 1 | 6750 line = self.markerLine(handle) + 1 |
6639 self.toggleSyntaxError(line, 0, False) | 6751 self.toggleSyntaxError(line, 0, False) |
6640 | 6752 |
6641 self.syntaxerrors.clear() | 6753 self.syntaxerrors.clear() |
6642 self.syntaxerrorToggled.emit(self) | 6754 self.syntaxerrorToggled.emit(self) |
6643 | 6755 |
6756 @pyqtSlot() | |
6644 def __showSyntaxError(self, line=-1): | 6757 def __showSyntaxError(self, line=-1): |
6645 """ | 6758 """ |
6646 Private slot to handle the 'Show syntax error message' | 6759 Private slot to handle the 'Show syntax error message' |
6647 context menu action. | 6760 context menu action. |
6648 | 6761 |
6649 @param line line number to show the syntax error for (integer) | 6762 @param line line number to show the syntax error for |
6763 @type int | |
6650 """ | 6764 """ |
6651 if line == -1: | 6765 if line == -1: |
6652 line = self.line | 6766 line = self.line |
6653 | 6767 |
6654 for handle in list(self.syntaxerrors.keys()): | 6768 for handle in self.syntaxerrors: |
6655 if self.markerLine(handle) == line: | 6769 if self.markerLine(handle) == line: |
6656 errors = [e[0] for e in self.syntaxerrors[handle]] | 6770 errors = [e[0] for e in self.syntaxerrors[handle]] |
6657 EricMessageBox.critical( | 6771 EricMessageBox.critical( |
6658 self, self.tr("Syntax Error"), "\n".join(errors) | 6772 self, self.tr("Syntax Error"), "\n".join(errors) |
6659 ) | 6773 ) |
6714 # set/amend a new warning marker | 6828 # set/amend a new warning marker |
6715 warn = (msg, warningType) | 6829 warn = (msg, warningType) |
6716 markers = self.markersAtLine(line - 1) | 6830 markers = self.markersAtLine(line - 1) |
6717 if not (markers & (1 << self.warning)): | 6831 if not (markers & (1 << self.warning)): |
6718 handle = self.markerAdd(line - 1, self.warning) | 6832 handle = self.markerAdd(line - 1, self.warning) |
6719 self.warnings[handle] = [warn] | 6833 self._warnings[handle] = [warn] |
6720 self.syntaxerrorToggled.emit(self) | |
6721 else: | 6834 else: |
6722 for handle in list(self.warnings.keys()): | 6835 for handle in self._warnings: |
6723 if ( | 6836 if ( |
6724 self.markerLine(handle) == line - 1 | 6837 self.markerLine(handle) == line - 1 |
6725 and warn not in self.warnings[handle] | 6838 and warn not in self._warnings[handle] |
6726 ): | 6839 ): |
6727 self.warnings[handle].append(warn) | 6840 self._warnings[handle].append(warn) |
6728 else: | 6841 else: |
6729 for handle in list(self.warnings.keys()): | 6842 for handle in self._warnings: |
6730 if self.markerLine(handle) == line - 1: | 6843 if self.markerLine(handle) == line - 1: |
6731 del self.warnings[handle] | 6844 del self._warnings[handle] |
6732 self.markerDeleteHandle(handle) | 6845 self.markerDeleteHandle(handle) |
6733 self.syntaxerrorToggled.emit(self) | |
6734 | 6846 |
6735 self.__setAnnotation(line - 1) | 6847 self.__setAnnotation(line - 1) |
6736 self.__markerMap.update() | 6848 self.__markerMap.update() |
6737 | |
6738 def getWarnings(self): | |
6739 """ | |
6740 Public method to retrieve the warning markers. | |
6741 | |
6742 @return sorted list of all lines containing a warning | |
6743 (list of integer) | |
6744 """ | |
6745 fwlist = [] | |
6746 for handle in list(self.warnings.keys()): | |
6747 fwlist.append(self.markerLine(handle) + 1) | |
6748 | |
6749 fwlist.sort() | |
6750 return fwlist | |
6751 | 6849 |
6752 def getWarningLines(self): | 6850 def getWarningLines(self): |
6753 """ | 6851 """ |
6754 Public method to get the lines containing a warning. | 6852 Public method to get the lines containing a warning. |
6755 | 6853 |
6769 """ | 6867 """ |
6770 Public method to check for the presence of warnings. | 6868 Public method to check for the presence of warnings. |
6771 | 6869 |
6772 @return flag indicating the presence of warnings (boolean) | 6870 @return flag indicating the presence of warnings (boolean) |
6773 """ | 6871 """ |
6774 return len(self.warnings) > 0 | 6872 return len(self._warnings) > 0 |
6775 | 6873 |
6874 @pyqtSlot() | |
6776 def nextWarning(self): | 6875 def nextWarning(self): |
6777 """ | 6876 """ |
6778 Public slot to handle the 'Next warning' context menu action. | 6877 Public slot to handle the 'Next warning' context menu action. |
6779 """ | 6878 """ |
6780 line, index = self.getCursorPosition() | 6879 line, index = self.getCursorPosition() |
6788 fwline = self.markerFindNext(0, 1 << self.warning) | 6887 fwline = self.markerFindNext(0, 1 << self.warning) |
6789 if fwline >= 0: | 6888 if fwline >= 0: |
6790 self.setCursorPosition(fwline, 0) | 6889 self.setCursorPosition(fwline, 0) |
6791 self.ensureLineVisible(fwline) | 6890 self.ensureLineVisible(fwline) |
6792 | 6891 |
6892 @pyqtSlot() | |
6793 def previousWarning(self): | 6893 def previousWarning(self): |
6794 """ | 6894 """ |
6795 Public slot to handle the 'Previous warning' context menu action. | 6895 Public slot to handle the 'Previous warning' context menu action. |
6796 """ | 6896 """ |
6797 line, index = self.getCursorPosition() | 6897 line, index = self.getCursorPosition() |
6805 fwline = self.markerFindPrevious(self.lines() - 1, 1 << self.warning) | 6905 fwline = self.markerFindPrevious(self.lines() - 1, 1 << self.warning) |
6806 if fwline >= 0: | 6906 if fwline >= 0: |
6807 self.setCursorPosition(fwline, 0) | 6907 self.setCursorPosition(fwline, 0) |
6808 self.ensureLineVisible(fwline) | 6908 self.ensureLineVisible(fwline) |
6809 | 6909 |
6910 @pyqtSlot() | |
6810 def clearFlakesWarnings(self): | 6911 def clearFlakesWarnings(self): |
6811 """ | 6912 """ |
6812 Public slot to clear all pyflakes warnings. | 6913 Public slot to clear all pyflakes warnings. |
6813 """ | 6914 """ |
6814 self.__clearTypedWarning(Editor.WarningCode) | 6915 self.__clearTypedWarning(Editor.WarningCode) |
6815 self.__clearTypedWarning(Editor.WarningPython) | 6916 self.__clearTypedWarning(Editor.WarningPython) |
6816 | 6917 |
6918 @pyqtSlot() | |
6817 def clearStyleWarnings(self): | 6919 def clearStyleWarnings(self): |
6818 """ | 6920 """ |
6819 Public slot to clear all style warnings. | 6921 Public slot to clear all style warnings. |
6820 """ | 6922 """ |
6821 self.__clearTypedWarning(Editor.WarningStyle) | 6923 self.__clearTypedWarning(Editor.WarningStyle) |
6924 | |
6925 @pyqtSlot() | |
6926 def clearInfoWarnings(self): | |
6927 """ | |
6928 Public slot to clear all info warnings. | |
6929 """ | |
6930 self.__clearTypedWarning(Editor.WarningInfo) | |
6822 | 6931 |
6823 def __clearTypedWarning(self, warningKind): | 6932 def __clearTypedWarning(self, warningKind): |
6824 """ | 6933 """ |
6825 Private method to clear warnings of a specific kind. | 6934 Private method to clear warnings of a specific kind. |
6826 | 6935 |
6827 @param warningKind kind of warning to clear (Editor.WarningCode, | 6936 @param warningKind kind of warning to clear (Editor.WarningCode, |
6828 Editor.WarningPython, Editor.WarningStyle) | 6937 Editor.WarningPython, Editor.WarningStyle) |
6829 """ | 6938 """ |
6830 for handle in list(self.warnings.keys()): | 6939 for handle in self._warnings: |
6831 warnings = [] | 6940 issues = [] |
6832 for msg, warningType in self.warnings[handle]: | 6941 for msg, warningType in self._warnings[handle]: |
6833 if warningType == warningKind: | 6942 if warningType == warningKind: |
6834 continue | 6943 continue |
6835 | 6944 |
6836 warnings.append((msg, warningType)) | 6945 issues.append((msg, warningType)) |
6837 | 6946 |
6838 if warnings: | 6947 if issues: |
6839 self.warnings[handle] = warnings | 6948 self._warnings[handle] = issues |
6840 self.__setAnnotation(self.markerLine(handle)) | 6949 self.__setAnnotation(self.markerLine(handle)) |
6841 else: | 6950 else: |
6842 del self.warnings[handle] | 6951 del self._warnings[handle] |
6843 self.__setAnnotation(self.markerLine(handle)) | 6952 self.__setAnnotation(self.markerLine(handle)) |
6844 self.markerDeleteHandle(handle) | 6953 self.markerDeleteHandle(handle) |
6845 self.syntaxerrorToggled.emit(self) | 6954 self.syntaxerrorToggled.emit(self) |
6846 self.__markerMap.update() | 6955 self.__markerMap.update() |
6847 | 6956 |
6957 @pyqtSlot() | |
6848 def clearWarnings(self): | 6958 def clearWarnings(self): |
6849 """ | 6959 """ |
6850 Public slot to clear all warnings. | 6960 Public slot to clear all warnings. |
6851 """ | 6961 """ |
6852 for handle in self.warnings: | 6962 for handle in self._warnings: |
6853 self.warnings[handle] = [] | 6963 self._warnings[handle] = [] |
6854 self.__setAnnotation(self.markerLine(handle)) | 6964 self.__setAnnotation(self.markerLine(handle)) |
6855 self.markerDeleteHandle(handle) | 6965 self.markerDeleteHandle(handle) |
6856 self.warnings.clear() | 6966 self._warnings.clear() |
6857 self.syntaxerrorToggled.emit(self) | 6967 self.syntaxerrorToggled.emit(self) |
6858 self.__markerMap.update() | 6968 self.__markerMap.update() |
6859 | 6969 |
6970 @pyqtSlot() | |
6860 def __showWarning(self, line=-1): | 6971 def __showWarning(self, line=-1): |
6861 """ | 6972 """ |
6862 Private slot to handle the 'Show warning' context menu action. | 6973 Private slot to handle the 'Show warning' context menu action. |
6863 | 6974 |
6864 @param line line number to show the warning for (integer) | 6975 @param line line number to show the warning for |
6976 @type int | |
6865 """ | 6977 """ |
6866 if line == -1: | 6978 if line == -1: |
6867 line = self.line | 6979 line = self.line |
6868 | 6980 |
6869 for handle in list(self.warnings.keys()): | 6981 for handle in self._warnings: |
6870 if self.markerLine(handle) == line: | 6982 if self.markerLine(handle) == line: |
6871 EricMessageBox.warning( | 6983 EricMessageBox.warning( |
6872 self, | 6984 self, |
6873 self.tr("Warning"), | 6985 self.tr("Warning"), |
6874 "\n".join([w[0] for w in self.warnings[handle]]), | 6986 "\n".join([w[0] for w in self._warnings[handle]]), |
6875 ) | 6987 ) |
6876 break | 6988 break |
6877 else: | 6989 else: |
6878 EricMessageBox.warning( | 6990 EricMessageBox.warning( |
6879 self, self.tr("Warning"), self.tr("No warning messages available.") | 6991 self, self.tr("Warning"), self.tr("No warning messages available.") |
6881 | 6993 |
6882 ########################################################################### | 6994 ########################################################################### |
6883 ## Annotation handling methods below | 6995 ## Annotation handling methods below |
6884 ########################################################################### | 6996 ########################################################################### |
6885 | 6997 |
6998 @pyqtSlot() | |
6886 def __setAnnotationStyles(self): | 6999 def __setAnnotationStyles(self): |
6887 """ | 7000 """ |
6888 Private slot to define the style used by inline annotations. | 7001 Private slot to define the style used by inline annotations. |
6889 """ | 7002 """ |
6890 if hasattr(QsciScintilla, "annotate"): | 7003 if hasattr(QsciScintilla, "annotate"): |
6922 QsciScintilla.SCI_STYLESETBACK, | 7035 QsciScintilla.SCI_STYLESETBACK, |
6923 self.annotationStyleStyle, | 7036 self.annotationStyleStyle, |
6924 Preferences.getEditorColour("AnnotationsStyleBackground"), | 7037 Preferences.getEditorColour("AnnotationsStyleBackground"), |
6925 ) | 7038 ) |
6926 | 7039 |
7040 self.annotationInfoStyle = self.annotationStyleStyle + 1 | |
7041 self.SendScintilla( | |
7042 QsciScintilla.SCI_STYLESETFORE, | |
7043 self.annotationInfoStyle, | |
7044 Preferences.getEditorColour("AnnotationsInfoForeground"), | |
7045 ) | |
7046 self.SendScintilla( | |
7047 QsciScintilla.SCI_STYLESETBACK, | |
7048 self.annotationInfoStyle, | |
7049 Preferences.getEditorColour("AnnotationsInfoBackground"), | |
7050 ) | |
7051 | |
6927 def __setAnnotation(self, line): | 7052 def __setAnnotation(self, line): |
6928 """ | 7053 """ |
6929 Private method to set the annotations for the given line. | 7054 Private method to set the annotations for the given line. |
6930 | 7055 |
6931 @param line number of the line that needs annotation (integer) | 7056 @param line number of the line that needs annotation (integer) |
6932 """ | 7057 """ |
6933 if hasattr(QsciScintilla, "annotate"): | 7058 if hasattr(QsciScintilla, "annotate"): |
6934 warningAnnotations = [] | 7059 warningAnnotations = [] |
6935 errorAnnotations = [] | 7060 errorAnnotations = [] |
6936 styleAnnotations = [] | 7061 styleAnnotations = [] |
7062 infoAnnotations = [] | |
6937 | 7063 |
6938 # step 1: do warnings | 7064 # step 1: do warnings |
6939 for handle in self.warnings: | 7065 for handle in self._warnings: |
6940 if self.markerLine(handle) == line: | 7066 if self.markerLine(handle) == line: |
6941 for msg, warningType in self.warnings[handle]: | 7067 for msg, warningType in self._warnings[handle]: |
6942 if warningType == Editor.WarningStyle: | 7068 if warningType == Editor.WarningInfo: |
7069 infoAnnotations.append(self.tr("Info: {0}").format(msg)) | |
7070 elif warningType == Editor.WarningStyle: | |
6943 styleAnnotations.append(self.tr("Style: {0}").format(msg)) | 7071 styleAnnotations.append(self.tr("Style: {0}").format(msg)) |
6944 elif warningType == Editor.WarningPython: | 7072 elif warningType == Editor.WarningPython: |
6945 warningAnnotations.append(msg) | 7073 warningAnnotations.append(msg) |
6946 else: | 7074 else: |
6947 warningAnnotations.append( | 7075 warningAnnotations.append( |
6953 if self.markerLine(handle) == line: | 7081 if self.markerLine(handle) == line: |
6954 for msg, _ in self.syntaxerrors[handle]: | 7082 for msg, _ in self.syntaxerrors[handle]: |
6955 errorAnnotations.append(self.tr("Error: {0}").format(msg)) | 7083 errorAnnotations.append(self.tr("Error: {0}").format(msg)) |
6956 | 7084 |
6957 annotations = [] | 7085 annotations = [] |
7086 if infoAnnotations: | |
7087 annotationInfoTxt = "\n".join(infoAnnotations) | |
7088 if styleAnnotations or warningAnnotations or errorAnnotations: | |
7089 annotationInfoTxt += "\n" | |
7090 annotations.append( | |
7091 QsciStyledText(annotationInfoTxt, self.annotationInfoStyle) | |
7092 ) | |
7093 | |
6958 if styleAnnotations: | 7094 if styleAnnotations: |
6959 annotationStyleTxt = "\n".join(styleAnnotations) | 7095 annotationStyleTxt = "\n".join(styleAnnotations) |
6960 if warningAnnotations or errorAnnotations: | 7096 if warningAnnotations or errorAnnotations: |
6961 annotationStyleTxt += "\n" | 7097 annotationStyleTxt += "\n" |
6962 annotations.append( | 7098 annotations.append( |
6986 """ | 7122 """ |
6987 Private method to refresh the annotations. | 7123 Private method to refresh the annotations. |
6988 """ | 7124 """ |
6989 if hasattr(QsciScintilla, "annotate"): | 7125 if hasattr(QsciScintilla, "annotate"): |
6990 self.clearAnnotations() | 7126 self.clearAnnotations() |
6991 for handle in list(self.warnings.keys()) + list(self.syntaxerrors.keys()): | 7127 for handle in self._warnings: |
7128 line = self.markerLine(handle) | |
7129 self.__setAnnotation(line) | |
7130 for handle in self.syntaxerrors: | |
6992 line = self.markerLine(handle) | 7131 line = self.markerLine(handle) |
6993 self.__setAnnotation(line) | 7132 self.__setAnnotation(line) |
6994 | 7133 |
6995 ################################################################# | 7134 ################################################################# |
6996 ## Fold handling methods | 7135 ## Fold handling methods |
6997 ################################################################# | 7136 ################################################################# |
6998 | 7137 |
7138 @pyqtSlot() | |
6999 def toggleCurrentFold(self): | 7139 def toggleCurrentFold(self): |
7000 """ | 7140 """ |
7001 Public slot to toggle the fold containing the current line. | 7141 Public slot to toggle the fold containing the current line. |
7002 """ | 7142 """ |
7003 line, index = self.getCursorPosition() | 7143 line, index = self.getCursorPosition() |
7004 self.foldLine(line) | 7144 self.foldLine(line) |
7005 | 7145 |
7006 def expandFoldWithChildren(self, line=-1): | 7146 def expandFoldWithChildren(self, line=-1): |
7007 """ | 7147 """ |
7008 Public slot to expand the current fold including its children. | 7148 Public method to expand the current fold including its children. |
7009 | 7149 |
7010 @param line number of line to be expanded | 7150 @param line number of line to be expanded |
7011 @type int | 7151 @type int |
7012 """ | 7152 """ |
7013 if line == -1: | 7153 if line == -1: |
7017 QsciScintilla.SCI_FOLDCHILDREN, line, QsciScintilla.SC_FOLDACTION_EXPAND | 7157 QsciScintilla.SCI_FOLDCHILDREN, line, QsciScintilla.SC_FOLDACTION_EXPAND |
7018 ) | 7158 ) |
7019 | 7159 |
7020 def collapseFoldWithChildren(self, line=-1): | 7160 def collapseFoldWithChildren(self, line=-1): |
7021 """ | 7161 """ |
7022 Public slot to collapse the current fold including its children. | 7162 Public method to collapse the current fold including its children. |
7023 | 7163 |
7024 @param line number of line to be expanded | 7164 @param line number of line to be expanded |
7025 @type int | 7165 @type int |
7026 """ | 7166 """ |
7027 if line == -1: | 7167 if line == -1: |
7029 | 7169 |
7030 self.SendScintilla( | 7170 self.SendScintilla( |
7031 QsciScintilla.SCI_FOLDCHILDREN, line, QsciScintilla.SC_FOLDACTION_CONTRACT | 7171 QsciScintilla.SCI_FOLDCHILDREN, line, QsciScintilla.SC_FOLDACTION_CONTRACT |
7032 ) | 7172 ) |
7033 | 7173 |
7174 @pyqtSlot() | |
7034 def __contextMenuExpandFoldWithChildren(self): | 7175 def __contextMenuExpandFoldWithChildren(self): |
7035 """ | 7176 """ |
7036 Private slot to handle the context menu expand with children action. | 7177 Private slot to handle the context menu expand with children action. |
7037 """ | 7178 """ |
7038 self.expandFoldWithChildren(self.line) | 7179 self.expandFoldWithChildren(self.line) |
7039 | 7180 |
7181 @pyqtSlot() | |
7040 def __contextMenuCollapseFoldWithChildren(self): | 7182 def __contextMenuCollapseFoldWithChildren(self): |
7041 """ | 7183 """ |
7042 Private slot to handle the context menu collapse with children action. | 7184 Private slot to handle the context menu collapse with children action. |
7043 """ | 7185 """ |
7044 self.collapseFoldWithChildren(self.line) | 7186 self.collapseFoldWithChildren(self.line) |
7053 | 7195 |
7054 @return Tuple of macro name and a flag, indicating, if the user | 7196 @return Tuple of macro name and a flag, indicating, if the user |
7055 pressed ok or canceled the operation. (string, boolean) | 7197 pressed ok or canceled the operation. (string, boolean) |
7056 """ | 7198 """ |
7057 qs = [] | 7199 qs = [] |
7058 for s in list(self.macros.keys()): | 7200 for s in self.macros: |
7059 qs.append(s) | 7201 qs.append(s) |
7060 qs.sort() | 7202 qs.sort() |
7061 return QInputDialog.getItem( | 7203 return QInputDialog.getItem( |
7062 self, self.tr("Macro Name"), self.tr("Select a macro name:"), qs, 0, False | 7204 self, self.tr("Macro Name"), self.tr("Select a macro name:"), qs, 0, False |
7063 ) | 7205 ) |
7583 """ | 7725 """ |
7584 return ( | 7726 return ( |
7585 self.isLocalFile() and not os.access(self.fileName, os.W_OK) | 7727 self.isLocalFile() and not os.access(self.fileName, os.W_OK) |
7586 ) or self.isReadOnly() | 7728 ) or self.isReadOnly() |
7587 | 7729 |
7730 @pyqtSlot() | |
7588 def refresh(self): | 7731 def refresh(self): |
7589 """ | 7732 """ |
7590 Public slot to refresh the editor contents. | 7733 Public slot to refresh the editor contents. |
7591 """ | 7734 """ |
7592 # save cursor position | 7735 # save cursor position |
7601 | 7744 |
7602 # clear flakes warning markers | 7745 # clear flakes warning markers |
7603 self.clearWarnings() | 7746 self.clearWarnings() |
7604 | 7747 |
7605 # clear breakpoint markers | 7748 # clear breakpoint markers |
7606 for handle in list(self.breaks.keys()): | 7749 for handle in self.breaks: |
7607 self.markerDeleteHandle(handle) | 7750 self.markerDeleteHandle(handle) |
7608 self.breaks.clear() | 7751 self.breaks.clear() |
7609 | 7752 |
7610 if not os.path.exists(self.fileName): | 7753 if not os.path.exists(self.fileName): |
7611 # close the file, if it was deleted in the background | 7754 # close the file, if it was deleted in the background |
7757 | 7900 |
7758 menu.aboutToShow.connect(self.__showContextMenuResources) | 7901 menu.aboutToShow.connect(self.__showContextMenuResources) |
7759 | 7902 |
7760 return menu | 7903 return menu |
7761 | 7904 |
7905 @pyqtSlot() | |
7762 def __showContextMenuResources(self): | 7906 def __showContextMenuResources(self): |
7763 """ | 7907 """ |
7764 Private slot handling the aboutToShow signal of the resources context | 7908 Private slot handling the aboutToShow signal of the resources context |
7765 menu. | 7909 menu. |
7766 """ | 7910 """ |
7934 self.applicationDiagram = UMLDialog( | 8078 self.applicationDiagram = UMLDialog( |
7935 UMLDialogType.APPLICATION_DIAGRAM, self.project, self, noModules=not res | 8079 UMLDialogType.APPLICATION_DIAGRAM, self.project, self, noModules=not res |
7936 ) | 8080 ) |
7937 self.applicationDiagram.show() | 8081 self.applicationDiagram.show() |
7938 | 8082 |
8083 @pyqtSlot() | |
7939 def __loadDiagram(self): | 8084 def __loadDiagram(self): |
7940 """ | 8085 """ |
7941 Private slot to load a diagram from file. | 8086 Private slot to load a diagram from file. |
7942 """ | 8087 """ |
7943 from eric7.Graphics.UMLDialog import UMLDialog, UMLDialogType | 8088 from eric7.Graphics.UMLDialog import UMLDialog, UMLDialogType |
7952 | 8097 |
7953 ####################################################################### | 8098 ####################################################################### |
7954 ## Typing aids related methods below | 8099 ## Typing aids related methods below |
7955 ####################################################################### | 8100 ####################################################################### |
7956 | 8101 |
8102 @pyqtSlot() | |
7957 def __toggleTypingAids(self): | 8103 def __toggleTypingAids(self): |
7958 """ | 8104 """ |
7959 Private slot to toggle the typing aids. | 8105 Private slot to toggle the typing aids. |
7960 """ | 8106 """ |
7961 if self.menuActs["TypingAidsEnabled"].isChecked(): | 8107 if self.menuActs["TypingAidsEnabled"].isChecked(): |
8049 | 8195 |
8050 ####################################################################### | 8196 ####################################################################### |
8051 ## Project related methods | 8197 ## Project related methods |
8052 ####################################################################### | 8198 ####################################################################### |
8053 | 8199 |
8200 @pyqtSlot() | |
8054 def __projectPropertiesChanged(self): | 8201 def __projectPropertiesChanged(self): |
8055 """ | 8202 """ |
8056 Private slot to handle changes of the project properties. | 8203 Private slot to handle changes of the project properties. |
8057 """ | 8204 """ |
8058 if self.spell: | 8205 if self.spell: |
8078 self.project.getProjectSpellLanguage(), pwl=pwl, pel=pel | 8225 self.project.getProjectSpellLanguage(), pwl=pwl, pel=pel |
8079 ) | 8226 ) |
8080 | 8227 |
8081 self.project.projectPropertiesChanged.connect(self.__projectPropertiesChanged) | 8228 self.project.projectPropertiesChanged.connect(self.__projectPropertiesChanged) |
8082 | 8229 |
8230 @pyqtSlot() | |
8083 def projectOpened(self): | 8231 def projectOpened(self): |
8084 """ | 8232 """ |
8085 Public slot to handle the opening of a project. | 8233 Public slot to handle the opening of a project. |
8086 """ | 8234 """ |
8087 if self.fileName and self.project.isProjectCategory(self.fileName, "SOURCES"): | 8235 if self.fileName and self.project.isProjectCategory(self.fileName, "SOURCES"): |
8088 self.project.projectPropertiesChanged.connect( | 8236 self.project.projectPropertiesChanged.connect( |
8089 self.__projectPropertiesChanged | 8237 self.__projectPropertiesChanged |
8090 ) | 8238 ) |
8091 self.setSpellingForProject() | 8239 self.setSpellingForProject() |
8092 | 8240 |
8241 @pyqtSlot() | |
8093 def projectClosed(self): | 8242 def projectClosed(self): |
8094 """ | 8243 """ |
8095 Public slot to handle the closing of a project. | 8244 Public slot to handle the closing of a project. |
8096 """ | 8245 """ |
8097 with contextlib.suppress(TypeError): | 8246 with contextlib.suppress(TypeError): |
8115 | 8264 |
8116 return "" | 8265 return "" |
8117 | 8266 |
8118 def __setSpellingLanguage(self, language, pwl="", pel=""): | 8267 def __setSpellingLanguage(self, language, pwl="", pel=""): |
8119 """ | 8268 """ |
8120 Private slot to set the spell checking language. | 8269 Private method to set the spell checking language. |
8121 | 8270 |
8122 @param language spell checking language to be set (string) | 8271 @param language spell checking language to be set (string) |
8123 @param pwl name of the personal/project word list (string) | 8272 @param pwl name of the personal/project word list (string) |
8124 @param pel name of the personal/project exclude list (string) | 8273 @param pel name of the personal/project exclude list (string) |
8125 """ | 8274 """ |
8215 @pyqtSlot(int) | 8364 @pyqtSlot(int) |
8216 def __spellCharAdded(self, charNumber): | 8365 def __spellCharAdded(self, charNumber): |
8217 """ | 8366 """ |
8218 Private slot called to handle the user entering a character. | 8367 Private slot called to handle the user entering a character. |
8219 | 8368 |
8220 @param charNumber value of the character entered (integer) | 8369 @param charNumber value of the character entered |
8370 @type int | |
8221 """ | 8371 """ |
8222 if self.spell: | 8372 if self.spell: |
8223 if not chr(charNumber).isalnum(): | 8373 if not chr(charNumber).isalnum(): |
8224 self.spell.checkWord(self.positionBefore(self.currentPosition()), True) | 8374 self.spell.checkWord(self.positionBefore(self.currentPosition()), True) |
8225 elif self.hasIndicator(self.spellingIndicator, self.currentPosition()): | 8375 elif self.hasIndicator(self.spellingIndicator, self.currentPosition()): |
8226 self.spell.checkWord(self.currentPosition()) | 8376 self.spell.checkWord(self.currentPosition()) |
8227 | 8377 |
8378 @pyqtSlot() | |
8228 def checkSpelling(self): | 8379 def checkSpelling(self): |
8229 """ | 8380 """ |
8230 Public slot to perform an interactive spell check of the document. | 8381 Public slot to perform an interactive spell check of the document. |
8231 """ | 8382 """ |
8232 from .SpellCheckingDialog import SpellCheckingDialog | 8383 from .SpellCheckingDialog import SpellCheckingDialog |
8237 dlg.exec() | 8388 dlg.exec() |
8238 self.setCursorPosition(cline, cindex) | 8389 self.setCursorPosition(cline, cindex) |
8239 if Preferences.getEditor("AutoSpellCheckingEnabled"): | 8390 if Preferences.getEditor("AutoSpellCheckingEnabled"): |
8240 self.spell.checkDocumentIncrementally() | 8391 self.spell.checkDocumentIncrementally() |
8241 | 8392 |
8393 @pyqtSlot() | |
8242 def __checkSpellingSelection(self): | 8394 def __checkSpellingSelection(self): |
8243 """ | 8395 """ |
8244 Private slot to spell check the current selection. | 8396 Private slot to spell check the current selection. |
8245 """ | 8397 """ |
8246 from .SpellCheckingDialog import SpellCheckingDialog | 8398 from .SpellCheckingDialog import SpellCheckingDialog |
8249 startPos = self.positionFromLineIndex(sline, sindex) | 8401 startPos = self.positionFromLineIndex(sline, sindex) |
8250 endPos = self.positionFromLineIndex(eline, eindex) | 8402 endPos = self.positionFromLineIndex(eline, eindex) |
8251 dlg = SpellCheckingDialog(self.spell, startPos, endPos, self) | 8403 dlg = SpellCheckingDialog(self.spell, startPos, endPos, self) |
8252 dlg.exec() | 8404 dlg.exec() |
8253 | 8405 |
8406 @pyqtSlot() | |
8254 def __checkSpellingWord(self): | 8407 def __checkSpellingWord(self): |
8255 """ | 8408 """ |
8256 Private slot to check the word below the spelling context menu. | 8409 Private slot to check the word below the spelling context menu. |
8257 """ | 8410 """ |
8258 from .SpellCheckingDialog import SpellCheckingDialog | 8411 from .SpellCheckingDialog import SpellCheckingDialog |
8262 wordStartPos = self.positionFromLineIndex(line, wordStart) | 8415 wordStartPos = self.positionFromLineIndex(line, wordStart) |
8263 wordEndPos = self.positionFromLineIndex(line, wordEnd) | 8416 wordEndPos = self.positionFromLineIndex(line, wordEnd) |
8264 dlg = SpellCheckingDialog(self.spell, wordStartPos, wordEndPos, self) | 8417 dlg = SpellCheckingDialog(self.spell, wordStartPos, wordEndPos, self) |
8265 dlg.exec() | 8418 dlg.exec() |
8266 | 8419 |
8420 @pyqtSlot() | |
8267 def __showContextMenuSpelling(self): | 8421 def __showContextMenuSpelling(self): |
8268 """ | 8422 """ |
8269 Private slot to set up the spelling menu before it is shown. | 8423 Private slot to set up the spelling menu before it is shown. |
8270 """ | 8424 """ |
8271 self.spellingMenu.clear() | 8425 self.spellingMenu.clear() |
8287 ) | 8441 ) |
8288 self.spellingMenu.addAction(self.tr("Ignore All"), self.__ignoreSpellingAlways) | 8442 self.spellingMenu.addAction(self.tr("Ignore All"), self.__ignoreSpellingAlways) |
8289 | 8443 |
8290 self.showMenu.emit("Spelling", self.spellingMenu, self) | 8444 self.showMenu.emit("Spelling", self.spellingMenu, self) |
8291 | 8445 |
8446 @pyqtSlot(QAction) | |
8292 def __contextMenuSpellingTriggered(self, action): | 8447 def __contextMenuSpellingTriggered(self, action): |
8293 """ | 8448 """ |
8294 Private slot to handle the selection of a suggestion of the spelling | 8449 Private slot to handle the selection of a suggestion of the spelling |
8295 context menu. | 8450 context menu. |
8296 | 8451 |
8297 @param action reference to the action that was selected (QAction) | 8452 @param action reference to the action that was selected |
8453 @type QAction | |
8298 """ | 8454 """ |
8299 if action in self.spellingSuggActs: | 8455 if action in self.spellingSuggActs: |
8300 replacement = action.text() | 8456 replacement = action.text() |
8301 line, index = self.lineIndexFromPosition(self.spellingMenuPos) | 8457 line, index = self.lineIndexFromPosition(self.spellingMenuPos) |
8302 wordStart, wordEnd = self.getWordBoundaries(line, index) | 8458 wordStart, wordEnd = self.getWordBoundaries(line, index) |
8304 self.beginUndoAction() | 8460 self.beginUndoAction() |
8305 self.removeSelectedText() | 8461 self.removeSelectedText() |
8306 self.insert(replacement) | 8462 self.insert(replacement) |
8307 self.endUndoAction() | 8463 self.endUndoAction() |
8308 | 8464 |
8465 @pyqtSlot() | |
8309 def __addToSpellingDictionary(self): | 8466 def __addToSpellingDictionary(self): |
8310 """ | 8467 """ |
8311 Private slot to add the word below the spelling context menu to the | 8468 Private slot to add the word below the spelling context menu to the |
8312 dictionary. | 8469 dictionary. |
8313 """ | 8470 """ |
8318 wordStart, wordEnd = self.getWordBoundaries(line, index) | 8475 wordStart, wordEnd = self.getWordBoundaries(line, index) |
8319 self.clearIndicator(self.spellingIndicator, line, wordStart, line, wordEnd) | 8476 self.clearIndicator(self.spellingIndicator, line, wordStart, line, wordEnd) |
8320 if Preferences.getEditor("AutoSpellCheckingEnabled"): | 8477 if Preferences.getEditor("AutoSpellCheckingEnabled"): |
8321 self.spell.checkDocumentIncrementally() | 8478 self.spell.checkDocumentIncrementally() |
8322 | 8479 |
8480 @pyqtSlot() | |
8323 def __removeFromSpellingDictionary(self): | 8481 def __removeFromSpellingDictionary(self): |
8324 """ | 8482 """ |
8325 Private slot to remove the word below the context menu to the | 8483 Private slot to remove the word below the context menu to the |
8326 dictionary. | 8484 dictionary. |
8327 """ | 8485 """ |
8366 self.__inRemoteSharedEdit, | 8524 self.__inRemoteSharedEdit, |
8367 ) | 8525 ) |
8368 | 8526 |
8369 def shareConnected(self, connected): | 8527 def shareConnected(self, connected): |
8370 """ | 8528 """ |
8371 Public slot to handle a change of the connected state. | 8529 Public method to handle a change of the connected state. |
8372 | 8530 |
8373 @param connected flag indicating the connected state (boolean) | 8531 @param connected flag indicating the connected state (boolean) |
8374 """ | 8532 """ |
8375 if not connected: | 8533 if not connected: |
8376 self.__inRemoteSharedEdit = False | 8534 self.__inRemoteSharedEdit = False |
8380 self.__isSyncing = False | 8538 self.__isSyncing = False |
8381 self.__receivedWhileSyncing = [] | 8539 self.__receivedWhileSyncing = [] |
8382 | 8540 |
8383 def shareEditor(self, share): | 8541 def shareEditor(self, share): |
8384 """ | 8542 """ |
8385 Public slot to set the shared status of the editor. | 8543 Public method to set the shared status of the editor. |
8386 | 8544 |
8387 @param share flag indicating the share status (boolean) | 8545 @param share flag indicating the share status (boolean) |
8388 """ | 8546 """ |
8389 self.__isShared = share | 8547 self.__isShared = share |
8390 if not share: | 8548 if not share: |
8391 self.shareConnected(False) | 8549 self.shareConnected(False) |
8392 | 8550 |
8551 @pyqtSlot() | |
8393 def startSharedEdit(self): | 8552 def startSharedEdit(self): |
8394 """ | 8553 """ |
8395 Public slot to start a shared edit session for the editor. | 8554 Public slot to start a shared edit session for the editor. |
8396 """ | 8555 """ |
8397 self.__inSharedEdit = True | 8556 self.__inSharedEdit = True |
8403 ).toHex(), | 8562 ).toHex(), |
8404 encoding="utf-8", | 8563 encoding="utf-8", |
8405 ) | 8564 ) |
8406 self.__send(Editor.StartEditToken, hashStr) | 8565 self.__send(Editor.StartEditToken, hashStr) |
8407 | 8566 |
8567 @pyqtSlot() | |
8408 def sendSharedEdit(self): | 8568 def sendSharedEdit(self): |
8409 """ | 8569 """ |
8410 Public slot to end a shared edit session for the editor and | 8570 Public slot to end a shared edit session for the editor and |
8411 send the changes. | 8571 send the changes. |
8412 """ | 8572 """ |
8415 self.__inSharedEdit = False | 8575 self.__inSharedEdit = False |
8416 self.__savedText = "" | 8576 self.__savedText = "" |
8417 | 8577 |
8418 def cancelSharedEdit(self, send=True): | 8578 def cancelSharedEdit(self, send=True): |
8419 """ | 8579 """ |
8420 Public slot to cancel a shared edit session for the editor. | 8580 Public method to cancel a shared edit session for the editor. |
8421 | 8581 |
8422 @param send flag indicating to send the CancelEdit command (boolean) | 8582 @param send flag indicating to send the CancelEdit command (boolean) |
8423 """ | 8583 """ |
8424 self.__inSharedEdit = False | 8584 self.__inSharedEdit = False |
8425 self.__savedText = "" | 8585 self.__savedText = "" |
8445 elif token == Editor.CancelEditToken: | 8605 elif token == Editor.CancelEditToken: |
8446 msg = "{0}{1}c".format(token, Editor.Separator) | 8606 msg = "{0}{1}c".format(token, Editor.Separator) |
8447 | 8607 |
8448 self.vm.send(self.fileName, msg) | 8608 self.vm.send(self.fileName, msg) |
8449 | 8609 |
8610 @pyqtSlot(str) | |
8450 def receive(self, command): | 8611 def receive(self, command): |
8451 """ | 8612 """ |
8452 Public slot to handle received editor commands. | 8613 Public slot to handle received editor commands. |
8453 | 8614 |
8454 @param command command string (string) | 8615 @param command command string |
8616 @type str | |
8455 """ | 8617 """ |
8456 if self.__isShared: | 8618 if self.__isShared: |
8457 if self.__isSyncing and not command.startswith( | 8619 if self.__isSyncing and not command.startswith( |
8458 Editor.SyncToken + Editor.Separator | 8620 Editor.SyncToken + Editor.Separator |
8459 ): | 8621 ): |
8477 elif token == Editor.RequestSyncToken: | 8639 elif token == Editor.RequestSyncToken: |
8478 self.__processRequestSyncCommand(argsString) | 8640 self.__processRequestSyncCommand(argsString) |
8479 elif token == Editor.SyncToken: | 8641 elif token == Editor.SyncToken: |
8480 self.__processSyncCommand(argsString) | 8642 self.__processSyncCommand(argsString) |
8481 | 8643 |
8644 @pyqtSlot(str) | |
8482 def __processStartEditCommand(self, argsString): | 8645 def __processStartEditCommand(self, argsString): |
8483 """ | 8646 """ |
8484 Private slot to process a remote StartEdit command. | 8647 Private slot to process a remote StartEdit command. |
8485 | 8648 |
8486 @param argsString string containing the command parameters (string) | 8649 @param argsString string containing the command parameters |
8650 @type str | |
8487 """ | 8651 """ |
8488 if not self.__inSharedEdit and not self.__inRemoteSharedEdit: | 8652 if not self.__inSharedEdit and not self.__inRemoteSharedEdit: |
8489 self.__inRemoteSharedEdit = True | 8653 self.__inRemoteSharedEdit = True |
8490 self.setReadOnly(True) | 8654 self.setReadOnly(True) |
8491 self.__updateReadOnly() | 8655 self.__updateReadOnly() |
8526 commands.append(formatStr.format("r", j1, i2 - i1, j2 - j1)) | 8690 commands.append(formatStr.format("r", j1, i2 - i1, j2 - j1)) |
8527 commands.extend(newL[j1:j2]) | 8691 commands.extend(newL[j1:j2]) |
8528 | 8692 |
8529 return "\n".join(commands) + "\n" | 8693 return "\n".join(commands) + "\n" |
8530 | 8694 |
8695 @pyqtSlot(str) | |
8531 def __processEndEditCommand(self, argsString): | 8696 def __processEndEditCommand(self, argsString): |
8532 """ | 8697 """ |
8533 Private slot to process a remote EndEdit command. | 8698 Private slot to process a remote EndEdit command. |
8534 | 8699 |
8535 @param argsString string containing the command parameters (string) | 8700 @param argsString string containing the command parameters |
8701 @type str | |
8536 """ | 8702 """ |
8537 commands = argsString.splitlines() | 8703 commands = argsString.splitlines() |
8538 sep = self.getLineSeparator() | 8704 sep = self.getLineSeparator() |
8539 cur = self.getCursorPosition() | 8705 cur = self.getCursorPosition() |
8540 | 8706 |
8565 self.__updateReadOnly() | 8731 self.__updateReadOnly() |
8566 self.__inRemoteSharedEdit = False | 8732 self.__inRemoteSharedEdit = False |
8567 | 8733 |
8568 self.setCursorPosition(*cur) | 8734 self.setCursorPosition(*cur) |
8569 | 8735 |
8736 @pyqtSlot(str) | |
8570 def __processRequestSyncCommand(self, argsString): | 8737 def __processRequestSyncCommand(self, argsString): |
8571 """ | 8738 """ |
8572 Private slot to process a remote RequestSync command. | 8739 Private slot to process a remote RequestSync command. |
8573 | 8740 |
8574 @param argsString string containing the command parameters (string) | 8741 @param argsString string containing the command parameters |
8742 @type str | |
8575 """ | 8743 """ |
8576 if self.__inSharedEdit: | 8744 if self.__inSharedEdit: |
8577 hashStr = str( | 8745 hashStr = str( |
8578 QCryptographicHash.hash( | 8746 QCryptographicHash.hash( |
8579 Utilities.encode(self.__savedText, self.encoding)[0], | 8747 Utilities.encode(self.__savedText, self.encoding)[0], |
8583 ) | 8751 ) |
8584 | 8752 |
8585 if hashStr == argsString: | 8753 if hashStr == argsString: |
8586 self.__send(Editor.SyncToken, self.__savedText) | 8754 self.__send(Editor.SyncToken, self.__savedText) |
8587 | 8755 |
8756 @pyqtSlot(str) | |
8588 def __processSyncCommand(self, argsString): | 8757 def __processSyncCommand(self, argsString): |
8589 """ | 8758 """ |
8590 Private slot to process a remote Sync command. | 8759 Private slot to process a remote Sync command. |
8591 | 8760 |
8592 @param argsString string containing the command parameters (string) | 8761 @param argsString string containing the command parameters |
8762 @type str | |
8593 """ | 8763 """ |
8594 if self.__isSyncing: | 8764 if self.__isSyncing: |
8595 cur = self.getCursorPosition() | 8765 cur = self.getCursorPosition() |
8596 | 8766 |
8597 self.setReadOnly(False) | 8767 self.setReadOnly(False) |
8612 | 8782 |
8613 ####################################################################### | 8783 ####################################################################### |
8614 ## Special search related methods | 8784 ## Special search related methods |
8615 ####################################################################### | 8785 ####################################################################### |
8616 | 8786 |
8787 @pyqtSlot() | |
8617 def searchCurrentWordForward(self): | 8788 def searchCurrentWordForward(self): |
8618 """ | 8789 """ |
8619 Public slot to search the current word forward. | 8790 Public slot to search the current word forward. |
8620 """ | 8791 """ |
8621 self.__searchCurrentWord(forward=True) | 8792 self.__searchCurrentWord(forward=True) |
8622 | 8793 |
8794 @pyqtSlot() | |
8623 def searchCurrentWordBackward(self): | 8795 def searchCurrentWordBackward(self): |
8624 """ | 8796 """ |
8625 Public slot to search the current word backward. | 8797 Public slot to search the current word backward. |
8626 """ | 8798 """ |
8627 self.__searchCurrentWord(forward=False) | 8799 self.__searchCurrentWord(forward=False) |
8664 | 8836 |
8665 ####################################################################### | 8837 ####################################################################### |
8666 ## Sort related methods | 8838 ## Sort related methods |
8667 ####################################################################### | 8839 ####################################################################### |
8668 | 8840 |
8841 @pyqtSlot() | |
8669 def sortLines(self): | 8842 def sortLines(self): |
8670 """ | 8843 """ |
8671 Public slot to sort the lines spanned by a rectangular selection. | 8844 Public slot to sort the lines spanned by a rectangular selection. |
8672 """ | 8845 """ |
8673 from .SortOptionsDialog import SortOptionsDialog | 8846 from .SortOptionsDialog import SortOptionsDialog |
8922 | 9095 |
8923 ####################################################################### | 9096 ####################################################################### |
8924 ## Methods implementing a Shell interface | 9097 ## Methods implementing a Shell interface |
8925 ####################################################################### | 9098 ####################################################################### |
8926 | 9099 |
9100 @pyqtSlot() | |
8927 def __executeSelection(self): | 9101 def __executeSelection(self): |
8928 """ | 9102 """ |
8929 Private slot to execute the selected text in the shell window. | 9103 Private slot to execute the selected text in the shell window. |
8930 """ | 9104 """ |
8931 txt = self.selectedText() | 9105 txt = self.selectedText() |
9134 300, lambda: self.__popupDocstringMenu(lineText2Cursor, cursorPosition) | 9308 300, lambda: self.__popupDocstringMenu(lineText2Cursor, cursorPosition) |
9135 ) | 9309 ) |
9136 | 9310 |
9137 def __popupDocstringMenu(self, lastLineText, lastCursorPosition): | 9311 def __popupDocstringMenu(self, lastLineText, lastCursorPosition): |
9138 """ | 9312 """ |
9139 Private slot to pop up a menu asking the user, if a docstring should be | 9313 Private method to pop up a menu asking the user, if a docstring should be |
9140 inserted. | 9314 inserted. |
9141 | 9315 |
9142 @param lastLineText line contents when the delay timer was started | 9316 @param lastLineText line contents when the delay timer was started |
9143 @type str | 9317 @type str |
9144 @param lastCursorPosition position of the cursor when the delay timer | 9318 @param lastCursorPosition position of the cursor when the delay timer |
9197 else: | 9371 else: |
9198 self.__cancelMouseHoverHelp() | 9372 self.__cancelMouseHoverHelp() |
9199 else: | 9373 else: |
9200 self.__cancelMouseHoverHelp() | 9374 self.__cancelMouseHoverHelp() |
9201 | 9375 |
9376 @pyqtSlot() | |
9202 def __cancelMouseHoverHelp(self): | 9377 def __cancelMouseHoverHelp(self): |
9203 """ | 9378 """ |
9204 Private slot cancelling the display of mouse hover help. | 9379 Private slot cancelling the display of mouse hover help. |
9205 """ | 9380 """ |
9206 if self.__showingMouseHoverHelp: | 9381 if self.__showingMouseHoverHelp: |