RadonMetrics/MaintainabilityIndexDialog.py

changeset 9
7f6e04213998
parent 8
d02708288a22
child 10
8b1920a22df3
equal deleted inserted replaced
8:d02708288a22 9:7f6e04213998
51 self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) 51 self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True)
52 52
53 self.resultList.headerItem().setText(self.resultList.columnCount(), "") 53 self.resultList.headerItem().setText(self.resultList.columnCount(), "")
54 54
55 self.radonService = radonService 55 self.radonService = radonService
56 self.radonService.metricsDone.connect(self.__processResult) 56 self.radonService.maintainabilityIndexDone.connect(
57 self.radonService.metricsError.connect(self.__processError) 57 self.__processResult)
58 self.radonService.error.connect(self.__processError)
58 self.radonService.batchFinished.connect(self.__batchFinished) 59 self.radonService.batchFinished.connect(self.__batchFinished)
59 60
60 self.cancelled = False 61 self.cancelled = False
61 62
62 self.__project = e5App().getObject("Project") 63 self.__project = e5App().getObject("Project")
63 self.__locale = QLocale() 64 self.__locale = QLocale()
65 self.__finished = True
64 66
65 self.__fileList = [] 67 self.__fileList = []
66 self.filterFrame.setVisible(False) 68 self.filterFrame.setVisible(False)
67 69
68 self.explanationLabel.setText(self.tr( 70 self.explanationLabel.setText(self.tr(
88 @param filename name of the file 90 @param filename name of the file
89 @type str 91 @type str
90 @param values values to be displayed 92 @param values values to be displayed
91 @type dict 93 @type dict
92 """ 94 """
95 # TODO: colorize the rank column according to rank (green, orange, red)
93 data = [self.__project.getRelativePath(filename)] 96 data = [self.__project.getRelativePath(filename)]
94 try: 97 try:
95 data.append(self.__locale.toString(float(values["mi"]), "f", 2)) 98 data.append(self.__locale.toString(float(values["mi"]), "f", 2))
96 except ValueError: 99 except ValueError:
97 data.append(values["mi"]) 100 data.append(values["mi"])
98 data.append(values["rank"]) 101 data.append(values["rank"])
99 itm = QTreeWidgetItem(self.resultList, data) 102 itm = QTreeWidgetItem(self.resultList, data)
100 itm.setTextAlignment(1, Qt.Alignment(Qt.AlignRight)) 103 itm.setTextAlignment(1, Qt.Alignment(Qt.AlignRight))
101 itm.setTextAlignment(2, Qt.Alignment(Qt.AlignHCenter)) 104 itm.setTextAlignment(2, Qt.Alignment(Qt.AlignHCenter))
105
106 if values["rank"] in ["A", "B", "C"]:
107 self.__summary[values["rank"]] += 1
102 108
103 def __createErrorItem(self, filename, message): 109 def __createErrorItem(self, filename, message):
104 """ 110 """
105 Private slot to create a new error item in the result list. 111 Private slot to create a new error item in the result list.
106 112
170 # check for missing files 176 # check for missing files
171 for f in self.files[:]: 177 for f in self.files[:]:
172 if not os.path.exists(f): 178 if not os.path.exists(f):
173 self.files.remove(f) 179 self.files.remove(f)
174 180
175 self.__summary = {"files": 0} 181 self.__summary = {
176 for key in ['loc', 'sloc', 'lloc', 'comments', 'multi', 'blank']: 182 "A": 0,
177 self.__summary[key] = 0 183 "B": 0,
184 "C": 0,
185 }
178 186
179 if len(self.files) > 0: 187 if len(self.files) > 0:
180 # disable updates of the list for speed 188 # disable updates of the list for speed
181 self.resultList.setUpdatesEnabled(False) 189 self.resultList.setUpdatesEnabled(False)
182 self.resultList.setSortingEnabled(False) 190 self.resultList.setSortingEnabled(False)
192 self.__batch = False 200 self.__batch = False
193 self.maintainabilityIndex() 201 self.maintainabilityIndex()
194 else: 202 else:
195 self.__batch = True 203 self.__batch = True
196 self.maintainabilityIndexBatch() 204 self.maintainabilityIndexBatch()
205
206 def maintainabilityIndex(self, codestring=''):
207 """
208 Public method to start a maintainability index calculation for one
209 Python file.
210
211 The results are reported to the __processResult slot.
212
213 @keyparam codestring optional sourcestring
214 @type str
215 """
216 if not self.files:
217 self.checkProgressLabel.setPath("")
218 self.checkProgress.setMaximum(1)
219 self.checkProgress.setValue(1)
220 self.__finish()
221 return
222
223 self.filename = self.files.pop(0)
224 self.checkProgress.setValue(self.progress)
225 self.checkProgressLabel.setPath(self.filename)
226 QApplication.processEvents()
227
228 if self.cancelled:
229 return
230
231 try:
232 self.source = Utilities.readEncodedFile(self.filename)[0]
233 self.source = Utilities.normalizeCode(self.source)
234 except (UnicodeError, IOError) as msg:
235 self.__createErrorItem(self.filename, str(msg).rstrip())
236 self.progress += 1
237 # Continue with next file
238 self.rawMetrics()
239 return
240
241 self.__finished = False
242 self.radonService.maintainabilityIndex(
243 None, self.filename, self.source)
244
245 def maintainabilityIndexBatch(self):
246 """
247 Public method to start a maintainability index calculation batch job.
248
249 The results are reported to the __processResult slot.
250 """
251 self.__lastFileItem = None
252
253 self.checkProgressLabel.setPath(self.tr("Preparing files..."))
254 progress = 0
255
256 argumentsList = []
257 for filename in self.files:
258 progress += 1
259 self.checkProgress.setValue(progress)
260 QApplication.processEvents()
261
262 try:
263 source = Utilities.readEncodedFile(filename)[0]
264 source = Utilities.normalizeCode(source)
265 except (UnicodeError, IOError) as msg:
266 self.__createErrorItem(filename, str(msg).rstrip())
267 continue
268
269 argumentsList.append((filename, source))
270
271 # reset the progress bar to the checked files
272 self.checkProgress.setValue(self.progress)
273 QApplication.processEvents()
274
275 self.__finished = False
276 self.radonService.maintainabilityIndexBatch(argumentsList)
277
278 def __batchFinished(self):
279 """
280 Private slot handling the completion of a batch job.
281 """
282 self.checkProgressLabel.setPath("")
283 self.checkProgress.setMaximum(1)
284 self.checkProgress.setValue(1)
285 self.__finish()
286
287 def __processError(self, fn, msg):
288 """
289 Private slot to process an error indication from the service.
290
291 @param fn filename of the file
292 @type str
293 @param msg error message
294 @type str
295 """
296 self.__createErrorItem(fn, msg)
297
298 def __processResult(self, fn, result):
299 """
300 Private slot called after perfoming a maintainability index calculation
301 on one file.
302
303 @param fn filename of the file
304 @type str
305 @param result result dict
306 @type dict
307 """
308 if self.__finished:
309 return
310
311 # Check if it's the requested file, otherwise ignore signal if not
312 # in batch mode
313 if not self.__batch and fn != self.filename:
314 return
315
316 if "error" in result:
317 self.__createErrorItem(fn, result["error"])
318 else:
319 self.__createResultItem(fn, result)
320
321 self.progress += 1
322
323 self.checkProgress.setValue(self.progress)
324 self.checkProgressLabel.setPath(fn)
325 QApplication.processEvents()
326
327 if not self.__batch:
328 self.maintainabilityIndex()
329
330 def __finish(self):
331 """
332 Private slot called when the action or the user pressed the button.
333 """
334 if not self.__finished:
335 self.__finished = True
336
337 # reenable updates of the list
338 self.resultList.setSortingEnabled(True)
339 self.resultList.setUpdatesEnabled(True)
340
341 self.cancelled = True
342 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True)
343 self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False)
344 self.buttonBox.button(QDialogButtonBox.Close).setDefault(True)
345
346 self.resultList.header().resizeSections(
347 QHeaderView.ResizeToContents)
348 self.resultList.header().setStretchLastSection(True)
349 if qVersion() >= "5.0.0":
350 self.resultList.header().setSectionResizeMode(
351 QHeaderView.Interactive)
352 else:
353 self.resultList.header().setResizeMode(QHeaderView.Interactive)
354
355 self.summaryLabel.setText(self.tr(
356 "<table>"
357 "<tr><td colspan=2><b>Summary:</b></td></tr>"
358 "<tr><td><b>A</b></td><td>{0} files</td></tr>"
359 "<tr><td><b>B</b></td><td>{1} files</td></tr>"
360 "<tr><td><b>C</b></td><td>{2} files</td></tr>"
361 "</table>"
362 ).format(self.__summary["A"],
363 self.__summary["B"],
364 self.__summary["C"])
365 )
366
367 self.checkProgress.setVisible(False)
368 self.checkProgressLabel.setVisible(False)
369
370 @pyqtSlot(QAbstractButton)
371 def on_buttonBox_clicked(self, button):
372 """
373 Private slot called by a button of the button box clicked.
374
375 @param button button that was clicked
376 @type QAbstractButton
377 """
378 if button == self.buttonBox.button(QDialogButtonBox.Close):
379 self.close()
380 elif button == self.buttonBox.button(QDialogButtonBox.Cancel):
381 if self.__batch:
382 self.radonService.cancelMaintainabilityIndexBatch()
383 QTimer.singleShot(1000, self.__finish)
384 else:
385 self.__finish()
386
387 @pyqtSlot()
388 def on_startButton_clicked(self):
389 """
390 Private slot to start a maintainability index run.
391 """
392 fileList = self.__fileList[:]
393
394 filterString = self.excludeFilesEdit.text()
395 if "ExcludeFiles" not in self.__data or \
396 filterString != self.__data["ExcludeFiles"]:
397 self.__data["ExcludeFiles"] = filterString
398 self.__project.setData(
399 "OTHERTOOLSPARMS", "RadonCodeMetrics", self.__data)
400 filterList = [f.strip() for f in filterString.split(",")
401 if f.strip()]
402 if filterList:
403 for filter in filterList:
404 fileList = \
405 [f for f in fileList if not fnmatch.fnmatch(f, filter)]
406
407 self.resultList.clear()
408 self.cancelled = False
409 self.start(fileList)

eric ide

mercurial