KParts

navigationextension.cpp
1/*
2 This file is part of the KDE project
3 SPDX-FileCopyrightText: 1999 Simon Hausmann <hausmann@kde.org>
4 SPDX-FileCopyrightText: 1999 David Faure <faure@kde.org>
5
6 SPDX-License-Identifier: LGPL-2.0-or-later
7*/
8
9#include "navigationextension.h"
10
11#include "kparts_logging.h"
12
13#include <KLocalizedString>
14#include <KMessageBox>
15#include <KUriFilter>
16
17#include <QApplication>
18#include <QClipboard>
19#include <QMap>
20#include <QRegularExpression>
21#include <QTimer>
22
23using namespace KParts;
24
25namespace KParts
26{
27// Internal class, use to store the status of the actions
28class KBitArray
29{
30public:
31 int val = 0;
32 bool operator[](int index)
33 {
34 return (val & (1 << index)) ? true : false;
35 }
36 void setBit(int index, bool value)
37 {
38 if (value) {
39 val = val | (1 << index);
40 } else {
41 val = val & ~(1 << index);
42 }
43 }
44};
45
46class NavigationExtensionPrivate
47{
48public:
49 NavigationExtensionPrivate(KParts::ReadOnlyPart *parent)
50 : m_urlDropHandlingEnabled(false)
51 , m_part(parent)
52 {
53 }
54
55 struct DelayedRequest {
56 QUrl m_delayedURL;
57 KParts::OpenUrlArguments m_delayedArgs;
58 };
59
60 QList<DelayedRequest> m_requests;
61 bool m_urlDropHandlingEnabled;
62 KBitArray m_actionStatus;
63 QMap<int, QString> m_actionText;
64
65 static void createActionSlotMap();
66
68};
69
70Q_GLOBAL_STATIC(NavigationExtension::ActionSlotMap, s_actionSlotMap)
71Q_GLOBAL_STATIC(NavigationExtension::ActionNumberMap, s_actionNumberMap)
72
73void NavigationExtensionPrivate::createActionSlotMap()
74{
75 s_actionSlotMap()->insert("cut", SLOT(cut()));
76 s_actionSlotMap()->insert("copy", SLOT(copy()));
77 s_actionSlotMap()->insert("paste", SLOT(paste()));
78 s_actionSlotMap()->insert("print", SLOT(print()));
79 // Tricky. Those aren't actions in fact, but simply methods that a browserextension
80 // can have or not. No need to return them here.
81 // s_actionSlotMap()->insert( "reparseConfiguration", SLOT(reparseConfiguration()) );
82 // s_actionSlotMap()->insert( "refreshMimeTypes", SLOT(refreshMimeTypes()) );
83
84 // Create the action-number map
85 NavigationExtension::ActionSlotMap::ConstIterator it = s_actionSlotMap()->constBegin();
86 NavigationExtension::ActionSlotMap::ConstIterator itEnd = s_actionSlotMap()->constEnd();
87 for (int i = 0; it != itEnd; ++it, ++i) {
88 // qDebug() << " action " << it.key() << " number " << i;
89 s_actionNumberMap()->insert(it.key(), i);
90 }
91}
92
93}
94
96 : QObject(parent)
97 , d(new NavigationExtensionPrivate(parent))
98{
99 if (s_actionSlotMap()->isEmpty())
100 // Create the action-slot map
101 {
102 NavigationExtensionPrivate::createActionSlotMap();
103 }
104
105 // Set the initial status of the actions depending on whether
106 // they're supported or not
107 const QMetaObject *metaobj = metaObject();
108 ActionSlotMap::ConstIterator it = s_actionSlotMap()->constBegin();
109 ActionSlotMap::ConstIterator itEnd = s_actionSlotMap()->constEnd();
110 for (int i = 0; it != itEnd; ++it, ++i) {
111 // Does the extension have a slot with the name of this action ?
112 QByteArray slotSig = it.key() + "()";
113 d->m_actionStatus.setBit(i, metaobj->indexOfMethod(slotSig.constData()) != -1);
114 }
115
116 connect(this, &NavigationExtension::openUrlRequest, this, &NavigationExtension::slotOpenUrlRequest);
117 connect(this, &NavigationExtension::enableAction, this, &NavigationExtension::slotEnableAction);
118 connect(this, &NavigationExtension::setActionText, this, &NavigationExtension::slotSetActionText);
119}
120
121NavigationExtension::~NavigationExtension()
122{
123 // qDebug() << "BrowserExtension::~BrowserExtension() " << this;
124}
125
127{
128 return 0;
129}
130
132{
133 return 0;
134}
135
137{
138 // TODO add d->m_part->mimeType()
139 stream << d->m_part->url() << static_cast<qint32>(xOffset()) << static_cast<qint32>(yOffset());
140}
141
143{
144 QUrl u;
145 qint32 xOfs;
146 qint32 yOfs;
147 stream >> u >> xOfs >> yOfs;
148
149 OpenUrlArguments args;
150 args.setXOffset(xOfs);
151 args.setYOffset(yOfs);
152 // TODO add args.setMimeType
153 d->m_part->setArguments(args);
154 d->m_part->openUrl(u);
155}
156
158{
159 return d->m_urlDropHandlingEnabled;
160}
161
163{
164 d->m_urlDropHandlingEnabled = enable;
165}
166
168{
169 QString plain(QStringLiteral("plain"));
171 // Remove linefeeds and any whitespace surrounding it.
172 url.remove(QRegularExpression(QStringLiteral("[\\ ]*\\n+[\\ ]*")));
173
174 // Check if it's a URL
176 filters.removeAll(QStringLiteral("kuriikwsfilter"));
177 filters.removeAll(QStringLiteral("localdomainurifilter"));
178 KUriFilterData filterData;
179 filterData.setData(url);
180 filterData.setCheckForExecutables(false);
181 if (KUriFilter::self()->filterUri(filterData, filters)) {
182 switch (filterData.uriType()) {
186 slotOpenUrlRequest(filterData.uri());
187 break;
189 KMessageBox::error(d->m_part->widget(), filterData.errorMsg());
190 break;
191 default:
192 break;
193 }
194 } else if (KUriFilter::self()->filterUri(filterData, QStringList(QStringLiteral("kuriikwsfilter"))) && url.length() < 250) {
195 if (KMessageBox::questionTwoActions(d->m_part->widget(),
196 i18n("<qt>Do you want to search the Internet for <b>%1</b>?</qt>", url.toHtmlEscaped()),
197 i18n("Internet Search"),
198 KGuiItem(i18n("&Search"), QStringLiteral("edit-find")),
200 QStringLiteral("MiddleClickSearch"))
202 slotOpenUrlRequest(filterData.uri());
203 }
204 }
205}
206
207void NavigationExtension::slotOpenUrlRequest(const QUrl &url, const KParts::OpenUrlArguments &args)
208{
209 // qDebug() << this << " BrowserExtension::slotOpenURLRequest(): url=" << url.url();
210 NavigationExtensionPrivate::DelayedRequest req;
211 req.m_delayedURL = url;
212 req.m_delayedArgs = args;
213 d->m_requests.append(req);
214 QTimer::singleShot(0, this, &NavigationExtension::slotEmitOpenUrlRequestDelayed);
215}
216
217void NavigationExtension::slotEmitOpenUrlRequestDelayed()
218{
219 if (d->m_requests.isEmpty()) {
220 return;
221 }
222 NavigationExtensionPrivate::DelayedRequest req = d->m_requests.front();
223 d->m_requests.pop_front();
224 Q_EMIT openUrlRequestDelayed(req.m_delayedURL, req.m_delayedArgs);
225 // tricky: do not do anything here! (no access to member variables, etc.)
226}
227
228void NavigationExtension::slotEnableAction(const char *name, bool enabled)
229{
230 // qDebug() << "BrowserExtension::slotEnableAction " << name << " " << enabled;
231 ActionNumberMap::ConstIterator it = s_actionNumberMap()->constFind(name);
232 if (it != s_actionNumberMap()->constEnd()) {
233 d->m_actionStatus.setBit(it.value(), enabled);
234 // qDebug() << "BrowserExtension::slotEnableAction setting bit " << it.data() << " to " << enabled;
235 } else {
236 qCWarning(KPARTSLOG) << "BrowserExtension::slotEnableAction unknown action " << name;
237 }
238}
239
240bool NavigationExtension::isActionEnabled(const char *name) const
241{
242 int actionNumber = (*s_actionNumberMap())[name];
243 return d->m_actionStatus[actionNumber];
244}
245
246void NavigationExtension::slotSetActionText(const char *name, const QString &text)
247{
248 // qDebug() << "BrowserExtension::slotSetActionText " << name << " " << text;
249 ActionNumberMap::ConstIterator it = s_actionNumberMap()->constFind(name);
250 if (it != s_actionNumberMap()->constEnd()) {
251 d->m_actionText[it.value()] = text;
252 } else {
253 qCWarning(KPARTSLOG) << "BrowserExtension::slotSetActionText unknown action " << name;
254 }
255}
256
258{
259 int actionNumber = (*s_actionNumberMap())[name];
260 QMap<int, QString>::ConstIterator it = d->m_actionText.constFind(actionNumber);
261 if (it != d->m_actionText.constEnd()) {
262 return *it;
263 }
264 return QString();
265}
266
268{
269 if (s_actionSlotMap()->isEmpty()) {
270 NavigationExtensionPrivate::createActionSlotMap();
271 }
272 return s_actionSlotMap();
273}
274
279
280#include "moc_navigationextension.cpp"
An extension to KParts::ReadOnlyPart, which allows a better integration of parts with browsers (in pa...
NavigationExtension(KParts::ReadOnlyPart *parent)
Constructor.
void openUrlRequestDelayed(const QUrl &url, const KParts::OpenUrlArguments &arguments)
This signal is emitted when openUrlRequest() is called, after a 0-seconds timer.
static NavigationExtension * childObject(QObject *obj)
Queries obj for a child object which inherits from this BrowserExtension class.
void enableAction(const char *name, bool enabled)
Enables or disable a standard action held by the browser.
bool isURLDropHandlingEnabled() const
Returns whether url drop handling is enabled.
bool isActionEnabled(const char *name) const
virtual int yOffset()
Returns the current y offset.
virtual void restoreState(QDataStream &stream)
Used by the browser to restore the view in the state it was when we left it.
void pasteRequest()
Asks the hosting browser to perform a paste (using openUrlRequestDelayed())
virtual int xOffset()
Returns the current x offset.
void setURLDropHandlingEnabled(bool enable)
Enables or disables url drop handling.
QString actionText(const char *name) const
void openUrlRequest(const QUrl &url, const KParts::OpenUrlArguments &arguments=KParts::OpenUrlArguments())
Asks the host (browser) to open url.
static ActionSlotMap * actionSlotMap()
Returns a pointer to the static map containing the action names as keys and corresponding SLOT()'ifie...
virtual void saveState(QDataStream &stream)
Used by the browser to save the current state of the view (in order to restore it if going back in na...
void setActionText(const char *name, const QString &text)
Change the text of a standard action held by the browser.
OpenUrlArguments is the set of arguments that specify how a URL should be opened by KParts::ReadOnlyP...
Base class for any "viewer" part.
QString errorMsg() const
QUrl uri() const
void setData(const QString &url)
UriTypes uriType() const
void setCheckForExecutables(bool check)
QStringList pluginNames() const
static KUriFilter * self()
QString i18n(const char *text, const TYPE &arg...)
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
ButtonCode questionTwoActions(QWidget *parent, const QString &text, const QString &title, const KGuiItem &primaryAction, const KGuiItem &secondaryAction, const QString &dontAskAgainName=QString(), Options options=Notify)
The KParts namespace,.
QAction * paste(const QObject *recvr, const char *slot, QObject *parent)
QAction * cut(const QObject *recvr, const char *slot, QObject *parent)
QString name(StandardAction id)
QAction * copy(const QObject *recvr, const char *slot, QObject *parent)
QAction * print(const QObject *recvr, const char *slot, QObject *parent)
KGuiItem cancel()
const char * constData() const const
QString text(Mode mode) const const
QClipboard * clipboard()
qsizetype removeAll(const AT &t)
typedef ConstIterator
int indexOfMethod(const char *method) const const
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
T findChild(const QString &name, Qt::FindChildOptions options) const const
virtual const QMetaObject * metaObject() const const
qsizetype length() const const
QString & remove(QChar ch, Qt::CaseSensitivity cs)
QString toHtmlEscaped() const const
QString trimmed() const const
FindDirectChildrenOnly
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri May 17 2024 11:51:19 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.