eric6/Helpviewer/HelpIndexWidget.py

changeset 6942
2602857055c5
parent 6645
ad476851d7e0
equal deleted inserted replaced
6941:f99d60d6b59b 6942:2602857055c5
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2009 - 2019 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing a window for showing the QtHelp index.
8 """
9
10 from __future__ import unicode_literals
11
12 from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QUrl, QEvent
13 from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QLineEdit, QMenu, \
14 QDialog, QApplication
15
16
17 class HelpIndexWidget(QWidget):
18 """
19 Class implementing a window for showing the QtHelp index.
20
21 @signal linkActivated(QUrl) emitted when an index entry is activated
22 @signal linksActivated(links, keyword) emitted when an index entry
23 referencing multiple targets is activated
24 @signal escapePressed() emitted when the ESC key was pressed
25 """
26 linkActivated = pyqtSignal(QUrl)
27 linksActivated = pyqtSignal(dict, str)
28 escapePressed = pyqtSignal()
29
30 def __init__(self, engine, mainWindow, parent=None):
31 """
32 Constructor
33
34 @param engine reference to the help engine (QHelpEngine)
35 @param mainWindow reference to the main window object (QMainWindow)
36 @param parent reference to the parent widget (QWidget)
37 """
38 super(HelpIndexWidget, self).__init__(parent)
39
40 self.__engine = engine
41 self.__mw = mainWindow
42
43 self.__searchEdit = None
44 self.__index = None
45
46 self.__layout = QVBoxLayout(self)
47 label = QLabel(self.tr("&Look for:"))
48 self.__layout.addWidget(label)
49
50 self.__searchEdit = QLineEdit()
51 label.setBuddy(self.__searchEdit)
52 self.__searchEdit.textChanged.connect(self.__filterIndices)
53 self.__searchEdit.installEventFilter(self)
54 self.__layout.addWidget(self.__searchEdit)
55
56 self.__index = self.__engine.indexWidget()
57 self.__index.setContextMenuPolicy(Qt.CustomContextMenu)
58 self.__engine.indexModel().indexCreationStarted.connect(
59 self.__disableSearchEdit)
60 self.__engine.indexModel().indexCreated.connect(
61 self.__enableSearchEdit)
62 self.__index.linkActivated.connect(self.__linkActivated)
63 self.__index.linksActivated.connect(self.__linksActivated)
64 self.__index.customContextMenuRequested.connect(
65 self.__showContextMenu)
66 self.__searchEdit.returnPressed.connect(
67 self.__index.activateCurrentItem)
68 self.__layout.addWidget(self.__index)
69
70 @pyqtSlot(QUrl, str)
71 def __linkActivated(self, url, keyword, modifiers=None):
72 """
73 Private slot to handle the activation of a keyword entry.
74
75 @param url URL of the selected entry
76 @type QUrl
77 @param keyword keyword for the URL
78 @type str
79 @keyparam modifiers keyboard modifiers
80 @type Qt.KeyboardModifiers or None
81 """
82 if modifiers is None:
83 modifiers = QApplication.keyboardModifiers()
84 if not url.isEmpty() and url.isValid():
85 if modifiers & Qt.ControlModifier:
86 self.__mw.newTab(url)
87 else:
88 self.linkActivated.emit(url)
89
90 def __linksActivated(self, links, keyword):
91 """
92 Private slot to handle the activation of an entry with multiple links.
93
94 @param links dictionary containing the links
95 @type dict of key:str and value:QUrl
96 @param keyword keyword for the entry
97 @type str
98 """
99 modifiers = QApplication.keyboardModifiers()
100 if len(links) == 1:
101 url = QUrl(links[list(links.keys())[0]])
102 else:
103 url = self.__selectLink(links, keyword)
104 self.__linkActivated(url, keyword, modifiers)
105
106 def __selectLink(self, links, keyword):
107 """
108 Private method to give the user a chance to select among the
109 returned links.
110
111 @param links dictionary of document title and URL to select from
112 @type dictionary of str (key) and QUrl (value)
113 @param keyword keyword for the link set
114 @type str
115 @return selected link
116 @rtype QUrl
117 """
118 link = QUrl()
119 from .HelpTopicDialog import HelpTopicDialog
120 dlg = HelpTopicDialog(self, keyword, links)
121 if dlg.exec_() == QDialog.Accepted:
122 link = dlg.link()
123 return link
124
125 def __filterIndices(self, filterStr):
126 """
127 Private slot to filter the indices according to the given filter.
128
129 @param filterStr filter to be used (string)
130 """
131 if '*' in filterStr:
132 self.__index.filterIndices(filterStr, filterStr)
133 else:
134 self.__index.filterIndices(filterStr)
135
136 def __enableSearchEdit(self):
137 """
138 Private slot to enable the search edit.
139 """
140 self.__searchEdit.setEnabled(True)
141 self.__filterIndices(self.__searchEdit.text())
142
143 def __disableSearchEdit(self):
144 """
145 Private slot to enable the search edit.
146 """
147 self.__searchEdit.setEnabled(False)
148
149 def focusInEvent(self, evt):
150 """
151 Protected method handling focus in events.
152
153 @param evt reference to the focus event object (QFocusEvent)
154 """
155 if evt.reason() != Qt.MouseFocusReason:
156 self.__searchEdit.selectAll()
157 self.__searchEdit.setFocus()
158
159 def eventFilter(self, watched, event):
160 """
161 Public method called to filter the event queue.
162
163 @param watched the QObject being watched (QObject)
164 @param event the event that occurred (QEvent)
165 @return flag indicating whether the event was handled (boolean)
166 """
167 if self.__searchEdit and watched == self.__searchEdit and \
168 event.type() == QEvent.KeyPress:
169 idx = self.__index.currentIndex()
170 if event.key() == Qt.Key_Up:
171 idx = self.__index.model().index(
172 idx.row() - 1, idx.column(), idx.parent())
173 if idx.isValid():
174 self.__index.setCurrentIndex(idx)
175 elif event.key() == Qt.Key_Down:
176 idx = self.__index.model().index(
177 idx.row() + 1, idx.column(), idx.parent())
178 if idx.isValid():
179 self.__index.setCurrentIndex(idx)
180 elif event.key() == Qt.Key_Escape:
181 self.escapePressed.emit()
182
183 return QWidget.eventFilter(self, watched, event)
184
185 def __showContextMenu(self, pos):
186 """
187 Private slot showing the context menu.
188
189 @param pos position to show the menu at (QPoint)
190 """
191 idx = self.__index.indexAt(pos)
192 if idx.isValid():
193 menu = QMenu()
194 curTab = menu.addAction(self.tr("Open Link"))
195 newTab = menu.addAction(self.tr("Open Link in New Tab"))
196 menu.move(self.__index.mapToGlobal(pos))
197
198 act = menu.exec_()
199 model = self.__index.model()
200 if model is not None:
201 keyword = model.data(idx, Qt.DisplayRole)
202 links = model.linksForKeyword(keyword)
203 if len(links) == 1:
204 link = QUrl(links[list(links.keys())[0]])
205 else:
206 link = self.__selectLink(links, keyword)
207
208 if not link.isEmpty() and link.isValid():
209 if act == curTab:
210 self.linkActivated.emit(link)
211 elif act == newTab:
212 self.__mw.newTab(link)

eric ide

mercurial