7 Module implementing an embedded viewer for QtHelp and local HTML files. |
7 Module implementing an embedded viewer for QtHelp and local HTML files. |
8 """ |
8 """ |
9 |
9 |
10 import os |
10 import os |
11 |
11 |
12 from PyQt6.QtCore import pyqtSlot, QUrl |
12 from PyQt6.QtCore import pyqtSlot, Qt, QUrl |
13 from PyQt6.QtGui import QAction |
13 from PyQt6.QtGui import QAction |
14 from PyQt6.QtHelp import QHelpEngine |
14 from PyQt6.QtHelp import QHelpEngine |
15 from PyQt6.QtWidgets import ( |
15 from PyQt6.QtWidgets import ( |
16 QWidget, QHBoxLayout, QVBoxLayout, QComboBox, QSizePolicy, QStackedWidget, |
16 QWidget, QHBoxLayout, QVBoxLayout, QComboBox, QSizePolicy, QStackedWidget, |
17 QToolButton, QButtonGroup, QAbstractButton, QMenu, QFrame |
17 QToolButton, QButtonGroup, QAbstractButton, QMenu, QFrame |
39 """ |
41 """ |
40 super().__init__(parent) |
42 super().__init__(parent) |
41 self.setObjectName("HelpViewerWidget") |
43 self.setObjectName("HelpViewerWidget") |
42 |
44 |
43 self.__ui = parent |
45 self.__ui = parent |
|
46 |
|
47 self.__initHelpEngine() |
44 |
48 |
45 self.__layout = QVBoxLayout() |
49 self.__layout = QVBoxLayout() |
46 self.__layout.setObjectName("MainLayout") |
50 self.__layout.setObjectName("MainLayout") |
47 self.__layout.setContentsMargins(0, 3, 0, 0) |
51 self.__layout.setContentsMargins(0, 3, 0, 0) |
48 |
52 |
107 self.__buttonLine1 = QFrame(self) |
111 self.__buttonLine1 = QFrame(self) |
108 self.__buttonLine1.setFrameShape(QFrame.Shape.VLine) |
112 self.__buttonLine1.setFrameShape(QFrame.Shape.VLine) |
109 self.__buttonLine1.setFrameShadow(QFrame.Shadow.Sunken) |
113 self.__buttonLine1.setFrameShadow(QFrame.Shadow.Sunken) |
110 self.__navButtonsLayout.addWidget(self.__buttonLine1) |
114 self.__navButtonsLayout.addWidget(self.__buttonLine1) |
111 |
115 |
112 # TODO: add zoom in button |
|
113 self.__zoomInButton = QToolButton(self) |
116 self.__zoomInButton = QToolButton(self) |
114 self.__zoomInButton.setIcon(UI.PixmapCache.getIcon("zoomIn")) |
117 self.__zoomInButton.setIcon(UI.PixmapCache.getIcon("zoomIn")) |
115 self.__zoomInButton.setToolTip( |
118 self.__zoomInButton.setToolTip( |
116 self.tr("Zoom in on the current page")) |
119 self.tr("Zoom in on the current page")) |
117 self.__zoomInButton.clicked.connect(self.__zoomIn) |
120 self.__zoomInButton.clicked.connect(self.__zoomIn) |
118 self.__navButtonsLayout.addWidget(self.__zoomInButton) |
121 self.__navButtonsLayout.addWidget(self.__zoomInButton) |
119 |
122 |
120 # TODO: add zoom out button |
|
121 self.__zoomOutButton = QToolButton(self) |
123 self.__zoomOutButton = QToolButton(self) |
122 self.__zoomOutButton.setIcon(UI.PixmapCache.getIcon("zoomOut")) |
124 self.__zoomOutButton.setIcon(UI.PixmapCache.getIcon("zoomOut")) |
123 self.__zoomOutButton.setToolTip( |
125 self.__zoomOutButton.setToolTip( |
124 self.tr("Zoom out on the current page")) |
126 self.tr("Zoom out on the current page")) |
125 self.__zoomOutButton.clicked.connect(self.__zoomOut) |
127 self.__zoomOutButton.clicked.connect(self.__zoomOut) |
126 self.__navButtonsLayout.addWidget(self.__zoomOutButton) |
128 self.__navButtonsLayout.addWidget(self.__zoomOutButton) |
127 |
129 |
128 # TODO: add zoom reset button |
|
129 self.__zoomResetButton = QToolButton(self) |
130 self.__zoomResetButton = QToolButton(self) |
130 self.__zoomResetButton.setIcon(UI.PixmapCache.getIcon("zoomReset")) |
131 self.__zoomResetButton.setIcon(UI.PixmapCache.getIcon("zoomReset")) |
131 self.__zoomResetButton.setToolTip( |
132 self.__zoomResetButton.setToolTip( |
132 self.tr("Reset the zoom level of the current page")) |
133 self.tr("Reset the zoom level of the current page")) |
133 self.__zoomResetButton.clicked.connect(self.__zoomReset) |
134 self.__zoomResetButton.clicked.connect(self.__zoomReset) |
175 |
176 |
176 self.__buttonLayout.addStretch() |
177 self.__buttonLayout.addStretch() |
177 |
178 |
178 self.__openPagesButton = self.__addNavigationButton( |
179 self.__openPagesButton = self.__addNavigationButton( |
179 "fileMisc", self.tr("Show list of open pages")) |
180 "fileMisc", self.tr("Show list of open pages")) |
|
181 self.__helpTocButton = self.__addNavigationButton( |
|
182 "tableOfContents", self.tr("Show table of contents")) |
|
183 self.__openPagesButton.setChecked(True) |
180 |
184 |
181 # TODO: add buttons for the QHelp related widgets |
185 # TODO: add buttons for the QHelp related widgets |
182 |
186 |
183 self.__buttonLayout.addStretch() |
187 self.__buttonLayout.addStretch() |
184 |
188 |
221 |
225 |
222 def __populateNavigationStack(self): |
226 def __populateNavigationStack(self): |
223 """ |
227 """ |
224 Private method to populate the stack of navigation widgets. |
228 Private method to populate the stack of navigation widgets. |
225 """ |
229 """ |
|
230 # Open Pages |
226 self.__openPagesList = OpenPagesWidget(self.__helpStack, self) |
231 self.__openPagesList = OpenPagesWidget(self.__helpStack, self) |
227 self.__openPagesList.currentChanged.connect(self.__checkActionButtons) |
232 self.__openPagesList.currentChanged.connect(self.__checkActionButtons) |
228 self.__helpNavigationStack.addWidget(self.__openPagesList) |
233 self.__helpNavigationStack.addWidget(self.__openPagesList) |
229 |
234 |
|
235 # QtHelp TOC |
|
236 self.__tocWidget = HelpTocWidget(self.__helpEngine, internal=True) |
|
237 self.__tocWidget.escapePressed.connect(self.__activateCurrentPage) |
|
238 self.__tocWidget.openUrl.connect(self.openUrl) |
|
239 self.__tocWidget.newTab.connect(self.openUrlNewPage) |
|
240 self.__tocWidget.newBackgroundTab.connect( |
|
241 self.openUrlNewBackgroundPage) |
|
242 self.__helpNavigationStack.addWidget(self.__tocWidget) |
|
243 |
230 # TODO: not yet implemented |
244 # TODO: not yet implemented |
231 |
245 |
232 @pyqtSlot(QAbstractButton) |
246 @pyqtSlot(QAbstractButton) |
233 def __selectNavigationWidget(self, button): |
247 def __selectNavigationWidget(self, button): |
234 """ |
248 """ |
237 @param button reference to the clicked button |
251 @param button reference to the clicked button |
238 @type QAbstractButton |
252 @type QAbstractButton |
239 """ |
253 """ |
240 if button == self.__openPagesButton: |
254 if button == self.__openPagesButton: |
241 self.__helpNavigationStack.setCurrentWidget(self.__openPagesList) |
255 self.__helpNavigationStack.setCurrentWidget(self.__openPagesList) |
|
256 elif button == self.__helpTocButton: |
|
257 self.__helpNavigationStack.setCurrentWidget(self.__tocWidget) |
242 |
258 |
243 # TODO: not yet implemented |
259 # TODO: not yet implemented |
244 |
260 |
245 def __populateHelpSelector(self): |
261 def __populateHelpSelector(self): |
246 """ |
262 """ |
307 self.tr("HTML Files (*.htm *.html);;All Files (*)") |
325 self.tr("HTML Files (*.htm *.html);;All Files (*)") |
308 ) |
326 ) |
309 if htmlFile: |
327 if htmlFile: |
310 self.currentViewer().setUrl(QUrl.fromLocalFile(htmlFile)) |
328 self.currentViewer().setUrl(QUrl.fromLocalFile(htmlFile)) |
311 |
329 |
312 def addPage(self, url=QUrl("about:blank")): |
330 def addPage(self, url=QUrl("about:blank"), background=False): |
313 """ |
331 """ |
314 Public method to add a new help page with the given URL. |
332 Public method to add a new help page with the given URL. |
315 |
333 |
316 @param url requested URL (defaults to QUrl("about:blank")) |
334 @param url requested URL (defaults to QUrl("about:blank")) |
317 @type QUrl (optional) |
335 @type QUrl (optional) |
|
336 @param background flag indicating to open the page in the background |
|
337 (defaults to False) |
|
338 @type bool (optional) |
318 """ |
339 """ |
319 viewer = self.__newViewer() |
340 viewer = self.__newViewer() |
320 viewer.setUrl(url) |
341 viewer.setUrl(url) |
321 |
342 |
|
343 if background: |
|
344 cv = self.currentViewer() |
|
345 if cv: |
|
346 index = self.__helpStack.indexOf(cv) + 1 |
|
347 self.__helpStack.insertWidget(index, viewer) |
|
348 self.__openPagesList.insertPage( |
|
349 index, viewer, background=background) |
|
350 return |
|
351 |
322 self.__helpStack.addWidget(viewer) |
352 self.__helpStack.addWidget(viewer) |
323 self.__openPagesList.addPage(viewer) |
353 self.__openPagesList.addPage(viewer, background=background) |
|
354 |
|
355 @pyqtSlot(QUrl) |
|
356 def openUrl(self, url): |
|
357 """ |
|
358 Public slot to load a URL in the current page. |
|
359 |
|
360 @param url URL to be opened |
|
361 @type QUrl |
|
362 """ |
|
363 cv = self.currentViewer() |
|
364 if cv: |
|
365 cv.setUrl(url) |
|
366 |
|
367 @pyqtSlot(QUrl) |
|
368 def openUrlNewPage(self, url): |
|
369 """ |
|
370 Public slot to load a URL in a new page. |
|
371 |
|
372 @param url URL to be opened |
|
373 @type QUrl |
|
374 """ |
|
375 self.addPage(url=url) |
|
376 |
|
377 @pyqtSlot(QUrl) |
|
378 def openUrlNewBackgroundPage(self, url): |
|
379 """ |
|
380 Public slot to load a URL in a new background page. |
|
381 |
|
382 @param url URL to be opened |
|
383 @type QUrl |
|
384 """ |
|
385 self.addPage(url=url, background=True) |
|
386 |
|
387 @pyqtSlot() |
|
388 def __activateCurrentPage(self): |
|
389 """ |
|
390 Private slot to activate the current page. |
|
391 """ |
|
392 cv = self.currentViewer() |
|
393 if cv: |
|
394 cv.setFocus() |
324 |
395 |
325 def __newViewer(self): |
396 def __newViewer(self): |
326 """ |
397 """ |
327 Private method to create a new help viewer. |
398 Private method to create a new help viewer. |
328 |
399 |
472 def __checkActionButtons(self): |
543 def __checkActionButtons(self): |
473 """ |
544 """ |
474 Private slot to set the enabled state of the action buttons. |
545 Private slot to set the enabled state of the action buttons. |
475 """ |
546 """ |
476 cv = self.currentViewer() |
547 cv = self.currentViewer() |
477 self.__backwardButton.setEnabled(cv and cv.isBackwardAvailable()) |
548 if cv: |
478 self.__forwardButton.setEnabled(cv and cv.isForwardAvailable()) |
549 self.__backwardButton.setEnabled(cv.isBackwardAvailable()) |
479 self.__zoomInButton.setEnabled(cv and cv.isScaleUpAvailable()) |
550 self.__forwardButton.setEnabled(cv.isForwardAvailable()) |
480 self.__zoomOutButton.setEnabled(cv and cv.isScaleDownAvailable()) |
551 self.__zoomInButton.setEnabled(cv.isScaleUpAvailable()) |
|
552 self.__zoomOutButton.setEnabled(cv.isScaleDownAvailable()) |
|
553 else: |
|
554 self.__backwardButton.setEnabled(False) |
|
555 self.__forwardButton.setEnabled(False) |
|
556 self.__zoomInButton.setEnabled(False) |
|
557 self.__zoomOutButton.setEnabled(False) |
481 |
558 |
482 def __showBackMenu(self): |
559 def __showBackMenu(self): |
483 """ |
560 """ |
484 Private slot showing the backward navigation menu. |
561 Private slot showing the backward navigation menu. |
485 """ |
562 """ |