KParts

browserextension.cpp
1 /* This file is part of the KDE project
2  Copyright (C) 1999 Simon Hausmann <[email protected]>
3  (C) 1999 David Faure <[email protected]>
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License as published by the Free Software Foundation; either
8  version 2 of the License, or (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Library General Public License for more details.
14 
15  You should have received a copy of the GNU Library General Public License
16  along with this library; see the file COPYING.LIB. If not, write to
17  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  Boston, MA 02110-1301, USA.
19 */
20 #include "browserextension.h"
21 
22 #include "kparts_logging.h"
23 
24 #include <KLocalizedString>
25 #include <KMessageBox>
26 #include <KUriFilter>
27 
28 #include <QApplication>
29 #include <QClipboard>
30 #include <QTimer>
31 #include <QMap>
32 #include <QRegularExpression>
33 
34 using namespace KParts;
35 
36 
37 namespace KParts
38 {
39 
40 // Internal class, use to store the status of the actions
41 class KBitArray
42 {
43 public:
44  int val;
45  KBitArray()
46  {
47  val = 0;
48  }
49  bool operator [](int index)
50  {
51  return (val & (1 << index)) ? true : false;
52  }
53  void setBit(int index, bool value)
54  {
55  if (value) {
56  val = val | (1 << index);
57  } else {
58  val = val & ~(1 << index);
59  }
60  }
61 };
62 
63 class Q_DECL_HIDDEN BrowserExtension::BrowserExtensionPrivate
64 {
65 public:
66  BrowserExtensionPrivate(KParts::ReadOnlyPart *parent)
67  : m_urlDropHandlingEnabled(false),
68  m_browserInterface(nullptr),
69  m_part(parent)
70  {}
71 
72  struct DelayedRequest {
73  QUrl m_delayedURL;
74  KParts::OpenUrlArguments m_delayedArgs;
75  KParts::BrowserArguments m_delayedBrowserArgs;
76  };
77 
78  QList<DelayedRequest> m_requests;
79  bool m_urlDropHandlingEnabled;
80  KBitArray m_actionStatus;
81  QMap<int, QString> m_actionText;
82  BrowserInterface *m_browserInterface;
83 
84  static void createActionSlotMap();
85 
86  KParts::ReadOnlyPart *m_part;
87  OpenUrlArguments m_args;
88  BrowserArguments m_browserArgs;
89 };
90 
91 Q_GLOBAL_STATIC(BrowserExtension::ActionSlotMap, s_actionSlotMap)
92 Q_GLOBAL_STATIC(BrowserExtension::ActionNumberMap, s_actionNumberMap)
93 
94 void BrowserExtension::BrowserExtensionPrivate::createActionSlotMap()
95 {
96  s_actionSlotMap()->insert("cut", SLOT(cut()));
97  s_actionSlotMap()->insert("copy", SLOT(copy()));
98  s_actionSlotMap()->insert("paste", SLOT(paste()));
99  s_actionSlotMap()->insert("print", SLOT(print()));
100  // Tricky. Those aren't actions in fact, but simply methods that a browserextension
101  // can have or not. No need to return them here.
102  //s_actionSlotMap()->insert( "reparseConfiguration", SLOT(reparseConfiguration()) );
103  //s_actionSlotMap()->insert( "refreshMimeTypes", SLOT(refreshMimeTypes()) );
104 
105  // Create the action-number map
106  ActionSlotMap::ConstIterator it = s_actionSlotMap()->constBegin();
107  ActionSlotMap::ConstIterator itEnd = s_actionSlotMap()->constEnd();
108  for (int i = 0; it != itEnd; ++it, ++i) {
109  //qDebug() << " action " << it.key() << " number " << i;
110  s_actionNumberMap()->insert(it.key(), i);
111  }
112 }
113 
114 }
115 
117  : QObject(parent), d(new BrowserExtensionPrivate(parent))
118 {
119  //qDebug() << "BrowserExtension::BrowserExtension() " << this;
120 
121  if (s_actionSlotMap()->isEmpty())
122  // Create the action-slot map
123  {
124  BrowserExtensionPrivate::createActionSlotMap();
125  }
126 
127  // Set the initial status of the actions depending on whether
128  // they're supported or not
129  const QMetaObject *metaobj = metaObject();
130  ActionSlotMap::ConstIterator it = s_actionSlotMap()->constBegin();
131  ActionSlotMap::ConstIterator itEnd = s_actionSlotMap()->constEnd();
132  for (int i = 0; it != itEnd; ++it, ++i) {
133  // Does the extension have a slot with the name of this action ?
134  QByteArray slotSig = it.key() + "()";
135  d->m_actionStatus.setBit(i, metaobj->indexOfMethod(slotSig.constData()) != -1);
136  }
137 
138  connect(d->m_part, static_cast<void (KParts::ReadOnlyPart::*)()>(&KParts::ReadOnlyPart::completed),
139  this, &BrowserExtension::slotCompleted);
141  this, &BrowserExtension::slotOpenUrlRequest);
143  this, &BrowserExtension::slotEnableAction);
145  this, &BrowserExtension::slotSetActionText);
146 }
147 
148 BrowserExtension::~BrowserExtension()
149 {
150  //qDebug() << "BrowserExtension::~BrowserExtension() " << this;
151  delete d;
152 }
153 
155 {
156  d->m_browserArgs = args;
157 }
158 
160 {
161  return d->m_browserArgs;
162 }
163 
165 {
166  return 0;
167 }
168 
170 {
171  return 0;
172 }
173 
175 {
176  // TODO add d->m_part->mimeType()
177  stream << d->m_part->url() << static_cast<qint32>(xOffset()) << static_cast<qint32>(yOffset());
178 }
179 
181 {
182  QUrl u;
183  qint32 xOfs, yOfs;
184  stream >> u >> xOfs >> yOfs;
185 
186  OpenUrlArguments args;
187  args.setXOffset(xOfs);
188  args.setYOffset(yOfs);
189  // TODO add args.setMimeType
190  d->m_part->setArguments(args);
191  d->m_part->openUrl(u);
192 }
193 
195 {
196  return d->m_urlDropHandlingEnabled;
197 }
198 
200 {
201  d->m_urlDropHandlingEnabled = enable;
202 }
203 
204 void BrowserExtension::slotCompleted()
205 {
206  //empty the argument stuff, to avoid bogus/invalid values when opening a new url
208 }
209 
211 {
212  QString plain(QStringLiteral("plain"));
214  // Remove linefeeds and any whitespace surrounding it.
215  url.remove(QRegularExpression(QStringLiteral("[\\ ]*\\n+[\\ ]*")));
216 
217  // Check if it's a URL
219  filters.removeAll(QStringLiteral("kuriikwsfilter"));
220  filters.removeAll(QStringLiteral("localdomainurifilter"));
221  KUriFilterData filterData;
222  filterData.setData(url);
223  filterData.setCheckForExecutables(false);
224  if (KUriFilter::self()->filterUri(filterData, filters)) {
225  switch (filterData.uriType()) {
226  case KUriFilterData::LocalFile:
227  case KUriFilterData::LocalDir:
228  case KUriFilterData::NetProtocol:
229  slotOpenUrlRequest(filterData.uri());
230  break;
231  case KUriFilterData::Error:
232  KMessageBox::sorry(d->m_part->widget(), filterData.errorMsg());
233  break;
234  default:
235  break;
236  }
237  } else if (KUriFilter::self()->filterUri(filterData, QStringList(QStringLiteral("kuriikwsfilter"))) &&
238  url.length() < 250) {
239  if (KMessageBox::questionYesNo(d->m_part->widget(),
240  i18n("<qt>Do you want to search the Internet for <b>%1</b>?</qt>", url.toHtmlEscaped()),
241  i18n("Internet Search"), KGuiItem(i18n("&Search"), QStringLiteral("edit-find")),
242  KStandardGuiItem::cancel(), QStringLiteral("MiddleClickSearch")) == KMessageBox::Yes) {
243  slotOpenUrlRequest(filterData.uri());
244  }
245  }
246 }
247 
248 void BrowserExtension::slotOpenUrlRequest(const QUrl &url, const KParts::OpenUrlArguments &args, const KParts::BrowserArguments &browserArgs)
249 {
250  //qDebug() << this << " BrowserExtension::slotOpenURLRequest(): url=" << url.url();
251  BrowserExtensionPrivate::DelayedRequest req;
252  req.m_delayedURL = url;
253  req.m_delayedArgs = args;
254  req.m_delayedBrowserArgs = browserArgs;
255  d->m_requests.append(req);
256  QTimer::singleShot(0, this, &BrowserExtension::slotEmitOpenUrlRequestDelayed);
257 }
258 
259 void BrowserExtension::slotEmitOpenUrlRequestDelayed()
260 {
261  if (d->m_requests.isEmpty()) {
262  return;
263  }
264  BrowserExtensionPrivate::DelayedRequest req = d->m_requests.front();
265  d->m_requests.pop_front();
266  emit openUrlRequestDelayed(req.m_delayedURL, req.m_delayedArgs, req.m_delayedBrowserArgs);
267  // tricky: do not do anything here! (no access to member variables, etc.)
268 }
269 
270 void BrowserExtension::setBrowserInterface(BrowserInterface *impl)
271 {
272  d->m_browserInterface = impl;
273 }
274 
275 BrowserInterface *BrowserExtension::browserInterface() const
276 {
277  return d->m_browserInterface;
278 }
279 
280 void BrowserExtension::slotEnableAction(const char *name, bool enabled)
281 {
282  //qDebug() << "BrowserExtension::slotEnableAction " << name << " " << enabled;
283  ActionNumberMap::ConstIterator it = s_actionNumberMap()->constFind(name);
284  if (it != s_actionNumberMap()->constEnd()) {
285  d->m_actionStatus.setBit(it.value(), enabled);
286  //qDebug() << "BrowserExtension::slotEnableAction setting bit " << it.data() << " to " << enabled;
287  } else {
288  qCWarning(KPARTSLOG) << "BrowserExtension::slotEnableAction unknown action " << name;
289  }
290 }
291 
292 bool BrowserExtension::isActionEnabled(const char *name) const
293 {
294  int actionNumber = (*s_actionNumberMap())[ name ];
295  return d->m_actionStatus[ actionNumber ];
296 }
297 
298 void BrowserExtension::slotSetActionText(const char *name, const QString &text)
299 {
300  //qDebug() << "BrowserExtension::slotSetActionText " << name << " " << text;
301  ActionNumberMap::ConstIterator it = s_actionNumberMap()->constFind(name);
302  if (it != s_actionNumberMap()->constEnd()) {
303  d->m_actionText[ it.value() ] = text;
304  } else {
305  qCWarning(KPARTSLOG) << "BrowserExtension::slotSetActionText unknown action " << name;
306  }
307 }
308 
309 QString BrowserExtension::actionText(const char *name) const
310 {
311  int actionNumber = (*s_actionNumberMap())[ name ];
312  QMap<int, QString>::ConstIterator it = d->m_actionText.constFind(actionNumber);
313  if (it != d->m_actionText.constEnd()) {
314  return *it;
315  }
316  return QString();
317 }
318 
319 // for compatibility
321 {
322  return *actionSlotMapPtr();
323 }
324 
326 {
327  if (s_actionSlotMap()->isEmpty()) {
328  BrowserExtensionPrivate::createActionSlotMap();
329  }
330  return s_actionSlotMap();
331 }
332 
334 {
336 }
The Browser Extension is an extension (yes, no kidding) to KParts::ReadOnlyPart, which allows a bette...
QString errorMsg() const
FindDirectChildrenOnly
void openUrlRequestDelayed(const QUrl &url, const KParts::OpenUrlArguments &arguments, const KParts::BrowserArguments &browserArguments)
This signal is emitted when openUrlRequest() is called, after a 0-seconds timer.
int indexOfMethod(const char *method) const const
BrowserExtension(KParts::ReadOnlyPart *parent)
Constructor.
The purpose of this interface is to allow a direct communication between a KPart and the hosting brow...
void setURLDropHandlingEnabled(bool enable)
Enables or disables url drop handling.
void completed()
Emit this when you have completed loading data.
BrowserArguments is a set of web-browsing-specific arguments, which allow specifying how a URL should...
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...
virtual const QMetaObject * metaObject() const const
static ActionSlotMap actionSlotMap()
Returns a map containing the action names as keys and corresponding SLOT()&#39;ified method names as data...
QString & remove(int position, int n)
const QList< QKeySequence > & cut()
KGuiItem cancel()
BrowserArguments browserArguments() const
Retrieve the set of parameters to use for opening the URL (this must be called from openUrl() in the ...
virtual void restoreState(QDataStream &stream)
Used by the browser to restore the view in the state it was when we left it.
KIOCORE_EXPORT CopyJob * copy(const QUrl &src, const QUrl &dest, JobFlags flags=DefaultFlags)
void enableAction(const char *name, bool enabled)
Enables or disable a standard action held by the browser.
bool filterUri(KUriFilterData &data, const QStringList &filters=QStringList())
bool isURLDropHandlingEnabled() const
Returns whether url drop handling is enabled.
static BrowserExtension * childObject(QObject *obj)
Queries obj for a child object which inherits from this BrowserExtension class.
int removeAll(const T &value)
QString trimmed() const const
const char * constData() const const
QUrl uri() const
KIOWIDGETS_EXPORT PasteJob * paste(const QMimeData *mimeData, const QUrl &destDir, JobFlags flags=DefaultFlags)
const QList< QKeySequence > & print()
ButtonCode questionYesNo(QWidget *parent, const QString &text, const QString &caption=QString(), const KGuiItem &buttonYes=KStandardGuiItem::yes(), const KGuiItem &buttonNo=KStandardGuiItem::no(), const QString &dontAskAgainName=QString(), Options options=Notify)
virtual int yOffset()
Returns the current y offset.
static ActionSlotMap * actionSlotMapPtr()
static KUriFilter * self()
QString toHtmlEscaped() const const
void openUrlRequest(const QUrl &url, const KParts::OpenUrlArguments &arguments=KParts::OpenUrlArguments(), const KParts::BrowserArguments &browserArguments=KParts::BrowserArguments())
Asks the host (browser) to open url.
QStringList pluginNames() const
void setData(const QUrl &url)
QString i18n(const char *text, const TYPE &arg...)
QString text(QClipboard::Mode mode) const const
int length() const const
bool isActionEnabled(const char *name) const
void pasteRequest()
Asks the hosting browser to perform a paste (using openUrlRequestDelayed())
typedef ConstIterator
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
The KParts namespace,.
UriTypes uriType() const
virtual void setBrowserArguments(const BrowserArguments &args)
Set the parameters to use for opening the next URL.
QClipboard * clipboard()
void setCheckForExecutables(bool check)
virtual int xOffset()
Returns the current x offset.
void setActionText(const char *name, const QString &text)
Change the text of a standard action held by the browser.
QString actionText(const char *name) const
OpenUrlArguments is the set of arguments that specify how a URL should be opened by KParts::ReadOnlyP...
void sorry(QWidget *parent, const QString &text, const QString &caption=QString(), Options options=Notify)
Base class for any "viewer" part.
Definition: readonlypart.h:65
T findChild(const QString &name, Qt::FindChildOptions options) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Wed Aug 5 2020 22:52:41 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.