|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2017 - 2021 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing the navigation bar widget. |
|
8 """ |
|
9 |
|
10 from PyQt5.QtCore import Qt, QUrl |
|
11 from PyQt5.QtWidgets import ( |
|
12 QWidget, QHBoxLayout, QStyle, QToolButton, QSplitter, QSizePolicy, QMenu, |
|
13 QAction |
|
14 ) |
|
15 |
|
16 from E5Gui.E5ToolButton import E5ToolButton |
|
17 |
|
18 from WebBrowser.WebBrowserWindow import WebBrowserWindow |
|
19 from WebBrowser.Download.DownloadManagerButton import DownloadManagerButton |
|
20 |
|
21 import UI.PixmapCache |
|
22 import Preferences |
|
23 |
|
24 from .ReloadStopButton import ReloadStopButton |
|
25 |
|
26 |
|
27 class NavigationBar(QWidget): |
|
28 """ |
|
29 Class implementing the navigation bar. |
|
30 """ |
|
31 def __init__(self, mainWindow, parent=None): |
|
32 """ |
|
33 Constructor |
|
34 |
|
35 @param mainWindow reference to the browser main window |
|
36 @type WebBrowserWindow |
|
37 @param parent reference to the parent widget |
|
38 @type QWidget |
|
39 """ |
|
40 super().__init__(parent) |
|
41 self.setObjectName("navigationbar") |
|
42 |
|
43 self.__mw = mainWindow |
|
44 |
|
45 self.__layout = QHBoxLayout(self) |
|
46 margin = self.style().pixelMetric( |
|
47 QStyle.PixelMetric.PM_ToolBarItemMargin, None, self) |
|
48 self.__layout.setContentsMargins(margin, margin, margin, margin) |
|
49 self.__layout.setSpacing( |
|
50 self.style().pixelMetric( |
|
51 QStyle.PixelMetric.PM_ToolBarItemSpacing, None, self)) |
|
52 self.setLayout(self.__layout) |
|
53 |
|
54 self.__backButton = E5ToolButton(self) |
|
55 self.__backButton.setObjectName("navigation_back_button") |
|
56 self.__backButton.setToolTip(self.tr("Move one screen backward")) |
|
57 self.__backButton.setToolButtonStyle( |
|
58 Qt.ToolButtonStyle.ToolButtonIconOnly) |
|
59 self.__backButton.setFocusPolicy(Qt.FocusPolicy.NoFocus) |
|
60 self.__backButton.setAutoRaise(True) |
|
61 self.__backButton.setIcon( |
|
62 UI.PixmapCache.getIcon("back")) |
|
63 self.__backButton.setEnabled(False) |
|
64 |
|
65 self.__forwardButton = E5ToolButton(self) |
|
66 self.__forwardButton.setObjectName("navigation_forward_button") |
|
67 self.__forwardButton.setToolTip(self.tr("Move one screen forward")) |
|
68 self.__forwardButton.setToolButtonStyle( |
|
69 Qt.ToolButtonStyle.ToolButtonIconOnly) |
|
70 self.__forwardButton.setFocusPolicy(Qt.FocusPolicy.NoFocus) |
|
71 self.__forwardButton.setAutoRaise(True) |
|
72 self.__forwardButton.setIcon( |
|
73 UI.PixmapCache.getIcon("forward")) |
|
74 self.__forwardButton.setEnabled(False) |
|
75 |
|
76 self.__backNextLayout = QHBoxLayout() |
|
77 self.__backNextLayout.setContentsMargins(0, 0, 0, 0) |
|
78 self.__backNextLayout.setSpacing(0) |
|
79 self.__backNextLayout.addWidget(self.__backButton) |
|
80 self.__backNextLayout.addWidget(self.__forwardButton) |
|
81 |
|
82 self.__reloadStopButton = ReloadStopButton(self) |
|
83 |
|
84 self.__homeButton = E5ToolButton(self) |
|
85 self.__homeButton.setObjectName("navigation_home_button") |
|
86 self.__homeButton.setToolTip(self.tr("Move to the initial screen")) |
|
87 self.__homeButton.setToolButtonStyle( |
|
88 Qt.ToolButtonStyle.ToolButtonIconOnly) |
|
89 self.__homeButton.setFocusPolicy(Qt.FocusPolicy.NoFocus) |
|
90 self.__homeButton.setAutoRaise(True) |
|
91 self.__homeButton.setIcon( |
|
92 UI.PixmapCache.getIcon("home")) |
|
93 |
|
94 self.__exitFullScreenButton = E5ToolButton(self) |
|
95 self.__exitFullScreenButton.setObjectName( |
|
96 "navigation_exitfullscreen_button") |
|
97 self.__exitFullScreenButton.setIcon( |
|
98 UI.PixmapCache.getIcon("windowRestore")) |
|
99 self.__exitFullScreenButton.setToolTip(self.tr("Exit Fullscreen")) |
|
100 self.__exitFullScreenButton.setToolButtonStyle( |
|
101 Qt.ToolButtonStyle.ToolButtonIconOnly) |
|
102 self.__exitFullScreenButton.setFocusPolicy(Qt.FocusPolicy.NoFocus) |
|
103 self.__exitFullScreenButton.setAutoRaise(True) |
|
104 self.__exitFullScreenButton.clicked.connect(self.__mw.toggleFullScreen) |
|
105 self.__exitFullScreenButton.setVisible(False) |
|
106 |
|
107 self.__downloadManagerButton = DownloadManagerButton(self) |
|
108 |
|
109 self.__superMenuButton = E5ToolButton(self) |
|
110 self.__superMenuButton.setObjectName( |
|
111 "navigation_supermenu_button") |
|
112 self.__superMenuButton.setIcon(UI.PixmapCache.getIcon("superMenu")) |
|
113 self.__superMenuButton.setToolTip(self.tr("Main Menu")) |
|
114 self.__superMenuButton.setPopupMode( |
|
115 QToolButton.ToolButtonPopupMode.InstantPopup) |
|
116 self.__superMenuButton.setToolButtonStyle( |
|
117 Qt.ToolButtonStyle.ToolButtonIconOnly) |
|
118 self.__superMenuButton.setFocusPolicy(Qt.FocusPolicy.NoFocus) |
|
119 self.__superMenuButton.setAutoRaise(True) |
|
120 self.__superMenuButton.setShowMenuInside(True) |
|
121 |
|
122 self.__navigationSplitter = QSplitter(self) |
|
123 urlBar = self.__mw.tabWidget().stackedUrlBar() |
|
124 self.__navigationSplitter.addWidget(urlBar) |
|
125 |
|
126 from WebBrowser.WebBrowserWebSearchWidget import ( |
|
127 WebBrowserWebSearchWidget |
|
128 ) |
|
129 self.__searchEdit = WebBrowserWebSearchWidget(self.__mw, self) |
|
130 sizePolicy = QSizePolicy(QSizePolicy.Policy.Expanding, |
|
131 QSizePolicy.Policy.Preferred) |
|
132 sizePolicy.setHorizontalStretch(2) |
|
133 sizePolicy.setVerticalStretch(0) |
|
134 self.__searchEdit.setSizePolicy(sizePolicy) |
|
135 self.__searchEdit.search.connect(self.__mw.openUrl) |
|
136 self.__navigationSplitter.addWidget(self.__searchEdit) |
|
137 |
|
138 self.__navigationSplitter.setSizePolicy( |
|
139 QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Maximum) |
|
140 self.__navigationSplitter.setCollapsible(0, False) |
|
141 |
|
142 self.__layout.addLayout(self.__backNextLayout) |
|
143 self.__layout.addWidget(self.__reloadStopButton) |
|
144 self.__layout.addWidget(self.__homeButton) |
|
145 self.__layout.addWidget(self.__navigationSplitter) |
|
146 self.__layout.addWidget(self.__downloadManagerButton) |
|
147 self.__layout.addWidget(self.__exitFullScreenButton) |
|
148 self.__layout.addWidget(self.__superMenuButton) |
|
149 |
|
150 self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) |
|
151 self.customContextMenuRequested.connect(self.__contextMenuRequested) |
|
152 |
|
153 self.__backMenu = QMenu(self) |
|
154 self.__backMenu.triggered.connect(self.__navigationMenuActionTriggered) |
|
155 self.__backButton.setMenu(self.__backMenu) |
|
156 self.__backButton.aboutToShowMenu.connect(self.__showBackMenu) |
|
157 |
|
158 self.__forwardMenu = QMenu(self) |
|
159 self.__forwardMenu.triggered.connect( |
|
160 self.__navigationMenuActionTriggered) |
|
161 self.__forwardButton.setMenu(self.__forwardMenu) |
|
162 self.__forwardButton.aboutToShowMenu.connect(self.__showForwardMenu) |
|
163 |
|
164 self.__backButton.clicked.connect(self.__goBack) |
|
165 self.__backButton.middleClicked.connect(self.__goBackInNewTab) |
|
166 self.__backButton.controlClicked.connect(self.__goBackInNewTab) |
|
167 self.__forwardButton.clicked.connect(self.__goForward) |
|
168 self.__forwardButton.middleClicked.connect(self.__goForwardInNewTab) |
|
169 self.__forwardButton.controlClicked.connect(self.__goForwardInNewTab) |
|
170 self.__reloadStopButton.reloadClicked.connect(self.__reload) |
|
171 self.__reloadStopButton.stopClicked.connect(self.__stopLoad) |
|
172 self.__homeButton.clicked.connect(self.__goHome) |
|
173 self.__homeButton.middleClicked.connect(self.__goHomeInNewTab) |
|
174 self.__homeButton.controlClicked.connect(self.__goHomeInNewTab) |
|
175 |
|
176 def superMenuButton(self): |
|
177 """ |
|
178 Public method to get a reference to the super menu button. |
|
179 |
|
180 @return reference to the super menu button |
|
181 @rtype QToolButton |
|
182 """ |
|
183 return self.__superMenuButton |
|
184 |
|
185 def backButton(self): |
|
186 """ |
|
187 Public method to get a reference to the back button. |
|
188 |
|
189 @return reference to the back button |
|
190 @rtype QToolButton |
|
191 """ |
|
192 return self.__backButton |
|
193 |
|
194 def forwardButton(self): |
|
195 """ |
|
196 Public method to get a reference to the forward button. |
|
197 |
|
198 @return reference to the forward button |
|
199 @rtype QToolButton |
|
200 """ |
|
201 return self.__forwardButton |
|
202 |
|
203 def reloadStopButton(self): |
|
204 """ |
|
205 Public method to get a reference to the reload/stop button. |
|
206 |
|
207 @return reference to the reload/stop button |
|
208 @rtype QToolButton |
|
209 """ |
|
210 return self.__reloadStopButton |
|
211 |
|
212 def exitFullScreenButton(self): |
|
213 """ |
|
214 Public method to get a reference to the exit full screen button. |
|
215 |
|
216 @return reference to the exit full screen button |
|
217 @rtype QToolButton |
|
218 """ |
|
219 return self.__exitFullScreenButton |
|
220 |
|
221 def searchEdit(self): |
|
222 """ |
|
223 Public method to get a reference to the web search edit. |
|
224 |
|
225 @return reference to the web search edit |
|
226 @rtype WebBrowserWebSearchWidget |
|
227 """ |
|
228 return self.__searchEdit |
|
229 |
|
230 def __showBackMenu(self): |
|
231 """ |
|
232 Private slot showing the backwards navigation menu. |
|
233 """ |
|
234 self.__backMenu.clear() |
|
235 history = self.__mw.currentBrowser().history() |
|
236 backItems = history.backItems(20) |
|
237 # show max. 20 items |
|
238 |
|
239 for item in reversed(backItems): |
|
240 act = QAction(self) |
|
241 act.setData(item) |
|
242 icon = WebBrowserWindow.icon(item.url()) |
|
243 act.setIcon(icon) |
|
244 act.setText(item.title()) |
|
245 self.__backMenu.addAction(act) |
|
246 |
|
247 self.__backMenu.addSeparator() |
|
248 self.__backMenu.addAction(self.tr("Clear History"), |
|
249 self.__clearHistory) |
|
250 |
|
251 def __showForwardMenu(self): |
|
252 """ |
|
253 Private slot showing the forwards navigation menu. |
|
254 """ |
|
255 self.__forwardMenu.clear() |
|
256 history = self.__mw.currentBrowser().history() |
|
257 forwardItems = history.forwardItems(20) |
|
258 # show max. 20 items |
|
259 |
|
260 for item in forwardItems: |
|
261 act = QAction(self) |
|
262 act.setData(item) |
|
263 icon = WebBrowserWindow.icon(item.url()) |
|
264 act.setIcon(icon) |
|
265 act.setText(item.title()) |
|
266 self.__forwardMenu.addAction(act) |
|
267 |
|
268 self.__forwardMenu.addSeparator() |
|
269 self.__forwardMenu.addAction(self.tr("Clear History"), |
|
270 self.__clearHistory) |
|
271 |
|
272 def __navigationMenuActionTriggered(self, act): |
|
273 """ |
|
274 Private slot to go to the selected page. |
|
275 |
|
276 @param act reference to the action selected in the navigation menu |
|
277 (QAction) |
|
278 """ |
|
279 historyItem = act.data() |
|
280 if historyItem is not None: |
|
281 history = self.__mw.currentBrowser().history() |
|
282 history.goToItem(historyItem) |
|
283 |
|
284 def __goBack(self): |
|
285 """ |
|
286 Private slot called to handle the backward button. |
|
287 """ |
|
288 self.__mw.currentBrowser().backward() |
|
289 |
|
290 def __goBackInNewTab(self): |
|
291 """ |
|
292 Private slot handling a middle click or Ctrl left click of the |
|
293 backward button. |
|
294 """ |
|
295 history = self.__mw.currentBrowser().history() |
|
296 if history.canGoBack(): |
|
297 backItem = history.backItem() |
|
298 self.__mw.newTab(link=backItem.url(), |
|
299 addNextTo=self.__mw.currentBrowser(), |
|
300 background=True) |
|
301 |
|
302 def __goForward(self): |
|
303 """ |
|
304 Private slot called to handle the forward button. |
|
305 """ |
|
306 self.__mw.currentBrowser().forward() |
|
307 |
|
308 def __goForwardInNewTab(self): |
|
309 """ |
|
310 Private slot handling a middle click or Ctrl left click of the |
|
311 forward button. |
|
312 """ |
|
313 history = self.__mw.currentBrowser().history() |
|
314 if history.canGoForward(): |
|
315 forwardItem = history.forwardItem() |
|
316 self.__mw.newTab(link=forwardItem.url(), |
|
317 addNextTo=self.__mw.currentBrowser(), |
|
318 background=True) |
|
319 |
|
320 def __goHome(self): |
|
321 """ |
|
322 Private slot called to handle the home button. |
|
323 """ |
|
324 self.__mw.currentBrowser().home() |
|
325 |
|
326 def __goHomeInNewTab(self): |
|
327 """ |
|
328 Private slot handling a middle click or Ctrl left click of the |
|
329 home button. |
|
330 """ |
|
331 homeUrl = QUrl(Preferences.getWebBrowser("HomePage")) |
|
332 self.__mw.newTab(link=homeUrl, |
|
333 addNextTo=self.__mw.currentBrowser(), |
|
334 background=True) |
|
335 |
|
336 def __reload(self): |
|
337 """ |
|
338 Private slot called to handle the reload button. |
|
339 """ |
|
340 self.__mw.currentBrowser().reloadBypassingCache() |
|
341 |
|
342 def __stopLoad(self): |
|
343 """ |
|
344 Private slot called to handle loading of the current page. |
|
345 """ |
|
346 self.__mw.currentBrowser().stop() |
|
347 |
|
348 def __clearHistory(self): |
|
349 """ |
|
350 Private slot to clear the history of the current web browser tab. |
|
351 """ |
|
352 cb = self.__mw.currentBrowser() |
|
353 if cb is not None: |
|
354 cb.history().clear() |
|
355 self.__mw.setForwardAvailable(cb.isForwardAvailable()) |
|
356 self.__mw.setBackwardAvailable(cb.isBackwardAvailable()) |
|
357 |
|
358 def __contextMenuRequested(self, pos): |
|
359 """ |
|
360 Private method to handle a context menu request. |
|
361 |
|
362 @param pos position of the request |
|
363 @type QPoint |
|
364 """ |
|
365 menu = self.__mw.createPopupMenu() |
|
366 menu.exec(self.mapToGlobal(pos)) |