PluginMetricsRadon.py

branch
eric7
changeset 94
725eaca7bc4b
parent 93
1ae73306422a
child 102
f7b964ea22a1
equal deleted inserted replaced
93:1ae73306422a 94:725eaca7bc4b
47 47
48 48
49 class RadonMetricsPlugin(QObject): 49 class RadonMetricsPlugin(QObject):
50 """ 50 """
51 Class implementing the radon code metrics plug-in. 51 Class implementing the radon code metrics plug-in.
52 52
53 @signal metricsDone(str, dict) emitted when the code metrics were 53 @signal metricsDone(str, dict) emitted when the code metrics were
54 determined for a file 54 determined for a file
55 @signal maintainabilityIndexDone(str, dict) emitted when the 55 @signal maintainabilityIndexDone(str, dict) emitted when the
56 maintainability index was determined for a file 56 maintainability index was determined for a file
57 @signal complexityDone(str, dict) emitted when the 57 @signal complexityDone(str, dict) emitted when the
58 cyclomatic complexity was determined for a file 58 cyclomatic complexity was determined for a file
59 @signal error(str, str, str) emitted in case of an error 59 @signal error(str, str, str) emitted in case of an error
60 @signal batchFinished(str) emitted when a code metrics batch is done 60 @signal batchFinished(str) emitted when a code metrics batch is done
61 """ 61 """
62
62 metricsDone = pyqtSignal(str, dict) 63 metricsDone = pyqtSignal(str, dict)
63 maintainabilityIndexDone = pyqtSignal(str, dict) 64 maintainabilityIndexDone = pyqtSignal(str, dict)
64 complexityDone = pyqtSignal(str, dict) 65 complexityDone = pyqtSignal(str, dict)
65 error = pyqtSignal(str, str, str) 66 error = pyqtSignal(str, str, str)
66 batchFinished = pyqtSignal(str) 67 batchFinished = pyqtSignal(str)
67 68
68 def __init__(self, ui): 69 def __init__(self, ui):
69 """ 70 """
70 Constructor 71 Constructor
71 72
72 @param ui reference to the user interface object 73 @param ui reference to the user interface object
73 @type UserInterface 74 @type UserInterface
74 """ 75 """
75 super().__init__(ui) 76 super().__init__(ui)
76 self.__ui = ui 77 self.__ui = ui
77 self.__initialize() 78 self.__initialize()
78 79
79 self.backgroundService = ericApp().getObject("BackgroundService") 80 self.backgroundService = ericApp().getObject("BackgroundService")
80 81
81 path = os.path.join(os.path.dirname(__file__), packageName) 82 path = os.path.join(os.path.dirname(__file__), packageName)
82 83
83 # raw code metrics calculation 84 # raw code metrics calculation
84 self.backgroundService.serviceConnect( 85 self.backgroundService.serviceConnect(
85 'radon_raw', 'Python3', path, 'CodeMetricsCalculator', 86 "radon_raw",
87 "Python3",
88 path,
89 "CodeMetricsCalculator",
86 lambda fn, res: self.metricsCalculationDone("raw", fn, res), 90 lambda fn, res: self.metricsCalculationDone("raw", fn, res),
87 onErrorCallback=lambda fx, lang, fn, msg: self.serviceErrorPy3( 91 onErrorCallback=lambda fx, lang, fn, msg: self.serviceErrorPy3(
88 "raw", fx, lang, fn, msg), 92 "raw", fx, lang, fn, msg
89 onBatchDone=lambda fx, lang: self.batchJobDone( 93 ),
90 "raw", fx, lang)) 94 onBatchDone=lambda fx, lang: self.batchJobDone("raw", fx, lang),
91 95 )
96
92 # maintainability index calculation 97 # maintainability index calculation
93 self.backgroundService.serviceConnect( 98 self.backgroundService.serviceConnect(
94 'radon_mi', 'Python3', path, 'MaintainabilityIndexCalculator', 99 "radon_mi",
100 "Python3",
101 path,
102 "MaintainabilityIndexCalculator",
95 lambda fn, res: self.metricsCalculationDone("mi", fn, res), 103 lambda fn, res: self.metricsCalculationDone("mi", fn, res),
96 onErrorCallback=lambda fx, lang, fn, msg: self.serviceErrorPy3( 104 onErrorCallback=lambda fx, lang, fn, msg: self.serviceErrorPy3(
97 "mi", fx, lang, fn, msg), 105 "mi", fx, lang, fn, msg
98 onBatchDone=lambda fx, lang: self.batchJobDone( 106 ),
99 "mi", fx, lang)) 107 onBatchDone=lambda fx, lang: self.batchJobDone("mi", fx, lang),
100 108 )
109
101 # cyclomatic complexity 110 # cyclomatic complexity
102 self.backgroundService.serviceConnect( 111 self.backgroundService.serviceConnect(
103 'radon_cc', 'Python3', path, 'CyclomaticComplexityCalculator', 112 "radon_cc",
113 "Python3",
114 path,
115 "CyclomaticComplexityCalculator",
104 lambda fn, res: self.metricsCalculationDone("cc", fn, res), 116 lambda fn, res: self.metricsCalculationDone("cc", fn, res),
105 onErrorCallback=lambda fx, lang, fn, msg: self.serviceErrorPy3( 117 onErrorCallback=lambda fx, lang, fn, msg: self.serviceErrorPy3(
106 "cc", fx, lang, fn, msg), 118 "cc", fx, lang, fn, msg
107 onBatchDone=lambda fx, lang: self.batchJobDone( 119 ),
108 "cc", fx, lang)) 120 onBatchDone=lambda fx, lang: self.batchJobDone("cc", fx, lang),
109 121 )
122
110 self.queuedBatches = { 123 self.queuedBatches = {
111 "raw": [], 124 "raw": [],
112 "mi": [], 125 "mi": [],
113 "cc": [], 126 "cc": [],
114 } 127 }
115 self.batchesFinished = { 128 self.batchesFinished = {
116 "raw": True, 129 "raw": True,
117 "mi": True, 130 "mi": True,
118 "cc": True, 131 "cc": True,
119 } 132 }
120 133
121 self.__translator = None 134 self.__translator = None
122 self.__loadTranslator() 135 self.__loadTranslator()
123 136
124 def __serviceError(self, type_, fn, msg): 137 def __serviceError(self, type_, fn, msg):
125 """ 138 """
126 Private slot handling service errors. 139 Private slot handling service errors.
127 140
128 @param type_ type of the calculated metrics 141 @param type_ type of the calculated metrics
129 @type str, one of ["raw", "mi", "cc"] 142 @type str, one of ["raw", "mi", "cc"]
130 @param fn file name 143 @param fn file name
131 @type str 144 @type str
132 @param msg message text 145 @param msg message text
133 @type str 146 @type str
134 """ 147 """
135 self.error.emit(type_, fn, msg) 148 self.error.emit(type_, fn, msg)
136 149
137 def serviceErrorPy3(self, type_, fx, lang, fn, msg): 150 def serviceErrorPy3(self, type_, fx, lang, fn, msg):
138 """ 151 """
139 Public slot handling service errors for Python 3. 152 Public slot handling service errors for Python 3.
140 153
141 @param type_ type of the calculated metrics 154 @param type_ type of the calculated metrics
142 @type str, one of ["raw", "mi", "cc"] 155 @type str, one of ["raw", "mi", "cc"]
143 @param fx service name 156 @param fx service name
144 @type str 157 @type str
145 @param lang language 158 @param lang language
147 @param fn file name 160 @param fn file name
148 @type str 161 @type str
149 @param msg message text 162 @param msg message text
150 @type str 163 @type str
151 """ 164 """
152 if fx in ['radon_' + type_, 'batch_radon_' + type_]: 165 if fx in ["radon_" + type_, "batch_radon_" + type_]:
153 if fx == 'radon_' + type_: 166 if fx == "radon_" + type_:
154 self.__serviceError(type_, fn, msg) 167 self.__serviceError(type_, fn, msg)
155 else: 168 else:
156 self.__serviceError(type_, self.tr("Python 3 batch job"), msg) 169 self.__serviceError(type_, self.tr("Python 3 batch job"), msg)
157 self.batchJobDone(type_, fx, lang) 170 self.batchJobDone(type_, fx, lang)
158 171
159 def batchJobDone(self, type_, fx, lang): 172 def batchJobDone(self, type_, fx, lang):
160 """ 173 """
161 Public slot handling the completion of a batch job. 174 Public slot handling the completion of a batch job.
162 175
163 @param type_ type of the calculated metrics 176 @param type_ type of the calculated metrics
164 @type str, one of ["raw", "mi", "cc"] 177 @type str, one of ["raw", "mi", "cc"]
165 @param fx service name 178 @param fx service name
166 @type str 179 @type str
167 @param lang language 180 @param lang language
168 @type str 181 @type str
169 """ 182 """
170 if fx in ['radon_' + type_, 'batch_radon_' + type_]: 183 if fx in ["radon_" + type_, "batch_radon_" + type_]:
171 if lang in self.queuedBatches[type_]: 184 if lang in self.queuedBatches[type_]:
172 self.queuedBatches[type_].remove(lang) 185 self.queuedBatches[type_].remove(lang)
173 # prevent sending the signal multiple times 186 # prevent sending the signal multiple times
174 if ( 187 if len(self.queuedBatches[type_]) == 0 and not self.batchesFinished[type_]:
175 len(self.queuedBatches[type_]) == 0 and
176 not self.batchesFinished[type_]
177 ):
178 self.batchFinished.emit(type_) 188 self.batchFinished.emit(type_)
179 self.batchesFinished[type_] = True 189 self.batchesFinished[type_] = True
180 190
181 def metricsCalculationDone(self, type_, filename, result): 191 def metricsCalculationDone(self, type_, filename, result):
182 """ 192 """
183 Public slot to dispatch the result. 193 Public slot to dispatch the result.
184 194
185 @param type_ type of the calculated metrics 195 @param type_ type of the calculated metrics
186 @type str, one of ["raw", "mi", "cc"] 196 @type str, one of ["raw", "mi", "cc"]
187 @param filename name of the file the results belong to 197 @param filename name of the file the results belong to
188 @type str 198 @type str
189 @param result result dictionary 199 @param result result dictionary
197 self.complexityDone.emit(filename, result) 207 self.complexityDone.emit(filename, result)
198 else: 208 else:
199 self.error.emit( 209 self.error.emit(
200 type_, 210 type_,
201 filename, 211 filename,
202 self.tr("Unknown metrics result received ({0}).").format( 212 self.tr("Unknown metrics result received ({0}).").format(type_),
203 type_) 213 )
204 ) 214
205
206 def __initialize(self): 215 def __initialize(self):
207 """ 216 """
208 Private slot to (re)initialize the plugin. 217 Private slot to (re)initialize the plugin.
209 """ 218 """
210 self.__projectRawMetricsDialog = None 219 self.__projectRawMetricsDialog = None
211 self.__projectMIDialog = None 220 self.__projectMIDialog = None
212 self.__projectCCDialog = None 221 self.__projectCCDialog = None
213 self.__projectMetricsActs = [] 222 self.__projectMetricsActs = []
214 self.__projectSeparatorActs = [] 223 self.__projectSeparatorActs = []
215 224
216 self.__projectBrowserRawMetricsDialog = None 225 self.__projectBrowserRawMetricsDialog = None
217 self.__projectBrowserMIDialog = None 226 self.__projectBrowserMIDialog = None
218 self.__projectBrowserCCDialog = None 227 self.__projectBrowserCCDialog = None
219 self.__projectBrowserMenu = None 228 self.__projectBrowserMenu = None
220 self.__projectBrowserMetricsActs = [] 229 self.__projectBrowserMetricsActs = []
221 self.__projectBrowserSeparatorActs = [] 230 self.__projectBrowserSeparatorActs = []
222 231
223 self.__editors = [] 232 self.__editors = []
224 self.__editorRawMetricsDialog = None 233 self.__editorRawMetricsDialog = None
225 self.__editorMIDialog = None 234 self.__editorMIDialog = None
226 self.__editorCCDialog = None 235 self.__editorCCDialog = None
227 self.__editorMetricsActs = [] 236 self.__editorMetricsActs = []
239 @type str 248 @type str
240 @param source string containing the code 249 @param source string containing the code
241 @type str 250 @type str
242 """ 251 """
243 if lang is None: 252 if lang is None:
244 lang = 'Python{0}'.format(determinePythonVersion(filename, source)) 253 lang = "Python{0}".format(determinePythonVersion(filename, source))
245 if lang == 'Python3': 254 if lang == "Python3":
246 self.backgroundService.enqueueRequest( 255 self.backgroundService.enqueueRequest("radon_raw", lang, filename, [source])
247 'radon_raw', lang, filename, [source])
248 256
249 def rawMetricsBatch(self, argumentsList): 257 def rawMetricsBatch(self, argumentsList):
250 """ 258 """
251 Public method to prepare raw code metrics calculation on multiple 259 Public method to prepare raw code metrics calculation on multiple
252 Python source files. 260 Python source files.
253 261
254 @param argumentsList list of arguments tuples with each tuple 262 @param argumentsList list of arguments tuples with each tuple
255 containing filename and source 263 containing filename and source
256 @type (str, str) 264 @type (str, str)
257 """ 265 """
258 data = { 266 data = {
259 "Python3": [], 267 "Python3": [],
260 } 268 }
261 for filename, source in argumentsList: 269 for filename, source in argumentsList:
262 lang = 'Python{0}'.format(determinePythonVersion(filename, source)) 270 lang = "Python{0}".format(determinePythonVersion(filename, source))
263 if lang == 'Python3': 271 if lang == "Python3":
264 data[lang].append((filename, source)) 272 data[lang].append((filename, source))
265 273
266 self.queuedBatches["raw"] = [] 274 self.queuedBatches["raw"] = []
267 if data[lang]: 275 if data[lang]:
268 self.queuedBatches["raw"].append('Python3') 276 self.queuedBatches["raw"].append("Python3")
269 self.backgroundService.enqueueRequest( 277 self.backgroundService.enqueueRequest(
270 'batch_radon_raw', 'Python3', "", data['Python3']) 278 "batch_radon_raw", "Python3", "", data["Python3"]
279 )
271 self.batchesFinished["raw"] = False 280 self.batchesFinished["raw"] = False
272 281
273 def cancelRawMetricsBatch(self): 282 def cancelRawMetricsBatch(self):
274 """ 283 """
275 Public method to cancel all batch jobs. 284 Public method to cancel all batch jobs.
276 """ 285 """
277 self.backgroundService.requestCancel('batch_radon_raw', 'Python3') 286 self.backgroundService.requestCancel("batch_radon_raw", "Python3")
278 287
279 def maintainabilityIndex(self, lang, filename, source): 288 def maintainabilityIndex(self, lang, filename, source):
280 """ 289 """
281 Public method to prepare maintainability index calculation on one 290 Public method to prepare maintainability index calculation on one
282 Python source file. 291 Python source file.
288 @type str 297 @type str
289 @param source string containing the code 298 @param source string containing the code
290 @type str 299 @type str
291 """ 300 """
292 if lang is None: 301 if lang is None:
293 lang = 'Python{0}'.format(determinePythonVersion(filename, source)) 302 lang = "Python{0}".format(determinePythonVersion(filename, source))
294 if lang == 'Python3': 303 if lang == "Python3":
295 self.backgroundService.enqueueRequest( 304 self.backgroundService.enqueueRequest("radon_mi", lang, filename, [source])
296 'radon_mi', lang, filename, [source])
297 305
298 def maintainabilityIndexBatch(self, argumentsList): 306 def maintainabilityIndexBatch(self, argumentsList):
299 """ 307 """
300 Public method to prepare maintainability index calculation on multiple 308 Public method to prepare maintainability index calculation on multiple
301 Python source files. 309 Python source files.
302 310
303 @param argumentsList list of arguments tuples with each tuple 311 @param argumentsList list of arguments tuples with each tuple
304 containing filename and source 312 containing filename and source
305 @type (str, str) 313 @type (str, str)
306 """ 314 """
307 data = { 315 data = {
308 "Python3": [], 316 "Python3": [],
309 } 317 }
310 for filename, source in argumentsList: 318 for filename, source in argumentsList:
311 lang = 'Python{0}'.format(determinePythonVersion(filename, source)) 319 lang = "Python{0}".format(determinePythonVersion(filename, source))
312 if lang == 'Python3': 320 if lang == "Python3":
313 data[lang].append((filename, source)) 321 data[lang].append((filename, source))
314 322
315 self.queuedBatches["mi"] = [] 323 self.queuedBatches["mi"] = []
316 if data['Python3']: 324 if data["Python3"]:
317 self.queuedBatches["mi"].append('Python3') 325 self.queuedBatches["mi"].append("Python3")
318 self.backgroundService.enqueueRequest( 326 self.backgroundService.enqueueRequest(
319 'batch_radon_mi', 'Python3', "", data['Python3']) 327 "batch_radon_mi", "Python3", "", data["Python3"]
328 )
320 self.batchesFinished["mi"] = False 329 self.batchesFinished["mi"] = False
321 330
322 def cancelMaintainabilityIndexBatch(self): 331 def cancelMaintainabilityIndexBatch(self):
323 """ 332 """
324 Public method to cancel all batch jobs. 333 Public method to cancel all batch jobs.
325 """ 334 """
326 self.backgroundService.requestCancel('batch_radon_mi', 'Python3') 335 self.backgroundService.requestCancel("batch_radon_mi", "Python3")
327 336
328 def cyclomaticComplexity(self, lang, filename, source): 337 def cyclomaticComplexity(self, lang, filename, source):
329 """ 338 """
330 Public method to prepare cyclomatic complexity calculation on one 339 Public method to prepare cyclomatic complexity calculation on one
331 Python source file. 340 Python source file.
332 341
337 @type str 346 @type str
338 @param source string containing the code 347 @param source string containing the code
339 @type str 348 @type str
340 """ 349 """
341 if lang is None: 350 if lang is None:
342 lang = 'Python{0}'.format(determinePythonVersion(filename, source)) 351 lang = "Python{0}".format(determinePythonVersion(filename, source))
343 if lang == 'Python3': 352 if lang == "Python3":
344 self.backgroundService.enqueueRequest( 353 self.backgroundService.enqueueRequest("radon_cc", lang, filename, [source])
345 'radon_cc', lang, filename, [source])
346 354
347 def cyclomaticComplexityBatch(self, argumentsList): 355 def cyclomaticComplexityBatch(self, argumentsList):
348 """ 356 """
349 Public method to prepare cyclomatic complexity calculation on multiple 357 Public method to prepare cyclomatic complexity calculation on multiple
350 Python source files. 358 Python source files.
351 359
352 @param argumentsList list of arguments tuples with each tuple 360 @param argumentsList list of arguments tuples with each tuple
353 containing filename and source 361 containing filename and source
354 @type (str, str) 362 @type (str, str)
355 """ 363 """
356 data = { 364 data = {
357 "Python3": [], 365 "Python3": [],
358 } 366 }
359 for filename, source in argumentsList: 367 for filename, source in argumentsList:
360 lang = 'Python{0}'.format(determinePythonVersion(filename, source)) 368 lang = "Python{0}".format(determinePythonVersion(filename, source))
361 if lang == 'Python3': 369 if lang == "Python3":
362 data[lang].append((filename, source)) 370 data[lang].append((filename, source))
363 371
364 self.queuedBatches["raw"] = [] 372 self.queuedBatches["raw"] = []
365 if data['Python3']: 373 if data["Python3"]:
366 self.queuedBatches["cc"].append('Python3') 374 self.queuedBatches["cc"].append("Python3")
367 self.backgroundService.enqueueRequest( 375 self.backgroundService.enqueueRequest(
368 'batch_radon_cc', 'Python3', "", data['Python3']) 376 "batch_radon_cc", "Python3", "", data["Python3"]
377 )
369 self.batchesFinished["cc"] = False 378 self.batchesFinished["cc"] = False
370 379
371 def cancelComplexityBatch(self): 380 def cancelComplexityBatch(self):
372 """ 381 """
373 Public method to cancel all batch jobs. 382 Public method to cancel all batch jobs.
374 """ 383 """
375 self.backgroundService.requestCancel('batch_radon_cc', 'Python3') 384 self.backgroundService.requestCancel("batch_radon_cc", "Python3")
376 385
377 def activate(self): 386 def activate(self):
378 """ 387 """
379 Public method to activate this plug-in. 388 Public method to activate this plug-in.
380 389
381 @return tuple of None and activation status 390 @return tuple of None and activation status
382 @rtype (None, bool) 391 @rtype (None, bool)
383 """ 392 """
384 global error 393 global error
385 error = "" # clear previous error 394 error = "" # clear previous error
386 395
387 # Project menu actions 396 # Project menu actions
388 menu = ericApp().getObject("Project").getMenu("Show") 397 menu = ericApp().getObject("Project").getMenu("Show")
389 if menu: 398 if menu:
390 if not menu.isEmpty(): 399 if not menu.isEmpty():
391 act = menu.addSeparator() 400 act = menu.addSeparator()
392 self.__projectSeparatorActs.append(act) 401 self.__projectSeparatorActs.append(act)
393 402
394 # header action 403 # header action
395 act = QAction(self.tr("Radon"), self) 404 act = QAction(self.tr("Radon"), self)
396 font = act.font() 405 font = act.font()
397 font.setBold(True) 406 font.setBold(True)
398 act.setFont(font) 407 act.setFont(font)
399 act.triggered.connect(self.__showRadonVersion) 408 act.triggered.connect(self.__showRadonVersion)
400 menu.addAction(act) 409 menu.addAction(act)
401 self.__projectMetricsActs.append(act) 410 self.__projectMetricsActs.append(act)
402 411
403 act = EricAction( 412 act = EricAction(
404 self.tr('Code Metrics'), 413 self.tr("Code Metrics"),
405 self.tr('Code &Metrics...'), 0, 0, 414 self.tr("Code &Metrics..."),
406 self, 'project_show_radon_raw') 415 0,
407 act.setStatusTip( 416 0,
408 self.tr('Show raw code metrics.')) 417 self,
409 act.setWhatsThis(self.tr( 418 "project_show_radon_raw",
410 """<b>Code Metrics...</b>""" 419 )
411 """<p>This calculates raw code metrics of Python files""" 420 act.setStatusTip(self.tr("Show raw code metrics."))
412 """ and shows the amount of lines of code, logical lines""" 421 act.setWhatsThis(
413 """ of code, source lines of code, comment lines,""" 422 self.tr(
414 """ multi-line strings and blank lines.</p>""" 423 """<b>Code Metrics...</b>"""
415 )) 424 """<p>This calculates raw code metrics of Python files"""
425 """ and shows the amount of lines of code, logical lines"""
426 """ of code, source lines of code, comment lines,"""
427 """ multi-line strings and blank lines.</p>"""
428 )
429 )
416 act.triggered.connect(self.__projectRawMetrics) 430 act.triggered.connect(self.__projectRawMetrics)
417 menu.addAction(act) 431 menu.addAction(act)
418 self.__projectMetricsActs.append(act) 432 self.__projectMetricsActs.append(act)
419 433
420 act = EricAction( 434 act = EricAction(
421 self.tr('Maintainability Index'), 435 self.tr("Maintainability Index"),
422 self.tr('Maintainability &Index...'), 0, 0, 436 self.tr("Maintainability &Index..."),
423 self, 'project_show_radon_mi') 437 0,
438 0,
439 self,
440 "project_show_radon_mi",
441 )
424 act.setStatusTip( 442 act.setStatusTip(
425 self.tr('Show the maintainability index for Python files.')) 443 self.tr("Show the maintainability index for Python files.")
426 act.setWhatsThis(self.tr( 444 )
427 """<b>Maintainability Index...</b>""" 445 act.setWhatsThis(
428 """<p>This calculates the maintainability index of Python""" 446 self.tr(
429 """ files and shows it together with a ranking.</p>""" 447 """<b>Maintainability Index...</b>"""
430 )) 448 """<p>This calculates the maintainability index of Python"""
449 """ files and shows it together with a ranking.</p>"""
450 )
451 )
431 act.triggered.connect(self.__projectMaintainabilityIndex) 452 act.triggered.connect(self.__projectMaintainabilityIndex)
432 menu.addAction(act) 453 menu.addAction(act)
433 self.__projectMetricsActs.append(act) 454 self.__projectMetricsActs.append(act)
434 455
435 act = EricAction( 456 act = EricAction(
436 self.tr('Cyclomatic Complexity'), 457 self.tr("Cyclomatic Complexity"),
437 self.tr('Cyclomatic &Complexity...'), 0, 0, 458 self.tr("Cyclomatic &Complexity..."),
438 self, 'project_show_radon_cc') 459 0,
460 0,
461 self,
462 "project_show_radon_cc",
463 )
439 act.setStatusTip( 464 act.setStatusTip(
440 self.tr('Show the cyclomatic complexity for Python files.')) 465 self.tr("Show the cyclomatic complexity for Python files.")
441 act.setWhatsThis(self.tr( 466 )
442 """<b>Cyclomatic Complexity...</b>""" 467 act.setWhatsThis(
443 """<p>This calculates the cyclomatic complexity of Python""" 468 self.tr(
444 """ files and shows it together with a ranking.</p>""" 469 """<b>Cyclomatic Complexity...</b>"""
445 )) 470 """<p>This calculates the cyclomatic complexity of Python"""
471 """ files and shows it together with a ranking.</p>"""
472 )
473 )
446 act.triggered.connect(self.__projectCyclomaticComplexity) 474 act.triggered.connect(self.__projectCyclomaticComplexity)
447 menu.addAction(act) 475 menu.addAction(act)
448 self.__projectMetricsActs.append(act) 476 self.__projectMetricsActs.append(act)
449 477
450 act = menu.addSeparator() 478 act = menu.addSeparator()
451 self.__projectSeparatorActs.append(act) 479 self.__projectSeparatorActs.append(act)
452 480
453 ericApp().getObject("Project").addEricActions( 481 ericApp().getObject("Project").addEricActions(self.__projectMetricsActs[1:])
454 self.__projectMetricsActs[1:]) 482
455
456 # Editor menu actions (one separator each above and below) 483 # Editor menu actions (one separator each above and below)
457 act = QAction(self) 484 act = QAction(self)
458 act.setSeparator(True) 485 act.setSeparator(True)
459 self.__editorSeparatorActs.append(act) 486 self.__editorSeparatorActs.append(act)
460 act = QAction(self) 487 act = QAction(self)
461 act.setSeparator(True) 488 act.setSeparator(True)
462 self.__editorSeparatorActs.append(act) 489 self.__editorSeparatorActs.append(act)
463 490
464 # header action 491 # header action
465 act = QAction(self.tr("Radon"), self) 492 act = QAction(self.tr("Radon"), self)
466 font = act.font() 493 font = act.font()
467 font.setBold(True) 494 font.setBold(True)
468 act.setFont(font) 495 act.setFont(font)
469 act.triggered.connect(self.__showRadonVersion) 496 act.triggered.connect(self.__showRadonVersion)
470 self.__editorMetricsActs.append(act) 497 self.__editorMetricsActs.append(act)
471 498
472 act = EricAction( 499 act = EricAction(
473 self.tr('Code Metrics'), 500 self.tr("Code Metrics"), self.tr("Code &Metrics..."), 0, 0, self, ""
474 self.tr('Code &Metrics...'), 0, 0, 501 )
475 self, "") 502 act.setStatusTip(self.tr("Show raw code metrics."))
476 act.setStatusTip( 503 act.setWhatsThis(
477 self.tr('Show raw code metrics.')) 504 self.tr(
478 act.setWhatsThis(self.tr( 505 """<b>Code Metrics...</b>"""
479 """<b>Code Metrics...</b>""" 506 """<p>This calculates raw code metrics of Python files"""
480 """<p>This calculates raw code metrics of Python files""" 507 """ and shows the amount of lines of code, logical lines"""
481 """ and shows the amount of lines of code, logical lines""" 508 """ of code, source lines of code, comment lines,"""
482 """ of code, source lines of code, comment lines,""" 509 """ multi-line strings and blank lines.</p>"""
483 """ multi-line strings and blank lines.</p>""" 510 )
484 )) 511 )
485 act.triggered.connect(self.__editorRawMetrics) 512 act.triggered.connect(self.__editorRawMetrics)
486 self.__editorMetricsActs.append(act) 513 self.__editorMetricsActs.append(act)
487 514
488 act = EricAction( 515 act = EricAction(
489 self.tr('Maintainability Index'), 516 self.tr("Maintainability Index"),
490 self.tr('Maintainability &Index...'), 0, 0, 517 self.tr("Maintainability &Index..."),
491 self, "") 518 0,
492 act.setStatusTip( 519 0,
493 self.tr('Show the maintainability index for Python files.')) 520 self,
494 act.setWhatsThis(self.tr( 521 "",
495 """<b>Maintainability Index...</b>""" 522 )
496 """<p>This calculates the maintainability index of Python""" 523 act.setStatusTip(self.tr("Show the maintainability index for Python files."))
497 """ files and shows it together with a ranking.</p>""" 524 act.setWhatsThis(
498 )) 525 self.tr(
526 """<b>Maintainability Index...</b>"""
527 """<p>This calculates the maintainability index of Python"""
528 """ files and shows it together with a ranking.</p>"""
529 )
530 )
499 act.triggered.connect(self.__editorMaintainabilityIndex) 531 act.triggered.connect(self.__editorMaintainabilityIndex)
500 self.__editorMetricsActs.append(act) 532 self.__editorMetricsActs.append(act)
501 533
502 act = EricAction( 534 act = EricAction(
503 self.tr('Cyclomatic Complexity'), 535 self.tr("Cyclomatic Complexity"),
504 self.tr('Cyclomatic &Complexity...'), 0, 0, 536 self.tr("Cyclomatic &Complexity..."),
505 self, '') 537 0,
506 act.setStatusTip( 538 0,
507 self.tr('Show the cyclomatic complexity for Python files.')) 539 self,
508 act.setWhatsThis(self.tr( 540 "",
509 """<b>Cyclomatic Complexity...</b>""" 541 )
510 """<p>This calculates the cyclomatic complexity of Python""" 542 act.setStatusTip(self.tr("Show the cyclomatic complexity for Python files."))
511 """ files and shows it together with a ranking.</p>""" 543 act.setWhatsThis(
512 )) 544 self.tr(
545 """<b>Cyclomatic Complexity...</b>"""
546 """<p>This calculates the cyclomatic complexity of Python"""
547 """ files and shows it together with a ranking.</p>"""
548 )
549 )
513 act.triggered.connect(self.__editorCyclomaticComplexity) 550 act.triggered.connect(self.__editorCyclomaticComplexity)
514 self.__editorMetricsActs.append(act) 551 self.__editorMetricsActs.append(act)
515 552
516 ericApp().getObject("Project").showMenu.connect(self.__projectShowMenu) 553 ericApp().getObject("Project").showMenu.connect(self.__projectShowMenu)
517 ericApp().getObject("Project").projectClosed.connect( 554 ericApp().getObject("Project").projectClosed.connect(self.__projectClosed)
518 self.__projectClosed)
519 ericApp().getObject("ProjectBrowser").getProjectBrowser( 555 ericApp().getObject("ProjectBrowser").getProjectBrowser(
520 "sources").showMenu.connect(self.__projectBrowserShowMenu) 556 "sources"
521 ericApp().getObject("ViewManager").editorOpenedEd.connect( 557 ).showMenu.connect(self.__projectBrowserShowMenu)
522 self.__editorOpened) 558 ericApp().getObject("ViewManager").editorOpenedEd.connect(self.__editorOpened)
523 ericApp().getObject("ViewManager").editorClosedEd.connect( 559 ericApp().getObject("ViewManager").editorClosedEd.connect(self.__editorClosed)
524 self.__editorClosed) 560
525
526 for editor in ericApp().getObject("ViewManager").getOpenEditors(): 561 for editor in ericApp().getObject("ViewManager").getOpenEditors():
527 self.__editorOpened(editor) 562 self.__editorOpened(editor)
528 563
529 return None, True 564 return None, True
530 565
531 def deactivate(self): 566 def deactivate(self):
532 """ 567 """
533 Public method to deactivate this plug-in. 568 Public method to deactivate this plug-in.
534 """ 569 """
535 ericApp().getObject("Project").showMenu.disconnect( 570 ericApp().getObject("Project").showMenu.disconnect(self.__projectShowMenu)
536 self.__projectShowMenu) 571 ericApp().getObject("Project").projectClosed.disconnect(self.__projectClosed)
537 ericApp().getObject("Project").projectClosed.disconnect(
538 self.__projectClosed)
539 ericApp().getObject("ProjectBrowser").getProjectBrowser( 572 ericApp().getObject("ProjectBrowser").getProjectBrowser(
540 "sources").showMenu.disconnect(self.__projectBrowserShowMenu) 573 "sources"
574 ).showMenu.disconnect(self.__projectBrowserShowMenu)
541 ericApp().getObject("ViewManager").editorOpenedEd.disconnect( 575 ericApp().getObject("ViewManager").editorOpenedEd.disconnect(
542 self.__editorOpened) 576 self.__editorOpened
577 )
543 ericApp().getObject("ViewManager").editorClosedEd.disconnect( 578 ericApp().getObject("ViewManager").editorClosedEd.disconnect(
544 self.__editorClosed) 579 self.__editorClosed
545 580 )
581
546 menu = ericApp().getObject("Project").getMenu("Show") 582 menu = ericApp().getObject("Project").getMenu("Show")
547 if menu: 583 if menu:
548 for sep in self.__projectSeparatorActs: 584 for sep in self.__projectSeparatorActs:
549 menu.removeAction(sep) 585 menu.removeAction(sep)
550 for act in self.__projectMetricsActs: 586 for act in self.__projectMetricsActs:
551 menu.removeAction(act) 587 menu.removeAction(act)
552 ericApp().getObject("Project").removeEricActions( 588 ericApp().getObject("Project").removeEricActions(
553 self.__projectMetricsActs[1:]) 589 self.__projectMetricsActs[1:]
554 590 )
591
555 if self.__projectBrowserMenu: 592 if self.__projectBrowserMenu:
556 for sep in self.__projectBrowserSeparatorActs: 593 for sep in self.__projectBrowserSeparatorActs:
557 self.__projectBrowserMenu.removeAction(sep) 594 self.__projectBrowserMenu.removeAction(sep)
558 for act in self.__projectBrowserMetricsActs: 595 for act in self.__projectBrowserMetricsActs:
559 self.__projectBrowserMenu.removeAction(act) 596 self.__projectBrowserMenu.removeAction(act)
560 597
561 for editor in self.__editors: 598 for editor in self.__editors:
562 editor.showMenu.disconnect(self.__editorShowMenu) 599 editor.showMenu.disconnect(self.__editorShowMenu)
563 menu = editor.getMenu("Show") 600 menu = editor.getMenu("Show")
564 if menu is not None: 601 if menu is not None:
565 for sep in self.__editorSeparatorActs: 602 for sep in self.__editorSeparatorActs:
566 menu.removeAction(sep) 603 menu.removeAction(sep)
567 for act in self.__editorMetricsActs: 604 for act in self.__editorMetricsActs:
568 menu.removeAction(act) 605 menu.removeAction(act)
569 606
570 self.__initialize() 607 self.__initialize()
571 608
572 def __loadTranslator(self): 609 def __loadTranslator(self):
573 """ 610 """
574 Private method to load the translation file. 611 Private method to load the translation file.
575 """ 612 """
576 if self.__ui is not None: 613 if self.__ui is not None:
577 loc = self.__ui.getLocale() 614 loc = self.__ui.getLocale()
578 if loc and loc != "C": 615 if loc and loc != "C":
579 locale_dir = os.path.join( 616 locale_dir = os.path.join(
580 os.path.dirname(__file__), "RadonMetrics", "i18n") 617 os.path.dirname(__file__), "RadonMetrics", "i18n"
618 )
581 translation = "radon_{0}".format(loc) 619 translation = "radon_{0}".format(loc)
582 translator = QTranslator(None) 620 translator = QTranslator(None)
583 loaded = translator.load(translation, locale_dir) 621 loaded = translator.load(translation, locale_dir)
584 if loaded: 622 if loaded:
585 self.__translator = translator 623 self.__translator = translator
586 ericApp().installTranslator(self.__translator) 624 ericApp().installTranslator(self.__translator)
587 else: 625 else:
588 print("Warning: translation file '{0}' could not be" 626 print(
589 " loaded.".format(translation)) 627 "Warning: translation file '{0}' could not be"
628 " loaded.".format(translation)
629 )
590 print("Using default.") 630 print("Using default.")
591 631
592 def __projectShowMenu(self, menuName, menu): 632 def __projectShowMenu(self, menuName, menu):
593 """ 633 """
594 Private slot called, when the the project menu or a submenu is 634 Private slot called, when the the project menu or a submenu is
595 about to be shown. 635 about to be shown.
596 636
597 @param menuName name of the menu to be shown 637 @param menuName name of the menu to be shown
598 @type str 638 @type str
599 @param menu reference to the menu 639 @param menu reference to the menu
600 @type QMenu 640 @type QMenu
601 """ 641 """
602 if menuName == "Show": 642 if menuName == "Show":
603 for act in self.__projectMetricsActs[1:]: 643 for act in self.__projectMetricsActs[1:]:
604 act.setEnabled( 644 act.setEnabled(
605 ericApp().getObject("Project").getProjectLanguage() == 645 ericApp().getObject("Project").getProjectLanguage() == "Python3"
606 "Python3") 646 )
607 647
608 def __projectBrowserShowMenu(self, menuName, menu): 648 def __projectBrowserShowMenu(self, menuName, menu):
609 """ 649 """
610 Private slot called, when the the project browser context menu or a 650 Private slot called, when the the project browser context menu or a
611 submenu is about to be shown. 651 submenu is about to be shown.
612 652
613 @param menuName name of the menu to be shown 653 @param menuName name of the menu to be shown
614 @type str 654 @type str
615 @param menu reference to the menu 655 @param menu reference to the menu
616 @type QMenu 656 @type QMenu
617 """ 657 """
618 if ( 658 if (
619 menuName == "Show" and 659 menuName == "Show"
620 ericApp().getObject("Project").getProjectLanguage() == 660 and ericApp().getObject("Project").getProjectLanguage() == "Python3"
621 "Python3" and 661 and self.__projectBrowserMenu is None
622 self.__projectBrowserMenu is None
623 ): 662 ):
624 self.__projectBrowserMenu = menu 663 self.__projectBrowserMenu = menu
625 664
626 act = menu.addSeparator() 665 act = menu.addSeparator()
627 self.__projectBrowserSeparatorActs.append(act) 666 self.__projectBrowserSeparatorActs.append(act)
628 667
629 # header action 668 # header action
630 act = QAction(self.tr("Radon"), self) 669 act = QAction(self.tr("Radon"), self)
631 font = act.font() 670 font = act.font()
632 font.setBold(True) 671 font.setBold(True)
633 act.setFont(font) 672 act.setFont(font)
634 act.triggered.connect(self.__showRadonVersion) 673 act.triggered.connect(self.__showRadonVersion)
635 menu.addAction(act) 674 menu.addAction(act)
636 self.__projectBrowserMetricsActs.append(act) 675 self.__projectBrowserMetricsActs.append(act)
637 676
638 act = EricAction( 677 act = EricAction(
639 self.tr('Code Metrics'), 678 self.tr("Code Metrics"), self.tr("Code &Metrics..."), 0, 0, self, ""
640 self.tr('Code &Metrics...'), 0, 0, 679 )
641 self, '') 680 act.setStatusTip(self.tr("Show raw code metrics."))
642 act.setStatusTip(self.tr( 681 act.setWhatsThis(
643 'Show raw code metrics.')) 682 self.tr(
644 act.setWhatsThis(self.tr( 683 """<b>Code Metrics...</b>"""
645 """<b>Code Metrics...</b>""" 684 """<p>This calculates raw code metrics of Python files"""
646 """<p>This calculates raw code metrics of Python files""" 685 """ and shows the amount of lines of code, logical lines"""
647 """ and shows the amount of lines of code, logical lines""" 686 """ of code, source lines of code, comment lines,"""
648 """ of code, source lines of code, comment lines,""" 687 """ multi-line strings and blank lines.</p>"""
649 """ multi-line strings and blank lines.</p>""" 688 )
650 )) 689 )
651 act.triggered.connect(self.__projectBrowserRawMetrics) 690 act.triggered.connect(self.__projectBrowserRawMetrics)
652 menu.addAction(act) 691 menu.addAction(act)
653 self.__projectBrowserMetricsActs.append(act) 692 self.__projectBrowserMetricsActs.append(act)
654 693
655 act = EricAction( 694 act = EricAction(
656 self.tr('Maintainability Index'), 695 self.tr("Maintainability Index"),
657 self.tr('Maintainability &Index...'), 0, 0, 696 self.tr("Maintainability &Index..."),
658 self, '') 697 0,
659 act.setStatusTip(self.tr( 698 0,
660 'Show the maintainability index for Python files.')) 699 self,
661 act.setWhatsThis(self.tr( 700 "",
662 """<b>Maintainability Index...</b>""" 701 )
663 """<p>This calculates the maintainability index of""" 702 act.setStatusTip(
664 """ Python files and shows it together with a ranking.""" 703 self.tr("Show the maintainability index for Python files.")
665 """</p>""" 704 )
666 )) 705 act.setWhatsThis(
667 act.triggered.connect( 706 self.tr(
668 self.__projectBrowserMaintainabilityIndex) 707 """<b>Maintainability Index...</b>"""
708 """<p>This calculates the maintainability index of"""
709 """ Python files and shows it together with a ranking."""
710 """</p>"""
711 )
712 )
713 act.triggered.connect(self.__projectBrowserMaintainabilityIndex)
669 menu.addAction(act) 714 menu.addAction(act)
670 self.__projectBrowserMetricsActs.append(act) 715 self.__projectBrowserMetricsActs.append(act)
671 716
672 act = EricAction( 717 act = EricAction(
673 self.tr('Cyclomatic Complexity'), 718 self.tr("Cyclomatic Complexity"),
674 self.tr('Cyclomatic &Complexity...'), 0, 0, 719 self.tr("Cyclomatic &Complexity..."),
675 self, '') 720 0,
676 act.setStatusTip(self.tr( 721 0,
677 'Show the cyclomatic complexity for Python files.')) 722 self,
678 act.setWhatsThis(self.tr( 723 "",
679 """<b>Cyclomatic Complexity...</b>""" 724 )
680 """<p>This calculates the cyclomatic complexity of""" 725 act.setStatusTip(
681 """ Python files and shows it together with a ranking.""" 726 self.tr("Show the cyclomatic complexity for Python files.")
682 """</p>""" 727 )
683 )) 728 act.setWhatsThis(
684 act.triggered.connect( 729 self.tr(
685 self.__projectBrowserCyclomaticComplexity) 730 """<b>Cyclomatic Complexity...</b>"""
731 """<p>This calculates the cyclomatic complexity of"""
732 """ Python files and shows it together with a ranking."""
733 """</p>"""
734 )
735 )
736 act.triggered.connect(self.__projectBrowserCyclomaticComplexity)
686 menu.addAction(act) 737 menu.addAction(act)
687 self.__projectBrowserMetricsActs.append(act) 738 self.__projectBrowserMetricsActs.append(act)
688 739
689 act = menu.addSeparator() 740 act = menu.addSeparator()
690 self.__projectBrowserSeparatorActs.append(act) 741 self.__projectBrowserSeparatorActs.append(act)
691 742
692 def __editorOpened(self, editor): 743 def __editorOpened(self, editor):
693 """ 744 """
694 Private slot called, when a new editor was opened. 745 Private slot called, when a new editor was opened.
695 746
696 @param editor reference to the new editor 747 @param editor reference to the new editor
697 @type Editor 748 @type Editor
698 """ 749 """
699 menu = editor.getMenu("Show") 750 menu = editor.getMenu("Show")
700 if menu is not None: 751 if menu is not None:
702 menu.addActions(self.__editorMetricsActs) 753 menu.addActions(self.__editorMetricsActs)
703 menu.addAction(self.__editorSeparatorActs[1]) 754 menu.addAction(self.__editorSeparatorActs[1])
704 editor.showMenu.connect(self.__editorShowMenu) 755 editor.showMenu.connect(self.__editorShowMenu)
705 editor.editorRenamed.connect(lambda: self.__editorRenamed(editor)) 756 editor.editorRenamed.connect(lambda: self.__editorRenamed(editor))
706 self.__editors.append(editor) 757 self.__editors.append(editor)
707 758
708 def __editorClosed(self, editor): 759 def __editorClosed(self, editor):
709 """ 760 """
710 Private slot called, when an editor was closed. 761 Private slot called, when an editor was closed.
711 762
712 @param editor reference to the editor 763 @param editor reference to the editor
713 @type Editor 764 @type Editor
714 """ 765 """
715 with contextlib.suppress(ValueError): 766 with contextlib.suppress(ValueError):
716 self.__editors.remove(editor) 767 self.__editors.remove(editor)
717 768
718 def __editorRenamed(self, editor): 769 def __editorRenamed(self, editor):
719 """ 770 """
720 Private slot called, when an editor was renamed. 771 Private slot called, when an editor was renamed.
721 772
722 @param editor reference to the renamed editor 773 @param editor reference to the renamed editor
723 @type Editor 774 @type Editor
724 """ 775 """
725 menu = editor.getMenu("Show") 776 menu = editor.getMenu("Show")
726 if menu is not None: 777 if menu is not None:
727 menu.addAction(self.__editorSeparatorActs[0]) 778 menu.addAction(self.__editorSeparatorActs[0])
728 menu.addActions(self.__editorMetricsActs) 779 menu.addActions(self.__editorMetricsActs)
729 menu.addAction(self.__editorSeparatorActs[1]) 780 menu.addAction(self.__editorSeparatorActs[1])
730 781
731 def __editorShowMenu(self, menuName, menu, editor): 782 def __editorShowMenu(self, menuName, menu, editor):
732 """ 783 """
733 Private slot called, when the the editor context menu or a submenu is 784 Private slot called, when the the editor context menu or a submenu is
734 about to be shown. 785 about to be shown.
735 786
736 @param menuName name of the menu to be shown 787 @param menuName name of the menu to be shown
737 @type str 788 @type str
738 @param menu reference to the menu 789 @param menu reference to the menu
739 @type QMenu 790 @type QMenu
740 @param editor reference to the editor 791 @param editor reference to the editor
742 """ 793 """
743 if menuName == "Show": 794 if menuName == "Show":
744 enable = editor.isPyFile() 795 enable = editor.isPyFile()
745 for act in self.__editorMetricsActs: 796 for act in self.__editorMetricsActs:
746 act.setEnabled(enable) 797 act.setEnabled(enable)
747 798
748 ################################################################## 799 ##################################################################
749 ## Raw code metrics calculations 800 ## Raw code metrics calculations
750 ################################################################## 801 ##################################################################
751 802
752 def __projectRawMetrics(self): 803 def __projectRawMetrics(self):
753 """ 804 """
754 Private slot used to calculate raw code metrics for the project. 805 Private slot used to calculate raw code metrics for the project.
755 """ 806 """
756 project = ericApp().getObject("Project") 807 project = ericApp().getObject("Project")
759 files = [ 810 files = [
760 os.path.join(ppath, file) 811 os.path.join(ppath, file)
761 for file in project.getSources() 812 for file in project.getSources()
762 if file.endswith(tuple(Preferences.getPython("Python3Extensions"))) 813 if file.endswith(tuple(Preferences.getPython("Python3Extensions")))
763 ] 814 ]
764 815
765 if self.__projectRawMetricsDialog is None: 816 if self.__projectRawMetricsDialog is None:
766 from RadonMetrics.RawMetricsDialog import RawMetricsDialog 817 from RadonMetrics.RawMetricsDialog import RawMetricsDialog
818
767 self.__projectRawMetricsDialog = RawMetricsDialog(self) 819 self.__projectRawMetricsDialog = RawMetricsDialog(self)
768 self.__projectRawMetricsDialog.show() 820 self.__projectRawMetricsDialog.show()
769 self.__projectRawMetricsDialog.prepare(files, project) 821 self.__projectRawMetricsDialog.prepare(files, project)
770 822
771 def __projectBrowserRawMetrics(self): 823 def __projectBrowserRawMetrics(self):
772 """ 824 """
773 Private method to handle the code metrics context menu action of the 825 Private method to handle the code metrics context menu action of the
774 project sources browser. 826 project sources browser.
775 """ 827 """
776 browser = ( 828 browser = ericApp().getObject("ProjectBrowser").getProjectBrowser("sources")
777 ericApp().getObject("ProjectBrowser").getProjectBrowser("sources")
778 )
779 if browser.getSelectedItemsCount([ProjectBrowserFileItem]) > 1: 829 if browser.getSelectedItemsCount([ProjectBrowserFileItem]) > 1:
780 fn = [] 830 fn = []
781 for itm in browser.getSelectedItems([ProjectBrowserFileItem]): 831 for itm in browser.getSelectedItems([ProjectBrowserFileItem]):
782 fn.append(itm.fileName()) 832 fn.append(itm.fileName())
783 else: 833 else:
784 itm = browser.model().item(browser.currentIndex()) 834 itm = browser.model().item(browser.currentIndex())
785 try: 835 try:
786 fn = itm.fileName() 836 fn = itm.fileName()
787 except AttributeError: 837 except AttributeError:
788 fn = itm.dirName() 838 fn = itm.dirName()
789 839
790 if self.__projectBrowserRawMetricsDialog is None: 840 if self.__projectBrowserRawMetricsDialog is None:
791 from RadonMetrics.RawMetricsDialog import RawMetricsDialog 841 from RadonMetrics.RawMetricsDialog import RawMetricsDialog
842
792 self.__projectBrowserRawMetricsDialog = RawMetricsDialog(self) 843 self.__projectBrowserRawMetricsDialog = RawMetricsDialog(self)
793 self.__projectBrowserRawMetricsDialog.show() 844 self.__projectBrowserRawMetricsDialog.show()
794 self.__projectBrowserRawMetricsDialog.start(fn) 845 self.__projectBrowserRawMetricsDialog.start(fn)
795 846
796 def __editorRawMetrics(self): 847 def __editorRawMetrics(self):
797 """ 848 """
798 Private slot to handle the raw code metrics action of the editor show 849 Private slot to handle the raw code metrics action of the editor show
799 menu. 850 menu.
800 """ 851 """
801 editor = ericApp().getObject("ViewManager").activeWindow() 852 editor = ericApp().getObject("ViewManager").activeWindow()
802 if ( 853 if (
803 editor is not None and 854 editor is not None
804 editor.checkDirty() and 855 and editor.checkDirty()
805 editor.getFileName() is not None 856 and editor.getFileName() is not None
806 ): 857 ):
807 if self.__editorRawMetricsDialog is None: 858 if self.__editorRawMetricsDialog is None:
808 from RadonMetrics.RawMetricsDialog import RawMetricsDialog 859 from RadonMetrics.RawMetricsDialog import RawMetricsDialog
860
809 self.__editorRawMetricsDialog = RawMetricsDialog(self) 861 self.__editorRawMetricsDialog = RawMetricsDialog(self)
810 self.__editorRawMetricsDialog.show() 862 self.__editorRawMetricsDialog.show()
811 self.__editorRawMetricsDialog.start(editor.getFileName()) 863 self.__editorRawMetricsDialog.start(editor.getFileName())
812 864
813 ################################################################## 865 ##################################################################
814 ## Maintainability index calculations 866 ## Maintainability index calculations
815 ################################################################## 867 ##################################################################
816 868
817 def __projectMaintainabilityIndex(self): 869 def __projectMaintainabilityIndex(self):
818 """ 870 """
819 Private slot used to calculate the maintainability indexes for the 871 Private slot used to calculate the maintainability indexes for the
820 project. 872 project.
821 """ 873 """
825 files = [ 877 files = [
826 os.path.join(ppath, file) 878 os.path.join(ppath, file)
827 for file in project.getSources() 879 for file in project.getSources()
828 if file.endswith(tuple(Preferences.getPython("Python3Extensions"))) 880 if file.endswith(tuple(Preferences.getPython("Python3Extensions")))
829 ] 881 ]
830 882
831 if self.__projectMIDialog is None: 883 if self.__projectMIDialog is None:
832 from RadonMetrics.MaintainabilityIndexDialog import ( 884 from RadonMetrics.MaintainabilityIndexDialog import (
833 MaintainabilityIndexDialog 885 MaintainabilityIndexDialog,
834 ) 886 )
887
835 self.__projectMIDialog = MaintainabilityIndexDialog(self) 888 self.__projectMIDialog = MaintainabilityIndexDialog(self)
836 self.__projectMIDialog.show() 889 self.__projectMIDialog.show()
837 self.__projectMIDialog.prepare(files, project) 890 self.__projectMIDialog.prepare(files, project)
838 891
839 def __projectBrowserMaintainabilityIndex(self): 892 def __projectBrowserMaintainabilityIndex(self):
840 """ 893 """
841 Private method to handle the maintainability index context menu action 894 Private method to handle the maintainability index context menu action
842 of the project sources browser. 895 of the project sources browser.
843 """ 896 """
844 browser = ericApp().getObject("ProjectBrowser").getProjectBrowser( 897 browser = ericApp().getObject("ProjectBrowser").getProjectBrowser("sources")
845 "sources")
846 if browser.getSelectedItemsCount([ProjectBrowserFileItem]) > 1: 898 if browser.getSelectedItemsCount([ProjectBrowserFileItem]) > 1:
847 fn = [] 899 fn = []
848 for itm in browser.getSelectedItems([ProjectBrowserFileItem]): 900 for itm in browser.getSelectedItems([ProjectBrowserFileItem]):
849 fn.append(itm.fileName()) 901 fn.append(itm.fileName())
850 else: 902 else:
851 itm = browser.model().item(browser.currentIndex()) 903 itm = browser.model().item(browser.currentIndex())
852 try: 904 try:
853 fn = itm.fileName() 905 fn = itm.fileName()
854 except AttributeError: 906 except AttributeError:
855 fn = itm.dirName() 907 fn = itm.dirName()
856 908
857 if self.__projectBrowserMIDialog is None: 909 if self.__projectBrowserMIDialog is None:
858 from RadonMetrics.MaintainabilityIndexDialog import ( 910 from RadonMetrics.MaintainabilityIndexDialog import (
859 MaintainabilityIndexDialog 911 MaintainabilityIndexDialog,
860 ) 912 )
913
861 self.__projectBrowserMIDialog = MaintainabilityIndexDialog(self) 914 self.__projectBrowserMIDialog = MaintainabilityIndexDialog(self)
862 self.__projectBrowserMIDialog.show() 915 self.__projectBrowserMIDialog.show()
863 self.__projectBrowserMIDialog.start(fn) 916 self.__projectBrowserMIDialog.start(fn)
864 917
865 def __editorMaintainabilityIndex(self): 918 def __editorMaintainabilityIndex(self):
866 """ 919 """
867 Private slot to handle the maintainability index action of the editor 920 Private slot to handle the maintainability index action of the editor
868 show menu. 921 show menu.
869 """ 922 """
870 editor = ericApp().getObject("ViewManager").activeWindow() 923 editor = ericApp().getObject("ViewManager").activeWindow()
871 if ( 924 if (
872 editor is not None and 925 editor is not None
873 editor.checkDirty() and 926 and editor.checkDirty()
874 editor.getFileName() is not None 927 and editor.getFileName() is not None
875 ): 928 ):
876 if self.__editorMIDialog is None: 929 if self.__editorMIDialog is None:
877 from RadonMetrics.MaintainabilityIndexDialog import ( 930 from RadonMetrics.MaintainabilityIndexDialog import (
878 MaintainabilityIndexDialog 931 MaintainabilityIndexDialog,
879 ) 932 )
933
880 self.__editorMIDialog = MaintainabilityIndexDialog(self) 934 self.__editorMIDialog = MaintainabilityIndexDialog(self)
881 self.__editorMIDialog.show() 935 self.__editorMIDialog.show()
882 self.__editorMIDialog.start(editor.getFileName()) 936 self.__editorMIDialog.start(editor.getFileName())
883 937
884 ################################################################## 938 ##################################################################
885 ## Cyclomatic complexity calculations 939 ## Cyclomatic complexity calculations
886 ################################################################## 940 ##################################################################
887 941
888 def __projectCyclomaticComplexity(self): 942 def __projectCyclomaticComplexity(self):
889 """ 943 """
890 Private slot used to calculate the cyclomatic complexity for the 944 Private slot used to calculate the cyclomatic complexity for the
891 project. 945 project.
892 """ 946 """
896 files = [ 950 files = [
897 os.path.join(ppath, file) 951 os.path.join(ppath, file)
898 for file in project.getSources() 952 for file in project.getSources()
899 if file.endswith(tuple(Preferences.getPython("Python3Extensions"))) 953 if file.endswith(tuple(Preferences.getPython("Python3Extensions")))
900 ] 954 ]
901 955
902 if self.__projectCCDialog is None: 956 if self.__projectCCDialog is None:
903 from RadonMetrics.CyclomaticComplexityDialog import ( 957 from RadonMetrics.CyclomaticComplexityDialog import (
904 CyclomaticComplexityDialog 958 CyclomaticComplexityDialog,
905 ) 959 )
960
906 self.__projectCCDialog = CyclomaticComplexityDialog(self) 961 self.__projectCCDialog = CyclomaticComplexityDialog(self)
907 self.__projectCCDialog.show() 962 self.__projectCCDialog.show()
908 self.__projectCCDialog.prepare(files, project) 963 self.__projectCCDialog.prepare(files, project)
909 964
910 def __projectBrowserCyclomaticComplexity(self): 965 def __projectBrowserCyclomaticComplexity(self):
911 """ 966 """
912 Private method to handle the cyclomatic complexity context menu action 967 Private method to handle the cyclomatic complexity context menu action
913 of the project sources browser. 968 of the project sources browser.
914 """ 969 """
915 browser = ericApp().getObject("ProjectBrowser").getProjectBrowser( 970 browser = ericApp().getObject("ProjectBrowser").getProjectBrowser("sources")
916 "sources")
917 if browser.getSelectedItemsCount([ProjectBrowserFileItem]) > 1: 971 if browser.getSelectedItemsCount([ProjectBrowserFileItem]) > 1:
918 fn = [] 972 fn = []
919 for itm in browser.getSelectedItems([ProjectBrowserFileItem]): 973 for itm in browser.getSelectedItems([ProjectBrowserFileItem]):
920 fn.append(itm.fileName()) 974 fn.append(itm.fileName())
921 else: 975 else:
922 itm = browser.model().item(browser.currentIndex()) 976 itm = browser.model().item(browser.currentIndex())
923 try: 977 try:
924 fn = itm.fileName() 978 fn = itm.fileName()
925 except AttributeError: 979 except AttributeError:
926 fn = itm.dirName() 980 fn = itm.dirName()
927 981
928 if self.__projectBrowserCCDialog is None: 982 if self.__projectBrowserCCDialog is None:
929 from RadonMetrics.CyclomaticComplexityDialog import ( 983 from RadonMetrics.CyclomaticComplexityDialog import (
930 CyclomaticComplexityDialog 984 CyclomaticComplexityDialog,
931 ) 985 )
986
932 self.__projectBrowserCCDialog = CyclomaticComplexityDialog( 987 self.__projectBrowserCCDialog = CyclomaticComplexityDialog(
933 self, isSingle=True) 988 self, isSingle=True
989 )
934 self.__projectBrowserCCDialog.show() 990 self.__projectBrowserCCDialog.show()
935 self.__projectBrowserCCDialog.start(fn) 991 self.__projectBrowserCCDialog.start(fn)
936 992
937 def __editorCyclomaticComplexity(self): 993 def __editorCyclomaticComplexity(self):
938 """ 994 """
939 Private slot to handle the cyclomatic complexity action of the editor 995 Private slot to handle the cyclomatic complexity action of the editor
940 show menu. 996 show menu.
941 """ 997 """
942 editor = ericApp().getObject("ViewManager").activeWindow() 998 editor = ericApp().getObject("ViewManager").activeWindow()
943 if ( 999 if (
944 editor is not None and 1000 editor is not None
945 editor.checkDirty() and 1001 and editor.checkDirty()
946 editor.getFileName() is not None 1002 and editor.getFileName() is not None
947 ): 1003 ):
948 if self.__editorCCDialog is None: 1004 if self.__editorCCDialog is None:
949 from RadonMetrics.CyclomaticComplexityDialog import ( 1005 from RadonMetrics.CyclomaticComplexityDialog import (
950 CyclomaticComplexityDialog 1006 CyclomaticComplexityDialog,
951 ) 1007 )
952 self.__editorCCDialog = CyclomaticComplexityDialog( 1008
953 self, isSingle=True) 1009 self.__editorCCDialog = CyclomaticComplexityDialog(self, isSingle=True)
954 self.__editorCCDialog.show() 1010 self.__editorCCDialog.show()
955 self.__editorCCDialog.start(editor.getFileName()) 1011 self.__editorCCDialog.start(editor.getFileName())
956 1012
957 ################################################################## 1013 ##################################################################
958 ## Radon info display 1014 ## Radon info display
959 ################################################################## 1015 ##################################################################
960 1016
961 def __showRadonVersion(self): 1017 def __showRadonVersion(self):
962 """ 1018 """
963 Private slot to show the version number of the used radon library. 1019 Private slot to show the version number of the used radon library.
964 """ 1020 """
965 from radon import __version__ 1021 from radon import __version__
1022
966 EricMessageBox.information( 1023 EricMessageBox.information(
967 None, 1024 None,
968 self.tr("Radon"), 1025 self.tr("Radon"),
969 self.tr( 1026 self.tr(
970 """<p><b>Radon Version {0}</b></p>""" 1027 """<p><b>Radon Version {0}</b></p>"""
976 """<li><b>Maintainability Index</b> (the one used in Visual""" 1033 """<li><b>Maintainability Index</b> (the one used in Visual"""
977 """ Studio)</li>""" 1034 """ Studio)</li>"""
978 """<li><b>McCabe's complexity</b>, i.e. cyclomatic""" 1035 """<li><b>McCabe's complexity</b>, i.e. cyclomatic"""
979 """ complexity</li>""" 1036 """ complexity</li>"""
980 """</ul></p>""" 1037 """</ul></p>"""
981 ).format(__version__)) 1038 ).format(__version__),
982 1039 )
1040
983 ################################################################## 1041 ##################################################################
984 ## Project handling methods 1042 ## Project handling methods
985 ################################################################## 1043 ##################################################################
986 1044
987 def __projectClosed(self): 1045 def __projectClosed(self):
988 """ 1046 """
989 Private slot to handle closing a project. 1047 Private slot to handle closing a project.
990 """ 1048 """
991 self.__projectCCDialog and self.__projectCCDialog.clear() 1049 self.__projectCCDialog and self.__projectCCDialog.clear()
995 1053
996 1054
997 def installDependencies(pipInstall): 1055 def installDependencies(pipInstall):
998 """ 1056 """
999 Function to install dependencies of this plug-in. 1057 Function to install dependencies of this plug-in.
1000 1058
1001 @param pipInstall function to be called with a list of package names. 1059 @param pipInstall function to be called with a list of package names.
1002 @type function 1060 @type function
1003 """ 1061 """
1004 try: 1062 try:
1005 from radon import __version__ as radon_version 1063 from radon import __version__ as radon_version
1006 import Globals 1064 import Globals
1065
1007 if Globals.versionToTuple(radon_version) < (4, 5, 0): 1066 if Globals.versionToTuple(radon_version) < (4, 5, 0):
1008 # force an upgrade 1067 # force an upgrade
1009 pipInstall(["radon>=4.5.0"]) 1068 pipInstall(["radon>=4.5.0"])
1010 except ImportError: 1069 except ImportError:
1011 pipInstall(["radon>=4.5.0"]) 1070 pipInstall(["radon>=4.5.0"])
1012 1071
1072
1013 # 1073 #
1014 # eflag: noqa = M801 1074 # eflag: noqa = M801

eric ide

mercurial