src/eric7/WebBrowser/QtHelp/HelpSearchWidget.py

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

eric ide

mercurial