Alkimia API

alkwebview.cpp
1/*
2 SPDX-FileCopyrightText: 2018, 2024 Ralf Habacker ralf.habacker @freenet.de
3
4 This file is part of libalkimia.
5
6 SPDX-License-Identifier: LGPL-2.1-or-later
7*/
8
9#include "alkwebview.h"
10
11#include "alkdebug.h"
12#include "alkwebpage.h"
13
14#include <QEventLoop>
15#include <QNetworkAccessManager>
16#include <QNetworkReply>
17
18#if defined(BUILD_WITH_WEBENGINE)
19#include <klocalizedstring.h>
20
21#include <QContextMenuEvent>
22#include <QDesktopServices>
23#include <QMenu>
24
25// Port used by web inspector, may be converted into a tool setting attribute
26static const int s_webInspectorPort{8181};
27static bool s_webInspectorEnabled{false};
28
29AlkWebView::AlkWebView(QWidget *parent)
30 : QWebEngineView(parent)
31{
32 connect(page(), SIGNAL(urlChanged(QUrl)), this, SIGNAL(loadRedirectedTo(QUrl)));
33}
34
35AlkWebView::~AlkWebView()
36{
37}
38
39void AlkWebView::load(const QUrl &url)
40{
41 QWebEngineView::load(url);
42 if (QWebEngineView::url() == url)
43 triggerPageAction(QWebEnginePage::Reload);
44}
45
46void AlkWebView::setWebInspectorEnabled(bool state)
47{
48 s_webInspectorEnabled = state;
49 if (state)
50 qputenv("QTWEBENGINE_REMOTE_DEBUGGING", QByteArray::number(s_webInspectorPort));
51 else
52 qunsetenv("QTWEBENGINE_REMOTE_DEBUGGING");
53}
54
55bool AlkWebView::webInspectorEnabled()
56{
57 return s_webInspectorEnabled;
58}
59
60AlkWebPage *AlkWebView::webPage()
61{
62 return dynamic_cast<AlkWebPage*>(page());
63}
64
65void AlkWebView::setWebPage(AlkWebPage *webPage)
66{
67 setPage(dynamic_cast<QWebEnginePage*>(webPage));
68}
69
71{
72 if (!s_webInspectorEnabled) {
73 QWebEngineView::contextMenuEvent(event);
74 return;
75 }
76#if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
78#else
79 QMenu *menu = page()->createStandardContextMenu();
80#endif
81 const QList<QAction *> actions = menu->actions();
82 auto inspectElement = std::find(actions.cbegin(), actions.cend(), page()->action(QWebEnginePage::InspectElement));
83 if (inspectElement == actions.cend()) {
84 auto viewSource = std::find(actions.cbegin(), actions.cend(), page()->action(QWebEnginePage::ViewSource));
85 if (viewSource == actions.cend())
86 menu->addSeparator();
87
88 QAction *action = new QAction(menu);
89 action->setText(i18n("Open inspector in new window"));
90 connect(action, &QAction::triggered, [this]() {
91#if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
92 QDesktopServices::openUrl(QString("http://localhost:%1/devtools/page/%2").arg(s_webInspectorPort).arg(page()->devToolsId()));
93#else
94 Q_UNUSED(this)
95 QDesktopServices::openUrl(QString("http://localhost:%1").arg(s_webInspectorPort));
96#endif
97 });
98
99 QAction *before(inspectElement == actions.cend() ? nullptr : *inspectElement);
100 menu->insertAction(before, action);
101 } else {
102 (*inspectElement)->setText(i18n("Inspect element"));
103 }
104 menu->popup(event->globalPos());
105}
106
107#elif defined(BUILD_WITH_WEBKIT)
108#include <QPointer>
109#include <QWebInspector>
110#include <QWebView>
111
112static QPointer<QWebInspector> s_webInspector{nullptr};
113
114AlkWebView::AlkWebView(QWidget *parent)
115 : QWebView(parent)
116{
117 page()->settings()->setAttribute(QWebSettings::JavaEnabled, false);
118 page()->settings()->setAttribute(QWebSettings::AutoLoadImages, false);
119 page()->settings()->setAttribute(QWebSettings::PluginsEnabled, false);
120 // TODO catch unchanged urls
121 connect(this, SIGNAL(urlChanged(QUrl)), this, SIGNAL(loadRedirectedTo(QUrl)));
122}
123
124AlkWebView::~AlkWebView()
125{
126}
127
128void AlkWebView::setWebInspectorEnabled(bool enable)
129{
130 page()->settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, enable);
131 if (enable && !s_webInspector) {
132 s_webInspector = new QWebInspector();
133 s_webInspector->setPage(page());
134 }
135}
136
137bool AlkWebView::webInspectorEnabled()
138{
139 return page()->settings()->testAttribute(QWebSettings::DeveloperExtrasEnabled);
140}
141
142AlkWebPage *AlkWebView::webPage()
143{
144 return dynamic_cast<AlkWebPage*>(page());
145}
146
147void AlkWebView::setWebPage(AlkWebPage *webPage)
148{
149 setPage(dynamic_cast<QWebPage*>(webPage));
150}
151
152#else
153
154AlkWebView::AlkWebView(QWidget *parent)
155 : QTextBrowser(parent)
156{
157 setOpenExternalLinks(false);
158 setOpenLinks(false);
159}
160
161AlkWebView::~AlkWebView()
162{
163}
164
165void AlkWebView::load(const QUrl &url)
166{
167#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
169#else
170 setSource(url);
171#endif
172 if (source() == url)
173 reload();
174 Q_EMIT loadStarted();
175}
176
177void AlkWebView::setHtml(const QString &data, const QUrl &baseUrl)
178{
179 Q_UNUSED(baseUrl);
181}
182
183void AlkWebView::setWebInspectorEnabled(bool enable)
184{
185 Q_UNUSED(enable);
186}
187
188bool AlkWebView::webInspectorEnabled()
189{
190 return false;
191}
192
193AlkWebPage *AlkWebView::webPage()
194{
195 return m_page;
196}
197
198void AlkWebView::setWebPage(AlkWebPage *webPage)
199{
200 m_page = webPage;
201}
202
203QVariant AlkWebView::loadResource(int type, const QUrl &name)
204{
205 switch(type) {
208 QNetworkAccessManager networkManager;
209 QNetworkRequest request;
210 QUrl url = name;
211 QNetworkReply* reply;
212 int counts = 3;
213 while(--counts > 0) {
214 request.setUrl(url);
215 reply = networkManager.get(request);
216 QEventLoop loop;
217 connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
218 connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), &loop, SLOT(quit()));
219 loop.exec();
220 if (reply->error() == QNetworkReply::NoError) {
222 if (!url.isEmpty() && url != reply->url()) {
223 Q_EMIT loadRedirectedTo(reply->url().resolved(url));
224 } else {
225 break;
226 }
227 } else {
228 alkDebug() << reply->error();
229 return QString();
230 }
231 }
232 QString data = reply->readAll();
233 Q_EMIT loadFinished(true);
234 return data;
235 }
236
237 return QVariant();
238}
239
240#endif
Wrapper for debug output.
The AlkWebPage class provides an object to load and view web documents to provide functionality like ...
Definition alkwebpage.h:100
QString i18n(const char *text, const TYPE &arg...)
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
QString name(StandardAction id)
const QList< QKeySequence > & quit()
virtual void contextMenuEvent(QContextMenuEvent *e) override
void setText(const QString &text)
void triggered(bool checked)
QByteArray number(double n, char format, int precision)
bool openUrl(const QUrl &url)
int exec(ProcessEventsFlags flags)
QByteArray readAll()
const_iterator cbegin() const const
const_iterator cend() const const
QAction * addSeparator()
void popup(const QPoint &p, QAction *atAction)
QNetworkReply * get(const QNetworkRequest &request)
QVariant attribute(QNetworkRequest::Attribute code) const const
NetworkError error() const const
QUrl url() const const
void setUrl(const QUrl &url)
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
virtual bool event(QEvent *e) override
virtual void reload()
void setSource(const QUrl &url, QTextDocument::ResourceType type)
QMenu * createStandardContextMenu()
void setHtml(const QString &text)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
bool isEmpty() const const
QUrl resolved(const QUrl &relative) const const
QUrl toUrl() const const
QList< QAction * > actions() const const
void insertAction(QAction *before, QAction *action)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Dec 21 2024 17:01:13 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.