Source code for vdat.gui.help_window
# Virus Data Analysis Tool: a data reduction GUI for HETDEX/VIRUS data
# Copyright (C) 2016, 2017 "The HETDEX collaboration"
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
from __future__ import (absolute_import, division, print_function,
unicode_literals)
from qtpy import QtCore, QtGui, QtHelp, QtWidgets
from vdat.gui.utils import help_collection
[docs]class HelpBrowser(QtWidgets.QTextBrowser):
'''Custom :class:`~PyQt5.QtWidgets.QTextBrowser` that can deal with
documentation and external links
.. list-table:: **Custom slot**
:header-rows: 1
* - Name
- Signature
- Description
* - :meth:`setSource`
- :class:`PyQt5.QtCore.QUrl`
- if the input url is http/https opens in the default internet
browser, other wise pass it further
Parameters
----------
help_engine : :class:`PyQt5.QtHelp.QHelpEngine`
help engine containing the documentation
'''
def __init__(self, help_engine, parent=None):
super(HelpBrowser, self).__init__(parent=parent)
self._help_engine = help_engine
[docs] @QtCore.Slot(QtCore.QUrl)
def setSource(self, url):
'''Reimplement slot to properly handle http/https links via
:meth:`PyQt5.QtGui.QDesktopServices.openUrl`. All the other types are
passed to the original implementation.
Parameters
----------
url : :class:`PyQt5.QtCore.QUrl`
url that has being clicked
Returns
-------
resource to show
'''
if url.scheme() in ['http', 'https', 'mailto']:
QtGui.QDesktopServices.openUrl(url)
return
super(HelpBrowser, self).setSource(url)
[docs] def loadResource(self, type_, url):
'''Reimplement the method to get ``qthelp`` urls from the help engine.
All the other types are passed unchanged to the original
implementation.
Parameters
----------
type_ : int
ignored
url : :class:`PyQt5.QtCore.QUrl`
url that has being clicked
Returns
-------
resources to show
'''
if url.scheme() == 'qthelp':
return self._help_engine.fileData(url)
return super(HelpBrowser, self).loadResource(type_, url)
[docs]class HelpWidget(QtWidgets.QWidget):
'''Create a widget containing the offline help.
.. list-table:: **Custom slot**
:header-rows: 1
* - Name
- Signature
- Description
* - :meth:`expand_and_set`
-
- show the first page of the documentation and expand the first level
of the content
* - :meth:`on_click_content`
- :class:`PyQt5.QtCore.QModelIndex`
- Extract the url of the selected item and send it to
:class:`HelpBrowser` for displaying
.. list-table:: **Connections between custom signals and/or slots**
:header-rows: 1
* - Signal
- Slot
* - :attr:`PyQt5.QtHelp.QHelpContentModel.contentsCreated`
- :meth:`expand_and_set`
* - :attr:`PyQt5.QtHelp.QHelpContentWidget.clicked`
- :meth:`on_click_content`
* - :attr:`PyQt5.QtHelp.QHelpIndexWidget.linkActivated`
- :meth:`HelpBrowser.setSource`
Parameters
----------
parent : :class:`PyQt5.QtWidgets.QWidget` instance
parent of the menu' bar
'''
def __init__(self, parent=None):
super(HelpWidget, self).__init__(parent=parent)
self.help_engine = QtHelp.QHelpEngine(help_collection(), parent=self)
self.text_widget = HelpBrowser(self.help_engine, parent=self)
[docs] def setup(self):
'''Setup the gui elements into a resizable splitter and connect all the
signals'''
layout = QtWidgets.QHBoxLayout(self)
self.setLayout(layout)
splitter = QtWidgets.QSplitter(QtCore.Qt.Horizontal)
layout.addWidget(splitter)
tabwidget = QtWidgets.QTabWidget(parent=self)
content = self.help_engine.contentWidget()
index = self.help_engine.indexWidget()
tabwidget.addTab(content, 'Contents')
tabwidget.addTab(index, 'Index')
splitter.insertWidget(0, tabwidget)
splitter.insertWidget(1, self.text_widget)
splitter.setSizes([200, 800])
splitter.setStretchFactor(1, 1)
splitter.setStretchFactor(0, 0)
index.linkActivated.connect(self.text_widget.setSource)
content.clicked.connect(self.on_click_content)
model = self.help_engine.contentModel()
model.contentsCreated.connect(self.expand_and_set)
self.help_engine.setupData()
[docs] @QtCore.Slot()
def expand_and_set(self):
'''Custom slot: it gets the index of the first element, set it as first
page in the help browser and expand the sections below it.
'''
content = self.help_engine.contentWidget()
model = self.help_engine.contentModel()
root_index = content.rootIndex()
index = model.index(0, 0, parent=root_index)
item = model.contentItemAt(index)
self.text_widget.setSource(item.url())
content.expand(index)
[docs] @QtCore.Slot(QtCore.QModelIndex)
def on_click_content(self, index):
'''Custom slot: receive the clicked index in the content tree, get the
underlying url and send it to the :class:`HelpBrowser`
Parameters
----------
index : :class:`PyQt5.QtCore.QModelIndex`
index of the selected item
'''
model = self.help_engine.contentModel()
item = model.contentItemAt(index)
self.text_widget.setSource(item.url())
[docs]class HelpWindow(QtWidgets.QMainWindow):
'''Window wrapping the HelpWidget
Parameters
----------
parent : :class:`PyQt5.QtWidgets.QWidget` instance
parent of the menu' bar
'''
def __init__(self, parent=None):
super(HelpWindow, self).__init__(parent=parent)
self.resize(1000, 600)
help_widget = HelpWidget(parent=self)
help_widget.setup()
self.setCentralWidget(help_widget)