34#include "ui_pqHelpWindow.h"
40#include <QHelpIndexWidget>
41#include <QHelpSearchQueryWidget>
42#include <QHelpSearchResultWidget>
43#include <QMimeDatabase>
45#include <QNetworkProxy>
47#include <QPrintDialog>
50#include <QTextBrowser>
59constexpr auto QTHELP_SCHEME =
"qthelp";
62#if defined(USE_QTWEBKIT)
63#include <QNetworkReply>
72class pqHelpWindowNetworkReply :
public QNetworkReply {
73 using Superclass = QNetworkReply;
76 pqHelpWindowNetworkReply(
const QUrl &url, QHelpEngineCore *helpEngine, QObject *parent =
nullptr);
78 void abort()
override {}
80 qint64 bytesAvailable()
const override {
81 return (this->RawData.size() - this->Offset) + this->Superclass::bytesAvailable();
83 bool isSequential()
const override {
return true; }
86 qint64 readData(
char *data, qint64 maxSize)
override;
92 Q_DISABLE_COPY(pqHelpWindowNetworkReply)
96pqHelpWindowNetworkReply::pqHelpWindowNetworkReply(
const QUrl &my_url, QHelpEngineCore *engine, QObject *parent)
97 : Superclass(parent), Offset(0) {
100 this->RawData = engine->fileData(my_url);
102 QString content_type =
"text/plain";
103 QString extension = QFileInfo(my_url.path()).suffix().toLower();
104 QMap<QString, QString> extension_type_map;
105 extension_type_map[
"jpg"] =
"image/jpeg";
106 extension_type_map[
"jpeg"] =
"image/jpeg";
107 extension_type_map[
"png"] =
"image/png";
108 extension_type_map[
"gif"] =
"image/gif";
109 extension_type_map[
"tiff"] =
"image/tiff";
110 extension_type_map[
"htm"] =
"text/html";
111 extension_type_map[
"html"] =
"text/html";
112 extension_type_map[
"css"] =
"text/css";
113 extension_type_map[
"xml"] =
"text/xml";
115 if (extension_type_map.contains(extension)) {
116 content_type = extension_type_map[extension];
119 this->setHeader(QNetworkRequest::ContentLengthHeader, QVariant(this->RawData.size()));
120 this->setHeader(QNetworkRequest::ContentTypeHeader, content_type);
121 this->open(QIODevice::ReadOnly | QIODevice::Unbuffered);
122 this->setUrl(my_url);
123 QTimer::singleShot(0,
this, SIGNAL(readyRead()));
124 QTimer::singleShot(0,
this, SLOT(finished()));
128qint64 pqHelpWindowNetworkReply::readData(
char *data, qint64 maxSize) {
129 if (this->Offset <= this->RawData.size()) {
130 qint64 end = qMin(this->Offset + maxSize,
static_cast<qint64
>(this->RawData.size()));
131 qint64
delta = end - this->Offset;
132 memcpy(data, this->RawData.constData() + this->Offset, delta);
133 this->Offset +=
delta;
145 QPointer<QHelpEngineCore> Engine;
148 pqNetworkAccessManager(QHelpEngineCore *helpEngine, QNetworkAccessManager *manager, QObject *parentObject)
149 :
Superclass(parentObject), Engine(helpEngine) {
150 Q_ASSERT(manager !=
nullptr && helpEngine !=
nullptr);
152 this->setCache(manager->cache());
153 this->setCookieJar(manager->cookieJar());
154 this->setProxy(manager->proxy());
155 this->setProxyFactory(manager->proxyFactory());
159 QNetworkReply *createRequest(Operation operation,
const QNetworkRequest &request, QIODevice *device)
override {
160 if (request.url().scheme() == QTHELP_SCHEME && operation == GetOperation) {
161 return new pqHelpWindowNetworkReply(request.url(), this->Engine,
this);
163 return this->Superclass::createRequest(operation, request, device);
172#include <QWebEngineHistory>
173#include <QWebEnginePage>
174#include <QWebEngineProfile>
175#include <QWebEngineUrlRequestJob>
176#include <QWebEngineUrlSchemeHandler>
177#include <QWebEngineView>
179#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
180#include <QWebEngineUrlScheme>
186 auto scheme = QWebEngineUrlScheme(QTHELP_SCHEME);
187 scheme.setFlags(QWebEngineUrlScheme::LocalScheme | QWebEngineUrlScheme::LocalAccessAllowed);
188 QWebEngineUrlScheme::registerScheme(scheme);
199 : QWebEngineUrlSchemeHandler(parent),
m_helpEngine(helpEngine) {}
203 const auto url = request->requestUrl();
206 QBuffer *buffer =
new QBuffer;
207 buffer->setData(array);
208 buffer->open(QIODevice::ReadOnly);
209 connect(buffer, &QIODevice::aboutToClose, buffer, &QObject::deleteLater);
210 request->reply(resourceType.toLocal8Bit(), buffer);
219 QMimeDatabase mimeTypes;
220 return mimeTypes.mimeTypeForFile(url.path(), QMimeDatabase::MatchExtension).name();
235 :
Superclass(parentObject, parentFlags), m_helpEngine(engine) {
236 Q_ASSERT(engine !=
nullptr);
244 QObject::connect(this->
m_helpEngine, SIGNAL(warning(
const QString &)),
this, SIGNAL(
helpWarnings(
const QString &)));
247 auto *navigation =
new QToolBar(
"Navigation");
248 auto *home =
new QPushButton(
"Home");
249 auto *print =
new QPushButton(
"Print...");
250 print->setToolTip(
"Print the current page");
264 navigation->addWidget(home);
265 navigation->addWidget(print);
268 navigation->setAllowedAreas(Qt::TopToolBarArea | Qt::RightToolBarArea);
269 this->addToolBar(navigation);
271 this->setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North);
274 this->tabifyDockWidget(ui.indexDock, ui.searchDock);
275 ui.indexDock->setWidget(this->
m_helpEngine->indexWidget());
278 auto *searchPane =
new QWidget(
this);
279 auto *vbox =
new QVBoxLayout();
280 searchPane->setLayout(vbox);
281 vbox->addWidget(this->
m_helpEngine->searchEngine()->queryWidget());
282 vbox->addWidget(this->
m_helpEngine->searchEngine()->resultWidget());
283 connect(this->
m_helpEngine->searchEngine()->resultWidget(), SIGNAL(requestShowLink(QUrl)),
this,
287 ui.searchDock->setWidget(searchPane);
291 connect(this->
m_helpEngine->indexWidget(), SIGNAL(linkActivated(QUrl, QString)),
this, SLOT(
showPage(QUrl)));
294#if defined(USE_QTWEBKIT)
296 QNetworkAccessManager *oldManager =
m_browser->page()->networkAccessManager();
298 m_browser->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
299 m_browser->page()->setNetworkAccessManager(newManager);
300 m_browser->page()->setForwardUnsupportedContent(
false);
306 QWebEngineProfile::defaultProfile()->installUrlSchemeHandler(QTHELP_SCHEME,
new QtHelpUrlHandler(engine,
this));
316 connect(home, SIGNAL(clicked()),
this, SLOT(
showHomePage()));
317 connect(print, SIGNAL(clicked()),
this, SLOT(
printPage()));
335 QString(QLatin1String(
"<html><head><title>Invalid Url - %1</title></head><body>")).arg(url.toString());
337 htmlDoc += QString(QLatin1String(
"<center><h1>Missing page - %1</h1></center>")).arg(url.toString());
339 htmlDoc += QLatin1String(
"</body></html>");
346 this->
showPage(QUrl::fromUserInput(url), linkClicked);
351 if (url.scheme() == QTHELP_SCHEME) {
363 MantidDesktopServices::openUrl(url);
373 QPrintDialog dialog(&printer,
this);
374 dialog.setWindowTitle(tr(
"Print Document"));
375 if (dialog.exec() != QDialog::Accepted)
377#if defined(USE_QTWEBKIT)
380 m_browser->page()->print(&printer, [](
bool) {});
400 this->statusBar()->showMessage(link);
409 foreach (QUrl url, html_pages) {
410 if (url.path().endsWith(
"index.html")) {
420 return (this->
m_helpEngine->findFile(url).isValid() && (this->m_helpEngine->fileData(url).size() > 0));
Mimic the WebKit class to emit linkClicked signal from the page.
This class provides a wrapper around QDesktopServices to fix a bug in opening URLs in firefox when tc...
Adds support for qthelp scheme links that load content from them QHelpEngine.
QString contentType(const QUrl &url)
Given a url return the content type of the resource based on the extension.
QtHelpUrlHandler(QHelpEngineCore *helpEngine, QObject *parent=nullptr)
void requestStarted(QWebEngineUrlRequestJob *request) override
QHelpEngineCore * m_helpEngine
virtual void showPage(const QString &url, bool linkClicked=false)
Requests showing of a particular page.
QWebEngineView * m_browser
QHelpEngine * m_helpEngine
pqHelpWindow(QHelpEngine *engine, QWidget *parent=nullptr, const Qt::WindowFlags &flags=Qt::WindowFlags())
virtual void showHomePage(const QString &namespace_name)
Tries to locate a file name index.html in the given namespace and then shows that page.
virtual void printPage()
Prints the current open page.
void helpWarnings(const QString &)
fired to relay warning messages from the help system.
bool isExistingPage(const QUrl &url)
Check if the url is an existing page.
void errorMissingPage(const QUrl &url)
Set the contents of the browser to show an error message.
virtual void showLinkedPage(const QUrl &url)
Show a page linked to by another page in the help window.
friend class pqNetworkAccessManager
void linkHovered(const QString &link, const QString &title="", const QString &textContent="")
const QtHelpSchemeRegistration QTHELP_REGISTRATION
Register on the scheme on library load as it must be done before QApplication is created.
QtHelpSchemeRegistration()