9 |
9 |
10 from __future__ import unicode_literals |
10 from __future__ import unicode_literals |
11 |
11 |
12 import os |
12 import os |
13 |
13 |
14 from PyQt4.QtCore import QObject |
14 from PyQt4.QtCore import QObject, pyqtSignal |
|
15 from PyQt4.QtGui import QApplication |
15 |
16 |
16 from E5Gui.E5Application import e5App |
17 from E5Gui.E5Application import e5App |
17 |
|
18 from E5Gui.E5Action import E5Action |
18 from E5Gui.E5Action import E5Action |
19 |
19 |
|
20 from Utilities import determinePythonVersion |
20 import Preferences |
21 import Preferences |
21 |
22 |
22 # Start-Of-Header |
23 # Start-Of-Header |
23 name = "Code Style Checker Plugin" |
24 name = "Code Style Checker Plugin" |
24 author = "Detlev Offenbach <detlev@die-offenbachs.de>" |
25 author = "Detlev Offenbach <detlev@die-offenbachs.de>" |
42 |
43 |
43 |
44 |
44 class CodeStyleCheckerPlugin(QObject): |
45 class CodeStyleCheckerPlugin(QObject): |
45 """ |
46 """ |
46 Class implementing the code style checker plug-in. |
47 Class implementing the code style checker plug-in. |
|
48 |
|
49 @signal styleChecked(str, dict, int, list) emited when the style check was |
|
50 done. |
47 """ |
51 """ |
|
52 styleChecked = pyqtSignal(str, dict, int, list) |
|
53 |
48 def __init__(self, ui): |
54 def __init__(self, ui): |
49 """ |
55 """ |
50 Constructor |
56 Constructor |
51 |
57 |
52 @param ui reference to the user interface object (UI.UserInterface) |
58 @param ui reference to the user interface object (UI.UserInterface) |
53 """ |
59 """ |
54 super(CodeStyleCheckerPlugin, self).__init__(ui) |
60 super(CodeStyleCheckerPlugin, self).__init__(ui) |
55 self.__ui = ui |
61 self.__ui = ui |
56 self.__initialize() |
62 self.__initialize() |
57 |
63 |
|
64 self.backgroundService = e5App().getObject("BackgroundService") |
|
65 |
|
66 path = os.path.join( |
|
67 os.path.dirname(__file__), 'CheckerPlugins', 'CodeStyleChecker') |
|
68 for lang in ['Python2', 'Python3']: |
|
69 self.backgroundService.serviceConnect( |
|
70 'style', lang, path, 'CodeStyleChecker', |
|
71 self.__translateStyleCheck, |
|
72 lambda fx, fn, ver, msg: self.styleChecked.emit( |
|
73 fn, {}, 0, [[1, 1, '---- ' + msg, False, False]])) |
|
74 |
58 def __initialize(self): |
75 def __initialize(self): |
59 """ |
76 """ |
60 Private slot to (re)initialize the plugin. |
77 Private slot to (re)initialize the plugin. |
61 """ |
78 """ |
62 self.__projectAct = None |
79 self.__projectAct = None |
67 self.__projectBrowserCodeStyleCheckerDialog = None |
84 self.__projectBrowserCodeStyleCheckerDialog = None |
68 |
85 |
69 self.__editors = [] |
86 self.__editors = [] |
70 self.__editorAct = None |
87 self.__editorAct = None |
71 self.__editorCodeStyleCheckerDialog = None |
88 self.__editorCodeStyleCheckerDialog = None |
|
89 |
|
90 def styleCheck(self, lang, filename, source, args): |
|
91 """ |
|
92 Method to prepare a style check on one Python source file in another |
|
93 task. |
|
94 |
|
95 @param lang language of the file or None to determine by internal |
|
96 algorithm (str or None) |
|
97 @param filename source filename (string) |
|
98 @param source string containing the code to check (string) |
|
99 @param args arguments used by the codeStyleCheck function (list of |
|
100 excludeMessages (str), includeMessages (str), repeatMessages |
|
101 (bool), fixCodes (str), noFixCodes (str), fixIssues (bool), |
|
102 maxLineLength (int), hangClosing (bool), docType (str), errors |
|
103 (list of str), eol (str), encoding (str)) |
|
104 """ |
|
105 if lang is None: |
|
106 lang = 'Python{0}'.format(determinePythonVersion(filename, source)) |
|
107 if lang not in ['Python2', 'Python3']: |
|
108 return |
|
109 |
|
110 data = [source, args] |
|
111 self.backgroundService.enqueueRequest('style', lang, filename, data) |
|
112 |
|
113 def __translateStyleCheck(self, fn, codeStyleCheckerStats, results): |
|
114 """ |
|
115 Privat slot called after perfoming a style check on one file. |
|
116 |
|
117 @param fn filename of the just checked file (str) |
|
118 @param codeStyleCheckerStats stats of style and name check (dict) |
|
119 @param results tuple for each found violation of style (tuple of |
|
120 lineno (int), position (int), text (str), fixed (bool), |
|
121 autofixing (bool), fixedMsg (str)) |
|
122 """ |
|
123 from CheckerPlugins.CodeStyleChecker.translations import \ |
|
124 getTranslatedMessage |
|
125 |
|
126 fixes = 0 |
|
127 for result in results: |
|
128 msg = getTranslatedMessage(result[2]) |
|
129 |
|
130 fixedMsg = result.pop() |
|
131 if fixedMsg: |
|
132 fixes += 1 |
|
133 trFixedMsg = getTranslatedMessage(fixedMsg) |
|
134 |
|
135 msg += "\n" + QApplication.translate( |
|
136 'CodeStyleCheckerDialog', "Fix: {0}").format(trFixedMsg) |
|
137 |
|
138 result[2] = msg |
|
139 self.styleChecked.emit(fn, codeStyleCheckerStats, fixes, results) |
72 |
140 |
73 def activate(self): |
141 def activate(self): |
74 """ |
142 """ |
75 Public method to activate this plugin. |
143 Public method to activate this plugin. |
76 |
144 |
201 tuple(Preferences.getPython("Python3Extensions")) + |
269 tuple(Preferences.getPython("Python3Extensions")) + |
202 tuple(Preferences.getPython("PythonExtensions")))] |
270 tuple(Preferences.getPython("PythonExtensions")))] |
203 |
271 |
204 from CheckerPlugins.CodeStyleChecker.CodeStyleCheckerDialog import \ |
272 from CheckerPlugins.CodeStyleChecker.CodeStyleCheckerDialog import \ |
205 CodeStyleCheckerDialog |
273 CodeStyleCheckerDialog |
206 self.__projectCodeStyleCheckerDialog = CodeStyleCheckerDialog() |
274 self.__projectCodeStyleCheckerDialog = CodeStyleCheckerDialog(self) |
207 self.__projectCodeStyleCheckerDialog.show() |
275 self.__projectCodeStyleCheckerDialog.show() |
208 self.__projectCodeStyleCheckerDialog.prepare(files, project) |
276 self.__projectCodeStyleCheckerDialog.prepare(files, project) |
209 |
277 |
210 def __projectBrowserCodeStyleCheck(self): |
278 def __projectBrowserCodeStyleCheck(self): |
211 """ |
279 """ |
266 @param editor reference to the editor |
335 @param editor reference to the editor |
267 """ |
336 """ |
268 if menuName == "Checks": |
337 if menuName == "Checks": |
269 if not self.__editorAct in menu.actions(): |
338 if not self.__editorAct in menu.actions(): |
270 menu.addAction(self.__editorAct) |
339 menu.addAction(self.__editorAct) |
271 self.__editorAct.setEnabled( |
340 self.__editorAct.setEnabled(editor.getPyVersion()) |
272 editor.isPy3File() or editor.isPy2File()) |
|
273 |
341 |
274 def __editorCodeStyleCheck(self): |
342 def __editorCodeStyleCheck(self): |
275 """ |
343 """ |
276 Private slot to handle the code style check context menu action |
344 Private slot to handle the code style check context menu action |
277 of the editors. |
345 of the editors. |
279 editor = e5App().getObject("ViewManager").activeWindow() |
347 editor = e5App().getObject("ViewManager").activeWindow() |
280 if editor is not None: |
348 if editor is not None: |
281 if editor.checkDirty() and editor.getFileName() is not None: |
349 if editor.checkDirty() and editor.getFileName() is not None: |
282 from CheckerPlugins.CodeStyleChecker.CodeStyleCheckerDialog \ |
350 from CheckerPlugins.CodeStyleChecker.CodeStyleCheckerDialog \ |
283 import CodeStyleCheckerDialog |
351 import CodeStyleCheckerDialog |
284 self.__editorCodeStyleCheckerDialog = CodeStyleCheckerDialog() |
352 self.__editorCodeStyleCheckerDialog = CodeStyleCheckerDialog( |
|
353 self) |
285 self.__editorCodeStyleCheckerDialog.show() |
354 self.__editorCodeStyleCheckerDialog.show() |
286 self.__editorCodeStyleCheckerDialog.start( |
355 self.__editorCodeStyleCheckerDialog.start( |
287 editor.getFileName(), |
356 editor.getFileName(), |
288 save=True, |
357 save=True, |
289 repeat=True) |
358 repeat=True) |