eric6/WebBrowser/QtHelp/QtHelpFiltersDialog.py

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

eric ide

mercurial