PyLint/PyLintConfigDialog.py

changeset 0
1c1ac27f3cf1
child 4
2285b6fbf267
equal deleted inserted replaced
-1:000000000000 0:1c1ac27f3cf1
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2005 - 2011 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing a dialog to configure the PyLint process
8 """
9
10 import os
11 import copy
12
13 from PyQt4.QtCore import pyqtSlot, QProcess, SIGNAL
14 from PyQt4.QtGui import QDialog, QFileDialog
15
16 from E5Gui.E5Application import e5App
17 from E5Gui import E5FileDialog, E5MessageBox
18 from E5Gui.E5Completers import E5FileCompleter
19
20 from .Ui_PyLintConfigDialog import Ui_PyLintConfigDialog
21
22 import Preferences
23 import Utilities
24
25
26 class PyLintConfigDialog(QDialog, Ui_PyLintConfigDialog):
27 """
28 Class implementing a dialog to configure the PyLint process
29 """
30 def __init__(self, ppath, exe, parms=None, parent=None):
31 """
32 Constructor
33
34 @param ppath project path (string or QString)
35 Used to set the default path for the rcfile selection dialog
36 @param exe name of the pylint executable (string)
37 @param parms parameters to set in the dialog
38 @param parent reference to the parent widget (QWidget)
39 """
40 super().__init__(parent)
41 self.setupUi(self)
42
43 self.pylintProc = None
44 self.lint = exe
45
46 self.__initializeDefaults()
47
48 # get a copy of the defaults to store the user settings
49 self.parameters = copy.deepcopy(self.defaults)
50
51 # combine it with the values of parms
52 if parms is not None:
53 for key, value in parms.items():
54 self.parameters[key] = parms[key]
55
56 self.configfileCompleter = E5FileCompleter(self.configfileEdit)
57 self.reportfileCompleter = E5FileCompleter(self.reportfileEdit)
58
59 # initialize general tab
60 self.configfileEdit.setText(self.parameters['configFile'])
61 self.txtOutputButton.setChecked(self.parameters['txtReport'])
62 self.htmlOutputButton.setChecked(self.parameters['htmlReport'])
63 self.dialogOutputButton.setChecked(self.parameters['dialogReport'])
64 self.reportfileEdit.setText(self.parameters['reportFile'])
65
66 # initialize checkers tab
67 self.basicCheckBox.setChecked(self.parameters['enableBasic'])
68 self.classesCheckBox.setChecked(self.parameters['enableClasses'])
69 self.designCheckBox.setChecked(self.parameters['enableDesign'])
70 self.exceptionsCheckBox.setChecked(self.parameters['enableExceptions'])
71 self.formatCheckBox.setChecked(self.parameters['enableFormat'])
72 self.importsCheckBox.setChecked(self.parameters['enableImports'])
73 self.metricsCheckBox.setChecked(self.parameters['enableMetrics'])
74 self.miscellaneousCheckBox.setChecked(self.parameters['enableMiscellaneous'])
75 self.newstyleCheckBox.setChecked(self.parameters['enableNewstyle'])
76 self.similaritiesCheckBox.setChecked(self.parameters['enableSimilarities'])
77 self.typecheckCheckBox.setChecked(self.parameters['enableTypecheck'])
78 self.variablesCheckBox.setChecked(self.parameters['enableVariables'])
79 self.rpythonCheckBox.setChecked(self.parameters['enableRPython'])
80
81 self.ppath = ppath
82
83 def __initializeDefaults(self):
84 """
85 Private method to set the default values.
86
87 These are needed later on to generate the commandline
88 parameters.
89 """
90 self.defaults = {
91 # general options
92 'configFile': '',
93 'reportFile': '',
94 'txtReport': False,
95 'htmlReport': True,
96 'dialogReport': False,
97
98 # enabled checkers
99 'enableBasic': False,
100 'enableClasses': False,
101 'enableDesign': False,
102 'enableExceptions': False,
103 'enableFormat': False,
104 'enableImports': False,
105 'enableMetrics': True,
106 'enableMiscellaneous': False,
107 'enableNewstyle': False,
108 'enableSimilarities': False,
109 'enableTypecheck': False,
110 'enableVariables': False,
111 'enableRPython': False,
112 }
113
114 def generateParameters(self):
115 """
116 Public method that generates the commandline parameters.
117
118 It generates a QStringList to be used
119 to set the QProcess arguments for the pylint call and
120 a list containing the non default parameters. The second
121 list can be passed back upon object generation to overwrite
122 the default settings.
123
124 <b>Note</b>: The arguments list contains the name of the pylint executable as
125 the first parameter.
126
127 @return a tuple of the commandline parameters and non default parameters
128 (list of strings, dictionary)
129 """
130 parms = {}
131 args = []
132
133 # 1. the program name
134 args.append(self.lint)
135
136 # 2. the commandline options
137 # 2.1 general options
138 if self.parameters['configFile'] != self.defaults['configFile']:
139 parms['configFile'] = self.parameters['configFile']
140 args.append('--rcfile={0}'.format(self.parameters['configFile']))
141 parms['txtReport'] = self.parameters['txtReport']
142 parms['htmlReport'] = self.parameters['htmlReport']
143 parms['dialogReport'] = self.parameters['dialogReport']
144 if self.parameters['htmlReport']:
145 args.append('--output-format=html')
146 elif self.parameters['dialogReport']:
147 args.append('--output-format=parseable')
148 args.append('--report=n')
149 else:
150 args.append('--output-format=text')
151 if self.parameters['reportFile'] != self.defaults['reportFile']:
152 parms['reportFile'] = self.parameters['reportFile']
153
154 # 2.2 checkers options
155 parms['enableBasic'] = self.parameters['enableBasic']
156 parms['enableClasses'] = self.parameters['enableClasses']
157 parms['enableDesign'] = self.parameters['enableDesign']
158 parms['enableExceptions'] = self.parameters['enableExceptions']
159 parms['enableFormat'] = self.parameters['enableFormat']
160 parms['enableImports'] = self.parameters['enableImports']
161 parms['enableMetrics'] = self.parameters['enableMetrics']
162 parms['enableMiscellaneous'] = self.parameters['enableMiscellaneous']
163 parms['enableNewstyle'] = self.parameters['enableNewstyle']
164 parms['enableSimilarities'] = self.parameters['enableSimilarities']
165 parms['enableTypecheck'] = self.parameters['enableTypecheck']
166 parms['enableVariables'] = self.parameters['enableVariables']
167 parms['enableRPython'] = self.parameters['enableRPython']
168
169 checkers = []
170 if self.parameters['enableBasic']:
171 checkers.append('basic')
172 if self.parameters['enableClasses']:
173 checkers.append('classes')
174 if self.parameters['enableDesign']:
175 checkers.append('design')
176 if self.parameters['enableExceptions']:
177 checkers.append('exceptions')
178 if self.parameters['enableFormat']:
179 checkers.append('format')
180 if self.parameters['enableImports']:
181 checkers.append('imports')
182 if self.parameters['enableMetrics']:
183 checkers.append('metrics')
184 if self.parameters['enableMiscellaneous']:
185 checkers.append('miscellaneous')
186 if self.parameters['enableNewstyle']:
187 checkers.append('newstyle')
188 if self.parameters['enableSimilarities']:
189 checkers.append('similarities')
190 if self.parameters['enableTypecheck']:
191 checkers.append('typecheck')
192 if self.parameters['enableVariables']:
193 checkers.append('variables')
194 if self.parameters['enableRPython']:
195 checkers.append('rpython')
196 args.append('--enable={0}'.format(','.join(checkers)))
197
198 return (args, parms)
199
200 @pyqtSlot()
201 def on_configfileButton_clicked(self):
202 """
203 Private slot to select the configuration file.
204
205 It displays a file selection dialog to select the configuration file.
206 """
207 startWith = self.configfileEdit.text()
208 if startWith == "":
209 startWith = self.ppath
210 config = E5FileDialog.getOpenFileName(
211 self,
212 self.trUtf8("Select configuration file"),
213 startWith,
214 self.trUtf8("Configuration Files (*.cfg *.cnf *.rc);;All Files (*)"))
215 if config:
216 self.configfileEdit.setText(Utilities.toNativeSeparators(config))
217
218 @pyqtSlot()
219 def on_reportfileButton_clicked(self):
220 """
221 Private slot to select the report file.
222
223 It displays a file selection dialog to select the report file.
224 """
225 report = E5FileDialog.getSaveFileName(
226 self,
227 self.trUtf8("Select report file"),
228 self.reportfileEdit.text(),
229 None,
230 None,
231 QFileDialog.Options(QFileDialog.DontConfirmOverwrite))
232
233 if report:
234 self.reportfileEdit.setText(Utilities.toNativeSeparators(report))
235
236 def accept(self):
237 """
238 Protected slot called by the Ok button.
239
240 It saves the values in the parameters dictionary.
241 """
242 # get data of general tab
243 self.parameters['configFile'] = self.configfileEdit.text()
244 self.parameters['txtReport'] = self.txtOutputButton.isChecked()
245 self.parameters['htmlReport'] = self.htmlOutputButton.isChecked()
246 self.parameters['dialogReport'] = self.dialogOutputButton.isChecked()
247 self.parameters['reportFile'] = self.reportfileEdit.text()
248
249 # get data of checkers tab
250 self.parameters['enableBasic'] = self.basicCheckBox.isChecked()
251 self.parameters['enableClasses'] = self.classesCheckBox.isChecked()
252 self.parameters['enableDesign'] = self.designCheckBox.isChecked()
253 self.parameters['enableExceptions'] = self.exceptionsCheckBox.isChecked()
254 self.parameters['enableFormat'] = self.formatCheckBox.isChecked()
255 self.parameters['enableImports'] = self.importsCheckBox.isChecked()
256 self.parameters['enableMetrics'] = self.metricsCheckBox.isChecked()
257 self.parameters['enableMiscellaneous'] = self.miscellaneousCheckBox.isChecked()
258 self.parameters['enableNewstyle'] = self.newstyleCheckBox.isChecked()
259 self.parameters['enableSimilarities'] = self.similaritiesCheckBox.isChecked()
260 self.parameters['enableTypecheck'] = self.typecheckCheckBox.isChecked()
261 self.parameters['enableVariables'] = self.variablesCheckBox.isChecked()
262 self.parameters['enableRPython'] = self.rpythonCheckBox.isChecked()
263
264 # call the accept slot of the base class
265 super().accept()
266
267 ############################################################################
268 ## Methods below are needed to generate a configuration file template
269 ############################################################################
270
271 @pyqtSlot()
272 def on_configButton_clicked(self):
273 """
274 Public slot to handle the generation of a sample configuration.
275 """
276 self.buf = ""
277 self.pylintProc = QProcess()
278 args = []
279
280 self.__ioEncoding = Preferences.getSystem("IOEncoding")
281
282 args.append('--generate-rcfile')
283
284 self.pylintProc.readyReadStandardOutput.connect(self.__readStdout)
285 self.pylintProc.readyReadStandardError.connect(self.__readStderr)
286 self.pylintProc.finished.connect(self.__createConfigDone)
287
288 self.pylintProc.start(self.lint, args)
289 procStarted = self.pylintProc.waitForStarted()
290 if procStarted:
291 e5App().getObject("ViewManager").enableEditorsCheckFocusIn(False)
292 else:
293 E5MessageBox.critical(self,
294 self.trUtf8('Process Generation Error'),
295 self.trUtf8(
296 'Could not start {0}.<br>'
297 'Ensure that it is in the search path.'
298 ).format(self.lint))
299
300 def __createConfigDone(self, exitCode, exitStatus):
301 """
302 Private slot to handle the the finished signal of the pylint process.
303
304 @param exitCode exit code of the process (integer)
305 @param exitStatus exit status of the process (QProcess.ExitStatus)
306 """
307 vm = e5App().getObject("ViewManager")
308 vm.enableEditorsCheckFocusIn(True)
309 if exitStatus == QProcess.NormalExit and exitCode == 0:
310 vm.newEditor()
311 aw = vm.activeWindow()
312 aw.insertAt(self.buf, 0, 0)
313 aw.setLanguage('dummy.rc')
314 self.reject()
315
316 def __readStdout(self):
317 """
318 Private slot to handle the readyReadStandardOutput signal of the pylint process.
319 """
320 if self.pylintProc is None:
321 return
322 self.pylintProc.setReadChannel(QProcess.StandardOutput)
323
324 while self.pylintProc and self.pylintProc.canReadLine():
325 line = str(self.pylintProc.readLine(), self.__ioEncoding, "replace").rstrip()
326 self.buf += line + os.linesep
327
328 def __readStderr(self):
329 """
330 Private slot to handle the readyReadStandardError signal of the pylint process.
331 """
332 if self.pylintProc is None:
333 return
334 self.pylintProc.setReadChannel(QProcess.StandardError)
335 while self.pylintProc and self.pylintProc.canReadLine():
336 s = 'pylint: ' + str(
337 self.pylintProc.readLine(), self.__ioEncoding, "replace")
338 e5App().getObject("UserInterface").emit(SIGNAL('appendStderr'), s)

eric ide

mercurial