|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2004 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing a dialog to enter the parameters for eric6_api. |
|
8 """ |
|
9 |
|
10 from __future__ import unicode_literals |
|
11 |
|
12 import sys |
|
13 import os |
|
14 import copy |
|
15 |
|
16 from PyQt5.QtCore import pyqtSlot, Qt |
|
17 from PyQt5.QtWidgets import QDialog, QDialogButtonBox |
|
18 |
|
19 from E5Gui.E5PathPicker import E5PathPickerModes |
|
20 |
|
21 from .Ui_EricapiConfigDialog import Ui_EricapiConfigDialog |
|
22 import Utilities |
|
23 import DocumentationTools |
|
24 |
|
25 from eric6config import getConfig |
|
26 |
|
27 |
|
28 class EricapiConfigDialog(QDialog, Ui_EricapiConfigDialog): |
|
29 """ |
|
30 Class implementing a dialog to enter the parameters for eric6_api. |
|
31 """ |
|
32 def __init__(self, project, parms=None, parent=None): |
|
33 """ |
|
34 Constructor |
|
35 |
|
36 @param project reference to the project object (Project.Project) |
|
37 @param parms parameters to set in the dialog |
|
38 @param parent parent widget of this dialog |
|
39 """ |
|
40 super(EricapiConfigDialog, self).__init__(parent) |
|
41 self.setupUi(self) |
|
42 |
|
43 self.outputFilePicker.setMode(E5PathPickerModes.SaveFileMode) |
|
44 self.outputFilePicker.setDefaultDirectory(project.getProjectPath()) |
|
45 self.outputFilePicker.setFilters(self.tr( |
|
46 "API files (*.api);;All files (*)")) |
|
47 |
|
48 self.ignoreDirPicker.setMode(E5PathPickerModes.DirectoryMode) |
|
49 self.ignoreDirPicker.setDefaultDirectory(project.getProjectPath()) |
|
50 |
|
51 self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) |
|
52 for language in sorted( |
|
53 DocumentationTools.supportedExtensionsDictForApis.keys()): |
|
54 self.languagesList.addItem(language) |
|
55 |
|
56 self.ppath = project.getProjectPath() |
|
57 self.project = project |
|
58 |
|
59 self.__initializeDefaults() |
|
60 |
|
61 # get a copy of the defaults to store the user settings |
|
62 self.parameters = copy.deepcopy(self.defaults) |
|
63 |
|
64 # combine it with the values of parms |
|
65 if parms is not None: |
|
66 self.parameters.update(parms) |
|
67 self.parameters['outputFile'] = \ |
|
68 Utilities.toNativeSeparators(self.parameters['outputFile']) |
|
69 |
|
70 self.recursionCheckBox.setChecked(self.parameters['useRecursion']) |
|
71 self.includePrivateCheckBox.setChecked( |
|
72 self.parameters['includePrivate']) |
|
73 self.outputFilePicker.setText(self.parameters['outputFile']) |
|
74 self.baseEdit.setText(self.parameters['basePackage']) |
|
75 self.ignoreDirsList.clear() |
|
76 for d in self.parameters['ignoreDirectories']: |
|
77 self.ignoreDirsList.addItem(d) |
|
78 self.sourceExtEdit.setText( |
|
79 ", ".join(self.parameters['sourceExtensions'])) |
|
80 self.excludeFilesEdit.setText( |
|
81 ", ".join(self.parameters['ignoreFilePatterns'])) |
|
82 for language in self.parameters['languages']: |
|
83 if language == "Python": |
|
84 # convert Python to the more specific Python2 |
|
85 language = "Python2" |
|
86 items = self.languagesList.findItems( |
|
87 language, Qt.MatchFlags(Qt.MatchExactly)) |
|
88 items and items[0].setSelected(True) |
|
89 |
|
90 def __initializeDefaults(self): |
|
91 """ |
|
92 Private method to set the default values. |
|
93 |
|
94 These are needed later on to generate the commandline |
|
95 parameters. |
|
96 """ |
|
97 self.defaults = { |
|
98 'useRecursion': False, |
|
99 'includePrivate': False, |
|
100 'outputFile': '', |
|
101 'basePackage': '', |
|
102 'ignoreDirectories': [], |
|
103 'ignoreFilePatterns': [], |
|
104 'sourceExtensions': [], |
|
105 } |
|
106 |
|
107 lang = self.project.getProjectLanguage() |
|
108 if lang in DocumentationTools.supportedExtensionsDictForApis: |
|
109 self.defaults['languages'] = [lang] |
|
110 else: |
|
111 self.defaults['languages'] = ["Python3"] |
|
112 |
|
113 def generateParameters(self): |
|
114 """ |
|
115 Public method that generates the commandline parameters. |
|
116 |
|
117 It generates a list of strings to be used |
|
118 to set the QProcess arguments for the ericapi call and |
|
119 a dictionary containing the non default parameters. This |
|
120 dictionary can be passed back upon object generation to overwrite |
|
121 the default settings. |
|
122 |
|
123 @return a tuple of the commandline parameters and non default |
|
124 parameters (list of strings, dictionary) |
|
125 """ |
|
126 parms = {} |
|
127 args = [] |
|
128 |
|
129 # 1. the program name |
|
130 args.append(sys.executable) |
|
131 args.append( |
|
132 Utilities.normabsjoinpath(getConfig('ericDir'), "eric6_api.py")) |
|
133 |
|
134 # 2. the commandline options |
|
135 if self.parameters['outputFile'] != self.defaults['outputFile']: |
|
136 parms['outputFile'] = Utilities.fromNativeSeparators( |
|
137 self.project.getRelativePath(self.parameters['outputFile'])) |
|
138 args.append('-o') |
|
139 if os.path.isabs(self.parameters['outputFile']): |
|
140 args.append(self.parameters['outputFile']) |
|
141 else: |
|
142 args.append( |
|
143 os.path.join(self.ppath, self.parameters['outputFile'])) |
|
144 else: |
|
145 self.parameters['outputFile'] = self.defaults['outputFile'] |
|
146 if self.parameters['basePackage'] != self.defaults['basePackage']: |
|
147 parms['basePackage'] = self.parameters['basePackage'] |
|
148 args.append('-b') |
|
149 args.append(self.parameters['basePackage']) |
|
150 if self.parameters['ignoreDirectories'] != \ |
|
151 self.defaults['ignoreDirectories']: |
|
152 parms['ignoreDirectories'] = \ |
|
153 self.parameters['ignoreDirectories'][:] |
|
154 for d in self.parameters['ignoreDirectories']: |
|
155 args.append('-x') |
|
156 args.append(d) |
|
157 if self.parameters['ignoreFilePatterns'] != \ |
|
158 self.defaults['ignoreFilePatterns']: |
|
159 parms['ignoreFilePatterns'] = \ |
|
160 self.parameters['ignoreFilePatterns'][:] |
|
161 for pattern in self.parameters['ignoreFilePatterns']: |
|
162 args.append("--exclude-file={0}".format(pattern)) |
|
163 if self.parameters['useRecursion'] != self.defaults['useRecursion']: |
|
164 parms['useRecursion'] = self.parameters['useRecursion'] |
|
165 args.append('-r') |
|
166 if self.parameters['sourceExtensions'] != \ |
|
167 self.defaults['sourceExtensions']: |
|
168 parms['sourceExtensions'] = self.parameters['sourceExtensions'][:] |
|
169 for ext in self.parameters['sourceExtensions']: |
|
170 args.append('-t') |
|
171 args.append(ext) |
|
172 if self.parameters['includePrivate'] != \ |
|
173 self.defaults['includePrivate']: |
|
174 parms['includePrivate'] = self.parameters['includePrivate'] |
|
175 args.append('-p') |
|
176 parms['languages'] = self.parameters['languages'][:] |
|
177 for lang in self.parameters['languages']: |
|
178 args.append('--language={0}'.format(lang)) |
|
179 |
|
180 return (args, parms) |
|
181 |
|
182 @pyqtSlot() |
|
183 def on_outputFilePicker_aboutToShowPathPickerDialog(self): |
|
184 """ |
|
185 Private slot called before the file selection dialog is shown. |
|
186 """ |
|
187 startFile = self.outputFilePicker.text() |
|
188 if not startFile: |
|
189 self.outputFilePicker.setText( |
|
190 self.project.getProjectName() + ".api") |
|
191 |
|
192 @pyqtSlot(str) |
|
193 def on_outputFilePicker_pathSelected(self, path): |
|
194 """ |
|
195 Private slot handling the selection of an output file. |
|
196 |
|
197 @param path path of the output file |
|
198 @type str |
|
199 """ |
|
200 # make it relative, if it is in a subdirectory of the project path |
|
201 fn = self.project.getRelativePath(path) |
|
202 self.outputFilePicker.setText(fn) |
|
203 |
|
204 def on_outputFilePicker_textChanged(self, filename): |
|
205 """ |
|
206 Private slot to enable/disable the "OK" button. |
|
207 |
|
208 @param filename name of the file (string) |
|
209 """ |
|
210 self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(filename != "") |
|
211 |
|
212 @pyqtSlot(str) |
|
213 def on_ignoreDirPicker_pathSelected(self, path): |
|
214 """ |
|
215 Private slot handling the selection of a directory to be ignored. |
|
216 |
|
217 @param path path of the directory to be ignored |
|
218 @type str |
|
219 """ |
|
220 # make it relative, if it is in a subdirectory of the project path |
|
221 dn = self.project.getRelativePath(path) |
|
222 while dn.endswith(os.sep): |
|
223 dn = dn[:-1] |
|
224 self.ignoreDirPicker.setText(dn) |
|
225 |
|
226 @pyqtSlot() |
|
227 def on_addButton_clicked(self): |
|
228 """ |
|
229 Private slot to add the directory displayed to the listview. |
|
230 |
|
231 The directory in the ignore directories |
|
232 line edit is moved to the listbox above and the edit is cleared. |
|
233 """ |
|
234 basename = os.path.basename(self.ignoreDirPicker.text()) |
|
235 if basename: |
|
236 self.ignoreDirsList.addItem(basename) |
|
237 self.ignoreDirPicker.clear() |
|
238 |
|
239 @pyqtSlot() |
|
240 def on_deleteButton_clicked(self): |
|
241 """ |
|
242 Private slot to delete the currently selected directory of the listbox. |
|
243 """ |
|
244 itm = self.ignoreDirsList.takeItem(self.ignoreDirsList.currentRow()) |
|
245 del itm |
|
246 |
|
247 def accept(self): |
|
248 """ |
|
249 Public slot called by the Ok button. |
|
250 |
|
251 It saves the values in the parameters dictionary. |
|
252 """ |
|
253 self.parameters['useRecursion'] = self.recursionCheckBox.isChecked() |
|
254 self.parameters['includePrivate'] = \ |
|
255 self.includePrivateCheckBox.isChecked() |
|
256 outfile = self.outputFilePicker.text() |
|
257 if outfile != '': |
|
258 outfile = os.path.normpath(outfile) |
|
259 self.parameters['outputFile'] = outfile |
|
260 self.parameters['basePackage'] = self.baseEdit.text() |
|
261 self.parameters['ignoreDirectories'] = [] |
|
262 for row in range(0, self.ignoreDirsList.count()): |
|
263 itm = self.ignoreDirsList.item(row) |
|
264 self.parameters['ignoreDirectories'].append( |
|
265 os.path.normpath(itm.text())) |
|
266 extensions = self.sourceExtEdit.text().split(',') |
|
267 self.parameters['sourceExtensions'] = \ |
|
268 [ext.strip() for ext in extensions if len(ext) > 0] |
|
269 patterns = self.excludeFilesEdit.text().split(',') |
|
270 self.parameters['ignoreFilePatterns'] = \ |
|
271 [pattern.strip() for pattern in patterns] |
|
272 self.parameters['languages'] = [] |
|
273 for itm in self.languagesList.selectedItems(): |
|
274 self.parameters['languages'].append(itm.text()) |
|
275 |
|
276 # call the accept slot of the base class |
|
277 super(EricapiConfigDialog, self).accept() |