Plugins/PluginCodeStyleChecker.py

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

eric ide

mercurial