7 Module implementing a window for showing the QtHelp index. |
7 Module implementing a window for showing the QtHelp index. |
8 """ |
8 """ |
9 |
9 |
10 from PyQt6.QtCore import pyqtSignal, pyqtSlot, Qt, QUrl |
10 from PyQt6.QtCore import pyqtSignal, pyqtSlot, Qt, QUrl |
11 from PyQt6.QtGui import QGuiApplication, QClipboard |
11 from PyQt6.QtGui import QGuiApplication, QClipboard |
12 from PyQt6.QtWidgets import ( |
12 from PyQt6.QtWidgets import QWidget, QVBoxLayout, QTextBrowser, QApplication, QMenu |
13 QWidget, QVBoxLayout, QTextBrowser, QApplication, QMenu |
|
14 ) |
|
15 |
13 |
16 |
14 |
17 class HelpSearchWidget(QWidget): |
15 class HelpSearchWidget(QWidget): |
18 """ |
16 """ |
19 Class implementing a window for showing the QtHelp index. |
17 Class implementing a window for showing the QtHelp index. |
20 |
18 |
21 @signal escapePressed() emitted when the ESC key was pressed |
19 @signal escapePressed() emitted when the ESC key was pressed |
22 @signal openUrl(QUrl, str) emitted to open a search result entry in the |
20 @signal openUrl(QUrl, str) emitted to open a search result entry in the |
23 current tab |
21 current tab |
24 @signal newTab(QUrl, str) emitted to open a search result entry in a |
22 @signal newTab(QUrl, str) emitted to open a search result entry in a |
25 new tab |
23 new tab |
26 @signal newBackgroundTab(QUrl, str) emitted to open a search result entry |
24 @signal newBackgroundTab(QUrl, str) emitted to open a search result entry |
27 in a new background tab |
25 in a new background tab |
28 @signal newWindow(QUrl, str) emitted to open a search result entry in a |
26 @signal newWindow(QUrl, str) emitted to open a search result entry in a |
29 new window |
27 new window |
30 """ |
28 """ |
|
29 |
31 escapePressed = pyqtSignal() |
30 escapePressed = pyqtSignal() |
32 openUrl = pyqtSignal(QUrl) |
31 openUrl = pyqtSignal(QUrl) |
33 newTab = pyqtSignal(QUrl) |
32 newTab = pyqtSignal(QUrl) |
34 newBackgroundTab = pyqtSignal(QUrl) |
33 newBackgroundTab = pyqtSignal(QUrl) |
35 newWindow = pyqtSignal(QUrl) |
34 newWindow = pyqtSignal(QUrl) |
36 |
35 |
37 def __init__(self, engine, internal=False, parent=None): |
36 def __init__(self, engine, internal=False, parent=None): |
38 """ |
37 """ |
39 Constructor |
38 Constructor |
40 |
39 |
41 @param engine reference to the help search engine |
40 @param engine reference to the help search engine |
42 @type QHelpSearchEngine |
41 @type QHelpSearchEngine |
43 @param internal flag indicating the internal help viewer |
42 @param internal flag indicating the internal help viewer |
44 @type bool |
43 @type bool |
45 @param parent reference to the parent widget |
44 @param parent reference to the parent widget |
46 @type QWidget |
45 @type QWidget |
47 """ |
46 """ |
48 super().__init__(parent) |
47 super().__init__(parent) |
49 |
48 |
50 self.__engine = engine |
49 self.__engine = engine |
51 self.__internal = internal |
50 self.__internal = internal |
52 |
51 |
53 self.__layout = QVBoxLayout(self) |
52 self.__layout = QVBoxLayout(self) |
54 if internal: |
53 if internal: |
55 # no margins for the internal variant |
54 # no margins for the internal variant |
56 self.__layout.setContentsMargins(0, 0, 0, 0) |
55 self.__layout.setContentsMargins(0, 0, 0, 0) |
57 |
56 |
58 self.__result = self.__engine.resultWidget() |
57 self.__result = self.__engine.resultWidget() |
59 self.__query = self.__engine.queryWidget() |
58 self.__query = self.__engine.queryWidget() |
60 |
59 |
61 self.__layout.addWidget(self.__query) |
60 self.__layout.addWidget(self.__query) |
62 self.__layout.addWidget(self.__result) |
61 self.__layout.addWidget(self.__result) |
63 |
62 |
64 self.setFocusProxy(self.__query) |
63 self.setFocusProxy(self.__query) |
65 |
64 |
66 self.__query.search.connect(self.__search) |
65 self.__query.search.connect(self.__search) |
67 self.__result.requestShowLink.connect(self.__linkActivated) |
66 self.__result.requestShowLink.connect(self.__linkActivated) |
68 |
67 |
69 self.__engine.searchingStarted.connect(self.__searchingStarted) |
68 self.__engine.searchingStarted.connect(self.__searchingStarted) |
70 self.__engine.searchingFinished.connect(self.__searchingFinished) |
69 self.__engine.searchingFinished.connect(self.__searchingFinished) |
71 |
70 |
72 self.__browser = self.__result.findChildren(QTextBrowser)[0] |
71 self.__browser = self.__result.findChildren(QTextBrowser)[0] |
73 |
72 |
74 def __search(self): |
73 def __search(self): |
75 """ |
74 """ |
76 Private slot to perform a search of the database. |
75 Private slot to perform a search of the database. |
77 """ |
76 """ |
78 query = self.__query.searchInput() |
77 query = self.__query.searchInput() |
79 self.__engine.search(query) |
78 self.__engine.search(query) |
80 |
79 |
81 def __searchingStarted(self): |
80 def __searchingStarted(self): |
82 """ |
81 """ |
83 Private slot to handle the start of a search. |
82 Private slot to handle the start of a search. |
84 """ |
83 """ |
85 QApplication.setOverrideCursor(Qt.CursorShape.WaitCursor) |
84 QApplication.setOverrideCursor(Qt.CursorShape.WaitCursor) |
86 |
85 |
87 def __searchingFinished(self, hits): |
86 def __searchingFinished(self, hits): |
88 """ |
87 """ |
89 Private slot to handle the end of the search. |
88 Private slot to handle the end of the search. |
90 |
89 |
91 @param hits number of hits (unused) |
90 @param hits number of hits (unused) |
92 @type int |
91 @type int |
93 """ |
92 """ |
94 QApplication.restoreOverrideCursor() |
93 QApplication.restoreOverrideCursor() |
95 |
94 |
96 @pyqtSlot(QUrl) |
95 @pyqtSlot(QUrl) |
97 def __linkActivated(self, url): |
96 def __linkActivated(self, url): |
98 """ |
97 """ |
99 Private slot handling the activation of an entry. |
98 Private slot handling the activation of an entry. |
100 |
99 |
101 @param url URL of the activated entry |
100 @param url URL of the activated entry |
102 @type QUrl |
101 @type QUrl |
103 """ |
102 """ |
104 if not url.isEmpty() and url.isValid(): |
103 if not url.isEmpty() and url.isValid(): |
105 buttons = QApplication.mouseButtons() |
104 buttons = QApplication.mouseButtons() |
106 modifiers = QApplication.keyboardModifiers() |
105 modifiers = QApplication.keyboardModifiers() |
107 |
106 |
108 if buttons & Qt.MouseButton.MiddleButton: |
107 if buttons & Qt.MouseButton.MiddleButton: |
109 self.newTab.emit(url) |
108 self.newTab.emit(url) |
110 else: |
109 else: |
111 if ( |
110 if modifiers & ( |
112 modifiers & ( |
111 Qt.KeyboardModifier.ControlModifier |
113 Qt.KeyboardModifier.ControlModifier | |
112 | Qt.KeyboardModifier.ShiftModifier |
114 Qt.KeyboardModifier.ShiftModifier |
113 ) == ( |
115 ) == ( |
114 Qt.KeyboardModifier.ControlModifier |
116 Qt.KeyboardModifier.ControlModifier | |
115 | Qt.KeyboardModifier.ShiftModifier |
117 Qt.KeyboardModifier.ShiftModifier |
|
118 ) |
|
119 ): |
116 ): |
120 self.newBackgroundTab.emit(url) |
117 self.newBackgroundTab.emit(url) |
121 elif modifiers & Qt.KeyboardModifier.ControlModifier: |
118 elif modifiers & Qt.KeyboardModifier.ControlModifier: |
122 self.newTab.emit(url) |
119 self.newTab.emit(url) |
123 elif ( |
120 elif ( |
124 modifiers & Qt.KeyboardModifier.ShiftModifier and |
121 modifiers & Qt.KeyboardModifier.ShiftModifier |
125 not self.__internal |
122 and not self.__internal |
126 ): |
123 ): |
127 self.newWindow.emit(url) |
124 self.newWindow.emit(url) |
128 else: |
125 else: |
129 self.openUrl.emit(url) |
126 self.openUrl.emit(url) |
130 |
127 |
131 def keyPressEvent(self, evt): |
128 def keyPressEvent(self, evt): |
132 """ |
129 """ |
133 Protected method handling key press events. |
130 Protected method handling key press events. |
134 |
131 |
135 @param evt reference to the key press event |
132 @param evt reference to the key press event |
136 @type QKeyEvent |
133 @type QKeyEvent |
137 """ |
134 """ |
138 if evt.key() == Qt.Key.Key_Escape: |
135 if evt.key() == Qt.Key.Key_Escape: |
139 self.escapePressed.emit() |
136 self.escapePressed.emit() |
140 else: |
137 else: |
141 evt.ignore() |
138 evt.ignore() |
142 |
139 |
143 def contextMenuEvent(self, evt): |
140 def contextMenuEvent(self, evt): |
144 """ |
141 """ |
145 Protected method handling context menu events. |
142 Protected method handling context menu events. |
146 |
143 |
147 @param evt reference to the context menu event (QContextMenuEvent) |
144 @param evt reference to the context menu event (QContextMenuEvent) |
148 """ |
145 """ |
149 point = evt.globalPos() |
146 point = evt.globalPos() |
150 |
147 |
151 if self.__browser: |
148 if self.__browser: |
152 point = self.__browser.mapFromGlobal(point) |
149 point = self.__browser.mapFromGlobal(point) |
153 if not self.__browser.rect().contains(point, True): |
150 if not self.__browser.rect().contains(point, True): |
154 return |
151 return |
155 link = QUrl(self.__browser.anchorAt(point)) |
152 link = QUrl(self.__browser.anchorAt(point)) |
156 else: |
153 else: |
157 point = self.__result.mapFromGlobal(point) |
154 point = self.__result.mapFromGlobal(point) |
158 link = self.__result.linkAt(point) |
155 link = self.__result.linkAt(point) |
159 |
156 |
160 if link.isEmpty() or not link.isValid(): |
157 if link.isEmpty() or not link.isValid(): |
161 return |
158 return |
162 |
159 |
163 menu = QMenu() |
160 menu = QMenu() |
164 curTab = menu.addAction(self.tr("Open Link")) |
161 curTab = menu.addAction(self.tr("Open Link")) |
165 if self.__internal: |
162 if self.__internal: |
166 newTab = menu.addAction(self.tr("Open Link in New Page")) |
163 newTab = menu.addAction(self.tr("Open Link in New Page")) |
167 newBackgroundTab = menu.addAction( |
164 newBackgroundTab = menu.addAction(self.tr("Open Link in Background Page")) |
168 self.tr("Open Link in Background Page")) |
|
169 else: |
165 else: |
170 newTab = menu.addAction(self.tr("Open Link in New Tab")) |
166 newTab = menu.addAction(self.tr("Open Link in New Tab")) |
171 newBackgroundTab = menu.addAction( |
167 newBackgroundTab = menu.addAction(self.tr("Open Link in Background Tab")) |
172 self.tr("Open Link in Background Tab")) |
|
173 newWindow = menu.addAction(self.tr("Open Link in New Window")) |
168 newWindow = menu.addAction(self.tr("Open Link in New Window")) |
174 menu.addSeparator() |
169 menu.addSeparator() |
175 copyLink = menu.addAction(self.tr("Copy URL to Clipboard")) |
170 copyLink = menu.addAction(self.tr("Copy URL to Clipboard")) |
176 menu.move(evt.globalPos()) |
171 menu.move(evt.globalPos()) |
177 |
172 |
178 act = menu.exec() |
173 act = menu.exec() |
179 if act == curTab: |
174 if act == curTab: |
180 self.openUrl.emit(link) |
175 self.openUrl.emit(link) |
181 elif act == newTab: |
176 elif act == newTab: |
182 self.newTab.emit(link) |
177 self.newTab.emit(link) |