eric6/Helpviewer/QtHelpFiltersDialog.py

branch
maintenance
changeset 7286
7eb04391adf7
parent 7226
babe80d84a3e
parent 7285
1ff497f33f31
child 7287
1c17f2191bdd
equal deleted inserted replaced
7226:babe80d84a3e 7286:7eb04391adf7
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2009 - 2019 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing a dialog to manage the QtHelp filters.
8 """
9
10 from __future__ import unicode_literals
11
12 import sqlite3
13
14 from PyQt5.QtCore import pyqtSlot, Qt, QItemSelectionModel
15 from PyQt5.QtWidgets import QDialog, QTreeWidgetItem, QListWidgetItem, \
16 QInputDialog, QLineEdit
17 from PyQt5.QtHelp import QHelpEngineCore
18
19 from E5Gui import E5MessageBox
20
21 from .Ui_QtHelpFiltersDialog import Ui_QtHelpFiltersDialog
22
23
24 class QtHelpFiltersDialog(QDialog, Ui_QtHelpFiltersDialog):
25 """
26 Class implementing a dialog to manage the QtHelp filters.
27 """
28 def __init__(self, engine, parent=None):
29 """
30 Constructor
31
32 @param engine reference to the help engine (QHelpEngine)
33 @param parent reference to the parent widget (QWidget)
34 """
35 super(QtHelpFiltersDialog, self).__init__(parent)
36 self.setupUi(self)
37
38 self.removeButton.setEnabled(False)
39 self.removeAttributeButton.setEnabled(False)
40
41 self.__engine = engine
42
43 self.filtersList.clear()
44 self.attributesList.clear()
45
46 helpEngineCore = QHelpEngineCore(self.__engine.collectionFile())
47 helpEngineCore.setupData()
48
49 self.__removedFilters = []
50 self.__filterMap = {}
51 self.__filterMapBackup = {}
52 self.__removedAttributes = []
53
54 for customFilter in helpEngineCore.customFilters():
55 atts = helpEngineCore.filterAttributes(customFilter)
56 self.__filterMapBackup[customFilter] = atts
57 if customFilter not in self.__filterMap:
58 self.__filterMap[customFilter] = atts
59
60 self.filtersList.addItems(sorted(self.__filterMap.keys()))
61 for attr in helpEngineCore.filterAttributes():
62 QTreeWidgetItem(self.attributesList, [attr])
63 self.attributesList.sortItems(0, Qt.AscendingOrder)
64
65 if self.__filterMap:
66 self.filtersList.setCurrentRow(0)
67
68 @pyqtSlot(QListWidgetItem, QListWidgetItem)
69 def on_filtersList_currentItemChanged(self, current, previous):
70 """
71 Private slot to update the attributes depending on the current filter.
72
73 @param current reference to the current item (QListWidgetitem)
74 @param previous reference to the previous current item
75 (QListWidgetItem)
76 """
77 checkedList = []
78 if current is not None:
79 checkedList = self.__filterMap[current.text()]
80 for index in range(0, self.attributesList.topLevelItemCount()):
81 itm = self.attributesList.topLevelItem(index)
82 if itm.text(0) in checkedList:
83 itm.setCheckState(0, Qt.Checked)
84 else:
85 itm.setCheckState(0, Qt.Unchecked)
86
87 @pyqtSlot()
88 def on_filtersList_itemSelectionChanged(self):
89 """
90 Private slot handling a change of selected filters.
91 """
92 self.removeButton.setEnabled(
93 len(self.filtersList.selectedItems()) > 0)
94
95 @pyqtSlot(QTreeWidgetItem, int)
96 def on_attributesList_itemChanged(self, item, column):
97 """
98 Private slot to handle a change of an attribute.
99
100 @param item reference to the changed item (QTreeWidgetItem)
101 @param column column containing the change (integer)
102 """
103 if self.filtersList.currentItem() is None:
104 return
105
106 filterText = self.filtersList.currentItem().text()
107 if filterText not in self.__filterMap:
108 return
109
110 newAtts = []
111 for index in range(0, self.attributesList.topLevelItemCount()):
112 itm = self.attributesList.topLevelItem(index)
113 if itm.checkState(0) == Qt.Checked:
114 newAtts.append(itm.text(0))
115 self.__filterMap[filterText] = newAtts
116
117 @pyqtSlot()
118 def on_attributesList_itemSelectionChanged(self):
119 """
120 Private slot handling the selection of attributes.
121 """
122 self.removeAttributeButton.setEnabled(
123 len(self.attributesList.selectedItems()) != 0)
124
125 @pyqtSlot()
126 def on_addButton_clicked(self):
127 """
128 Private slot to add a new filter.
129 """
130 customFilter, ok = QInputDialog.getText(
131 None,
132 self.tr("Add Filter"),
133 self.tr("Filter name:"),
134 QLineEdit.Normal)
135 if not customFilter:
136 return
137
138 if customFilter not in self.__filterMap:
139 self.__filterMap[customFilter] = []
140 self.filtersList.addItem(customFilter)
141
142 itm = self.filtersList.findItems(
143 customFilter, Qt.MatchCaseSensitive)[0]
144 self.filtersList.setCurrentItem(itm)
145
146 @pyqtSlot()
147 def on_removeButton_clicked(self):
148 """
149 Private slot to remove the selected filters.
150 """
151 ok = E5MessageBox.yesNo(
152 self,
153 self.tr("Remove Filters"),
154 self.tr(
155 """Do you really want to remove the selected filters """
156 """from the database?"""))
157 if not ok:
158 return
159
160 items = self.filtersList.selectedItems()
161 for item in items:
162 itm = self.filtersList.takeItem(self.filtersList.row(item))
163 if itm is None:
164 continue
165
166 del self.__filterMap[itm.text()]
167 self.__removedFilters.append(itm.text())
168 del itm
169
170 if self.filtersList.count():
171 self.filtersList.setCurrentRow(
172 0, QItemSelectionModel.ClearAndSelect)
173
174 @pyqtSlot()
175 def on_removeAttributeButton_clicked(self):
176 """
177 Private slot to remove the selected filter attributes.
178 """
179 ok = E5MessageBox.yesNo(
180 self,
181 self.tr("Remove Attributes"),
182 self.tr(
183 """Do you really want to remove the selected attributes """
184 """from the database?"""))
185 if not ok:
186 return
187
188 items = self.attributesList.selectedItems()
189 for item in items:
190 itm = self.attributesList.takeTopLevelItem(
191 self.attributesList.indexOfTopLevelItem(item))
192 if itm is None:
193 continue
194
195 attr = itm.text(0)
196 self.__removedAttributes.append(attr)
197 for customFilter in self.__filterMap:
198 if attr in self.__filterMap[customFilter]:
199 self.__filterMap[customFilter].remove(attr)
200
201 del itm
202
203 @pyqtSlot()
204 def on_unusedAttributesButton_clicked(self):
205 """
206 Private slot to select all unused attributes.
207 """
208 # step 1: determine all used attributes
209 attributes = set()
210 for customFilter in self.__filterMap:
211 attributes |= set(self.__filterMap[customFilter])
212
213 # step 2: select all unused attribute items
214 self.attributesList.clearSelection()
215 for row in range(self.attributesList.topLevelItemCount()):
216 itm = self.attributesList.topLevelItem(row)
217 if itm.text(0) not in attributes:
218 itm.setSelected(True)
219
220 def __removeAttributes(self):
221 """
222 Private method to remove attributes from the Qt Help database.
223 """
224 try:
225 self.__db = sqlite3.connect(self.__engine.collectionFile())
226 except sqlite3.DatabaseError:
227 pass # ignore database errors
228
229 for attr in self.__removedAttributes:
230 self.__db.execute(
231 "DELETE FROM FilterAttributeTable WHERE Name = '{0}'"
232 .format(attr))
233 self.__db.commit()
234 self.__db.close()
235
236 @pyqtSlot()
237 def on_buttonBox_accepted(self):
238 """
239 Private slot to update the database, if the dialog is accepted.
240 """
241 filtersChanged = False
242 if len(self.__filterMapBackup) != len(self.__filterMap):
243 filtersChanged = True
244 else:
245 for customFilter in self.__filterMapBackup:
246 if customFilter not in self.__filterMap:
247 filtersChanged = True
248 else:
249 oldFilterAtts = self.__filterMapBackup[customFilter]
250 newFilterAtts = self.__filterMap[customFilter]
251 if len(oldFilterAtts) != len(newFilterAtts):
252 filtersChanged = True
253 else:
254 for attr in oldFilterAtts:
255 if attr not in newFilterAtts:
256 filtersChanged = True
257 break
258
259 if filtersChanged:
260 break
261
262 if filtersChanged:
263 for customFilter in self.__removedFilters:
264 self.__engine.removeCustomFilter(customFilter)
265 for customFilter in self.__filterMap:
266 self.__engine.addCustomFilter(
267 customFilter, self.__filterMap[customFilter])
268
269 if self.__removedAttributes:
270 self.__removeAttributes()
271
272 if filtersChanged or self.__removedAttributes:
273 self.__engine.setupData()
274
275 self.accept()

eric ide

mercurial