Helpviewer/AdBlock/AdBlockDialog.py

changeset 1970
02cf3bac079b
parent 1963
9c5b3235abf9
child 1972
5341662d6cfb
equal deleted inserted replaced
1969:5522b3266c8b 1970:02cf3bac079b
5 5
6 """ 6 """
7 Module implementing the AdBlock configuration dialog. 7 Module implementing the AdBlock configuration dialog.
8 """ 8 """
9 9
10 from PyQt4.QtCore import pyqtSlot, Qt, QUrl 10 from PyQt4.QtCore import pyqtSlot, QTimer, QCoreApplication
11 from PyQt4.QtGui import QDialog, QMenu, QToolButton, QApplication, QDesktopServices 11 from PyQt4.QtGui import QDialog, QMenu, QToolButton
12 12
13 from E5Gui.E5TreeSortFilterProxyModel import E5TreeSortFilterProxyModel 13 from E5Gui.E5LineEditButton import E5LineEditButton
14 from E5Gui.E5LineEdit import E5LineEdit
15 from E5Gui import E5MessageBox
14 16
15 import Helpviewer.HelpWindow 17 import Helpviewer.HelpWindow
16 18
17 from .Ui_AdBlockDialog import Ui_AdBlockDialog 19 from .Ui_AdBlockDialog import Ui_AdBlockDialog
18 20
19 from .AdBlockModel import AdBlockModel 21 from .AdBlockTreeWidget import AdBlockTreeWidget
20 from .AdBlockRule import AdBlockRule
21 22
22 import UI.PixmapCache 23 import UI.PixmapCache
23 import Preferences 24 import Preferences
24 25
25 26
32 Constructor 33 Constructor
33 """ 34 """
34 super().__init__(parent) 35 super().__init__(parent)
35 self.setupUi(self) 36 self.setupUi(self)
36 37
37 self.clearButton.setIcon(UI.PixmapCache.getIcon("clearLeft.png"))
38 self.iconLabel.setPixmap(UI.PixmapCache.getPixmap("adBlockPlus48.png")) 38 self.iconLabel.setPixmap(UI.PixmapCache.getPixmap("adBlockPlus48.png"))
39 39
40 self.updateSpinBox.setValue(Preferences.getHelp("AdBlockUpdatePeriod")) 40 self.updateSpinBox.setValue(Preferences.getHelp("AdBlockUpdatePeriod"))
41 41
42 self.__adBlockModel = AdBlockModel(self) 42 self.searchEdit.setInactiveText(self.trUtf8("Search..."))
43 self.__proxyModel = E5TreeSortFilterProxyModel(self) 43 self.__clearSearchButton = E5LineEditButton(self)
44 self.__proxyModel.setSourceModel(self.__adBlockModel) 44 self.__clearSearchButton.setIcon(UI.PixmapCache.getIcon("clearLeft.png"))
45 self.subscriptionsTree.setModel(self.__proxyModel) 45 self.searchEdit.addWidget(self.__clearSearchButton, E5LineEdit.RightSide)
46 46 self.__clearSearchButton.clicked[()].connect(self.searchEdit.clear)
47 self.searchEdit.textChanged.connect(self.__proxyModel.setFilterFixedString) 47
48 48 self.__manager = Helpviewer.HelpWindow.HelpWindow.adBlockManager()
49 manager = Helpviewer.HelpWindow.HelpWindow.adblockManager() 49 self.adBlockGroup.setChecked(self.__manager.isEnabled())
50 self.adBlockGroup.setChecked(manager.isEnabled()) 50 self.__manager.requiredSubscriptionLoaded.connect(self.addSubscription)
51 self.adBlockGroup.toggled[bool].connect(manager.setEnabled) 51
52 self.__currentTreeWidget = None
53 self.__currentSubscription = None
54 self.__loaded = False
52 55
53 menu = QMenu(self) 56 menu = QMenu(self)
54 menu.aboutToShow.connect(self.__aboutToShowActionMenu) 57 menu.aboutToShow.connect(self.__aboutToShowActionMenu)
55 self.actionButton.setMenu(menu) 58 self.actionButton.setMenu(menu)
56 self.actionButton.setIcon(UI.PixmapCache.getIcon("adBlockAction.png")) 59 self.actionButton.setIcon(UI.PixmapCache.getIcon("adBlockAction.png"))
57 self.actionButton.setPopupMode(QToolButton.InstantPopup) 60 self.actionButton.setPopupMode(QToolButton.InstantPopup)
58 61
59 if self.adBlockGroup.isChecked(): 62 self.__load()
60 subscription = manager.customRules() 63
61 subscriptionIndex = self.__adBlockModel.subscriptionIndex(subscription) 64 self.buttonBox.setFocus()
62 self.subscriptionsTree.expand( 65
63 self.__proxyModel.mapFromSource(subscriptionIndex)) 66 def __loadSubscriptions(self):
64 67 """
65 def model(self): 68 Private slot to load the AdBlock subscription rules.
66 """ 69 """
67 Public method to return a reference to the subscriptions tree model. 70 for index in range(self.subscriptionsTabWidget.count()):
68 """ 71 tree = self.subscriptionsTabWidget.widget(index)
69 return self.subscriptionsTree.model() 72 tree.refresh()
70 73
71 def setCurrentIndex(self, index): 74 def __load(self):
72 """ 75 """
73 Private slot to set the current index of the subscriptions tree. 76 Private slot to populate the tab widget with subscriptions.
74 77 """
75 @param index index to be set (QModelIndex) 78 if self.__loaded or not self.adBlockGroup.isChecked():
76 """ 79 return
77 self.subscriptionsTree.setCurrentIndex(index) 80
81 for subscription in self.__manager.subscriptions():
82 tree = AdBlockTreeWidget(subscription, self.subscriptionsTabWidget)
83 if subscription.isEnabled():
84 icon = UI.PixmapCache.getIcon("adBlockPlus.png")
85 else:
86 icon = UI.PixmapCache.getIcon("adBlockPlusDisabled.png")
87 self.subscriptionsTabWidget.addTab(tree, icon, subscription.title())
88
89 self.__loaded = True
90 QCoreApplication.processEvents()
91
92 QTimer.singleShot(50, self.__loadSubscriptions)
93
94 def addSubscription(self, subscription, refresh=True):
95 """
96 Public slot adding a subscription to the list.
97
98 @param subscription reference to the subscription to be
99 added (AdBlockSubscription)
100 @param refresh flag indicating to refresh the tree (boolean)
101 """
102 tree = AdBlockTreeWidget(subscription, self.subscriptionsTabWidget)
103 index = self.subscriptionsTabWidget.insertTab(
104 self.subscriptionsTabWidget.count() - 1, tree, subscription.title())
105 self.subscriptionsTabWidget.setCurrentIndex(index)
106 QCoreApplication.processEvents()
107 if refresh:
108 tree.refresh()
109 self.__setSubscriptionEnabled(subscription, True)
78 110
79 def __aboutToShowActionMenu(self): 111 def __aboutToShowActionMenu(self):
80 """ 112 """
81 Private slot to show the actions menu. 113 Private slot to show the actions menu.
82 """ 114 """
115 subscriptionEditable = self.__currentSubscription and \
116 self.__currentSubscription.canEditRules()
117 subscriptionRemovable = self.__currentSubscription and \
118 self.__currentSubscription.canBeRemoved()
119 subscriptionEnabled = self.__currentSubscription and \
120 self.__currentSubscription.isEnabled()
121
83 menu = self.actionButton.menu() 122 menu = self.actionButton.menu()
84 menu.clear() 123 menu.clear()
85 124
86 menu.addAction(self.trUtf8("Add Custom Rule"), self.addCustomRule) 125 menu.addAction(self.trUtf8("Add Rule"), self.__addCustomRule)\
87 126 .setEnabled(subscriptionEditable)
127 menu.addAction(self.trUtf8("Remove Rule"), self.__removeCustomRule)\
128 .setEnabled(subscriptionEditable)
129 menu.addSeparator()
130 menu.addAction(self.trUtf8("Browse Subscriptions..."), self.__browseSubscriptions)
131 menu.addAction(self.trUtf8("Remove Subscription"), self.__removeSubscription)\
132 .setEnabled(subscriptionRemovable)
133 if self.__currentSubscription:
134 menu.addSeparator()
135 if subscriptionEnabled:
136 txt = self.trUtf8("Disable Subscription")
137 else:
138 txt = self.trUtf8("Enable Subscription")
139 menu.addAction(txt, self.__switchSubscriptionEnabled)
140 menu.addSeparator()
141 menu.addAction(self.trUtf8("Update Subscription"), self.__updateSubscription)\
142 .setEnabled(not subscriptionEditable)
143 menu.addAction(self.trUtf8("Update All Subscriptions"),
144 self.__updateAllSubscriptions)
145 menu.addSeparator()
88 menu.addAction(self.trUtf8("Learn more about writing rules..."), 146 menu.addAction(self.trUtf8("Learn more about writing rules..."),
89 self.__learnAboutWritingFilters) 147 self.__learnAboutWritingFilters)
90 148
91 menu.addSeparator() 149 def __addCustomRule(self):
92 150 """
93 idx = self.__proxyModel.mapToSource(self.subscriptionsTree.currentIndex()) 151 Private slot to add a custom AdBlock rule.
94 152 """
95 act = menu.addAction(self.trUtf8("Update Subscription"), 153 self.__currentTreeWidget.addRule()
96 self.__updateSubscription) 154
97 act.setEnabled(idx.isValid()) 155 def __removeCustomRule(self):
98 156 """
99 menu.addAction(self.trUtf8("Browse Subscriptions..."), self.__browseSubscriptions) 157 Private slot to remove a custom AdBlock rule.
100 158 """
101 menu.addSeparator() 159 self.__currentTreeWidget.removeRule()
102
103 act = menu.addAction(self.trUtf8("Remove Subscription"),
104 self.__removeSubscription)
105 act.setEnabled(idx.isValid())
106
107 def addCustomRule(self, rule=""):
108 """
109 Public slot to add a custom AdBlock rule.
110
111 @param rule string defining the rule to be added (string)
112 """
113 manager = Helpviewer.HelpWindow.HelpWindow.adblockManager()
114 subscription = manager.customRules()
115 assert subscription is not None
116 subscription.addRule(AdBlockRule(rule, subscription))
117 QApplication.processEvents()
118
119 parent = self.__adBlockModel.subscriptionIndex(subscription)
120 cnt = self.__adBlockModel.rowCount(parent)
121 ruleIndex = self.__adBlockModel.index(cnt - 1, 0, parent)
122 self.subscriptionsTree.expand(self.__proxyModel.mapFromSource(parent))
123 self.subscriptionsTree.edit(self.__proxyModel.mapFromSource(ruleIndex))
124 160
125 def __updateSubscription(self): 161 def __updateSubscription(self):
126 """ 162 """
127 Private slot to update the selected subscription. 163 Private slot to update the selected subscription.
128 """ 164 """
129 idx = self.__proxyModel.mapToSource(self.subscriptionsTree.currentIndex()) 165 self.__currentSubscription.updateNow()
130 if not idx.isValid(): 166
131 return 167 def __updateAllSubscriptions(self):
132 if idx.parent().isValid(): 168 """
133 idx = idx.parent() 169 Private slot to update all subscriptions.
134 subscription = self.__adBlockModel.subscription(idx) 170 """
135 subscription.updateNow() 171 self.__manager.updateAllSubscriptions()
136 172
137 def __browseSubscriptions(self): 173 def __browseSubscriptions(self):
138 """ 174 """
139 Private slot to browse the list of available AdBlock subscriptions. 175 Private slot to browse the list of available AdBlock subscriptions.
140 """ 176 """
141 QDesktopServices.openUrl(QUrl("http://adblockplus.org/en/subscriptions")) 177 mw = Helpviewer.HelpWindow.HelpWindow.mainWindow()
178 mw.newTab("http://adblockplus.org/en/subscriptions")
179 mw.raise_()
142 180
143 def __learnAboutWritingFilters(self): 181 def __learnAboutWritingFilters(self):
144 """ 182 """
145 Private slot to show the web page about how to write filters. 183 Private slot to show the web page about how to write filters.
146 """ 184 """
147 QDesktopServices.openUrl(QUrl("http://adblockplus.org/en/filters")) 185 mw = Helpviewer.HelpWindow.HelpWindow.mainWindow()
186 mw.newTab("http://adblockplus.org/en/filters")
187 mw.raise_()
148 188
149 def __removeSubscription(self): 189 def __removeSubscription(self):
150 """ 190 """
151 Private slot to remove the selected subscription. 191 Private slot to remove the selected subscription.
152 """ 192 """
153 idx = self.__proxyModel.mapToSource(self.subscriptionsTree.currentIndex()) 193 requiresTitles = []
154 if not idx.isValid(): 194 requiresSubscriptions = \
155 return 195 self.__manager.getRequiresSubscriptions(self.__currentSubscription)
156 if idx.parent().isValid(): 196 for subscription in requiresSubscriptions:
157 idx = idx.parent() 197 requiresTitles.append(subscription.title())
158 subscription = self.__adBlockModel.subscription(idx) 198 if requiresTitles:
159 manager = Helpviewer.HelpWindow.HelpWindow.adblockManager() 199 message = self.trUtf8("<p>Do you really want to remove subscription"
160 manager.removeSubscription(subscription) 200 " <b>{0}</b> and all subscriptions requiring it?</p>"
201 "<ul><li>{1}</li></ul>").format(
202 self.__currentSubscription.title(),
203 "</li><li>".join(requiresTitles))
204 else:
205 message = self.trUtf8("<p>Do you really want to remove subscription"
206 " <b>{0}</b>?</p>").format(self.__currentSubscription.title())
207 res = E5MessageBox.yesNo(self,
208 self.trUtf8("Remove Subscription"),
209 message)
210
211 if res:
212 removeSubscription = self.__currentSubscription
213 removeTrees = [self.__currentTreeWidget]
214 for index in range(self.subscriptionsTabWidget.count()):
215 tree = self.subscriptionsTabWidget.widget(index)
216 if tree.subscription() in requiresSubscriptions:
217 removeTrees.append(tree)
218 for tree in removeTrees:
219 self.subscriptionsTabWidget.removeTab(
220 self.subscriptionsTabWidget.indexOf(tree))
221 self.__manager.removeSubscription(removeSubscription)
222
223 def __switchSubscriptionEnabled(self):
224 """
225 Private slot to switch the enabled state of the selected subscription
226 """
227 newState = not self.__currentSubscription.isEnabled()
228 self.__setSubscriptionEnabled(self.__currentSubscription, newState)
229
230 def __setSubscriptionEnabled(self, subscription, enable):
231 """
232 Private slot to set the enabled state of a subscription.
233
234 @param subscription subscription to set the state for (AdBlockSubscription)
235 @param enable state to set to (boolean)
236 """
237 if enable:
238 # enable required one as well
239 sub = self.__manager.subscription(subscription.requiresLocation())
240 requiresSubscriptions = [] if sub is None else [sub]
241 icon = UI.PixmapCache.getIcon("adBlockPlus.png")
242 else:
243 # disable dependent ones as well
244 requiresSubscriptions = \
245 self.__manager.getRequiresSubscriptions(subscription)
246 icon = UI.PixmapCache.getIcon("adBlockPlusDisabled.png")
247 requiresSubscriptions.append(subscription)
248 for sub in requiresSubscriptions:
249 sub.setEnabled(enable)
250
251 for index in range(self.subscriptionsTabWidget.count()):
252 tree = self.subscriptionsTabWidget.widget(index)
253 if tree.subscription() in requiresSubscriptions:
254 self.subscriptionsTabWidget.setTabIcon(
255 self.subscriptionsTabWidget.indexOf(tree), icon)
161 256
162 @pyqtSlot(int) 257 @pyqtSlot(int)
163 def on_updateSpinBox_valueChanged(self, value): 258 def on_updateSpinBox_valueChanged(self, value):
164 """ 259 """
165 Private slot to handle changes of the update period. 260 Private slot to handle changes of the update period.
167 @param value update period (integer) 262 @param value update period (integer)
168 """ 263 """
169 if value != Preferences.getHelp("AdBlockUpdatePeriod"): 264 if value != Preferences.getHelp("AdBlockUpdatePeriod"):
170 Preferences.setHelp("AdBlockUpdatePeriod", value) 265 Preferences.setHelp("AdBlockUpdatePeriod", value)
171 266
172 manager = Helpviewer.HelpWindow.HelpWindow.adblockManager() 267 manager = Helpviewer.HelpWindow.HelpWindow.adBlockManager()
173 for subscription in manager.subscriptions(): 268 for subscription in manager.subscriptions():
174 subscription.checkForUpdate() 269 subscription.checkForUpdate()
270
271 @pyqtSlot(int)
272 def on_subscriptionsTabWidget_currentChanged(self, index):
273 """
274 Private slot handling the selection of another tab.
275
276 @param index index of the new current tab (integer)
277 """
278 if index != -1:
279 self.__currentTreeWidget = self.subscriptionsTabWidget.widget(index)
280 self.__currentSubscription = self.__currentTreeWidget.subscription()
281
282 @pyqtSlot(str)
283 def on_searchEdit_textChanged(self, filter):
284 """
285 Private slot to set a new filter on the current widget.
286
287 @param filter filter to be set (string)
288 """
289 if self.__currentTreeWidget and self.adBlockGroup.isChecked():
290 self.__currentTreeWidget.filterString(filter)
291
292 @pyqtSlot(bool)
293 def on_adBlockGroup_toggled(self, state):
294 """
295 Private slot handling the enabling/disabling of AdBlock.
296
297 @param state state of the toggle (boolean)
298 """
299 self.__manager.setEnabled(state)
300
301 if state:
302 self.__load()
175 303
176 def showRule(self, rule): 304 def showRule(self, rule):
177 """ 305 """
178 Public slot to show the given rule. 306 Public slot to show the given rule.
179 307
184 312
185 subscription = rule.subscription() 313 subscription = rule.subscription()
186 if subscription is None: 314 if subscription is None:
187 return 315 return
188 316
189 self.searchEdit.clear() 317 for index in range(self.subscriptionsTabWidget.count()):
190 318 tree = self.subscriptionsTabWidget.widget(index)
191 subscriptionIndex = self.__adBlockModel.subscriptionIndex(subscription) 319 if subscription == tree.subscription():
192 subscriptionProxyIndex = self.__proxyModel.mapFromSource(subscriptionIndex) 320 tree.showRule(rule)
193 filter = rule.filter() 321 self.subscriptionsTabWidget.setCurrentIndex(index)
194 if filter:
195 indexes = self.__proxyModel.match(
196 subscriptionProxyIndex, Qt.DisplayRole, filter, 1,
197 Qt.MatchStartsWith | Qt.MatchRecursive)
198 if indexes:
199 self.subscriptionsTree.expand(subscriptionProxyIndex)
200 self.subscriptionsTree.scrollTo(indexes[0])
201 self.subscriptionsTree.setCurrentIndex(indexes[0])
202 self.raise_() 322 self.raise_()
323 break

eric ide

mercurial