src/eric7/WebBrowser/TabManager/TabManagerWidget.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9413
80c06d472826
equal deleted inserted replaced
9220:e9e7eca7efee 9221:bf71ee032bb4
16 import collections 16 import collections
17 17
18 from PyQt6.QtCore import pyqtSignal, pyqtSlot, Qt, QPoint, QTimer, QRect 18 from PyQt6.QtCore import pyqtSignal, pyqtSlot, Qt, QPoint, QTimer, QRect
19 from PyQt6.QtGui import QAction 19 from PyQt6.QtGui import QAction
20 from PyQt6.QtWidgets import ( 20 from PyQt6.QtWidgets import (
21 QWidget, QVBoxLayout, QTreeWidget, QTreeWidgetItem, QMenu, QStyle 21 QWidget,
22 QVBoxLayout,
23 QTreeWidget,
24 QTreeWidgetItem,
25 QMenu,
26 QStyle,
22 ) 27 )
23 28
24 from EricNetwork import EricTldExtractor, EricNetworkUtilities 29 from EricNetwork import EricTldExtractor, EricNetworkUtilities
25 30
26 from EricWidgets.EricApplication import ericApp 31 from EricWidgets.EricApplication import ericApp
32 37
33 38
34 class TabManagerWidget(QWidget): 39 class TabManagerWidget(QWidget):
35 """ 40 """
36 Class implementing a window for managing the web browser tabs. 41 Class implementing a window for managing the web browser tabs.
37 42
38 @signal groupTypeChanged(int) emitted when the 'Group By' value was changed 43 @signal groupTypeChanged(int) emitted when the 'Group By' value was changed
39 """ 44 """
45
40 GroupByWindow = 0 46 GroupByWindow = 0
41 GroupByDomain = 1 47 GroupByDomain = 1
42 GroupByHost = 2 48 GroupByHost = 2
43 49
44 WebBrowserRole = Qt.ItemDataRole.UserRole + 1 50 WebBrowserRole = Qt.ItemDataRole.UserRole + 1
45 WebWindowRole = Qt.ItemDataRole.UserRole + 2 51 WebWindowRole = Qt.ItemDataRole.UserRole + 2
46 52
47 groupTypeChanged = pyqtSignal(int) 53 groupTypeChanged = pyqtSignal(int)
48 54
49 _tldExtractor = None 55 _tldExtractor = None
50 56
51 def __init__(self, mainWindow, parent=None, defaultWidget=False): 57 def __init__(self, mainWindow, parent=None, defaultWidget=False):
52 """ 58 """
53 Constructor 59 Constructor
54 60
55 @param mainWindow reference to the main window 61 @param mainWindow reference to the main window
56 @type WebBrowserWindow 62 @type WebBrowserWindow
57 @param parent reference to the parent widget 63 @param parent reference to the parent widget
58 @type QWidget 64 @type QWidget
59 @param defaultWidget flag indicating the default widget 65 @param defaultWidget flag indicating the default widget
60 @type bool 66 @type bool
61 """ 67 """
62 super().__init__(parent) 68 super().__init__(parent)
63 self.setWindowFlags(Qt.WindowType.Window) 69 self.setWindowFlags(Qt.WindowType.Window)
64 70
65 self.__layout = QVBoxLayout(self) 71 self.__layout = QVBoxLayout(self)
66 self.__layout.setContentsMargins(0, 0, 0, 0) 72 self.__layout.setContentsMargins(0, 0, 0, 0)
67 self.__tree = QTreeWidget(self) 73 self.__tree = QTreeWidget(self)
68 self.__tree.setHeaderHidden(True) 74 self.__tree.setHeaderHidden(True)
69 self.__tree.setExpandsOnDoubleClick(False) 75 self.__tree.setExpandsOnDoubleClick(False)
70 self.__tree.setContextMenuPolicy( 76 self.__tree.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
71 Qt.ContextMenuPolicy.CustomContextMenu)
72 self.__layout.addWidget(self.__tree) 77 self.__layout.addWidget(self.__tree)
73 78
74 self.setWindowTitle(self.tr("Tab Manager")) 79 self.setWindowTitle(self.tr("Tab Manager"))
75 80
76 self.__mw = mainWindow 81 self.__mw = mainWindow
77 self.__page = None 82 self.__page = None
78 83
79 self.__isRefreshing = False 84 self.__isRefreshing = False
80 self.__refreshBlocked = False 85 self.__refreshBlocked = False
81 self.__waitForRefresh = False 86 self.__waitForRefresh = False
82 self.__isDefaultWidget = defaultWidget 87 self.__isDefaultWidget = defaultWidget
83 self.__groupType = Preferences.getWebBrowser("TabManagerGroupByType") 88 self.__groupType = Preferences.getWebBrowser("TabManagerGroupByType")
84 89
85 if TabManagerWidget._tldExtractor is None: 90 if TabManagerWidget._tldExtractor is None:
86 TabManagerWidget._tldExtractor = EricTldExtractor.instance() 91 TabManagerWidget._tldExtractor = EricTldExtractor.instance()
87 TabManagerWidget._tldExtractor.setDataSearchPaths([ 92 TabManagerWidget._tldExtractor.setDataSearchPaths(
88 os.path.join(Utilities.getConfigDir(), "web_browser")]) 93 [os.path.join(Utilities.getConfigDir(), "web_browser")]
89 94 )
95
90 self.__tree.itemDoubleClicked.connect(self.__itemDoubleClicked) 96 self.__tree.itemDoubleClicked.connect(self.__itemDoubleClicked)
91 self.__tree.customContextMenuRequested.connect( 97 self.__tree.customContextMenuRequested.connect(
92 self.__customContextMenuRequested) 98 self.__customContextMenuRequested
93 99 )
100
94 self.resize(400, 600) 101 self.resize(400, 600)
95 102
96 def closeSelectedBrowsers(self, browsersDict): 103 def closeSelectedBrowsers(self, browsersDict):
97 """ 104 """
98 Public method to close the selected browsers. 105 Public method to close the selected browsers.
99 106
100 @param browsersDict dictionary containing the browsers per window 107 @param browsersDict dictionary containing the browsers per window
101 @type dict with WebBrowserWindow as key and list of WebBrowserView 108 @type dict with WebBrowserWindow as key and list of WebBrowserView
102 as value 109 as value
103 """ 110 """
104 if not browsersDict: 111 if not browsersDict:
105 return 112 return
106 113
107 for mainWindow in browsersDict: 114 for mainWindow in browsersDict:
108 tabWidget = mainWindow.tabWidget() 115 tabWidget = mainWindow.tabWidget()
109 for browser in browsersDict[mainWindow]: 116 for browser in browsersDict[mainWindow]:
110 tabWidget.closeBrowserAt(tabWidget.indexOf(browser)) 117 tabWidget.closeBrowserAt(tabWidget.indexOf(browser))
111 118
112 def bookmarkSelectedBrowsers(self, browsersDict): 119 def bookmarkSelectedBrowsers(self, browsersDict):
113 """ 120 """
114 Public method to bookmark the selected browsers. 121 Public method to bookmark the selected browsers.
115 122
116 @param browsersDict dictionary containing the browsers per window 123 @param browsersDict dictionary containing the browsers per window
117 @type dict with WebBrowserWindow as key and list of WebBrowserView 124 @type dict with WebBrowserWindow as key and list of WebBrowserView
118 as value 125 as value
119 """ 126 """
120 if not browsersDict: 127 if not browsersDict:
121 return 128 return
122 129
123 from ..Bookmarks.BookmarkNode import BookmarkNode 130 from ..Bookmarks.BookmarkNode import BookmarkNode
124 from ..Bookmarks.AddBookmarkDialog import AddBookmarkDialog 131 from ..Bookmarks.AddBookmarkDialog import AddBookmarkDialog
125 132
126 dlg = AddBookmarkDialog() 133 dlg = AddBookmarkDialog()
127 dlg.setFolder(True) 134 dlg.setFolder(True)
128 dlg.setTitle(self.tr("Saved Tabs")) 135 dlg.setTitle(self.tr("Saved Tabs"))
129 dlg.exec() 136 dlg.exec()
130 137
131 folder = dlg.addedNode() 138 folder = dlg.addedNode()
132 if folder is None: 139 if folder is None:
133 return 140 return
134 141
135 for mainWin in browsersDict: 142 for mainWin in browsersDict:
136 for browser in browsersDict[mainWin]: 143 for browser in browsersDict[mainWin]:
137 if ( 144 if not browser.url().isEmpty() and browser.url().scheme() != "eric":
138 not browser.url().isEmpty() and
139 browser.url().scheme() != "eric"
140 ):
141 bookmark = BookmarkNode(BookmarkNode.Bookmark) 145 bookmark = BookmarkNode(BookmarkNode.Bookmark)
142 bookmark.url = bytes(browser.url().toEncoded()).decode() 146 bookmark.url = bytes(browser.url().toEncoded()).decode()
143 bookmark.title = browser.title() 147 bookmark.title = browser.title()
144 148
145 self.__mw.bookmarksManager().addBookmark(folder, bookmark) 149 self.__mw.bookmarksManager().addBookmark(folder, bookmark)
146 150
147 def __setGroupType(self, groupType): 151 def __setGroupType(self, groupType):
148 """ 152 """
149 Private method to set the 'Group By' type. 153 Private method to set the 'Group By' type.
150 154
151 @param groupType 'Group By' type to be set 155 @param groupType 'Group By' type to be set
152 @type int (0 - 2) 156 @type int (0 - 2)
153 """ 157 """
154 self.__groupType = groupType 158 self.__groupType = groupType
155 Preferences.setWebBrowser("TabManagerGroupByType", groupType) 159 Preferences.setWebBrowser("TabManagerGroupByType", groupType)
156 160
157 def domainFromUrl(self, url, useHostName=False): 161 def domainFromUrl(self, url, useHostName=False):
158 """ 162 """
159 Public method to extract the domain from an URL. 163 Public method to extract the domain from an URL.
160 164
161 @param url URL to extract the domain from 165 @param url URL to extract the domain from
162 @type QUrl 166 @type QUrl
163 @param useHostName flag indicating to use the host name 167 @param useHostName flag indicating to use the host name
164 @type bool 168 @type bool
165 @return domain name 169 @return domain name
166 @rtype str 170 @rtype str
167 """ 171 """
168 appendStr = ":" 172 appendStr = ":"
169 urlString = url.toString() 173 urlString = url.toString()
170 174
171 if url.scheme() == "file": 175 if url.scheme() == "file":
172 return self.tr("Local File System:") 176 return self.tr("Local File System:")
173 elif url.scheme() == "eric" or not urlString: 177 elif url.scheme() == "eric" or not urlString:
174 return self.tr("eric Web Browser:") 178 return self.tr("eric Web Browser:")
175 elif url.scheme() == "ftp": 179 elif url.scheme() == "ftp":
176 appendStr = self.tr(" [FTP]:") 180 appendStr = self.tr(" [FTP]:")
177 181
178 host = url.host() 182 host = url.host()
179 if not host: 183 if not host:
180 return urlString + appendStr 184 return urlString + appendStr
181 185
182 if useHostName or EricNetworkUtilities.isValidAddress(host): 186 if useHostName or EricNetworkUtilities.isValidAddress(host):
183 if host.lower().startswith("www."): 187 if host.lower().startswith("www."):
184 host = host[4:] 188 host = host[4:]
185 else: 189 else:
186 registeredDomain = ( 190 registeredDomain = TabManagerWidget._tldExtractor.registrableDomain(host)
187 TabManagerWidget._tldExtractor.registrableDomain(host)
188 )
189 if registeredDomain: 191 if registeredDomain:
190 host = registeredDomain 192 host = registeredDomain
191 193
192 return host + appendStr 194 return host + appendStr
193 195
194 def delayedRefreshTree(self, page=None): 196 def delayedRefreshTree(self, page=None):
195 """ 197 """
196 Public slot to do a delyed refresh of the tree. 198 Public slot to do a delyed refresh of the tree.
197 199
198 @param page reference to the web page 200 @param page reference to the web page
199 @type WebBrowserPage 201 @type WebBrowserPage
200 """ 202 """
201 if self.__refreshBlocked or self.__waitForRefresh: 203 if self.__refreshBlocked or self.__waitForRefresh:
202 return 204 return
203 205
204 if self.__isRefreshing and not page: 206 if self.__isRefreshing and not page:
205 return 207 return
206 208
207 self.__page = page 209 self.__page = page
208 self.__waitForRefresh = True 210 self.__waitForRefresh = True
209 QTimer.singleShot(50, self.__refreshTree) 211 QTimer.singleShot(50, self.__refreshTree)
210 212
211 def changeGroupType(self, act): 213 def changeGroupType(self, act):
212 """ 214 """
213 Public slot to change the 'Group By' type. 215 Public slot to change the 'Group By' type.
214 216
215 @param act reference to the action that was triggered 217 @param act reference to the action that was triggered
216 @type QAction 218 @type QAction
217 """ 219 """
218 if act is None: 220 if act is None:
219 return 221 return
220 222
221 groupType = act.data() 223 groupType = act.data()
222 if self.__groupType != groupType: 224 if self.__groupType != groupType:
223 self.__setGroupType(groupType) 225 self.__setGroupType(groupType)
224 self.delayedRefreshTree() 226 self.delayedRefreshTree()
225 self.groupTypeChanged.emit(self.__groupType) 227 self.groupTypeChanged.emit(self.__groupType)
226 228
227 def __createEmptyItem(self, parent=None, addToTree=True): 229 def __createEmptyItem(self, parent=None, addToTree=True):
228 """ 230 """
229 Private method to create an empty tree item. 231 Private method to create an empty tree item.
230 232
231 @param parent reference to the parent item 233 @param parent reference to the parent item
232 @type QTreeWidgetItem or QTreeWidget 234 @type QTreeWidgetItem or QTreeWidget
233 @param addToTree flag indicating to add the item to the tree 235 @param addToTree flag indicating to add the item to the tree
234 @type bool 236 @type bool
235 @return created item 237 @return created item
243 else: 245 else:
244 parentItem = None 246 parentItem = None
245 itm = QTreeWidgetItem(parentItem) 247 itm = QTreeWidgetItem(parentItem)
246 addFlags = ( 248 addFlags = (
247 Qt.ItemFlag.ItemIsUserCheckable 249 Qt.ItemFlag.ItemIsUserCheckable
248 if parent else 250 if parent
249 (Qt.ItemFlag.ItemIsUserCheckable | Qt.ItemFlag.ItemIsAutoTristate) 251 else (Qt.ItemFlag.ItemIsUserCheckable | Qt.ItemFlag.ItemIsAutoTristate)
250 ) 252 )
251 itm.setFlags(itm.flags() | addFlags) 253 itm.setFlags(itm.flags() | addFlags)
252 itm.setCheckState(0, Qt.CheckState.Unchecked) 254 itm.setCheckState(0, Qt.CheckState.Unchecked)
253 255
254 return itm 256 return itm
255 257
256 def __groupByDomainName(self, useHostName=False): 258 def __groupByDomainName(self, useHostName=False):
257 """ 259 """
258 Private method to group the tree items by domain name. 260 Private method to group the tree items by domain name.
259 261
260 @param useHostName flag indicating to use the host name 262 @param useHostName flag indicating to use the host name
261 @type bool 263 @type bool
262 """ 264 """
263 windows = self.__mw.mainWindows() 265 windows = self.__mw.mainWindows()
264 266
265 tabsGroupedByDomain = {} 267 tabsGroupedByDomain = {}
266 268
267 for mainWin in windows: 269 for mainWin in windows:
268 for browser in mainWin.tabWidget().browsers(): 270 for browser in mainWin.tabWidget().browsers():
269 if self.__page == browser.page(): 271 if self.__page == browser.page():
270 self.__page = None 272 self.__page = None
271 continue 273 continue
272 domain = self.domainFromUrl(browser.url(), useHostName) 274 domain = self.domainFromUrl(browser.url(), useHostName)
273 275
274 if domain not in tabsGroupedByDomain: 276 if domain not in tabsGroupedByDomain:
275 groupItem = self.__createEmptyItem(None, False) 277 groupItem = self.__createEmptyItem(None, False)
276 groupItem.setText(0, domain) 278 groupItem.setText(0, domain)
277 groupItem.setToolTip(0, domain) 279 groupItem.setToolTip(0, domain)
278 font = groupItem.font(0) 280 font = groupItem.font(0)
279 font.setBold(True) 281 font.setBold(True)
280 groupItem.setFont(0, font) 282 groupItem.setFont(0, font)
281 tabsGroupedByDomain[domain] = groupItem 283 tabsGroupedByDomain[domain] = groupItem
282 groupItem = tabsGroupedByDomain[domain] 284 groupItem = tabsGroupedByDomain[domain]
283 285
284 tabItem = self.__createEmptyItem(groupItem) 286 tabItem = self.__createEmptyItem(groupItem)
285 if browser == mainWin.tabWidget().currentBrowser(): 287 if browser == mainWin.tabWidget().currentBrowser():
286 font = tabItem.font(0) 288 font = tabItem.font(0)
287 font.setBold(True) 289 font.setBold(True)
288 tabItem.setFont(0, font) 290 tabItem.setFont(0, font)
290 tabItem.setIcon(0, browser.icon()) 292 tabItem.setIcon(0, browser.icon())
291 else: 293 else:
292 tabItem.setIcon(0, UI.PixmapCache.getIcon("loading")) 294 tabItem.setIcon(0, UI.PixmapCache.getIcon("loading"))
293 tabItem.setText(0, browser.title()) 295 tabItem.setText(0, browser.title())
294 tabItem.setToolTip(0, browser.title()) 296 tabItem.setToolTip(0, browser.title())
295 297
296 tabItem.setData(0, TabManagerWidget.WebBrowserRole, browser) 298 tabItem.setData(0, TabManagerWidget.WebBrowserRole, browser)
297 tabItem.setData(0, TabManagerWidget.WebWindowRole, mainWin) 299 tabItem.setData(0, TabManagerWidget.WebWindowRole, mainWin)
298 300
299 self.__makeWebBrowserViewConnections(browser) 301 self.__makeWebBrowserViewConnections(browser)
300 302
301 self.__tree.insertTopLevelItems(0, tabsGroupedByDomain.values()) 303 self.__tree.insertTopLevelItems(0, tabsGroupedByDomain.values())
302 304
303 def __groupByWindow(self): 305 def __groupByWindow(self):
304 """ 306 """
305 Private method to group the tree items by window. 307 Private method to group the tree items by window.
306 """ 308 """
307 windows = self.__mw.mainWindows() 309 windows = self.__mw.mainWindows()
308 310
309 self.__isRefreshing = True 311 self.__isRefreshing = True
310 312
311 for winCount, mainWin in enumerate(windows, start=1): 313 for winCount, mainWin in enumerate(windows, start=1):
312 winItem = self.__createEmptyItem() 314 winItem = self.__createEmptyItem()
313 winItem.setText(0, self.tr("Window {0}").format(winCount)) 315 winItem.setText(0, self.tr("Window {0}").format(winCount))
314 winItem.setToolTip(0, self.tr("Double click to switch")) 316 winItem.setToolTip(0, self.tr("Double click to switch"))
315 if mainWin == self.__mw: 317 if mainWin == self.__mw:
316 font = winItem.font(0) 318 font = winItem.font(0)
317 font.setBold(True) 319 font.setBold(True)
318 winItem.setFont(0, font) 320 winItem.setFont(0, font)
319 winItem.setData(0, TabManagerWidget.WebWindowRole, mainWin) 321 winItem.setData(0, TabManagerWidget.WebWindowRole, mainWin)
320 322
321 for browser in mainWin.tabWidget().browsers(): 323 for browser in mainWin.tabWidget().browsers():
322 if self.__page == browser.page(): 324 if self.__page == browser.page():
323 self.__page = None 325 self.__page = None
324 continue 326 continue
325 327
326 tabItem = self.__createEmptyItem(winItem) 328 tabItem = self.__createEmptyItem(winItem)
327 if browser == mainWin.tabWidget().currentBrowser(): 329 if browser == mainWin.tabWidget().currentBrowser():
328 font = tabItem.font(0) 330 font = tabItem.font(0)
329 font.setBold(True) 331 font.setBold(True)
330 tabItem.setFont(0, font) 332 tabItem.setFont(0, font)
332 tabItem.setIcon(0, browser.icon()) 334 tabItem.setIcon(0, browser.icon())
333 else: 335 else:
334 tabItem.setIcon(0, UI.PixmapCache.getIcon("loading")) 336 tabItem.setIcon(0, UI.PixmapCache.getIcon("loading"))
335 tabItem.setText(0, browser.title()) 337 tabItem.setText(0, browser.title())
336 tabItem.setToolTip(0, browser.title()) 338 tabItem.setToolTip(0, browser.title())
337 339
338 tabItem.setData(0, TabManagerWidget.WebBrowserRole, browser) 340 tabItem.setData(0, TabManagerWidget.WebBrowserRole, browser)
339 tabItem.setData(0, TabManagerWidget.WebWindowRole, mainWin) 341 tabItem.setData(0, TabManagerWidget.WebWindowRole, mainWin)
340 342
341 self.__makeWebBrowserViewConnections(browser) 343 self.__makeWebBrowserViewConnections(browser)
342 344
343 def __makeWebBrowserViewConnections(self, view): 345 def __makeWebBrowserViewConnections(self, view):
344 """ 346 """
345 Private method to create the signal connections to the web view. 347 Private method to create the signal connections to the web view.
346 348
347 @param view reference to the web view 349 @param view reference to the web view
348 @type WebBrowserView 350 @type WebBrowserView
349 """ 351 """
350 if view: 352 if view:
351 view.loadFinished.connect(self.delayedRefreshTree) 353 view.loadFinished.connect(self.delayedRefreshTree)
352 view.loadStarted.connect(self.delayedRefreshTree) 354 view.loadStarted.connect(self.delayedRefreshTree)
353 view.titleChanged.connect(self.delayedRefreshTree) 355 view.titleChanged.connect(self.delayedRefreshTree)
354 view.faviconChanged.connect(self.delayedRefreshTree) 356 view.faviconChanged.connect(self.delayedRefreshTree)
355 357
356 @pyqtSlot() 358 @pyqtSlot()
357 def __refreshTree(self): 359 def __refreshTree(self):
358 """ 360 """
359 Private slot to referesh the tree. 361 Private slot to referesh the tree.
360 """ 362 """
361 if self.__refreshBlocked: 363 if self.__refreshBlocked:
362 return 364 return
363 365
364 if self.__isRefreshing and not self.__page: 366 if self.__isRefreshing and not self.__page:
365 return 367 return
366 368
367 # store selected items 369 # store selected items
368 selectedBrowsers = [] 370 selectedBrowsers = []
369 for index in range(self.__tree.topLevelItemCount()): 371 for index in range(self.__tree.topLevelItemCount()):
370 winItem = self.__tree.topLevelItem(index) 372 winItem = self.__tree.topLevelItem(index)
371 if winItem.checkState(0) == Qt.CheckState.Unchecked: 373 if winItem.checkState(0) == Qt.CheckState.Unchecked:
372 continue 374 continue
373 375
374 for row in range(winItem.childCount()): 376 for row in range(winItem.childCount()):
375 tabItem = winItem.child(row) 377 tabItem = winItem.child(row)
376 if tabItem.checkState(0) == Qt.CheckState.Unchecked: 378 if tabItem.checkState(0) == Qt.CheckState.Unchecked:
377 continue 379 continue
378 selectedBrowsers.append( 380 selectedBrowsers.append(
379 tabItem.data(0, TabManagerWidget.WebBrowserRole)) 381 tabItem.data(0, TabManagerWidget.WebBrowserRole)
380 382 )
383
381 self.__tree.clear() 384 self.__tree.clear()
382 385
383 if self.__groupType == TabManagerWidget.GroupByHost: 386 if self.__groupType == TabManagerWidget.GroupByHost:
384 self.__groupByDomainName(True) 387 self.__groupByDomainName(True)
385 elif self.__groupType == TabManagerWidget.GroupByDomain: 388 elif self.__groupType == TabManagerWidget.GroupByDomain:
386 self.__groupByDomainName() 389 self.__groupByDomainName()
387 else: 390 else:
388 # default is group by window 391 # default is group by window
389 self.__setGroupType(TabManagerWidget.GroupByWindow) 392 self.__setGroupType(TabManagerWidget.GroupByWindow)
390 self.__groupByWindow() 393 self.__groupByWindow()
391 394
392 # restore selected items 395 # restore selected items
393 for index in range(self.__tree.topLevelItemCount()): 396 for index in range(self.__tree.topLevelItemCount()):
394 winItem = self.__tree.topLevelItem(index) 397 winItem = self.__tree.topLevelItem(index)
395 398
396 for row in range(winItem.childCount()): 399 for row in range(winItem.childCount()):
397 tabItem = winItem.child(row) 400 tabItem = winItem.child(row)
398 if tabItem.data(0, TabManagerWidget.WebBrowserRole) in ( 401 if tabItem.data(0, TabManagerWidget.WebBrowserRole) in (
399 selectedBrowsers 402 selectedBrowsers
400 ): 403 ):
401 tabItem.setCheckState(0, Qt.CheckState.Checked) 404 tabItem.setCheckState(0, Qt.CheckState.Checked)
402 405
403 self.__tree.expandAll() 406 self.__tree.expandAll()
404 self.__isRefreshing = False 407 self.__isRefreshing = False
405 self.__waitForRefresh = False 408 self.__waitForRefresh = False
406 409
407 @pyqtSlot() 410 @pyqtSlot()
408 def __processActions(self, act): 411 def __processActions(self, act):
409 """ 412 """
410 Private slot to process the actions. 413 Private slot to process the actions.
411 414
412 @param act reference to the action that triggered 415 @param act reference to the action that triggered
413 @type QAction 416 @type QAction
414 """ 417 """
415 self.__refreshBlocked = True 418 self.__refreshBlocked = True
416 419
417 selectedBrowsers = collections.defaultdict(list) 420 selectedBrowsers = collections.defaultdict(list)
418 421
419 command = act.objectName() 422 command = act.objectName()
420 423
421 for index in range(self.__tree.topLevelItemCount()): 424 for index in range(self.__tree.topLevelItemCount()):
422 winItem = self.__tree.topLevelItem(index) 425 winItem = self.__tree.topLevelItem(index)
423 if winItem.checkState(0) == Qt.CheckState.Unchecked: 426 if winItem.checkState(0) == Qt.CheckState.Unchecked:
424 continue 427 continue
425 428
426 for row in range(winItem.childCount()): 429 for row in range(winItem.childCount()):
427 tabItem = winItem.child(row) 430 tabItem = winItem.child(row)
428 if tabItem.checkState(0) == Qt.CheckState.Unchecked: 431 if tabItem.checkState(0) == Qt.CheckState.Unchecked:
429 continue 432 continue
430 433
431 mainWin = tabItem.data(0, TabManagerWidget.WebWindowRole) 434 mainWin = tabItem.data(0, TabManagerWidget.WebWindowRole)
432 browser = tabItem.data(0, TabManagerWidget.WebBrowserRole) 435 browser = tabItem.data(0, TabManagerWidget.WebBrowserRole)
433 436
434 selectedBrowsers[mainWin].append(browser) 437 selectedBrowsers[mainWin].append(browser)
435 438
436 winItem.setCheckState(0, Qt.CheckState.Unchecked) 439 winItem.setCheckState(0, Qt.CheckState.Unchecked)
437 440
438 if selectedBrowsers: 441 if selectedBrowsers:
439 if command == "closeSelection": 442 if command == "closeSelection":
440 self.closeSelectedBrowsers(selectedBrowsers) 443 self.closeSelectedBrowsers(selectedBrowsers)
441 elif command == "bookmarkSelection": 444 elif command == "bookmarkSelection":
442 self.bookmarkSelectedBrowsers(selectedBrowsers) 445 self.bookmarkSelectedBrowsers(selectedBrowsers)
443 446
444 self.__refreshBlocked = False 447 self.__refreshBlocked = False
445 self.delayedRefreshTree() 448 self.delayedRefreshTree()
446 449
447 @pyqtSlot(QTreeWidgetItem, int) 450 @pyqtSlot(QTreeWidgetItem, int)
448 def __itemDoubleClicked(self, itm, column): 451 def __itemDoubleClicked(self, itm, column):
449 """ 452 """
450 Private slot to handle double clicking a tree item. 453 Private slot to handle double clicking a tree item.
451 454
452 @param itm reference to the item having been double clicked 455 @param itm reference to the item having been double clicked
453 @type QTreeWidgetItem 456 @type QTreeWidgetItem
454 @param column column of the double click 457 @param column column of the double click
455 @type int 458 @type int
456 """ 459 """
457 if not itm: 460 if not itm:
458 return 461 return
459 462
460 mainWin = itm.data(0, TabManagerWidget.WebWindowRole) 463 mainWin = itm.data(0, TabManagerWidget.WebWindowRole)
461 browser = itm.data(0, TabManagerWidget.WebBrowserRole) 464 browser = itm.data(0, TabManagerWidget.WebBrowserRole)
462 465
463 if not mainWin: 466 if not mainWin:
464 return 467 return
465 468
466 if mainWin.isMinimized(): 469 if mainWin.isMinimized():
467 mainWin.showNormal() 470 mainWin.showNormal()
468 else: 471 else:
469 mainWin.show() 472 mainWin.show()
470 mainWin.activateWindow() 473 mainWin.activateWindow()
471 mainWin.raise_() 474 mainWin.raise_()
472 mainWin.setFocus() 475 mainWin.setFocus()
473 476
474 tabWidget = mainWin.tabWidget() 477 tabWidget = mainWin.tabWidget()
475 if browser and browser != tabWidget.currentWidget(): 478 if browser and browser != tabWidget.currentWidget():
476 tabWidget.setCurrentWidget(browser) 479 tabWidget.setCurrentWidget(browser)
477 browser.setFocus() 480 browser.setFocus()
478 481
479 @pyqtSlot() 482 @pyqtSlot()
480 def __isBrowserSelected(self): 483 def __isBrowserSelected(self):
481 """ 484 """
482 Private slot to check, if any browser entry is selected. 485 Private slot to check, if any browser entry is selected.
483 486
484 @return flag indicating the existence of a selected entry 487 @return flag indicating the existence of a selected entry
485 @rtype bool 488 @rtype bool
486 """ 489 """
487 selected = False 490 selected = False
488 for topRow in range(self.__tree.topLevelItemCount()): 491 for topRow in range(self.__tree.topLevelItemCount()):
489 topItm = self.__tree.topLevelItem(topRow) 492 topItm = self.__tree.topLevelItem(topRow)
490 if topItm.checkState(0) != Qt.CheckState.Unchecked: 493 if topItm.checkState(0) != Qt.CheckState.Unchecked:
491 selected = True 494 selected = True
492 break 495 break
493 496
494 return selected 497 return selected
495 498
496 @pyqtSlot(QPoint) 499 @pyqtSlot(QPoint)
497 def __customContextMenuRequested(self, pos): 500 def __customContextMenuRequested(self, pos):
498 """ 501 """
499 Private slot to show the context menu. 502 Private slot to show the context menu.
500 503
501 @param pos position the menu should be shown at 504 @param pos position the menu should be shown at
502 @type QPoint 505 @type QPoint
503 """ 506 """
504 menu = QMenu() 507 menu = QMenu()
505 groupTypeSubMenu = QMenu(self.tr("Group by")) 508 groupTypeSubMenu = QMenu(self.tr("Group by"))
506 act = groupTypeSubMenu.addAction(self.tr("&Window")) 509 act = groupTypeSubMenu.addAction(self.tr("&Window"))
507 act.setData(TabManagerWidget.GroupByWindow) 510 act.setData(TabManagerWidget.GroupByWindow)
508 act.setCheckable(True) 511 act.setCheckable(True)
509 act.setChecked(self.__groupType == TabManagerWidget.GroupByWindow) 512 act.setChecked(self.__groupType == TabManagerWidget.GroupByWindow)
510 513
511 act = groupTypeSubMenu.addAction(self.tr("&Domain")) 514 act = groupTypeSubMenu.addAction(self.tr("&Domain"))
512 act.setData(TabManagerWidget.GroupByDomain) 515 act.setData(TabManagerWidget.GroupByDomain)
513 act.setCheckable(True) 516 act.setCheckable(True)
514 act.setChecked(self.__groupType == TabManagerWidget.GroupByDomain) 517 act.setChecked(self.__groupType == TabManagerWidget.GroupByDomain)
515 518
516 act = groupTypeSubMenu.addAction(self.tr("&Host")) 519 act = groupTypeSubMenu.addAction(self.tr("&Host"))
517 act.setData(TabManagerWidget.GroupByHost) 520 act.setData(TabManagerWidget.GroupByHost)
518 act.setCheckable(True) 521 act.setCheckable(True)
519 act.setChecked(self.__groupType == TabManagerWidget.GroupByHost) 522 act.setChecked(self.__groupType == TabManagerWidget.GroupByHost)
520 groupTypeSubMenu.triggered.connect(self.changeGroupType) 523 groupTypeSubMenu.triggered.connect(self.changeGroupType)
521 524
522 menu.addMenu(groupTypeSubMenu) 525 menu.addMenu(groupTypeSubMenu)
523 526
524 menu.addSeparator() 527 menu.addSeparator()
525 528
526 if self.__isBrowserSelected(): 529 if self.__isBrowserSelected():
527 act1 = menu.addAction( 530 act1 = menu.addAction(
528 UI.PixmapCache.getIcon("bookmark22"), 531 UI.PixmapCache.getIcon("bookmark22"), self.tr("&Bookmark checked tabs")
529 self.tr("&Bookmark checked tabs")) 532 )
530 act1.setObjectName("bookmarkSelection") 533 act1.setObjectName("bookmarkSelection")
531 act1.triggered.connect(lambda: self.__processActions(act1)) 534 act1.triggered.connect(lambda: self.__processActions(act1))
532 act2 = menu.addAction( 535 act2 = menu.addAction(
533 UI.PixmapCache.getIcon("tabClose"), 536 UI.PixmapCache.getIcon("tabClose"), self.tr("&Close checked tabs")
534 self.tr("&Close checked tabs")) 537 )
535 act2.setObjectName("closeSelection") 538 act2.setObjectName("closeSelection")
536 act2.triggered.connect(lambda: self.__processActions(act2)) 539 act2.triggered.connect(lambda: self.__processActions(act2))
537 540
538 menu.exec(self.__tree.viewport().mapToGlobal(pos)) 541 menu.exec(self.__tree.viewport().mapToGlobal(pos))
539 542
540 def mainWindowCreated(self, mainWin, refresh=True): 543 def mainWindowCreated(self, mainWin, refresh=True):
541 """ 544 """
542 Public method to act on the creation of a new web browser window. 545 Public method to act on the creation of a new web browser window.
543 546
544 @param mainWin reference to the web browser window 547 @param mainWin reference to the web browser window
545 @type WebBrowserWindow 548 @type WebBrowserWindow
546 @param refresh flag indicating to refresh the widget 549 @param refresh flag indicating to refresh the widget
547 @type bool 550 @type bool
548 """ 551 """
550 mainWin.webBrowserWindowOpened.connect(self.mainWindowCreated) 553 mainWin.webBrowserWindowOpened.connect(self.mainWindowCreated)
551 mainWin.webBrowserOpened.connect(self.delayedRefreshTree) 554 mainWin.webBrowserOpened.connect(self.delayedRefreshTree)
552 mainWin.webBrowserClosed.connect(self.delayedRefreshTree) 555 mainWin.webBrowserClosed.connect(self.delayedRefreshTree)
553 mainWin.tabWidget().currentUrlChanged.connect(self.delayedRefreshTree) 556 mainWin.tabWidget().currentUrlChanged.connect(self.delayedRefreshTree)
554 mainWin.tabWidget().currentChanged.connect(self.delayedRefreshTree) 557 mainWin.tabWidget().currentChanged.connect(self.delayedRefreshTree)
555 558
556 def createStatusBarIcon(self): 559 def createStatusBarIcon(self):
557 """ 560 """
558 Public method to create a status bar icon. 561 Public method to create a status bar icon.
559 562
560 @return generated icon 563 @return generated icon
561 @rtype EricClickableLabel 564 @rtype EricClickableLabel
562 """ 565 """
563 icon = EricClickableLabel() 566 icon = EricClickableLabel()
564 icon.setPixmap( 567 icon.setPixmap(UI.PixmapCache.getPixmap("tabManager").scaled(16, 16))
565 UI.PixmapCache.getPixmap("tabManager").scaled(16, 16))
566 icon.setToolTip(self.tr("Show Tab Manager")) 568 icon.setToolTip(self.tr("Show Tab Manager"))
567 icon.clicked.connect(lambda: self.raiseTabManager(icon)) 569 icon.clicked.connect(lambda: self.raiseTabManager(icon))
568 570
569 return icon 571 return icon
570 572
571 def raiseTabManager(self, icon): 573 def raiseTabManager(self, icon):
572 """ 574 """
573 Public slot to show the tab manager. 575 Public slot to show the tab manager.
574 576
575 @param icon reference to the clicked icon 577 @param icon reference to the clicked icon
576 @type EricClickableLabel or QAction 578 @type EricClickableLabel or QAction
577 """ 579 """
578 window = None 580 window = None
579 if isinstance(icon, EricClickableLabel): 581 if isinstance(icon, EricClickableLabel):
580 window = icon.window() 582 window = icon.window()
581 elif isinstance(icon, QAction): 583 elif isinstance(icon, QAction):
582 window = icon.parent() 584 window = icon.parent()
583 585
584 if window is not None: 586 if window is not None:
585 titleBarHeight = self.style().pixelMetric( 587 titleBarHeight = self.style().pixelMetric(
586 QStyle.PixelMetric.PM_TitleBarHeight) 588 QStyle.PixelMetric.PM_TitleBarHeight
587 589 )
590
588 y = max(0, window.frameGeometry().top() + titleBarHeight + 1) 591 y = max(0, window.frameGeometry().top() + titleBarHeight + 1)
589 592
590 availableGeometry = ericApp().primaryScreen().availableGeometry() 593 availableGeometry = ericApp().primaryScreen().availableGeometry()
591 windowFrameGeometry = window.frameGeometry() 594 windowFrameGeometry = window.frameGeometry()
592 if (availableGeometry.width() - windowFrameGeometry.right() - 1 > 595 if (
593 self.frameGeometry().width()): 596 availableGeometry.width() - windowFrameGeometry.right() - 1
597 > self.frameGeometry().width()
598 ):
594 x = windowFrameGeometry.right() + 1 599 x = windowFrameGeometry.right() + 1
595 else: 600 else:
596 x = windowFrameGeometry.x() - 1 - self.frameGeometry().width() 601 x = windowFrameGeometry.x() - 1 - self.frameGeometry().width()
597 602
598 newGeo = QRect(x, y, self.width(), window.height()) 603 newGeo = QRect(x, y, self.width(), window.height())
599 self.setGeometry(newGeo) 604 self.setGeometry(newGeo)
600 605
601 self.activateWindow() 606 self.activateWindow()
602 self.showNormal() 607 self.showNormal()
603 self.raise_() 608 self.raise_()

eric ide

mercurial