Plugins/CheckerPlugins/Pep8/Pep8Dialog.py

changeset 849
996367a89673
parent 847
cc18fbcde9fc
child 853
ec7dd115e26b
equal deleted inserted replaced
848:e2fad77b41ba 849:996367a89673
19 from E5Gui.E5Application import e5App 19 from E5Gui.E5Application import e5App
20 20
21 from .Pep8Checker import Pep8Checker, Pep8Py2Checker 21 from .Pep8Checker import Pep8Checker, Pep8Py2Checker
22 from .Pep8CodeSelectionDialog import Pep8CodeSelectionDialog 22 from .Pep8CodeSelectionDialog import Pep8CodeSelectionDialog
23 from .Pep8StatisticsDialog import Pep8StatisticsDialog 23 from .Pep8StatisticsDialog import Pep8StatisticsDialog
24 from .Pep8Fixer import Pep8Fixer
24 25
25 from .Ui_Pep8Dialog import Ui_Pep8Dialog 26 from .Ui_Pep8Dialog import Ui_Pep8Dialog
26 27
27 import UI.PixmapCache 28 import UI.PixmapCache
28 import Preferences 29 import Preferences
78 UI.PixmapCache.getIcon("clearLeft.png")) 79 UI.PixmapCache.getIcon("clearLeft.png"))
79 self.clearButtonExcludeMessages.setIcon( 80 self.clearButtonExcludeMessages.setIcon(
80 UI.PixmapCache.getIcon("clearLeft.png")) 81 UI.PixmapCache.getIcon("clearLeft.png"))
81 self.clearButtonIncludeMessages.setIcon( 82 self.clearButtonIncludeMessages.setIcon(
82 UI.PixmapCache.getIcon("clearLeft.png")) 83 UI.PixmapCache.getIcon("clearLeft.png"))
84 self.clearButtonFixIssues.setIcon(
85 UI.PixmapCache.getIcon("clearLeft.png"))
83 self.on_loadDefaultButton_clicked() 86 self.on_loadDefaultButton_clicked()
84 87
85 def __resort(self): 88 def __resort(self):
86 """ 89 """
87 Private method to resort the tree. 90 Private method to resort the tree.
160 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) 163 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True)
161 self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) 164 self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False)
162 self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) 165 self.buttonBox.button(QDialogButtonBox.Close).setDefault(True)
163 166
164 self.__data = self.__project.getData("CHECKERSPARMS", "Pep8Checker") 167 self.__data = self.__project.getData("CHECKERSPARMS", "Pep8Checker")
165 if self.__data is None or "ExcludeFiles" not in self.__data: 168 if self.__data is None or \
169 "ExcludeFiles" not in self.__data or \
170 len(self.__data) != 6:
166 # initialize the data structure 171 # initialize the data structure
167 self.__data = { 172 self.__data = {
168 "ExcludeFiles" : "", 173 "ExcludeFiles" : "",
169 "ExcludeMessages" : pep8.DEFAULT_IGNORE, 174 "ExcludeMessages" : pep8.DEFAULT_IGNORE,
170 "IncludeMessages" : "", 175 "IncludeMessages" : "",
171 "RepeatMessages" : False, 176 "RepeatMessages" : False,
177 "FixCodes" : "",
178 "FixIssues" : False,
172 } 179 }
173 self.excludeFilesEdit.setText(self.__data["ExcludeFiles"]) 180 self.excludeFilesEdit.setText(self.__data["ExcludeFiles"])
174 self.excludeMessagesEdit.setText(self.__data["ExcludeMessages"]) 181 self.excludeMessagesEdit.setText(self.__data["ExcludeMessages"])
175 self.includeMessagesEdit.setText(self.__data["IncludeMessages"]) 182 self.includeMessagesEdit.setText(self.__data["IncludeMessages"])
176 self.repeatCheckBox.setChecked(self.__data["RepeatMessages"]) 183 self.repeatCheckBox.setChecked(self.__data["RepeatMessages"])
177 184 self.fixIssuesEdit.setText(self.__data["FixCodes"])
178 def start(self, fn, codestring = "", save = False, repeat = None): 185 self.fixIssuesCheckBox.setChecked(self.__data["FixIssues"])
186
187 def start(self, fn, save = False, repeat = None):
179 """ 188 """
180 Public slot to start the PEP 8 check. 189 Public slot to start the PEP 8 check.
181 190
182 @param fn file or list of files or directory to be checked 191 @param fn file or list of files or directory to be checked
183 (string or list of strings) 192 (string or list of strings)
184 @keyparam codestring string containing the code to be checked (string).
185 If this is given, file must be a single file name.
186 @keyparam save flag indicating to save the given 193 @keyparam save flag indicating to save the given
187 file/file list/directory (boolean) 194 file/file list/directory (boolean)
188 @keyparam repeat state of the repeat check box if it is not None 195 @keyparam repeat state of the repeat check box if it is not None
189 (None or boolean) 196 (None or boolean)
190 """ 197 """
232 tuple(Preferences.getPython("Python3Extensions")))] 239 tuple(Preferences.getPython("Python3Extensions")))]
233 py2files = [f for f in files \ 240 py2files = [f for f in files \
234 if f.endswith( 241 if f.endswith(
235 tuple(Preferences.getPython("PythonExtensions")))] 242 tuple(Preferences.getPython("PythonExtensions")))]
236 243
237 if (codestring and len(py3files) == 1) or \ 244 if len(py3files) + len(py2files) > 0:
238 (codestring and len(py2files) == 1) or \
239 (not codestring and len(py3files) + len(py2files) > 0):
240 self.checkProgress.setMaximum(len(py3files) + len(py2files)) 245 self.checkProgress.setMaximum(len(py3files) + len(py2files))
241 QApplication.processEvents() 246 QApplication.processEvents()
242 247
243 # extract the configuration values 248 # extract the configuration values
244 excludeMessages = self.excludeMessagesEdit.text() 249 excludeMessages = self.excludeMessagesEdit.text()
245 includeMessages = self.includeMessagesEdit.text() 250 includeMessages = self.includeMessagesEdit.text()
246 repeatMessages = self.repeatCheckBox.isChecked() 251 repeatMessages = self.repeatCheckBox.isChecked()
252 fixCodes = self.fixIssuesEdit.text()
253 fixIssues = self.fixIssuesCheckBox.isChecked() and repeatMessages
247 254
248 # now go through all the files 255 # now go through all the files
249 progress = 0 256 progress = 0
250 for file in py3files + py2files: 257 for file in py3files + py2files:
251 self.checkProgress.setValue(progress) 258 self.checkProgress.setValue(progress)
255 self.__resort() 262 self.__resort()
256 return 263 return
257 264
258 self.__lastFileItem = None 265 self.__lastFileItem = None
259 266
260 if codestring: 267 try:
261 source = codestring.splitlines(True) 268 source, encoding = Utilities.readEncodedFile(file)
262 else: 269 source = source.splitlines(True)
263 try: 270 except (UnicodeError, IOError) as msg:
264 source = Utilities.readEncodedFile(file)[0] 271 self.noResults = False
265 # convert eols 272 self.__createResultItem(file, "1", "1",
266 source = Utilities.convertLineEnds(source, "\n") 273 self.trUtf8("Error: {0}").format(str(msg))\
267 source = source.splitlines(True) 274 .rstrip()[1:-1])
268 except (UnicodeError, IOError) as msg: 275 progress += 1
269 self.noResults = False 276 continue
270 self.__createResultItem(file, "1", "1",
271 self.trUtf8("Error: {0}").format(str(msg))\
272 .rstrip()[1:-1])
273 progress += 1
274 continue
275 277
276 flags = Utilities.extractFlags(source) 278 flags = Utilities.extractFlags(source)
277 ext = os.path.splitext(file)[1] 279 ext = os.path.splitext(file)[1]
280 if fixIssues:
281 fixer = Pep8Fixer(self.__project, file, source,
282 fixCodes, True) # always fix in place
283 else:
284 fixer = None
278 if ("FileType" in flags and 285 if ("FileType" in flags and
279 flags["FileType"] in ["Python", "Python2"]) or \ 286 flags["FileType"] in ["Python", "Python2"]) or \
280 file in py2files or \ 287 file in py2files or \
281 (ext in [".py", ".pyw"] and \ 288 (ext in [".py", ".pyw"] and \
282 Preferences.getProject("DeterminePyFromProject") and \ 289 Preferences.getProject("DeterminePyFromProject") and \
298 for message in checker.messages: 305 for message in checker.messages:
299 fname, lineno, position, text = message 306 fname, lineno, position, text = message
300 if not source[lineno - 1].strip()\ 307 if not source[lineno - 1].strip()\
301 .endswith("__IGNORE_WARNING__"): 308 .endswith("__IGNORE_WARNING__"):
302 self.noResults = False 309 self.noResults = False
310 if fixer:
311 fixed, msg = fixer.fixIssue(lineno, position, text)
312 if fixed:
313 text += "\n" + \
314 self.trUtf8("Fix: {0}").format(msg)
303 self.__createResultItem( 315 self.__createResultItem(
304 fname, lineno, position, text) 316 fname, lineno, position, text)
317 fixer and fixer.saveFile(encoding)
305 self.__updateStatistics(checker.statistics) 318 self.__updateStatistics(checker.statistics)
306 progress += 1 319 progress += 1
307 self.checkProgress.setValue(progress) 320 self.checkProgress.setValue(progress)
308 QApplication.processEvents() 321 QApplication.processEvents()
309 self.__resort() 322 self.__resort()
343 data = { 356 data = {
344 "ExcludeFiles" : self.excludeFilesEdit.text(), 357 "ExcludeFiles" : self.excludeFilesEdit.text(),
345 "ExcludeMessages" : self.excludeMessagesEdit.text(), 358 "ExcludeMessages" : self.excludeMessagesEdit.text(),
346 "IncludeMessages" : self.includeMessagesEdit.text(), 359 "IncludeMessages" : self.includeMessagesEdit.text(),
347 "RepeatMessages" : self.repeatCheckBox.isChecked(), 360 "RepeatMessages" : self.repeatCheckBox.isChecked(),
361 "FixCodes" : self.fixIssuesEdit.text(),
362 "FixIssues" : self.fixIssuesCheckBox.isChecked(),
348 } 363 }
349 if data != self.__data: 364 if data != self.__data:
350 self.__data = data 365 self.__data = data
351 self.__project.setData("CHECKERSPARMS", "Pep8Checker", 366 self.__project.setData("CHECKERSPARMS", "Pep8Checker",
352 self.__data) 367 self.__data)
360 def on_excludeMessagesSelectButton_clicked(self): 375 def on_excludeMessagesSelectButton_clicked(self):
361 """ 376 """
362 Private slot to select the message codes to be excluded via a 377 Private slot to select the message codes to be excluded via a
363 selection dialog. 378 selection dialog.
364 """ 379 """
365 dlg = Pep8CodeSelectionDialog(self.excludeMessagesEdit.text(), self) 380 dlg = Pep8CodeSelectionDialog(
381 self.excludeMessagesEdit.text(), False, self)
366 if dlg.exec_() == QDialog.Accepted: 382 if dlg.exec_() == QDialog.Accepted:
367 self.excludeMessagesEdit.setText(dlg.getSelectedCodes()) 383 self.excludeMessagesEdit.setText(dlg.getSelectedCodes())
368 384
369 @pyqtSlot() 385 @pyqtSlot()
370 def on_includeMessagesSelectButton_clicked(self): 386 def on_includeMessagesSelectButton_clicked(self):
371 """ 387 """
372 Private slot to select the message codes to be included via a 388 Private slot to select the message codes to be included via a
373 selection dialog. 389 selection dialog.
374 """ 390 """
375 dlg = Pep8CodeSelectionDialog(self.includeMessagesEdit.text(), self) 391 dlg = Pep8CodeSelectionDialog(
392 self.includeMessagesEdit.text(), False, self)
376 if dlg.exec_() == QDialog.Accepted: 393 if dlg.exec_() == QDialog.Accepted:
377 self.includeMessagesEdit.setText(dlg.getSelectedCodes()) 394 self.includeMessagesEdit.setText(dlg.getSelectedCodes())
395
396 @pyqtSlot()
397 def on_fixIssuesSelectButton_clicked(self):
398 """
399 Private slot to select the issue codes to be fixed via a
400 selection dialog.
401 """
402 dlg = Pep8CodeSelectionDialog(
403 self.fixIssuesEdit.text(), True, self)
404 if dlg.exec_() == QDialog.Accepted:
405 self.fixIssuesEdit.setText(dlg.getSelectedCodes())
378 406
379 @pyqtSlot(QTreeWidgetItem, int) 407 @pyqtSlot(QTreeWidgetItem, int)
380 def on_resultList_itemActivated(self, item, column): 408 def on_resultList_itemActivated(self, item, column):
381 """ 409 """
382 Private slot to handle the activation of an item. 410 Private slot to handle the activation of an item.
456 "PEP8/ExcludeMessages", pep8.DEFAULT_IGNORE)) 484 "PEP8/ExcludeMessages", pep8.DEFAULT_IGNORE))
457 self.includeMessagesEdit.setText(Preferences.Prefs.settings.value( 485 self.includeMessagesEdit.setText(Preferences.Prefs.settings.value(
458 "PEP8/IncludeMessages")) 486 "PEP8/IncludeMessages"))
459 ## self.repeatCheckBox.setChecked(Preferences.toBool( 487 ## self.repeatCheckBox.setChecked(Preferences.toBool(
460 ## Preferences.Prefs.settings.value("PEP8/RepeatMessages"))) 488 ## Preferences.Prefs.settings.value("PEP8/RepeatMessages")))
489 self.fixIssuesEdit.setText(Preferences.Prefs.settings.value(
490 "PEP8/FixCodes"))
491 self.fixIssuesCheckBox.setChecked(Preferences.toBool(
492 Preferences.Prefs.settings.value("PEP8/FixIssues")))
461 493
462 @pyqtSlot() 494 @pyqtSlot()
463 def on_storeDefaultButton_clicked(self): 495 def on_storeDefaultButton_clicked(self):
464 """ 496 """
465 Private slot to store the current configuration values as 497 Private slot to store the current configuration values as
471 self.excludeMessagesEdit.text()) 503 self.excludeMessagesEdit.text())
472 Preferences.Prefs.settings.setValue("PEP8/IncludeMessages", 504 Preferences.Prefs.settings.setValue("PEP8/IncludeMessages",
473 self.includeMessagesEdit.text()) 505 self.includeMessagesEdit.text())
474 ## Preferences.Prefs.settings.setValue("PEP8/RepeatMessages", 506 ## Preferences.Prefs.settings.setValue("PEP8/RepeatMessages",
475 ## self.repeatCheckBox.isChecked()) 507 ## self.repeatCheckBox.isChecked())
508 Preferences.Prefs.settings.setValue("PEP8/FixCodes",
509 self.fixIssuesEdit.text())
510 Preferences.Prefs.settings.setValue("PEP8/FixIssues",
511 self.fixIssuesCheckBox.isChecked())
476 512
477 @pyqtSlot(QAbstractButton) 513 @pyqtSlot(QAbstractButton)
478 def on_buttonBox_clicked(self, button): 514 def on_buttonBox_clicked(self, button):
479 """ 515 """
480 Private slot called by a button of the button box clicked. 516 Private slot called by a button of the button box clicked.

eric ide

mercurial