Plugins/PluginCodeStyleChecker.py

branch
Py2 comp.
changeset 3057
10516539f238
parent 3056
9986ec0e559a
parent 3004
c4bf32c791d0
child 3145
a9de05d4a22f
equal deleted inserted replaced
3056:9986ec0e559a 3057:10516539f238
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2011 - 2013 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing the code style checker plug-in.
8 """
9
10 from __future__ import unicode_literals # __IGNORE_WARNING__
11
12 import os
13
14 from PyQt4.QtCore import QObject
15
16 from E5Gui.E5Application import e5App
17
18 from E5Gui.E5Action import E5Action
19
20 import Preferences
21
22 # Start-Of-Header
23 name = "Code Style Checker Plugin"
24 author = "Detlev Offenbach <detlev@die-offenbachs.de>"
25 autoactivate = True
26 deactivateable = True
27 version = "5.4.0"
28 className = "CodeStyleCheckerPlugin"
29 packageName = "__core__"
30 shortDescription = "Show the Python Code Style Checker dialog."
31 longDescription = """This plugin implements the Python Code Style""" \
32 """ Checker dialog. A PEP-8 checker is used to check Python source""" \
33 """ files for compliance to the code style conventions given in PEP-8.""" \
34 """ A PEP-257 checker is used to check Python source files for""" \
35 """ compliance to docstring conventions given in PEP-257 and an""" \
36 """ eric5 variant is used to check against eric conventions."""
37 pyqtApi = 2
38 # End-Of-Header
39
40
41 error = ""
42
43
44 class CodeStyleCheckerPlugin(QObject):
45 """
46 Class implementing the code style checker plug-in.
47 """
48 def __init__(self, ui):
49 """
50 Constructor
51
52 @param ui reference to the user interface object (UI.UserInterface)
53 """
54 super(CodeStyleCheckerPlugin, self).__init__(ui)
55 self.__ui = ui
56 self.__initialize()
57
58 def __initialize(self):
59 """
60 Private slot to (re)initialize the plugin.
61 """
62 self.__projectAct = None
63 self.__projectCodeStyleCheckerDialog = None
64
65 self.__projectBrowserAct = None
66 self.__projectBrowserMenu = None
67 self.__projectBrowserCodeStyleCheckerDialog = None
68
69 self.__editors = []
70 self.__editorAct = None
71 self.__editorCodeStyleCheckerDialog = None
72
73 def activate(self):
74 """
75 Public method to activate this plugin.
76
77 @return tuple of None and activation status (boolean)
78 """
79 menu = e5App().getObject("Project").getMenu("Checks")
80 if menu:
81 self.__projectAct = E5Action(
82 self.trUtf8('Check Code Style'),
83 self.trUtf8('&Code Style...'), 0, 0,
84 self, 'project_check_pep8')
85 self.__projectAct.setStatusTip(
86 self.trUtf8('Check code style.'))
87 self.__projectAct.setWhatsThis(self.trUtf8(
88 """<b>Check Code Style...</b>"""
89 """<p>This checks Python files for compliance to the"""
90 """ code style conventions given in various PEPs.</p>"""
91 ))
92 self.__projectAct.triggered[()].connect(
93 self.__projectCodeStyleCheck)
94 e5App().getObject("Project").addE5Actions([self.__projectAct])
95 menu.addAction(self.__projectAct)
96
97 self.__editorAct = E5Action(
98 self.trUtf8('Check Code Style'),
99 self.trUtf8('&Code Style...'), 0, 0,
100 self, "")
101 self.__editorAct.setWhatsThis(self.trUtf8(
102 """<b>Check Code Style...</b>"""
103 """<p>This checks Python files for compliance to the"""
104 """ code style conventions given in various PEPs.</p>"""
105 ))
106 self.__editorAct.triggered[()].connect(self.__editorCodeStyleCheck)
107
108 e5App().getObject("Project").showMenu.connect(self.__projectShowMenu)
109 e5App().getObject("ProjectBrowser").getProjectBrowser("sources")\
110 .showMenu.connect(self.__projectBrowserShowMenu)
111 e5App().getObject("ViewManager").editorOpenedEd.connect(
112 self.__editorOpened)
113 e5App().getObject("ViewManager").editorClosedEd.connect(
114 self.__editorClosed)
115
116 for editor in e5App().getObject("ViewManager").getOpenEditors():
117 self.__editorOpened(editor)
118
119 return None, True
120
121 def deactivate(self):
122 """
123 Public method to deactivate this plugin.
124 """
125 e5App().getObject("Project").showMenu.disconnect(
126 self.__projectShowMenu)
127 e5App().getObject("ProjectBrowser").getProjectBrowser("sources")\
128 .showMenu.disconnect(self.__projectBrowserShowMenu)
129 e5App().getObject("ViewManager").editorOpenedEd.disconnect(
130 self.__editorOpened)
131 e5App().getObject("ViewManager").editorClosedEd.disconnect(
132 self.__editorClosed)
133
134 menu = e5App().getObject("Project").getMenu("Checks")
135 if menu:
136 menu.removeAction(self.__projectAct)
137
138 if self.__projectBrowserMenu:
139 if self.__projectBrowserAct:
140 self.__projectBrowserMenu.removeAction(
141 self.__projectBrowserAct)
142
143 for editor in self.__editors:
144 editor.showMenu.disconnect(self.__editorShowMenu)
145 menu = editor.getMenu("Checks")
146 if menu is not None:
147 menu.removeAction(self.__editorAct)
148
149 self.__initialize()
150
151 def __projectShowMenu(self, menuName, menu):
152 """
153 Private slot called, when the the project menu or a submenu is
154 about to be shown.
155
156 @param menuName name of the menu to be shown (string)
157 @param menu reference to the menu (QMenu)
158 """
159 if menuName == "Checks" and self.__projectAct is not None:
160 self.__projectAct.setEnabled(
161 e5App().getObject("Project").getProjectLanguage() in
162 ["Python3", "Python2", "Python"])
163
164 def __projectBrowserShowMenu(self, menuName, menu):
165 """
166 Private slot called, when the the project browser menu or a submenu is
167 about to be shown.
168
169 @param menuName name of the menu to be shown (string)
170 @param menu reference to the menu (QMenu)
171 """
172 if menuName == "Checks" and \
173 e5App().getObject("Project").getProjectLanguage() in \
174 ["Python3", "Python2", "Python"]:
175 self.__projectBrowserMenu = menu
176 if self.__projectBrowserAct is None:
177 self.__projectBrowserAct = E5Action(
178 self.trUtf8('Check Code Style'),
179 self.trUtf8('&Code Style...'), 0, 0,
180 self, "")
181 self.__projectBrowserAct.setWhatsThis(self.trUtf8(
182 """<b>Check Code Style...</b>"""
183 """<p>This checks Python files for compliance to the"""
184 """ code style conventions given in various PEPs.</p>"""
185 ))
186 self.__projectBrowserAct.triggered[()].connect(
187 self.__projectBrowserCodeStyleCheck)
188 if not self.__projectBrowserAct in menu.actions():
189 menu.addAction(self.__projectBrowserAct)
190
191 def __projectCodeStyleCheck(self):
192 """
193 Public slot used to check the project files for code style.
194 """
195 project = e5App().getObject("Project")
196 project.saveAllScripts()
197 ppath = project.getProjectPath()
198 files = [os.path.join(ppath, file)
199 for file in project.pdata["SOURCES"]
200 if file.endswith(
201 tuple(Preferences.getPython("Python3Extensions")) +
202 tuple(Preferences.getPython("PythonExtensions")))]
203
204 from CheckerPlugins.CodeStyleChecker.CodeStyleCheckerDialog import \
205 CodeStyleCheckerDialog
206 self.__projectCodeStyleCheckerDialog = CodeStyleCheckerDialog()
207 self.__projectCodeStyleCheckerDialog.show()
208 self.__projectCodeStyleCheckerDialog.prepare(files, project)
209
210 def __projectBrowserCodeStyleCheck(self):
211 """
212 Private method to handle the code style check context menu action of
213 the project sources browser.
214 """
215 browser = e5App().getObject("ProjectBrowser")\
216 .getProjectBrowser("sources")
217 itm = browser.model().item(browser.currentIndex())
218 try:
219 fn = itm.fileName()
220 isDir = False
221 except AttributeError:
222 fn = itm.dirName()
223 isDir = True
224
225 from CheckerPlugins.CodeStyleChecker.CodeStyleCheckerDialog import \
226 CodeStyleCheckerDialog
227 self.__projectBrowserCodeStyleCheckerDialog = CodeStyleCheckerDialog()
228 self.__projectBrowserCodeStyleCheckerDialog.show()
229 if isDir:
230 self.__projectBrowserCodeStyleCheckerDialog.start(
231 fn, save=True)
232 else:
233 self.__projectBrowserCodeStyleCheckerDialog.start(
234 fn, save=True, repeat=True)
235
236 def __editorOpened(self, editor):
237 """
238 Private slot called, when a new editor was opened.
239
240 @param editor reference to the new editor (QScintilla.Editor)
241 """
242 menu = editor.getMenu("Checks")
243 if menu is not None:
244 menu.addAction(self.__editorAct)
245 editor.showMenu.connect(self.__editorShowMenu)
246 self.__editors.append(editor)
247
248 def __editorClosed(self, editor):
249 """
250 Private slot called, when an editor was closed.
251
252 @param editor reference to the editor (QScintilla.Editor)
253 """
254 try:
255 self.__editors.remove(editor)
256 except ValueError:
257 pass
258
259 def __editorShowMenu(self, menuName, menu, editor):
260 """
261 Private slot called, when the the editor context menu or a submenu is
262 about to be shown.
263
264 @param menuName name of the menu to be shown (string)
265 @param menu reference to the menu (QMenu)
266 @param editor reference to the editor
267 """
268 if menuName == "Checks":
269 if not self.__editorAct in menu.actions():
270 menu.addAction(self.__editorAct)
271 self.__editorAct.setEnabled(
272 editor.isPy3File() or editor.isPy2File())
273
274 def __editorCodeStyleCheck(self):
275 """
276 Private slot to handle the code style check context menu action
277 of the editors.
278 """
279 editor = e5App().getObject("ViewManager").activeWindow()
280 if editor is not None:
281 if editor.checkDirty() and editor.getFileName() is not None:
282 from CheckerPlugins.CodeStyleChecker.CodeStyleCheckerDialog \
283 import CodeStyleCheckerDialog
284 self.__editorCodeStyleCheckerDialog = CodeStyleCheckerDialog()
285 self.__editorCodeStyleCheckerDialog.show()
286 self.__editorCodeStyleCheckerDialog.start(
287 editor.getFileName(),
288 save=True,
289 repeat=True)

eric ide

mercurial