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 QActionGroup, QFont, QPainter, QPalette, QPixmap |
35 from PyQt6.QtPrintSupport import QAbstractPrintDialog, QPrintDialog, QPrinter |
35 from PyQt6.QtPrintSupport import ( |
|
36 QAbstractPrintDialog, |
|
37 QPrintDialog, |
|
38 QPrinter, |
|
39 QPrintPreviewDialog, |
|
40 ) |
36 from PyQt6.QtWidgets import QApplication, QDialog, QInputDialog, QLineEdit, QMenu |
41 from PyQt6.QtWidgets import QApplication, QDialog, QInputDialog, QLineEdit, QMenu |
37 |
42 |
38 from eric7 import Preferences, Utilities |
43 from eric7 import Preferences, Utilities |
39 from eric7.CodeFormatting.BlackFormattingAction import BlackFormattingAction |
44 from eric7.CodeFormatting.BlackFormattingAction import BlackFormattingAction |
40 from eric7.CodeFormatting.BlackUtilities import aboutBlack |
45 from eric7.CodeFormatting.BlackUtilities import aboutBlack |
47 from eric7.EricWidgets.EricApplication import ericApp |
52 from eric7.EricWidgets.EricApplication import ericApp |
48 from eric7.Globals import recentNameBreakpointConditions |
53 from eric7.Globals import recentNameBreakpointConditions |
49 from eric7.UI import PythonDisViewer |
54 from eric7.UI import PythonDisViewer |
50 from eric7.Utilities import MouseUtilities |
55 from eric7.Utilities import MouseUtilities |
51 |
56 |
|
57 from . import Exporters, Lexers, TypingCompleters |
52 from .EditorMarkerMap import EditorMarkerMap |
58 from .EditorMarkerMap import EditorMarkerMap |
53 from .QsciScintillaCompat import QsciScintillaCompat |
59 from .QsciScintillaCompat import QsciScintillaCompat |
54 from .SpellChecker import SpellChecker |
60 from .SpellChecker import SpellChecker |
55 |
61 |
56 EditorAutoCompletionListID = 1 |
62 EditorAutoCompletionListID = 1 |
738 elif line0.startswith("\\documentclass"): |
744 elif line0.startswith("\\documentclass"): |
739 bindName = "dummy.tex" |
745 bindName = "dummy.tex" |
740 |
746 |
741 if not bindName and self.filetype: |
747 if not bindName and self.filetype: |
742 # check filetype |
748 # check filetype |
743 from . import Lexers |
|
744 |
|
745 supportedLanguages = Lexers.getSupportedLanguages() |
749 supportedLanguages = Lexers.getSupportedLanguages() |
746 if self.filetype in supportedLanguages: |
750 if self.filetype in supportedLanguages: |
747 bindName = supportedLanguages[self.filetype][1] |
751 bindName = supportedLanguages[self.filetype][1] |
748 elif self.filetype in ["Python", "Python3", "MicroPython"]: |
752 elif self.filetype in ["Python", "Python3", "MicroPython"]: |
749 bindName = "dummy.py" |
753 bindName = "dummy.py" |
1167 self.noLanguageAct.setCheckable(True) |
1171 self.noLanguageAct.setCheckable(True) |
1168 self.noLanguageAct.setData("None") |
1172 self.noLanguageAct.setData("None") |
1169 self.languagesActGrp.addAction(self.noLanguageAct) |
1173 self.languagesActGrp.addAction(self.noLanguageAct) |
1170 menu.addSeparator() |
1174 menu.addSeparator() |
1171 |
1175 |
1172 from . import Lexers |
|
1173 |
|
1174 self.supportedLanguages = {} |
1176 self.supportedLanguages = {} |
1175 supportedLanguages = Lexers.getSupportedLanguages() |
1177 supportedLanguages = Lexers.getSupportedLanguages() |
1176 languages = sorted(supportedLanguages.keys()) |
1178 languages = sorted(supportedLanguages.keys()) |
1177 for language in languages: |
1179 for language in languages: |
1178 if language != "Guessed": |
1180 if language != "Guessed": |
1485 Public method to export the file. |
1487 Public method to export the file. |
1486 |
1488 |
1487 @param exporterFormat format the file should be exported into (string) |
1489 @param exporterFormat format the file should be exported into (string) |
1488 """ |
1490 """ |
1489 if exporterFormat: |
1491 if exporterFormat: |
1490 from . import Exporters |
|
1491 |
|
1492 exporter = Exporters.getExporter(exporterFormat, self) |
1492 exporter = Exporters.getExporter(exporterFormat, self) |
1493 if exporter: |
1493 if exporter: |
1494 exporter.exportSource() |
1494 exporter.exportSource() |
1495 else: |
1495 else: |
1496 EricMessageBox.critical( |
1496 EricMessageBox.critical( |
1525 """ |
1525 """ |
1526 Private method to select a specific pygments lexer. |
1526 Private method to select a specific pygments lexer. |
1527 |
1527 |
1528 @return name of the selected pygments lexer (string) |
1528 @return name of the selected pygments lexer (string) |
1529 """ |
1529 """ |
1530 from pygments.lexers import get_all_lexers |
1530 from pygments.lexers import get_all_lexers # __IGNORE_WARNING_I102__ |
1531 |
1531 |
1532 lexerList = sorted(lex[0] for lex in get_all_lexers()) |
1532 lexerList = sorted(lex[0] for lex in get_all_lexers()) |
1533 try: |
1533 try: |
1534 lexerSel = lexerList.index( |
1534 lexerSel = lexerList.index( |
1535 self.getLanguage(normalized=False, forPygments=True) |
1535 self.getLanguage(normalized=False, forPygments=True) |
1886 if language.startswith("Pygments|"): |
1886 if language.startswith("Pygments|"): |
1887 pyname = language |
1887 pyname = language |
1888 self.filetype = language.split("|")[-1] |
1888 self.filetype = language.split("|")[-1] |
1889 language = "" |
1889 language = "" |
1890 |
1890 |
1891 from . import Lexers |
|
1892 |
|
1893 self.lexer_ = Lexers.getLexer(language, self, pyname=pyname) |
1891 self.lexer_ = Lexers.getLexer(language, self, pyname=pyname) |
1894 if self.lexer_ is None: |
1892 if self.lexer_ is None: |
1895 self.setLexer() |
1893 self.setLexer() |
1896 self.apiLanguage = "" |
1894 self.apiLanguage = "" |
1897 return |
1895 return |
2026 pyVer = self.__getPyVersion() |
2024 pyVer = self.__getPyVersion() |
2027 if pyVer: |
2025 if pyVer: |
2028 apiLanguage = "Python{0}".format(pyVer) |
2026 apiLanguage = "Python{0}".format(pyVer) |
2029 elif self.isRubyFile(): |
2027 elif self.isRubyFile(): |
2030 apiLanguage = "Ruby" |
2028 apiLanguage = "Ruby" |
2031 |
|
2032 from . import TypingCompleters |
|
2033 |
2029 |
2034 self.completer = TypingCompleters.getCompleter(apiLanguage, self) |
2030 self.completer = TypingCompleters.getCompleter(apiLanguage, self) |
2035 |
2031 |
2036 def getCompleter(self): |
2032 def getCompleter(self): |
2037 """ |
2033 """ |
2617 """ |
2613 """ |
2618 Public slot to handle the 'Edit breakpoint' context menu action. |
2614 Public slot to handle the 'Edit breakpoint' context menu action. |
2619 |
2615 |
2620 @param line linenumber of the breakpoint to edit |
2616 @param line linenumber of the breakpoint to edit |
2621 """ |
2617 """ |
|
2618 from eric7.Debugger.EditBreakpointDialog import EditBreakpointDialog |
|
2619 |
2622 if line is not None: |
2620 if line is not None: |
2623 self.line = line - 1 |
2621 self.line = line - 1 |
2624 if self.line < 0: |
2622 if self.line < 0: |
2625 self.line, index = self.getCursorPosition() |
2623 self.line, index = self.getCursorPosition() |
2626 |
2624 |
2636 condHistory = ( |
2634 condHistory = ( |
2637 Preferences.toList(rs)[: Preferences.getDebugger("RecentNumber")] |
2635 Preferences.toList(rs)[: Preferences.getDebugger("RecentNumber")] |
2638 if rs is not None |
2636 if rs is not None |
2639 else [] |
2637 else [] |
2640 ) |
2638 ) |
2641 |
|
2642 from eric7.Debugger.EditBreakpointDialog import EditBreakpointDialog |
|
2643 |
2639 |
2644 dlg = EditBreakpointDialog( |
2640 dlg = EditBreakpointDialog( |
2645 (self.fileName, ln), |
2641 (self.fileName, ln), |
2646 (cond, temp, enabled, ignorecount), |
2642 (cond, temp, enabled, ignorecount), |
2647 condHistory, |
2643 condHistory, |
2881 |
2877 |
2882 def printPreviewFile(self): |
2878 def printPreviewFile(self): |
2883 """ |
2879 """ |
2884 Public slot to show a print preview of the text. |
2880 Public slot to show a print preview of the text. |
2885 """ |
2881 """ |
2886 from PyQt6.QtPrintSupport import QPrintPreviewDialog |
|
2887 |
|
2888 from .Printer import Printer |
2882 from .Printer import Printer |
2889 |
2883 |
2890 printer = Printer(mode=QPrinter.PrinterMode.HighResolution) |
2884 printer = Printer(mode=QPrinter.PrinterMode.HighResolution) |
2891 fn = self.getFileName() |
2885 fn = self.getFileName() |
2892 if fn is not None: |
2886 if fn is not None: |
3436 |
3430 |
3437 if not path and self.fileName: |
3431 if not path and self.fileName: |
3438 path = os.path.dirname(self.fileName) |
3432 path = os.path.dirname(self.fileName) |
3439 if not path: |
3433 if not path: |
3440 path = Preferences.getMultiProject("Workspace") or Utilities.getHomeDir() |
3434 path = Preferences.getMultiProject("Workspace") or Utilities.getHomeDir() |
3441 |
|
3442 from . import Lexers |
|
3443 |
3435 |
3444 if self.fileName: |
3436 if self.fileName: |
3445 filterPattern = "(*{0})".format(os.path.splitext(self.fileName)[1]) |
3437 filterPattern = "(*{0})".format(os.path.splitext(self.fileName)[1]) |
3446 for fileFilter in Lexers.getSaveFileFiltersList(True): |
3438 for fileFilter in Lexers.getSaveFileFiltersList(True): |
3447 if filterPattern in fileFilter: |
3439 if filterPattern in fileFilter: |
6121 |
6113 |
6122 def __showCodeMetrics(self): |
6114 def __showCodeMetrics(self): |
6123 """ |
6115 """ |
6124 Private method to handle the code metrics context menu action. |
6116 Private method to handle the code metrics context menu action. |
6125 """ |
6117 """ |
|
6118 from eric7.DataViews.CodeMetricsDialog import CodeMetricsDialog |
|
6119 |
6126 if not self.checkDirty(): |
6120 if not self.checkDirty(): |
6127 return |
6121 return |
6128 |
|
6129 from eric7.DataViews.CodeMetricsDialog import CodeMetricsDialog |
|
6130 |
6122 |
6131 self.codemetrics = CodeMetricsDialog() |
6123 self.codemetrics = CodeMetricsDialog() |
6132 self.codemetrics.show() |
6124 self.codemetrics.show() |
6133 self.codemetrics.start(self.fileName) |
6125 self.codemetrics.start(self.fileName) |
6134 |
6126 |
6180 |
6172 |
6181 def __showCodeCoverage(self): |
6173 def __showCodeCoverage(self): |
6182 """ |
6174 """ |
6183 Private method to handle the code coverage context menu action. |
6175 Private method to handle the code coverage context menu action. |
6184 """ |
6176 """ |
|
6177 from eric7.DataViews.PyCoverageDialog import PyCoverageDialog |
|
6178 |
6185 fn = self.__getCodeCoverageFile() |
6179 fn = self.__getCodeCoverageFile() |
6186 self.__coverageFile = fn |
6180 self.__coverageFile = fn |
6187 if fn: |
6181 if fn: |
6188 from eric7.DataViews.PyCoverageDialog import PyCoverageDialog |
|
6189 |
|
6190 self.codecoverage = PyCoverageDialog() |
6182 self.codecoverage = PyCoverageDialog() |
6191 self.codecoverage.show() |
6183 self.codecoverage.show() |
6192 self.codecoverage.start(fn, self.fileName) |
6184 self.codecoverage.start(fn, self.fileName) |
6193 |
6185 |
6194 def refreshCoverageAnnotations(self): |
6186 def refreshCoverageAnnotations(self): |
6208 @type bool (optional) |
6200 @type bool (optional) |
6209 @param coverageFile path of the file containing the code coverage data |
6201 @param coverageFile path of the file containing the code coverage data |
6210 (defaults to None) |
6202 (defaults to None) |
6211 @type str (optional) |
6203 @type str (optional) |
6212 """ |
6204 """ |
|
6205 from eric7.DebugClients.Python.coverage import ( # __IGNORE_WARNING_I102__ |
|
6206 Coverage, |
|
6207 ) |
|
6208 |
6213 self.__codeCoverageHideAnnotations() |
6209 self.__codeCoverageHideAnnotations() |
6214 |
6210 |
6215 fn = coverageFile if bool(coverageFile) else self.__getCodeCoverageFile() |
6211 fn = coverageFile if bool(coverageFile) else self.__getCodeCoverageFile() |
6216 self.__coverageFile = fn |
6212 self.__coverageFile = fn |
6217 |
6213 |
6218 if fn: |
6214 if fn: |
6219 from coverage import Coverage |
|
6220 |
|
6221 cover = Coverage(data_file=fn) |
6215 cover = Coverage(data_file=fn) |
6222 cover.load() |
6216 cover.load() |
6223 missing = cover.analysis2(self.fileName)[3] |
6217 missing = cover.analysis2(self.fileName)[3] |
6224 if missing: |
6218 if missing: |
6225 for line in missing: |
6219 for line in missing: |
6315 |
6309 |
6316 def __showProfileData(self): |
6310 def __showProfileData(self): |
6317 """ |
6311 """ |
6318 Private method to handle the show profile data context menu action. |
6312 Private method to handle the show profile data context menu action. |
6319 """ |
6313 """ |
|
6314 from eric7.DataViews.PyProfileDialog import PyProfileDialog |
|
6315 |
6320 files = set() |
6316 files = set() |
6321 |
6317 |
6322 # first check if the file belongs to a project and there is |
6318 # first check if the file belongs to a project and there is |
6323 # a project profile file |
6319 # a project profile file |
6324 if self.project.isOpen() and self.project.isProjectSource(self.fileName): |
6320 if self.project.isOpen() and self.project.isProjectSource(self.fileName): |
8056 |
8050 |
8057 def checkSpelling(self): |
8051 def checkSpelling(self): |
8058 """ |
8052 """ |
8059 Public slot to perform an interactive spell check of the document. |
8053 Public slot to perform an interactive spell check of the document. |
8060 """ |
8054 """ |
|
8055 from .SpellCheckingDialog import SpellCheckingDialog |
|
8056 |
8061 if self.spell: |
8057 if self.spell: |
8062 cline, cindex = self.getCursorPosition() |
8058 cline, cindex = self.getCursorPosition() |
8063 from .SpellCheckingDialog import SpellCheckingDialog |
|
8064 |
|
8065 dlg = SpellCheckingDialog(self.spell, 0, self.length(), self) |
8059 dlg = SpellCheckingDialog(self.spell, 0, self.length(), self) |
8066 dlg.exec() |
8060 dlg.exec() |
8067 self.setCursorPosition(cline, cindex) |
8061 self.setCursorPosition(cline, cindex) |
8068 if Preferences.getEditor("AutoSpellCheckingEnabled"): |
8062 if Preferences.getEditor("AutoSpellCheckingEnabled"): |
8069 self.spell.checkDocumentIncrementally() |
8063 self.spell.checkDocumentIncrementally() |
8497 |
8491 |
8498 def sortLines(self): |
8492 def sortLines(self): |
8499 """ |
8493 """ |
8500 Public slot to sort the lines spanned by a rectangular selection. |
8494 Public slot to sort the lines spanned by a rectangular selection. |
8501 """ |
8495 """ |
|
8496 from .SortOptionsDialog import SortOptionsDialog |
|
8497 |
8502 if not self.selectionIsRectangle(): |
8498 if not self.selectionIsRectangle(): |
8503 return |
8499 return |
8504 |
|
8505 from .SortOptionsDialog import SortOptionsDialog |
|
8506 |
8500 |
8507 dlg = SortOptionsDialog() |
8501 dlg = SortOptionsDialog() |
8508 if dlg.exec() == QDialog.DialogCode.Accepted: |
8502 if dlg.exec() == QDialog.DialogCode.Accepted: |
8509 ascending, alnum, caseSensitive = dlg.getData() |
8503 ascending, alnum, caseSensitive = dlg.getData() |
8510 ( |
8504 ( |
8918 Public method to get a reference to the docstring generator. |
8912 Public method to get a reference to the docstring generator. |
8919 |
8913 |
8920 @return reference to the docstring generator |
8914 @return reference to the docstring generator |
8921 @rtype BaseDocstringGenerator |
8915 @rtype BaseDocstringGenerator |
8922 """ |
8916 """ |
|
8917 from . import DocstringGenerator |
|
8918 |
8923 if self.__docstringGenerator is None: |
8919 if self.__docstringGenerator is None: |
8924 from . import DocstringGenerator |
|
8925 |
|
8926 self.__docstringGenerator = DocstringGenerator.getDocstringGenerator(self) |
8920 self.__docstringGenerator = DocstringGenerator.getDocstringGenerator(self) |
8927 |
8921 |
8928 return self.__docstringGenerator |
8922 return self.__docstringGenerator |
8929 |
8923 |
8930 def insertDocstring(self): |
8924 def insertDocstring(self): |
8981 if self.text(cursorPosition[0])[: cursorPosition[1]] != lastLineText: |
8975 if self.text(cursorPosition[0])[: cursorPosition[1]] != lastLineText: |
8982 return |
8976 return |
8983 |
8977 |
8984 generator = self.getDocstringGenerator() |
8978 generator = self.getDocstringGenerator() |
8985 if generator.hasFunctionDefinition(cursorPosition): |
8979 if generator.hasFunctionDefinition(cursorPosition): |
8986 from .DocstringGenerator.BaseDocstringGenerator import ( |
8980 from .DocstringGenerator.BaseDocstringGenerator import ( # __IGNORE_WARNING__ |
8987 DocstringMenuForEnterOnly, |
8981 DocstringMenuForEnterOnly, |
8988 ) |
8982 ) |
8989 |
8983 |
8990 docstringMenu = DocstringMenuForEnterOnly(self) |
8984 docstringMenu = DocstringMenuForEnterOnly(self) |
8991 act = docstringMenu.addAction( |
8985 act = docstringMenu.addAction( |