diff --git a/src/widgets/openfilemanagerwindowjob.cpp b/src/widgets/openfilemanagerwindowjob.cpp index 370da68d..ce8ac207 100644 --- a/src/widgets/openfilemanagerwindowjob.cpp +++ b/src/widgets/openfilemanagerwindowjob.cpp @@ -1,156 +1,159 @@ /* This file is part of the KDE libraries Copyright (C) 2016 Kai Uwe Broulik This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "openfilemanagerwindowjob.h" #include "openfilemanagerwindowjob_p.h" #include #include #include #include #include #include +#include +#include + namespace KIO { class OpenFileManagerWindowJobPrivate { public: OpenFileManagerWindowJobPrivate() : strategy(nullptr) { } ~OpenFileManagerWindowJobPrivate() { delete strategy; } QList highlightUrls; QByteArray startupId; AbstractOpenFileManagerWindowStrategy *strategy; }; OpenFileManagerWindowJob::OpenFileManagerWindowJob(QObject *parent) : KJob(parent) , d(new OpenFileManagerWindowJobPrivate()) { #ifdef Q_OS_LINUX d->strategy = new OpenFileManagerWindowDBusStrategy(this); #else d->strategy = new OpenFileManagerWindowKRunStrategy(this); #endif } OpenFileManagerWindowJob::~OpenFileManagerWindowJob() { delete d; } QList OpenFileManagerWindowJob::highlightUrls() const { return d->highlightUrls; } void OpenFileManagerWindowJob::setHighlightUrls(const QList &highlightUrls) { d->highlightUrls = highlightUrls; } QByteArray OpenFileManagerWindowJob::startupId() const { return d->startupId; } void OpenFileManagerWindowJob::setStartupId(const QByteArray &startupId) { d->startupId = startupId; } void OpenFileManagerWindowJob::start() { if (d->highlightUrls.isEmpty()) { setError(NoValidUrlsError); emitResult(); return; } d->strategy->start(d->highlightUrls, d->startupId); } OpenFileManagerWindowJob *highlightInFileManager(const QList &urls, const QByteArray &asn) { auto *job = new OpenFileManagerWindowJob(); job->setHighlightUrls(urls); job->setStartupId(asn); job->start(); return job; } void OpenFileManagerWindowDBusStrategy::start(const QList &urls, const QByteArray &asn) { // see the spec at: https://www.freedesktop.org/wiki/Specifications/file-manager-interface/ QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.FileManager1"), QStringLiteral("/org/freedesktop/FileManager1"), QStringLiteral("org.freedesktop.FileManager1"), QStringLiteral("ShowItems")); msg << QUrl::toStringList(urls) << QString::fromUtf8(asn); QDBusPendingReply reply = QDBusConnection::sessionBus().asyncCall(msg); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, job); QObject::connect(watcher, &QDBusPendingCallWatcher::finished, job, [=](QDBusPendingCallWatcher *watcher) { QDBusPendingReply reply = *watcher; watcher->deleteLater(); if (reply.isError()) { // Try the KRun strategy as fallback, also calls emitResult inside OpenFileManagerWindowKRunStrategy kRunStrategy(job); kRunStrategy.start(urls, asn); return; } emitResultProxy(); }); } void OpenFileManagerWindowKRunStrategy::start(const QList &urls, const QByteArray &asn) { - if (!KRun::runUrl(urls.value(0).adjusted(QUrl::RemoveFilename), - QStringLiteral("inode/directory"), - KJobWidgets::window(job), // window - KRun::RunFlags(), - QString(), // suggested file name - asn)) { - emitResultProxy(OpenFileManagerWindowJob::LaunchFailedError); - return; - } - - emitResultProxy(); + KIO::OpenUrlJob *urlJob = new KIO::OpenUrlJob(urls.at(0).adjusted(QUrl::RemoveFilename), QStringLiteral("inode/directory")); + urlJob->setUiDelegate(new KIO::JobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, KJobWidgets::window(urlJob))); + urlJob->setStartupId(asn); + QObject::connect(urlJob, &KJob::result, this->job, [this](KJob *job) { + if (job->error()) { + emitResultProxy(OpenFileManagerWindowJob::LaunchFailedError); + } else { + emitResultProxy(); + } + }); + urlJob->start(); } } // namespace KIO diff --git a/src/widgets/openfilemanagerwindowjob.h b/src/widgets/openfilemanagerwindowjob.h index e25ff58f..4bd1f48e 100644 --- a/src/widgets/openfilemanagerwindowjob.h +++ b/src/widgets/openfilemanagerwindowjob.h @@ -1,124 +1,124 @@ /* This file is part of the KDE libraries Copyright (C) 2016 Kai Uwe Broulik This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef OPENFILEMANAGERWINDOWJOB_H #define OPENFILEMANAGERWINDOWJOB_H #include "kiowidgets_export.h" #include #include #include namespace KIO { class OpenFileManagerWindowJobPrivate; /** * @class KIO::OpenFileManagerWindowJob openfilemanagerwindowjob.h * * @brief Open a File Manager Window * * Using this job you can open a file manager window and highlight specific * files within a folder. This can be useful if you downloaded a file and want * to present it to the user without the user having to manually search the * file in its parent folder. This can also be used for a "Show in Parent Folder" * functionality. * * On Linux, this job will use the org.freedesktop.FileManager1 interface to highlight * the files and/or folders. If this fails, the parent directory of the first URL * will be opened in the default file manager instead. * * Note that this job is really only about highlighting certain items * which means if you, for example, pass it just a URL to a folder it will * not open this particular folder but instead highlight it within its parent folder. * - * If you just want to open a folder, use KRun instead. + * If you just want to open a folder, use OpenUrlJob instead. * * @since 5.24 */ class KIOWIDGETS_EXPORT OpenFileManagerWindowJob : public KJob { Q_OBJECT public: /** * Creates an OpenFileManagerWindowJob */ explicit OpenFileManagerWindowJob(QObject *parent = nullptr); /** * Destroys the OpenFileManagerWindowJob */ virtual ~OpenFileManagerWindowJob(); /** * Errors the job may emit */ enum Errors { NoValidUrlsError = KJob::UserDefinedError, ///< No valid URLs to highlight have been specified LaunchFailedError, ///< Failed to launch the file manager }; /** * The files and/or folders to highlight */ QList highlightUrls() const; /** * Set the files and/or folders to highlight */ void setHighlightUrls(const QList &highlightUrls); /** * The Startup ID */ QByteArray startupId() const; /** * Set the Startup ID */ void setStartupId(const QByteArray &startupId); /** * Starts the job */ void start() override; private: friend class AbstractOpenFileManagerWindowStrategy; OpenFileManagerWindowJobPrivate *const d; }; /** * Convenience method for creating a job to highlight a certain file or folder. * * It will create a job for a given URL(s) and automatically start it. * * @since 5.24 */ KIOWIDGETS_EXPORT OpenFileManagerWindowJob *highlightInFileManager(const QList &urls, const QByteArray &asn = QByteArray()); } // namespace KIO #endif // OPENFILEMANAGERWINDOWJOB_H diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a8146bc1..e193740b 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,50 +1,51 @@ include(ECMMarkAsTest) find_package(KF5XmlGui ${KF5_DEP_VERSION} REQUIRED) remove_definitions(-DQT_NO_CAST_FROM_ASCII) remove_definitions(-DQT_NO_CAST_FROM_BYTEARRAY) macro(KIOWIDGETS_EXECUTABLE_TESTS) foreach(_testname ${ARGN}) add_executable(${_testname} ${_testname}.cpp) target_link_libraries(${_testname} KF5::KIOCore KF5::KIOWidgets KF5::KIOFileWidgets Qt5::Test KF5::WidgetsAddons KF5::IconThemes) ecm_mark_as_test(${_testname}) endforeach() endmacro(KIOWIDGETS_EXECUTABLE_TESTS) if(NOT EXCLUDE_DEPRECATED_BEFORE_AND_AT STREQUAL "CURRENT" AND EXCLUDE_DEPRECATED_BEFORE_AND_AT VERSION_LESS 5.71.0) set(runapplication_EXE runapplication) endif() KIOWIDGETS_EXECUTABLE_TESTS( getalltest kruntest kioslavetest kopenwithtest kencodingfiledialogtest_gui kdirmodeltest_gui kdirlistertest_gui kfilecustomdialogtest_gui previewtest kurlrequestertest_gui kpropertiesdialogtest kmountpoint_debug listjobtest listrecursivetest kionetrctest ksycocaupdatetest udsentrybenchmark kurlnavigatortest_gui kprotocolinfo_dumper kfilewidgettest_gui kfilewidgettest_saving_gui + openfilemanagerwindowtest ${runapplication_EXE} ) diff --git a/tests/openfilemanagerwindowtest.cpp b/tests/openfilemanagerwindowtest.cpp new file mode 100644 index 00000000..3dcc9e30 --- /dev/null +++ b/tests/openfilemanagerwindowtest.cpp @@ -0,0 +1,44 @@ +/* This file is part of the KDE libraries + Copyright (C) 2020 David Faure + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include + +#include + +int main(int argc, char **argv) +{ + QApplication::setApplicationName(QStringLiteral("openfilemanagerwindowtest")); + QApplication app(argc, argv); + + const QList urls{ QUrl(QStringLiteral("file:///etc/fstab")), QUrl(QStringLiteral("file:///etc/passwd")) }; + + auto *job = new KIO::OpenFileManagerWindowJob(); + job->setHighlightUrls(urls); + job->start(); + + QObject::connect(job, &KJob::result, job, [&](KJob *job) { + app.exit(job->error()); + }); + + return app.exec(); +} +