KIO

openfilemanagerwindowjob.cpp
1 /*
2  This file is part of the KDE libraries
3  SPDX-FileCopyrightText: 2016 Kai Uwe Broulik <[email protected]>
4 
5  SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7 
8 #include "openfilemanagerwindowjob.h"
9 #include "openfilemanagerwindowjob_p.h"
10 
11 #include <QDBusConnection>
12 #include <QDBusMessage>
13 #include <QDBusPendingCallWatcher>
14 #include <QDBusPendingReply>
15 #include <QGuiApplication>
16 
17 #include <KJobWidgets>
18 #include <KWindowSystem>
19 
20 #include <KIO/JobUiDelegate>
21 #include <KIO/JobUiDelegateFactory>
22 #include <KIO/OpenUrlJob>
23 
24 namespace KIO
25 {
26 class OpenFileManagerWindowJobPrivate
27 {
28 public:
29  OpenFileManagerWindowJobPrivate(OpenFileManagerWindowJob *qq)
30  : q(qq)
31  , strategy(nullptr)
32  {
33  }
34 
35  ~OpenFileManagerWindowJobPrivate()
36  {
37  delete strategy;
38  }
39 
40  AbstractOpenFileManagerWindowStrategy *createDBusStrategy()
41  {
42  delete strategy;
43  strategy = new OpenFileManagerWindowDBusStrategy(q);
44  return strategy;
45  }
46 
47  AbstractOpenFileManagerWindowStrategy *createKRunStrategy()
48  {
49  delete strategy;
50  strategy = new OpenFileManagerWindowKRunStrategy(q);
51  return strategy;
52  }
53 
54  OpenFileManagerWindowJob *const q;
55  QList<QUrl> highlightUrls;
56  QByteArray startupId;
57 
58  AbstractOpenFileManagerWindowStrategy *strategy;
59 };
60 
62  : KJob(parent)
63  , d(new OpenFileManagerWindowJobPrivate(this))
64 {
65 #ifdef Q_OS_LINUX
66  d->createDBusStrategy();
67 #else
68  d->createKRunStrategy();
69 #endif
70 }
71 
73 
75 {
76  return d->highlightUrls;
77 }
78 
80 {
81  d->highlightUrls = highlightUrls;
82 }
83 
85 {
86  return d->startupId;
87 }
88 
90 {
91  d->startupId = startupId;
92 }
93 
95 {
96  if (d->highlightUrls.isEmpty()) {
98  emitResult();
99  return;
100  }
101 
102  d->strategy->start(d->highlightUrls, d->startupId);
103 }
104 
106 {
107  auto *job = new OpenFileManagerWindowJob();
108  job->setHighlightUrls(urls);
109 
110  if (asn.isNull()) {
111  auto window = qGuiApp->focusWindow();
112  if (!window && !qGuiApp->allWindows().isEmpty()) {
113  window = qGuiApp->allWindows().constFirst();
114  }
115  const int launchedSerial = KWindowSystem::lastInputSerial(window);
116  QObject::connect(KWindowSystem::self(), &KWindowSystem::xdgActivationTokenArrived, job, [launchedSerial, job](int serial, const QString &token) {
117  if (serial == launchedSerial) {
118  job->setStartupId(token.toLatin1());
119  job->start();
120  }
121  });
122  KWindowSystem::requestXdgActivationToken(window, launchedSerial, {});
123  } else {
124  job->setStartupId(asn);
125  job->start();
126  }
127 
128  return job;
129 }
130 
132 {
133  // see the spec at: https://www.freedesktop.org/wiki/Specifications/file-manager-interface/
134 
135  QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.FileManager1"),
136  QStringLiteral("/org/freedesktop/FileManager1"),
137  QStringLiteral("org.freedesktop.FileManager1"),
138  QStringLiteral("ShowItems"));
139 
140  msg << QUrl::toStringList(urls) << QString::fromUtf8(asn);
141 
143  QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, m_job);
145  QDBusPendingReply<void> reply = *watcher;
146  watcher->deleteLater();
147 
148  if (reply.isError()) {
149  // Try the KRun strategy as fallback, also calls emitResult inside
150  AbstractOpenFileManagerWindowStrategy *kRunStrategy = m_job->d->createKRunStrategy();
151  kRunStrategy->start(urls, asn);
152  return;
153  }
154 
155  emitResultProxy();
156  });
157 }
158 
160 {
161  KIO::OpenUrlJob *urlJob = new KIO::OpenUrlJob(urls.at(0).adjusted(QUrl::RemoveFilename), QStringLiteral("inode/directory"));
163  urlJob->setStartupId(asn);
164  QObject::connect(urlJob, &KJob::result, m_job, [this](KJob *urlJob) {
165  if (urlJob->error()) {
166  emitResultProxy(OpenFileManagerWindowJob::LaunchFailedError);
167  } else {
168  emitResultProxy();
169  }
170  });
171  urlJob->start();
172 }
173 
174 } // namespace KIO
bool isNull() const const
void finished(QDBusPendingCallWatcher *self)
QString fromUtf8(const char *str, int size)
virtual Q_SCRIPTABLE void start()=0
QStringList toStringList(const QList< QUrl > &urls, QUrl::FormattingOptions options)
OpenFileManagerWindowJob * highlightInFileManager(const QList< QUrl > &urls, const QByteArray &asn)
Convenience method for creating a job to highlight a certain file or folder.
void result(KJob *job)
Q_SCRIPTABLE Q_NOREPLY void start()
bool isError() const const
QByteArray toLatin1() const const
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QList< QUrl > highlightUrls() const
The files and/or folders to highlight.
OpenFileManagerWindowJob(QObject *parent=nullptr)
Creates an OpenFileManagerWindowJob.
void setStartupId(const QByteArray &startupId)
Sets the platform-specific startup id of the file manager launch.
void deleteLater()
QDBusConnection sessionBus()
RemoveFilename
void xdgActivationTokenArrived(int serial, const QString &token)
Open a File Manager Window.
static Q_INVOKABLE quint32 lastInputSerial(QWindow *window)
const T & at(int i) const const
KIOCORE_EXPORT KJobUiDelegate * createDefaultJobUiDelegate()
Convenience method: use default factory, if there's one, to create a delegate and return it.
~OpenFileManagerWindowJob() override
Destroys the OpenFileManagerWindowJob.
OpenUrlJob finds out the right way to "open" a URL. This includes finding out its MIME type,...
Definition: openurljob.h:41
QDBusMessage createMethodCall(const QString &service, const QString &path, const QString &interface, const QString &method)
static KWindowSystem * self()
static Q_INVOKABLE void requestXdgActivationToken(QWindow *win, uint32_t serial, const QString &app_id)
void setStartupId(const QByteArray &startupId)
Sets the platform-specific startup id of the application launch.
Definition: openurljob.cpp:115
void setUiDelegate(KJobUiDelegate *delegate)
QUrl adjusted(QUrl::FormattingOptions options) const const
A namespace for KIO globals.
void emitResult()
int error() const
KJOBWIDGETS_EXPORT QWidget * window(KJob *job)
void start() override
Starts the job.
@ NoValidUrlsError
No valid URLs to highlight have been specified.
QDBusPendingCall asyncCall(const QDBusMessage &message, int timeout) const const
void setError(int errorCode)
void setHighlightUrls(const QList< QUrl > &highlightUrls)
Set the files and/or folders to highlight.
QByteArray startupId() const
The Startup ID.
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Tue Feb 7 2023 04:00:36 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.