eric7/Plugins/DocumentationPlugins/Ericdoc/EricdocConfigDialog.py

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

eric ide

mercurial