21 |
25 |
22 class AdBlockTreeWidget(EricTreeWidget): |
26 class AdBlockTreeWidget(EricTreeWidget): |
23 """ |
27 """ |
24 Class implementing a tree widget for the AdBlock configuration dialog. |
28 Class implementing a tree widget for the AdBlock configuration dialog. |
25 """ |
29 """ |
|
30 |
26 def __init__(self, subscription, parent=None): |
31 def __init__(self, subscription, parent=None): |
27 """ |
32 """ |
28 Constructor |
33 Constructor |
29 |
34 |
30 @param subscription reference to the subscription |
35 @param subscription reference to the subscription |
31 @type AdBlockSubscription |
36 @type AdBlockSubscription |
32 @param parent reference to the parent widget |
37 @param parent reference to the parent widget |
33 @type QWidget |
38 @type QWidget |
34 """ |
39 """ |
35 super().__init__(parent) |
40 super().__init__(parent) |
36 |
41 |
37 self.__subscription = subscription |
42 self.__subscription = subscription |
38 self.__topItem = None |
43 self.__topItem = None |
39 self.__ruleToBeSelected = "" |
44 self.__ruleToBeSelected = "" |
40 self.__itemChangingBlock = False |
45 self.__itemChangingBlock = False |
41 |
46 |
42 self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) |
47 self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) |
43 self.setDefaultItemShowMode(EricTreeWidgetItemsState.EXPANDED) |
48 self.setDefaultItemShowMode(EricTreeWidgetItemsState.EXPANDED) |
44 self.setHeaderHidden(True) |
49 self.setHeaderHidden(True) |
45 self.setAlternatingRowColors(True) |
50 self.setAlternatingRowColors(True) |
46 |
51 |
47 self.__darkMode = ericApp().usesDarkPalette() |
52 self.__darkMode = ericApp().usesDarkPalette() |
48 |
53 |
49 self.customContextMenuRequested.connect(self.__contextMenuRequested) |
54 self.customContextMenuRequested.connect(self.__contextMenuRequested) |
50 self.itemChanged.connect(self.__itemChanged) |
55 self.itemChanged.connect(self.__itemChanged) |
51 self.__subscription.changed.connect(self.__subscriptionChanged) |
56 self.__subscription.changed.connect(self.__subscriptionChanged) |
52 self.__subscription.rulesChanged.connect(self.__subscriptionChanged) |
57 self.__subscription.rulesChanged.connect(self.__subscriptionChanged) |
53 |
58 |
54 def subscription(self): |
59 def subscription(self): |
55 """ |
60 """ |
56 Public method to get a reference to the subscription. |
61 Public method to get a reference to the subscription. |
57 |
62 |
58 @return reference to the subscription |
63 @return reference to the subscription |
59 @rtype AdBlockSubscription |
64 @rtype AdBlockSubscription |
60 """ |
65 """ |
61 return self.__subscription |
66 return self.__subscription |
62 |
67 |
63 def showRule(self, rule): |
68 def showRule(self, rule): |
64 """ |
69 """ |
65 Public method to highlight the given rule. |
70 Public method to highlight the given rule. |
66 |
71 |
67 @param rule AdBlock rule to be shown |
72 @param rule AdBlock rule to be shown |
68 @type AdBlockRule |
73 @type AdBlockRule |
69 """ |
74 """ |
70 if not bool(self.__topItem) and bool(rule): |
75 if not bool(self.__topItem) and bool(rule): |
71 self.__ruleToBeSelected = rule.filter() |
76 self.__ruleToBeSelected = rule.filter() |
72 elif self.__ruleToBeSelected: |
77 elif self.__ruleToBeSelected: |
73 items = self.findItems( |
78 items = self.findItems(self.__ruleToBeSelected, Qt.MatchFlag.MatchRecursive) |
74 self.__ruleToBeSelected, Qt.MatchFlag.MatchRecursive) |
|
75 if items: |
79 if items: |
76 item = items[0] |
80 item = items[0] |
77 self.setCurrentItem(item) |
81 self.setCurrentItem(item) |
78 self.scrollToItem( |
82 self.scrollToItem(item, QAbstractItemView.ScrollHint.PositionAtCenter) |
79 item, QAbstractItemView.ScrollHint.PositionAtCenter) |
83 |
80 |
|
81 self.__ruleToBeSelected = "" |
84 self.__ruleToBeSelected = "" |
82 |
85 |
83 def refresh(self): |
86 def refresh(self): |
84 """ |
87 """ |
85 Public method to refresh the tree. |
88 Public method to refresh the tree. |
86 """ |
89 """ |
87 with EricOverrideCursor(): |
90 with EricOverrideCursor(): |
88 self.__itemChangingBlock = True |
91 self.__itemChangingBlock = True |
89 self.clear() |
92 self.clear() |
90 |
93 |
91 boldFont = QFont() |
94 boldFont = QFont() |
92 boldFont.setBold(True) |
95 boldFont.setBold(True) |
93 |
96 |
94 self.__topItem = QTreeWidgetItem(self) |
97 self.__topItem = QTreeWidgetItem(self) |
95 self.__topItem.setText(0, self.__subscription.title()) |
98 self.__topItem.setText(0, self.__subscription.title()) |
96 self.__topItem.setFont(0, boldFont) |
99 self.__topItem.setFont(0, boldFont) |
97 self.addTopLevelItem(self.__topItem) |
100 self.addTopLevelItem(self.__topItem) |
98 |
101 |
99 allRules = self.__subscription.allRules() |
102 allRules = self.__subscription.allRules() |
100 |
103 |
101 for index, rule in enumerate(allRules): |
104 for index, rule in enumerate(allRules): |
102 item = QTreeWidgetItem(self.__topItem) |
105 item = QTreeWidgetItem(self.__topItem) |
103 item.setText(0, rule.filter()) |
106 item.setText(0, rule.filter()) |
104 item.setData(0, Qt.ItemDataRole.UserRole, index) |
107 item.setData(0, Qt.ItemDataRole.UserRole, index) |
105 if self.__subscription.canEditRules(): |
108 if self.__subscription.canEditRules(): |
106 item.setFlags(item.flags() | Qt.ItemFlag.ItemIsEditable) |
109 item.setFlags(item.flags() | Qt.ItemFlag.ItemIsEditable) |
107 self.__adjustItemFeatures(item, rule) |
110 self.__adjustItemFeatures(item, rule) |
108 |
111 |
109 self.expandAll() |
112 self.expandAll() |
110 self.showRule(None) |
113 self.showRule(None) |
111 self.__itemChangingBlock = False |
114 self.__itemChangingBlock = False |
112 |
115 |
113 def addRule(self, filterRule=""): |
116 def addRule(self, filterRule=""): |
114 """ |
117 """ |
115 Public slot to add a new rule. |
118 Public slot to add a new rule. |
116 |
119 |
117 @param filterRule filter to be added |
120 @param filterRule filter to be added |
118 @type str |
121 @type str |
119 """ |
122 """ |
120 if not self.__subscription.canEditRules(): |
123 if not self.__subscription.canEditRules(): |
121 return |
124 return |
122 |
125 |
123 if not filterRule: |
126 if not filterRule: |
124 filterRule, ok = QInputDialog.getText( |
127 filterRule, ok = QInputDialog.getText( |
125 self, |
128 self, |
126 self.tr("Add Custom Rule"), |
129 self.tr("Add Custom Rule"), |
127 self.tr("Write your rule here:"), |
130 self.tr("Write your rule here:"), |
128 QLineEdit.EchoMode.Normal) |
131 QLineEdit.EchoMode.Normal, |
|
132 ) |
129 if not ok or filterRule == "": |
133 if not ok or filterRule == "": |
130 return |
134 return |
131 |
135 |
132 from .AdBlockRule import AdBlockRule |
136 from .AdBlockRule import AdBlockRule |
|
137 |
133 rule = AdBlockRule(filterRule, self.__subscription) |
138 rule = AdBlockRule(filterRule, self.__subscription) |
134 self.__subscription.addRule(rule) |
139 self.__subscription.addRule(rule) |
135 |
140 |
136 def removeRule(self): |
141 def removeRule(self): |
137 """ |
142 """ |
138 Public slot to remove the current rule. |
143 Public slot to remove the current rule. |
139 """ |
144 """ |
140 item = self.currentItem() |
145 item = self.currentItem() |
141 if ( |
146 if ( |
142 item is None or |
147 item is None |
143 not self.__subscription.canEditRules() or |
148 or not self.__subscription.canEditRules() |
144 item == self.__topItem |
149 or item == self.__topItem |
145 ): |
150 ): |
146 return |
151 return |
147 |
152 |
148 offset = item.data(0, Qt.ItemDataRole.UserRole) |
153 offset = item.data(0, Qt.ItemDataRole.UserRole) |
149 self.__subscription.removeRule(offset) |
154 self.__subscription.removeRule(offset) |
150 self.deleteItem(item) |
155 self.deleteItem(item) |
151 |
156 |
152 def __contextMenuRequested(self, pos): |
157 def __contextMenuRequested(self, pos): |
153 """ |
158 """ |
154 Private slot to show the context menu. |
159 Private slot to show the context menu. |
155 |
160 |
156 @param pos position for the menu |
161 @param pos position for the menu |
157 @type QPoint |
162 @type QPoint |
158 """ |
163 """ |
159 if not self.__subscription.canEditRules(): |
164 if not self.__subscription.canEditRules(): |
160 return |
165 return |
161 |
166 |
162 item = self.itemAt(pos) |
167 item = self.itemAt(pos) |
163 if item is None: |
168 if item is None: |
164 return |
169 return |
165 |
170 |
166 menu = QMenu() |
171 menu = QMenu() |
167 menu.addAction(self.tr("Add Rule"), self.addRule) |
172 menu.addAction(self.tr("Add Rule"), self.addRule) |
168 menu.addSeparator() |
173 menu.addSeparator() |
169 act = menu.addAction(self.tr("Remove Rule"), self.removeRule) |
174 act = menu.addAction(self.tr("Remove Rule"), self.removeRule) |
170 if item.parent() is None: |
175 if item.parent() is None: |
171 act.setDisabled(True) |
176 act.setDisabled(True) |
172 |
177 |
173 menu.exec(self.viewport().mapToGlobal(pos)) |
178 menu.exec(self.viewport().mapToGlobal(pos)) |
174 |
179 |
175 def __itemChanged(self, itm): |
180 def __itemChanged(self, itm): |
176 """ |
181 """ |
177 Private slot to handle the change of an item. |
182 Private slot to handle the change of an item. |
178 |
183 |
179 @param itm changed item |
184 @param itm changed item |
180 @type QTreeWidgetItem |
185 @type QTreeWidgetItem |
181 """ |
186 """ |
182 if itm is None or self.__itemChangingBlock: |
187 if itm is None or self.__itemChangingBlock: |
183 return |
188 return |
184 |
189 |
185 self.__itemChangingBlock = True |
190 self.__itemChangingBlock = True |
186 |
191 |
187 offset = itm.data(0, Qt.ItemDataRole.UserRole) |
192 offset = itm.data(0, Qt.ItemDataRole.UserRole) |
188 oldRule = self.__subscription.rule(offset) |
193 oldRule = self.__subscription.rule(offset) |
189 |
194 |
190 if ( |
195 if itm.checkState(0) == Qt.CheckState.Unchecked and oldRule.isEnabled(): |
191 itm.checkState(0) == Qt.CheckState.Unchecked and |
|
192 oldRule.isEnabled() |
|
193 ): |
|
194 # Disable rule |
196 # Disable rule |
195 rule = self.__subscription.setRuleEnabled(offset, False) |
197 rule = self.__subscription.setRuleEnabled(offset, False) |
196 self.__adjustItemFeatures(itm, rule) |
198 self.__adjustItemFeatures(itm, rule) |
197 elif ( |
199 elif itm.checkState(0) == Qt.CheckState.Checked and not oldRule.isEnabled(): |
198 itm.checkState(0) == Qt.CheckState.Checked and |
|
199 not oldRule.isEnabled() |
|
200 ): |
|
201 # Enable rule |
200 # Enable rule |
202 rule = self.__subscription.setRuleEnabled(offset, True) |
201 rule = self.__subscription.setRuleEnabled(offset, True) |
203 self.__adjustItemFeatures(itm, rule) |
202 self.__adjustItemFeatures(itm, rule) |
204 elif self.__subscription.canEditRules(): |
203 elif self.__subscription.canEditRules(): |
205 from .AdBlockRule import AdBlockRule |
204 from .AdBlockRule import AdBlockRule |
|
205 |
206 # Custom rule has been changed |
206 # Custom rule has been changed |
207 rule = self.__subscription.replaceRule( |
207 rule = self.__subscription.replaceRule( |
208 AdBlockRule(itm.text(0), self.__subscription), offset) |
208 AdBlockRule(itm.text(0), self.__subscription), offset |
|
209 ) |
209 self.__adjustItemFeatures(itm, rule) |
210 self.__adjustItemFeatures(itm, rule) |
210 |
211 |
211 self.__itemChangingBlock = False |
212 self.__itemChangingBlock = False |
212 |
213 |
213 def __copyFilter(self): |
214 def __copyFilter(self): |
214 """ |
215 """ |
215 Private slot to copy the current filter to the clipboard. |
216 Private slot to copy the current filter to the clipboard. |
216 """ |
217 """ |
217 item = self.currentItem() |
218 item = self.currentItem() |
218 if item is not None: |
219 if item is not None: |
219 QApplication.clipboard().setText(item.text(0)) |
220 QApplication.clipboard().setText(item.text(0)) |
220 |
221 |
221 def __subscriptionChanged(self): |
222 def __subscriptionChanged(self): |
222 """ |
223 """ |
223 Private slot handling a subscription change. |
224 Private slot handling a subscription change. |
224 """ |
225 """ |
225 self.refresh() |
226 self.refresh() |
226 |
227 |
227 self.__itemChangingBlock = True |
228 self.__itemChangingBlock = True |
228 self.__topItem.setText( |
229 self.__topItem.setText( |
229 0, self.tr("{0} (recently updated)").format( |
230 0, self.tr("{0} (recently updated)").format(self.__subscription.title()) |
230 self.__subscription.title())) |
231 ) |
231 self.__itemChangingBlock = False |
232 self.__itemChangingBlock = False |
232 |
233 |
233 def __adjustItemFeatures(self, itm, rule): |
234 def __adjustItemFeatures(self, itm, rule): |
234 """ |
235 """ |
235 Private method to adjust an item. |
236 Private method to adjust an item. |
236 |
237 |
237 @param itm item to be adjusted |
238 @param itm item to be adjusted |
238 @type QTreeWidgetItem |
239 @type QTreeWidgetItem |
239 @param rule rule for the adjustment |
240 @param rule rule for the adjustment |
240 @type AdBlockRule |
241 @type AdBlockRule |
241 """ |
242 """ |