src/eric7/QtHelpInterface/HelpTocWidget.py

branch
eric7
changeset 9686
2eee7a645cba
parent 9653
e67609152c5e
child 10029
d9f2fa14cc65
equal deleted inserted replaced
9685:b43e04854aba 9686:2eee7a645cba
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2009 - 2023 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing a window for showing the QtHelp TOC.
8 """
9
10 from PyQt6.QtCore import Qt, QUrl, pyqtSignal, pyqtSlot
11 from PyQt6.QtGui import QClipboard, QGuiApplication
12 from PyQt6.QtWidgets import QApplication, QMenu, QVBoxLayout, QWidget
13
14
15 class HelpTocWidget(QWidget):
16 """
17 Class implementing a window for showing the QtHelp TOC.
18
19 @signal escapePressed() emitted when the ESC key was pressed
20 @signal openUrl(QUrl, str) emitted to open an entry in the current tab
21 @signal newTab(QUrl, str) emitted to open an entry in a new tab
22 @signal newBackgroundTab(QUrl, str) emitted to open an entry in a
23 new background tab
24 @signal newWindow(QUrl, str) emitted to open an entry in a new window
25 """
26
27 escapePressed = pyqtSignal()
28 openUrl = pyqtSignal(QUrl)
29 newTab = pyqtSignal(QUrl)
30 newBackgroundTab = pyqtSignal(QUrl)
31 newWindow = pyqtSignal(QUrl)
32
33 def __init__(self, engine, internal=False, parent=None):
34 """
35 Constructor
36
37 @param engine reference to the help engine
38 @type QHelpEngine
39 @param internal flag indicating the internal help viewer
40 @type bool
41 @param parent reference to the parent widget
42 @type QWidget
43 """
44 super().__init__(parent)
45
46 self.__engine = engine
47 self.__expandDepth = -2
48
49 self.__internal = internal
50
51 self.__tocWidget = self.__engine.contentWidget()
52 self.__tocWidget.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
53 self.__tocWidget.setSortingEnabled(True)
54
55 self.__layout = QVBoxLayout(self)
56 if internal:
57 # no margins for the internal variant
58 self.__layout.setContentsMargins(0, 0, 0, 0)
59 self.__layout.addWidget(self.__tocWidget)
60
61 self.__tocWidget.customContextMenuRequested.connect(self.__showContextMenu)
62 self.__tocWidget.linkActivated.connect(self.__linkActivated)
63
64 model = self.__tocWidget.model()
65 model.contentsCreated.connect(self.__contentsCreated)
66
67 @pyqtSlot(QUrl)
68 def __linkActivated(self, url):
69 """
70 Private slot handling the activation of an entry.
71
72 @param url URL of the activated entry
73 @type QUrl
74 """
75 if not url.isEmpty() and url.isValid():
76 buttons = QApplication.mouseButtons()
77 modifiers = QApplication.keyboardModifiers()
78
79 if buttons & Qt.MouseButton.MiddleButton:
80 self.newTab.emit(url)
81 else:
82 if modifiers & (
83 Qt.KeyboardModifier.ControlModifier
84 | Qt.KeyboardModifier.ShiftModifier
85 ) == (
86 Qt.KeyboardModifier.ControlModifier
87 | Qt.KeyboardModifier.ShiftModifier
88 ):
89 self.newBackgroundTab.emit(url)
90 elif modifiers & Qt.KeyboardModifier.ControlModifier:
91 self.newTab.emit(url)
92 elif (
93 modifiers & Qt.KeyboardModifier.ShiftModifier
94 and not self.__internal
95 ):
96 self.newWindow.emit(url)
97 else:
98 self.openUrl.emit(url)
99
100 def __contentsCreated(self):
101 """
102 Private slot to be run after the contents was generated.
103 """
104 self.__tocWidget.sortByColumn(0, Qt.SortOrder.AscendingOrder)
105 self.__expandTOC()
106
107 def __expandTOC(self):
108 """
109 Private slot to expand the table of contents.
110 """
111 if self.__expandDepth > -2:
112 self.expandToDepth(self.__expandDepth)
113 self.__expandDepth = -2
114
115 def expandToDepth(self, depth):
116 """
117 Public slot to expand the table of contents to a specific depth.
118
119 @param depth depth to expand to (integer)
120 """
121 self.__expandDepth = depth
122 if depth == -1:
123 self.__tocWidget.expandAll()
124 else:
125 self.__tocWidget.expandToDepth(depth)
126
127 def focusInEvent(self, evt):
128 """
129 Protected method handling focus in events.
130
131 @param evt reference to the focus event object (QFocusEvent)
132 """
133 if evt.reason() != Qt.FocusReason.MouseFocusReason:
134 self.__tocWidget.setFocus()
135
136 def keyPressEvent(self, evt):
137 """
138 Protected method handling key press events.
139
140 @param evt reference to the key press event (QKeyEvent)
141 """
142 if evt.key() == Qt.Key.Key_Escape:
143 self.escapePressed.emit()
144
145 def syncToContent(self, url):
146 """
147 Public method to sync the TOC to the displayed page.
148
149 @param url URL of the displayed page (QUrl)
150 @return flag indicating a successful synchronization (boolean)
151 """
152 idx = self.__tocWidget.indexOf(url)
153 if not idx.isValid():
154 return False
155 self.__tocWidget.setCurrentIndex(idx)
156 return True
157
158 def __showContextMenu(self, pos):
159 """
160 Private slot showing the context menu.
161
162 @param pos position to show the menu at (QPoint)
163 """
164 if not self.__tocWidget.indexAt(pos).isValid():
165 return
166
167 model = self.__tocWidget.model()
168 itm = model.contentItemAt(self.__tocWidget.currentIndex())
169 link = itm.url()
170 if link.isEmpty() or not link.isValid():
171 return
172
173 menu = QMenu()
174 curTab = menu.addAction(self.tr("Open Link"))
175 if self.__internal:
176 newTab = menu.addAction(self.tr("Open Link in New Page"))
177 newBackgroundTab = menu.addAction(self.tr("Open Link in Background Page"))
178 else:
179 newTab = menu.addAction(self.tr("Open Link in New Tab"))
180 newBackgroundTab = menu.addAction(self.tr("Open Link in Background Tab"))
181 newWindow = menu.addAction(self.tr("Open Link in New Window"))
182 menu.addSeparator()
183 copyLink = menu.addAction(self.tr("Copy URL to Clipboard"))
184 menu.move(self.__tocWidget.mapToGlobal(pos))
185
186 act = menu.exec()
187 if act == curTab:
188 self.openUrl.emit(link)
189 elif act == newTab:
190 self.newTab.emit(link)
191 elif act == newBackgroundTab:
192 self.newBackgroundTab.emit(link)
193 elif not self.__internal and act == newWindow:
194 self.newWindow.emit(link)
195 elif act == copyLink:
196 # copy the URL to both clipboard areas
197 QGuiApplication.clipboard().setText(
198 link.toString(), QClipboard.Mode.Clipboard
199 )
200 QGuiApplication.clipboard().setText(
201 link.toString(), QClipboard.Mode.Selection
202 )

eric ide

mercurial