src/eric7/Plugins/DocumentationPlugins/Ericdoc/EricdocConfigDialog.py

branch
eric7
changeset 9209
b99e7fd55fd3
parent 9016
6f079c524e99
child 9211
99eb1cb030a5
equal deleted inserted replaced
9208:3fc8dfeb6ebe 9209:b99e7fd55fd3
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2003 - 2022 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing a dialog to enter the parameters for eric7_doc.
8 """
9
10 import os
11 import copy
12
13 from PyQt6.QtCore import pyqtSlot
14 from PyQt6.QtGui import QColor
15 from PyQt6.QtWidgets import QDialog, QDialogButtonBox, QColorDialog
16
17 from EricWidgets.EricPathPicker import EricPathPickerModes
18
19 from .Ui_EricdocConfigDialog import Ui_EricdocConfigDialog
20 from DocumentationTools.Config import (
21 eric7docDefaultColors, eric7docColorParameterNames
22 )
23
24 import Globals
25 import Utilities
26
27 from eric7config import getConfig
28
29
30 class EricdocConfigDialog(QDialog, Ui_EricdocConfigDialog):
31 """
32 Class implementing a dialog to enter the parameters for eric7_doc.
33 """
34 def __init__(self, project, parms=None, parent=None):
35 """
36 Constructor
37
38 @param project reference to the project object (Project.Project)
39 @param parms parameters to set in the dialog
40 @param parent parent widget of this dialog
41 """
42 super().__init__(parent)
43 self.setupUi(self)
44
45 self.outputDirPicker.setMode(EricPathPickerModes.DIRECTORY_MODE)
46 self.outputDirPicker.setDefaultDirectory(project.getProjectPath())
47
48 self.ignoreDirPicker.setMode(EricPathPickerModes.DIRECTORY_MODE)
49 self.ignoreDirPicker.setDefaultDirectory(project.getProjectPath())
50
51 self.cssPicker.setMode(EricPathPickerModes.OPEN_FILE_MODE)
52 self.cssPicker.setDefaultDirectory(getConfig('ericCSSDir'))
53 self.cssPicker.setFilters(self.tr(
54 "Cascading Style Sheets (*.css);;All files (*)"))
55
56 self.qtHelpDirPicker.setMode(EricPathPickerModes.DIRECTORY_MODE)
57 self.qtHelpDirPicker.setDefaultDirectory(project.getProjectPath())
58
59 self.__okButton = self.buttonBox.button(
60 QDialogButtonBox.StandardButton.Ok)
61
62 self.__initializeDefaults()
63
64 self.sampleText = self.tr(
65 '''<!DOCTYPE html'''
66 '''<html><head>'''
67 '''<title></title>'''
68 '''</head>'''
69 '''<body style="background-color:{BodyBgColor};'''
70 '''color:{BodyColor}">'''
71 '''<h1 style="background-color:{Level1HeaderBgColor};'''
72 '''color:{Level1HeaderColor}">'''
73 '''Level 1 Header</h1>'''
74 '''<h3 style="background-color:{Level2HeaderBgColor};'''
75 '''color:{Level2HeaderColor}">'''
76 '''Level 2 Header</h3>'''
77 '''<h2 style="background-color:{CFBgColor};color:{CFColor}">'''
78 '''Class and Function Header</h2>'''
79 '''Standard body text with '''
80 '''<a style="color:{LinkColor}">some links</a> embedded.'''
81 '''</body></html>'''
82 )
83
84 # get a copy of the defaults to store the user settings
85 self.parameters = copy.deepcopy(self.defaults)
86 self.colors = eric7docDefaultColors.copy()
87
88 # combine it with the values of parms
89 if parms is not None:
90 for key in parms:
91 if key.endswith("Color"):
92 self.colors[key] = parms[key]
93 else:
94 self.parameters[key] = parms[key]
95 self.parameters['outputDirectory'] = Utilities.toNativeSeparators(
96 self.parameters['outputDirectory']
97 )
98 self.parameters['qtHelpOutputDirectory'] = (
99 Utilities.toNativeSeparators(
100 self.parameters['qtHelpOutputDirectory'])
101 )
102 self.parameters['cssFile'] = Utilities.toNativeSeparators(
103 self.parameters['cssFile']
104 )
105 if self.parameters['cssFile'].startswith("%PYTHON%"):
106 self.parameters['cssFile'] = self.parameters['cssFile'].replace(
107 "%PYTHON%", Utilities.getPythonLibraryDirectory())
108
109 self.ppath = project.getProjectPath()
110 self.project = project
111
112 self.recursionCheckBox.setChecked(self.parameters['useRecursion'])
113 self.noindexCheckBox.setChecked(self.parameters['noindex'])
114 self.noemptyCheckBox.setChecked(self.parameters['noempty'])
115 self.outputDirPicker.setText(self.parameters['outputDirectory'])
116 self.ignoreDirsList.clear()
117 for d in self.parameters['ignoreDirectories']:
118 self.ignoreDirsList.addItem(d)
119 self.cssPicker.setText(self.parameters['cssFile'])
120 self.sourceExtEdit.setText(
121 ", ".join(self.parameters['sourceExtensions']))
122 self.excludeFilesEdit.setText(
123 ", ".join(self.parameters['ignoreFilePatterns']))
124 self.sample.setHtml(self.sampleText.format(**self.colors))
125
126 self.qtHelpGroup.setChecked(self.parameters['qtHelpEnabled'])
127 self.qtHelpDirPicker.setText(self.parameters['qtHelpOutputDirectory'])
128 self.qtHelpNamespaceEdit.setText(self.parameters['qtHelpNamespace'])
129 self.qtHelpFolderEdit.setText(self.parameters['qtHelpVirtualFolder'])
130 self.qtHelpFilterNameEdit.setText(self.parameters['qtHelpFilterName'])
131 self.qtHelpFilterAttributesEdit.setText(
132 self.parameters['qtHelpFilterAttributes'])
133 self.qtHelpTitleEdit.setText(self.parameters['qtHelpTitle'])
134 self.qtHelpGenerateCollectionCheckBox.setChecked(
135 self.parameters['qtHelpCreateCollection'])
136
137 def __initializeDefaults(self):
138 """
139 Private method to set the default values.
140
141 These are needed later on to generate the commandline
142 parameters.
143 """
144 self.defaults = {
145 'useRecursion': False,
146 'noindex': False,
147 'noempty': False,
148 'outputDirectory': '',
149 'ignoreDirectories': [],
150 'ignoreFilePatterns': [],
151 'cssFile': '',
152 'sourceExtensions': [],
153
154 'qtHelpEnabled': False,
155 'qtHelpOutputDirectory': '',
156 'qtHelpNamespace': '',
157 'qtHelpVirtualFolder': 'source',
158 'qtHelpFilterName': 'unknown',
159 'qtHelpFilterAttributes': '',
160 'qtHelpTitle': '',
161 'qtHelpCreateCollection': False,
162 }
163
164 def generateParameters(self):
165 """
166 Public method that generates the commandline parameters.
167
168 It generates a list of strings to be used
169 to set the QProcess arguments for the ericdoc call and
170 a dictionary containing the non default parameters. This
171 dictionary can be passed back upon object generation to overwrite
172 the default settings.
173
174 @return a tuple of the commandline parameters and non default
175 parameters (list of strings, dictionary)
176 """
177 parms = {}
178 args = []
179
180 # 1. the program name
181 args.append(Globals.getPythonExecutable())
182 args.append(
183 Utilities.normabsjoinpath(getConfig('ericDir'), "eric7_doc.py"))
184
185 # 2. the commandline options
186 # 2a. general commandline options
187 if (
188 self.parameters['outputDirectory'] !=
189 self.defaults['outputDirectory']
190 ):
191 parms['outputDirectory'] = Utilities.fromNativeSeparators(
192 self.project.getRelativePath(
193 self.parameters['outputDirectory']))
194 args.append('-o')
195 if os.path.isabs(self.parameters['outputDirectory']):
196 args.append(self.parameters['outputDirectory'])
197 else:
198 args.append(os.path.join(
199 self.ppath, self.parameters['outputDirectory']))
200 else:
201 self.parameters['outputDirectory'] = (
202 self.defaults['outputDirectory']
203 )
204 parms['outputDirectory'] = self.parameters['outputDirectory']
205 if (
206 self.parameters['ignoreDirectories'] !=
207 self.defaults['ignoreDirectories']
208 ):
209 parms['ignoreDirectories'] = (
210 self.parameters['ignoreDirectories'][:]
211 )
212 for d in self.parameters['ignoreDirectories']:
213 args.append('-x')
214 args.append(d)
215 if (
216 self.parameters['ignoreFilePatterns'] !=
217 self.defaults['ignoreFilePatterns']
218 ):
219 parms['ignoreFilePatterns'] = (
220 self.parameters['ignoreFilePatterns'][:]
221 )
222 for pattern in self.parameters['ignoreFilePatterns']:
223 if pattern.strip():
224 args.append("--exclude-file={0}".format(pattern.strip()))
225 if self.parameters['useRecursion'] != self.defaults['useRecursion']:
226 parms['useRecursion'] = self.parameters['useRecursion']
227 args.append('-r')
228 if self.parameters['noindex'] != self.defaults['noindex']:
229 parms['noindex'] = self.parameters['noindex']
230 args.append('-i')
231 if self.parameters['noempty'] != self.defaults['noempty']:
232 parms['noempty'] = self.parameters['noempty']
233 args.append('-e')
234 if (
235 self.parameters['sourceExtensions'] !=
236 self.defaults['sourceExtensions']
237 ):
238 parms['sourceExtensions'] = self.parameters['sourceExtensions'][:]
239 for ext in self.parameters['sourceExtensions']:
240 if ext.strip():
241 args.append("--extension={0}".format(ext.strip()))
242
243 # 2b. style commandline options
244 if self.parameters['cssFile'] != self.defaults['cssFile']:
245 cssFile = self.project.getRelativePath(self.parameters['cssFile'])
246 if cssFile.startswith(Utilities.getPythonLibraryDirectory()):
247 cssFile = cssFile.replace(
248 Utilities.getPythonLibraryDirectory(), "%PYTHON%")
249 parms['cssFile'] = Utilities.fromNativeSeparators(cssFile)
250 args.append('-c')
251 if os.path.isabs(self.parameters['cssFile']):
252 args.append(self.parameters['cssFile'])
253 else:
254 args.append(
255 os.path.join(self.ppath, self.parameters['cssFile']))
256 for key in self.colors:
257 if self.colors[key] != eric7docDefaultColors[key]:
258 parms[key] = self.colors[key]
259 args.append("--{0}={1}".format(
260 eric7docColorParameterNames[key], self.colors[key]))
261
262 # 2c. QtHelp commandline options
263 parms['qtHelpEnabled'] = self.parameters['qtHelpEnabled']
264 if self.parameters['qtHelpEnabled']:
265 args.append('--create-qhp')
266 if (
267 self.parameters['qtHelpOutputDirectory'] !=
268 self.defaults['qtHelpOutputDirectory']
269 ):
270 parms['qtHelpOutputDirectory'] = Utilities.fromNativeSeparators(
271 self.project.getRelativePath(
272 self.parameters['qtHelpOutputDirectory']))
273 if os.path.isabs(self.parameters['outputDirectory']):
274 args.append("--qhp-outdir={0}".format(
275 self.parameters['qtHelpOutputDirectory']))
276 else:
277 args.append("--qhp-outdir={0}".format(
278 os.path.join(self.ppath,
279 self.parameters['qtHelpOutputDirectory'])))
280 if (
281 self.parameters['qtHelpNamespace'] !=
282 self.defaults['qtHelpNamespace']
283 ):
284 parms['qtHelpNamespace'] = self.parameters['qtHelpNamespace']
285 args.append("--qhp-namespace={0}".format(
286 self.parameters['qtHelpNamespace']))
287 if (
288 self.parameters['qtHelpVirtualFolder'] !=
289 self.defaults['qtHelpVirtualFolder']
290 ):
291 parms['qtHelpVirtualFolder'] = (
292 self.parameters['qtHelpVirtualFolder']
293 )
294 args.append("--qhp-virtualfolder={0}".format(
295 self.parameters['qtHelpVirtualFolder']))
296 if (
297 self.parameters['qtHelpFilterName'] !=
298 self.defaults['qtHelpFilterName']
299 ):
300 parms['qtHelpFilterName'] = self.parameters['qtHelpFilterName']
301 args.append("--qhp-filtername={0}".format(
302 self.parameters['qtHelpFilterName']))
303 if (
304 self.parameters['qtHelpFilterAttributes'] !=
305 self.defaults['qtHelpFilterAttributes']
306 ):
307 parms['qtHelpFilterAttributes'] = (
308 self.parameters['qtHelpFilterAttributes']
309 )
310 args.append("--qhp-filterattribs={0}".format(
311 self.parameters['qtHelpFilterAttributes']))
312 if self.parameters['qtHelpTitle'] != self.defaults['qtHelpTitle']:
313 parms['qtHelpTitle'] = self.parameters['qtHelpTitle']
314 args.append("--qhp-title={0}".format(
315 self.parameters['qtHelpTitle']))
316 if (
317 self.parameters['qtHelpCreateCollection'] !=
318 self.defaults['qtHelpCreateCollection']
319 ):
320 parms['qtHelpCreateCollection'] = (
321 self.parameters['qtHelpCreateCollection']
322 )
323 args.append('--create-qhc')
324
325 return (args, parms)
326
327 @pyqtSlot(str)
328 def on_outputDirPicker_pathSelected(self, path):
329 """
330 Private slot handling the selection of an output directory.
331
332 @param path path of the output directory
333 @type str
334 """
335 # make it relative, if it is in a subdirectory of the project path
336 dn = self.project.getRelativePath(path)
337 while dn.endswith(os.sep):
338 dn = dn[:-1]
339 self.outputDirPicker.setText(dn)
340
341 @pyqtSlot(str)
342 def on_ignoreDirPicker_pathSelected(self, path):
343 """
344 Private slot handling the selection of a directory to be ignored.
345
346 @param path path of the directory to be ignored
347 @type str
348 """
349 # make it relative, if it is in a subdirectory of the project path
350 dn = self.project.getRelativePath(path)
351 while dn.endswith(os.sep):
352 dn = dn[:-1]
353 self.ignoreDirPicker.setText(dn)
354
355 @pyqtSlot()
356 def on_addButton_clicked(self):
357 """
358 Private slot to add the directory displayed to the listview.
359
360 The directory in the ignore directories
361 line edit is moved to the listbox above and the edit is cleared.
362 """
363 basename = os.path.basename(self.ignoreDirPicker.text())
364 if basename:
365 self.ignoreDirsList.addItem(basename)
366 self.ignoreDirPicker.clear()
367
368 @pyqtSlot()
369 def on_deleteButton_clicked(self):
370 """
371 Private slot to delete the currently selected directory of the listbox.
372 """
373 itm = self.ignoreDirsList.takeItem(self.ignoreDirsList.currentRow())
374 del itm
375
376 @pyqtSlot(str)
377 def on_cssPicker_pathSelected(self, path):
378 """
379 Private slot handling the selection of a css style sheet.
380
381 @param path path of the css style sheet
382 @type str
383 """
384 # make it relative, if it is in a subdirectory of the project path
385 cf = self.project.getRelativePath(path)
386 self.cssPicker.setText(cf)
387
388 def __selectColor(self, colorKey):
389 """
390 Private method to select a color.
391
392 @param colorKey key of the color to select (string)
393 """
394 color = QColorDialog.getColor(QColor(self.colors[colorKey]))
395 if color.isValid():
396 self.colors[colorKey] = color.name()
397 self.sample.setHtml(self.sampleText.format(**self.colors))
398
399 @pyqtSlot()
400 def on_bodyFgButton_clicked(self):
401 """
402 Private slot to select the body foreground color.
403 """
404 self.__selectColor('BodyColor')
405
406 @pyqtSlot()
407 def on_bodyBgButton_clicked(self):
408 """
409 Private slot to select the body background color.
410 """
411 self.__selectColor('BodyBgColor')
412
413 @pyqtSlot()
414 def on_l1FgButton_clicked(self):
415 """
416 Private slot to select the level 1 header foreground color.
417 """
418 self.__selectColor('Level1HeaderColor')
419
420 @pyqtSlot()
421 def on_l1BgButton_clicked(self):
422 """
423 Private slot to select the level 1 header background color.
424 """
425 self.__selectColor('Level1HeaderBgColor')
426
427 @pyqtSlot()
428 def on_l2FgButton_clicked(self):
429 """
430 Private slot to select the level 2 header foreground color.
431 """
432 self.__selectColor('Level2HeaderColor')
433
434 @pyqtSlot()
435 def on_l2BgButton_clicked(self):
436 """
437 Private slot to select the level 2 header background color.
438 """
439 self.__selectColor('Level2HeaderBgColor')
440
441 @pyqtSlot()
442 def on_cfFgButton_clicked(self):
443 """
444 Private slot to select the class/function header foreground color.
445 """
446 self.__selectColor('CFColor')
447
448 @pyqtSlot()
449 def on_cfBgButton_clicked(self):
450 """
451 Private slot to select the class/function header background color.
452 """
453 self.__selectColor('CFBgColor')
454
455 @pyqtSlot()
456 def on_linkFgButton_clicked(self):
457 """
458 Private slot to select the foreground color of links.
459 """
460 self.__selectColor('LinkColor')
461
462 def __checkQtHelpOptions(self):
463 """
464 Private slot to check the QtHelp options and set the ok button
465 accordingly.
466 """
467 setOn = True
468 if self.qtHelpGroup.isChecked():
469 if not self.qtHelpNamespaceEdit.text():
470 setOn = False
471 if not self.qtHelpFolderEdit.text():
472 setOn = False
473 else:
474 if '/' in self.qtHelpFolderEdit.text():
475 setOn = False
476 if not self.qtHelpTitleEdit.text():
477 setOn = False
478
479 self.__okButton.setEnabled(setOn)
480
481 @pyqtSlot(bool)
482 def on_qtHelpGroup_toggled(self, enabled):
483 """
484 Private slot to toggle the generation of QtHelp files.
485
486 @param enabled flag indicating the state (boolean)
487 """
488 self.__checkQtHelpOptions()
489
490 @pyqtSlot(str)
491 def on_qtHelpNamespaceEdit_textChanged(self, txt):
492 """
493 Private slot to check the namespace.
494
495 @param txt text of the line edit (string)
496 """
497 self.__checkQtHelpOptions()
498
499 @pyqtSlot(str)
500 def on_qtHelpFolderEdit_textChanged(self, txt):
501 """
502 Private slot to check the virtual folder.
503
504 @param txt text of the line edit (string)
505 """
506 self.__checkQtHelpOptions()
507
508 @pyqtSlot(str)
509 def on_qtHelpTitleEdit_textChanged(self, txt):
510 """
511 Private slot to check the title.
512
513 @param txt text of the line edit (string)
514 """
515 self.__checkQtHelpOptions()
516
517 @pyqtSlot(str)
518 def on_qtHelpDirPicker_pathSelected(self, path):
519 """
520 Private slot handling the selection of the output directory for the
521 QtHelp files.
522
523 @param path path of the the output directory for the QtHelp files
524 @type str
525 """
526 # make it relative, if it is in a subdirectory of the project path
527 dn = self.project.getRelativePath(path)
528 while dn.endswith(os.sep):
529 dn = dn[:-1]
530 self.qtHelpDirPicker.setText(dn)
531
532 def accept(self):
533 """
534 Public slot called by the Ok button.
535
536 It saves the values in the parameters dictionary.
537 """
538 self.parameters['useRecursion'] = self.recursionCheckBox.isChecked()
539 self.parameters['noindex'] = self.noindexCheckBox.isChecked()
540 self.parameters['noempty'] = self.noemptyCheckBox.isChecked()
541 outdir = self.outputDirPicker.text()
542 if outdir != '':
543 outdir = os.path.normpath(outdir)
544 if outdir.endswith(os.sep):
545 outdir = outdir[:-1]
546 self.parameters['outputDirectory'] = outdir
547 self.parameters['ignoreDirectories'] = []
548 for row in range(0, self.ignoreDirsList.count()):
549 itm = self.ignoreDirsList.item(row)
550 self.parameters['ignoreDirectories'].append(
551 os.path.normpath(itm.text()))
552 cssFile = self.cssPicker.text()
553 if cssFile != '':
554 cssFile = os.path.normpath(cssFile)
555 self.parameters['cssFile'] = cssFile
556 extensions = self.sourceExtEdit.text().split(',')
557 self.parameters['sourceExtensions'] = [
558 ext.strip() for ext in extensions if ext.strip()
559 ]
560 patterns = self.excludeFilesEdit.text().split(',')
561 self.parameters['ignoreFilePatterns'] = [
562 pattern.strip() for pattern in patterns if pattern.strip()
563 ]
564
565 self.parameters['qtHelpEnabled'] = self.qtHelpGroup.isChecked()
566 self.parameters['qtHelpOutputDirectory'] = self.qtHelpDirPicker.text()
567 self.parameters['qtHelpNamespace'] = self.qtHelpNamespaceEdit.text()
568 self.parameters['qtHelpVirtualFolder'] = self.qtHelpFolderEdit.text()
569 self.parameters['qtHelpFilterName'] = self.qtHelpFilterNameEdit.text()
570 self.parameters['qtHelpFilterAttributes'] = (
571 self.qtHelpFilterAttributesEdit.text()
572 )
573 self.parameters['qtHelpTitle'] = self.qtHelpTitleEdit.text()
574 self.parameters['qtHelpCreateCollection'] = (
575 self.qtHelpGenerateCollectionCheckBox.isChecked()
576 )
577
578 # call the accept slot of the base class
579 super().accept()

eric ide

mercurial