--- a/WebBrowser/QtHelp/HelpIndexWidget.py Thu Jul 14 18:56:39 2016 +0200 +++ b/WebBrowser/QtHelp/HelpIndexWidget.py Sun Jul 17 15:36:11 2016 +0200 @@ -11,34 +11,36 @@ from PyQt5.QtCore import pyqtSignal, Qt, QUrl, QEvent from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QLineEdit, QMenu, \ - QDialog + QDialog, QApplication class HelpIndexWidget(QWidget): """ Class implementing a window for showing the QtHelp index. - @signal linkActivated(QUrl) emitted when an index entry is activated - @signal linksActivated(links, keyword) emitted when an index entry - referencing multiple targets is activated @signal escapePressed() emitted when the ESC key was pressed + @signal openUrl(QUrl, str) emitted to open an entry in the current tab + @signal newTab(QUrl, str) emitted to open an entry in a new tab + @signal newBackgroundTab(QUrl, str) emitted to open an entry in a + new background tab + @signal newWindow(QUrl, str) emitted to open an entry in a new window """ - linkActivated = pyqtSignal(QUrl) - linksActivated = pyqtSignal(dict, str) escapePressed = pyqtSignal() + openUrl = pyqtSignal(QUrl) + newTab = pyqtSignal(QUrl) + newBackgroundTab = pyqtSignal(QUrl) + newWindow = pyqtSignal(QUrl) - def __init__(self, engine, mainWindow, parent=None): + def __init__(self, engine, parent=None): """ Constructor @param engine reference to the help engine (QHelpEngine) - @param mainWindow reference to the main window object (QMainWindow) @param parent reference to the parent widget (QWidget) """ super(HelpIndexWidget, self).__init__(parent) self.__engine = engine - self.__mw = mainWindow self.__searchEdit = None self.__index = None @@ -55,31 +57,65 @@ self.__index = self.__engine.indexWidget() self.__index.installEventFilter(self) + self.__index.setContextMenuPolicy(Qt.CustomContextMenu) + self.__engine.indexModel().indexCreationStarted.connect( self.__disableSearchEdit) self.__engine.indexModel().indexCreated.connect( self.__enableSearchEdit) self.__index.activated.connect(self.__activated) + self.__index.customContextMenuRequested.connect( + self.__showContextMenu) self.__searchEdit.returnPressed.connect( self.__index.activateCurrentItem) self.__layout.addWidget(self.__index) self.__index.viewport().installEventFilter(self) - def __activated(self, idx): + def __activated(self, idx, midButton=False): """ Private slot to handle the activation of a keyword entry. - @param idx index of the activated entry (QModelIndex) + @param idx index of the activated entry + @type QModelIndex + @param midButton flag indicating a middle mouse button release + @type bool """ model = self.__index.model() if model is not None: + modifiers = QApplication.keyboardModifiers() keyword = model.data(idx, Qt.DisplayRole) links = model.linksForKeyword(keyword) if len(links) == 1: - self.linkActivated.emit(QUrl(links[list(links.keys())[0]])) + link = QUrl(links[list(links.keys())[0]]) else: - self.linksActivated.emit(links, keyword) + link = self.__selectLink(links, keyword) + if not link.isEmpty() and link.isValid(): + if modifiers & Qt.ControlModifier or midButton: + self.newTab.emit(link) + elif modifiers & Qt.ShiftModifier: + self.newWindow.emit(link) + else: + self.openUrl.emit(link) + + def __selectLink(self, links, keyword): + """ + Private method to give the user a chance to select among the + returned links. + + @param links dictionary of document title and URL to select from + @type dictionary of str (key) and QUrl (value) + @param keyword keyword for the link set + @type str + @return selected link + @rtype QUrl + """ + link = QUrl() + from .HelpTopicDialog import HelpTopicDialog + dlg = HelpTopicDialog(self, keyword, links) + if dlg.exec_() == QDialog.Accepted: + link = dlg.link() + return link def __filterIndices(self, filter): """ @@ -138,44 +174,45 @@ self.__index.setCurrentIndex(idx) elif event.key() == Qt.Key_Escape: self.escapePressed.emit() - elif self.__index and watched == self.__index and \ - event.type() == QEvent.ContextMenu: - idx = self.__index.indexAt(event.pos()) - if idx.isValid(): - menu = QMenu() - curTab = menu.addAction(self.tr("Open Link")) - newTab = menu.addAction(self.tr("Open Link in New Tab")) - menu.move(self.__index.mapToGlobal(event.pos())) - - act = menu.exec_() - if act == curTab: - self.__activated(idx) - elif act == newTab: - model = self.__index.model() - if model is not None: - keyword = model.data(idx, Qt.DisplayRole) - links = model.linksForKeyword(keyword) - if len(links) == 1: - self.__mw.newTab(list(links.values())[0]) - elif len(links) > 1: - from .HelpTopicDialog import HelpTopicDialog - dlg = HelpTopicDialog(self, keyword, links) - if dlg.exec_() == QDialog.Accepted: - self.__mw.newTab(dlg.link()) elif self.__index and watched == self.__index.viewport() and \ event.type() == QEvent.MouseButtonRelease: idx = self.__index.indexAt(event.pos()) - if idx.isValid() and event.button() == Qt.MidButton: - model = self.__index.model() - if model is not None: - keyword = model.data(idx, Qt.DisplayRole) - links = model.linksForKeyword(keyword) - if len(links) == 1: - self.__mw.newTab(list(links.values())[0]) - elif len(links) > 1: - from .HelpTopicDialog import HelpTopicDialog - dlg = HelpTopicDialog(self, keyword, links) - if dlg.exec_() == QDialog.Accepted: - self.__mw.newTab(dlg.link()) + if idx.isValid(): + self.__activated(idx, midButton=event.button() == Qt.MidButton) return QWidget.eventFilter(self, watched, event) + + def __showContextMenu(self, pos): + """ + Private slot showing the context menu. + + @param pos position to show the menu at (QPoint) + """ + idx = self.__index.indexAt(pos) + if idx.isValid(): + menu = QMenu() + curTab = menu.addAction(self.tr("Open Link")) + newTab = menu.addAction(self.tr("Open Link in New Tab")) + newBackgroundTab = menu.addAction( + self.tr("Open Link in Background Tab")) + newWindow = menu.addAction(self.tr("Open Link in New Window")) + menu.move(self.__index.mapToGlobal(pos)) + + act = menu.exec_() + model = self.__index.model() + if model is not None: + keyword = model.data(idx, Qt.DisplayRole) + links = model.linksForKeyword(keyword) + if len(links) == 1: + link = QUrl(links[list(links.keys())[0]]) + else: + link = self.__selectLink(links, keyword) + + if act == curTab: + self.openUrl.emit(link) + elif act == newTab: + self.newTab.emit(link) + elif act == newBackgroundTab: + self.newBackgroundTab.emit(link) + elif act == newWindow: + self.newWindow.emit(link)