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

eric ide

mercurial