diff --git a/src/alternativesmodel.h b/src/alternativesmodel.h index 2dc4f4f..5c2ea37 100644 --- a/src/alternativesmodel.h +++ b/src/alternativesmodel.h @@ -1,89 +1,89 @@ /* Copyright 2014 Aleix Pol Gonzalez This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef PURPOSEALTERNATIVESMODEL_H #define PURPOSEALTERNATIVESMODEL_H #include #include #include namespace Purpose { class Configuration; class AlternativesModelPrivate; /** * @short Interface for client applications to share data * * Lists all the alternatives to share a specified type of data then provides * a method to trigger a job. */ class PURPOSE_EXPORT AlternativesModel : public QAbstractListModel { Q_OBJECT Q_PROPERTY(QString pluginType READ pluginType WRITE setPluginType NOTIFY pluginTypeChanged) Q_PROPERTY(QJsonObject inputData READ inputData WRITE setInputData NOTIFY inputDataChanged) Q_PROPERTY(QStringList disabledPlugins READ disabledPlugins WRITE setDisabledPlugins NOTIFY disabledPluginsChanged) public: enum Roles { PluginIdRole = Qt::UserRole+1, IconNameRole }; AlternativesModel(QObject* parent = nullptr); - virtual ~AlternativesModel(); + ~AlternativesModel() override; QJsonObject inputData() const; void setInputData(const QJsonObject& input); QString pluginType() const; void setPluginType(const QString& pluginType); QStringList disabledPlugins() const; void setDisabledPlugins(const QStringList& pluginIds); /** * This shouldn't require to have the job actually running on the same process as the app. * * @param row specifies the alternative to be used * @param data specifies the data to have shared * * @returns the configuration instance that will offer the job. */ Q_SCRIPTABLE Purpose::Configuration* configureJob(int row); - virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; - virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override; - virtual QHash roleNames() const override; + QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; + int rowCount(const QModelIndex& parent = QModelIndex()) const override; + QHash roleNames() const override; Q_SIGNALS: void inputDataChanged(); void pluginTypeChanged(); void disabledPluginsChanged(); private: void initializeModel(); AlternativesModelPrivate *const d_ptr; Q_DECLARE_PRIVATE(AlternativesModel) }; } #endif diff --git a/src/externalprocess/processjob.h b/src/externalprocess/processjob.h index 4890478..0083835 100644 --- a/src/externalprocess/processjob.h +++ b/src/externalprocess/processjob.h @@ -1,63 +1,63 @@ /* Copyright 2015 Aleix Pol Gonzalez This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef PURPOSE_PROCESSJOB_H #define PURPOSE_PROCESSJOB_H #include "job.h" #include #include #include #include #include namespace Purpose { /** * @internal * * Purpose jobs can optionally run on an external process. This class interfaces * with the external process. */ class ProcessJob : public Job { Q_OBJECT public: ProcessJob(const QString& pluginPath, const QString& pluginType, const QJsonObject& data, QObject* parent); - ~ProcessJob(); + ~ProcessJob() override; void start() override; private: void writeSocket(); void readSocket(); void readAllSocket(bool ensureRead); void processStateChanged(QProcess::ProcessState state); QPointer m_process; QString m_pluginPath; QString m_pluginType; QJsonObject m_data; QLocalServer m_socket; QPointer m_localSocket; }; } #endif diff --git a/src/job.h b/src/job.h index 7cbcb1e..9500bd0 100644 --- a/src/job.h +++ b/src/job.h @@ -1,78 +1,78 @@ /* Copyright 2014 Aleix Pol Gonzalez This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef PURPOSEJOB_H #define PURPOSEJOB_H #include #include #include #include #include #include namespace Purpose { class JobPrivate; /** * @brief Job that will actually perform the sharing * * When start is called, the sharing process will start and when the job * emits finished, we'll know it's over. * * The start method called shouldn't be called before all data has been * filled in. isReady can be used to check whether it's all ready to go, * these arguments will have to be filled by the file provided by * configSourceCode() and should end up defining all the arguments defined * by neededArguments. */ class PURPOSE_EXPORT Job : public KJob { Q_OBJECT /** * Represents the data the job will have available to perform its task */ Q_PROPERTY(QJsonObject data READ data CONSTANT) Q_PROPERTY(QJsonObject output READ output WRITE setOutput NOTIFY outputChanged) public: Job(QObject* parent = nullptr); - virtual ~Job(); + ~Job() override; /** * Should only be called after constructing * * @internal */ void setData(const QJsonObject &data); QJsonObject data() const; QJsonObject output() const; void setOutput(const QJsonObject &output); Q_SIGNALS: void outputChanged(const QJsonObject& output); private: Q_DECLARE_PRIVATE(Job) QScopedPointer const d_ptr; }; } #endif diff --git a/src/pluginbase.h b/src/pluginbase.h index 9a79091..5f14a3e 100644 --- a/src/pluginbase.h +++ b/src/pluginbase.h @@ -1,49 +1,49 @@ /* Copyright 2014 Aleix Pol Gonzalez This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef PURPOSE_PLUGINBASE_H #define PURPOSE_PLUGINBASE_H #include #include "job.h" #define EXPORT_SHARE_VERSION K_EXPORT_PLUGIN_VERSION(2) namespace Purpose { /** * @brief Base class to implement by plugins * * This file shouldn't be included by any application. */ class PURPOSE_EXPORT PluginBase : public QObject { Q_OBJECT public: PluginBase(QObject* parent = nullptr); - virtual ~PluginBase(); + ~PluginBase() override; /** @returns the job that will perform the plugin's action. */ virtual Job* createJob() const = 0; }; } Q_DECLARE_INTERFACE(Purpose::PluginBase, "org.kde.purpose") #endif diff --git a/src/plugins/imgur/imgurplugin.cpp b/src/plugins/imgur/imgurplugin.cpp index 984e8bb..d6d8c2b 100644 --- a/src/plugins/imgur/imgurplugin.cpp +++ b/src/plugins/imgur/imgurplugin.cpp @@ -1,177 +1,177 @@ /* Copyright 2014 Aleix Pol Gonzalez This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include #include "mpform.h" #include #include #include #include #include #include #include #include #include #include #include #include EXPORT_SHARE_VERSION Q_GLOBAL_STATIC_WITH_ARGS(const QUrl, imageImgurUrl, (QLatin1String("https://api.imgur.com/3/image"))) Q_GLOBAL_STATIC_WITH_ARGS(const QUrl, albumImgurUrl, (QLatin1String("https://api.imgur.com/3/album"))) // key associated with aleixpol@kde.org Q_GLOBAL_STATIC_WITH_ARGS(const QString, YOUR_CLIENT_ID, (QLatin1String("0bffa5b4ac8383c"))) class ImgurShareJob : public Purpose::Job { Q_OBJECT public: ImgurShareJob(QObject* parent) : Purpose::Job(parent) , m_pendingJobs(0) {} - virtual void start() override + void start() override { m_pendingJobs = 0; const QJsonArray urls = data().value(QStringLiteral("urls")).toArray(); if (urls.isEmpty()) { qWarning() << "no urls to share" << urls << data(); emitResult(); return; } if (urls.count()>1) { KIO::TransferJob *tJob = KIO::storedHttpPost("", *albumImgurUrl, KIO::HideProgressInfo); tJob->setMetaData(QMap{ { QStringLiteral("customHTTPHeader"), QStringLiteral("Authorization: Client-ID ") + *YOUR_CLIENT_ID } }); connect(tJob, &KJob::result, this, &ImgurShareJob::albumCreated); } else { startUploading(); } } QJsonObject processResponse(KJob* job) { KIO::StoredTransferJob *sjob = qobject_cast(job); QJsonParseError error; const QJsonObject resultMap = QJsonDocument::fromJson(sjob->data(), &error).object(); if (sjob->isErrorPage()) { setError(3); setErrorText(i18n("Error page returned")); } else if (job->error()) { setError(job->error()); setErrorText(job->errorText()); } else if (error.error) { setError(1); setErrorText(error.errorString()); } else if (!resultMap.value(QStringLiteral("success")).toBool()) { setError(2); const QJsonObject dataMap = resultMap[QStringLiteral("data")].toObject(); setErrorText(dataMap[QStringLiteral("error")].toString()); } else { return resultMap[QStringLiteral("data")].toObject(); } emitResult(); return {}; } void albumCreated(KJob* job) { const QJsonObject dataMap = processResponse(job); if (!dataMap.isEmpty()) { m_albumId = dataMap[QStringLiteral("id")].toString(); m_albumDeleteHash = dataMap[QStringLiteral("deletehash")].toString(); startUploading(); } } void startUploading() { Q_EMIT infoMessage(this, i18n("Uploading files to imgur...")); const QJsonArray urls = data().value(QStringLiteral("urls")).toArray(); foreach(const QJsonValue &val, urls) { QString u = val.toString(); KIO::StoredTransferJob* job = KIO::storedGet(QUrl(u)); connect(job, &KJob::finished, this, &ImgurShareJob::fileFetched); m_pendingJobs++; } } void fileFetched(KJob* j) { if (j->error()) { setError(j->error()); setErrorText(j->errorText()); emitResult(); qDebug() << "error:" << j->errorText() << j->errorString(); return; } MPForm form; KIO::StoredTransferJob* job = qobject_cast(j); form.addFile(QStringLiteral("image"), job->url(), job->data()); form.addPair(QStringLiteral("album"), m_albumDeleteHash, {}); form.finish(); KIO::StoredTransferJob *tJob = KIO::storedHttpPost(form.formData(), *imageImgurUrl, KIO::HideProgressInfo); tJob->setMetaData(QMap{ { QStringLiteral("content-type"), QString::fromLocal8Bit(form.contentType()) }, { QStringLiteral("customHTTPHeader"), QStringLiteral("Authorization: Client-ID ") + *YOUR_CLIENT_ID } }); connect(tJob, &KJob::result, this, &ImgurShareJob::imageUploaded); } void imageUploaded(KJob* job) { const QJsonObject dataMap = processResponse(job); if (!dataMap.isEmpty()) { const QString url = dataMap[QStringLiteral("link")].toString(); Q_EMIT infoMessage(this, url, QStringLiteral("%1").arg(url)); --m_pendingJobs; if (m_pendingJobs == 0) { const QString finalUrl = m_albumId.isEmpty() ? url : QStringLiteral("https://imgur.com/a/") + m_albumId; setOutput({ { QStringLiteral("url"), finalUrl } }); emitResult(); } } } private: QString m_albumId; QString m_albumDeleteHash; int m_pendingJobs; }; class Q_DECL_EXPORT ImgurPlugin : public Purpose::PluginBase { Q_OBJECT public: ImgurPlugin(QObject* p, const QVariantList& ) : Purpose::PluginBase(p) {} - virtual Purpose::Job* createJob() const override + Purpose::Job* createJob() const override { return new ImgurShareJob(nullptr); } }; K_PLUGIN_FACTORY_WITH_JSON(ImgurShare, "imgurplugin.json", registerPlugin();) #include "imgurplugin.moc" diff --git a/src/plugins/kdeconnect/kdeconnectplugin.cpp b/src/plugins/kdeconnect/kdeconnectplugin.cpp index 2498a2d..2601505 100644 --- a/src/plugins/kdeconnect/kdeconnectplugin.cpp +++ b/src/plugins/kdeconnect/kdeconnectplugin.cpp @@ -1,84 +1,84 @@ /* Copyright 2014 Aleix Pol Gonzalez This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include #include #include #include #include #include #include #include EXPORT_SHARE_VERSION class KDEConnectJob : public Purpose::Job { Q_OBJECT public: KDEConnectJob(QObject* parent) : Purpose::Job(parent) {} QStringList arrayToList(const QJsonArray& array) { QStringList ret; foreach(const QJsonValue& val, array) { ret += val.toString(); } return ret; } - virtual void start() override + void start() override { QProcess* process = new QProcess(this); process->setProgram(QStringLiteral("kdeconnect-cli")); QJsonArray urlsJson = data().value(QStringLiteral("urls")).toArray(); process->setArguments(QStringList(QStringLiteral("--device")) << data().value(QStringLiteral("device")).toString() << QStringLiteral("--share") << arrayToList(urlsJson)); connect(process, static_cast(&QProcess::finished), this, &KDEConnectJob::jobFinished); process->start(); } void jobFinished(int code, QProcess::ExitStatus status) { if (status != QProcess::NormalExit) qWarning() << "kdeconnect-cli crashed"; setError(code); setOutput( {{ QStringLiteral("url"), QString() }}); emitResult(); } private: }; class Q_DECL_EXPORT KDEConnectPlugin : public Purpose::PluginBase { Q_OBJECT public: KDEConnectPlugin(QObject* p, const QVariantList& ) : Purpose::PluginBase(p) {} - virtual Purpose::Job* createJob() const override + Purpose::Job* createJob() const override { return new KDEConnectJob(nullptr); } }; K_PLUGIN_FACTORY_WITH_JSON(KDEConnect, "kdeconnectplugin.json", registerPlugin();) #include "kdeconnectplugin.moc" diff --git a/src/plugins/ktp-sendfile/ktpsendfileplugin.cpp b/src/plugins/ktp-sendfile/ktpsendfileplugin.cpp index edd3017..d8e51d6 100644 --- a/src/plugins/ktp-sendfile/ktpsendfileplugin.cpp +++ b/src/plugins/ktp-sendfile/ktpsendfileplugin.cpp @@ -1,87 +1,87 @@ /* Copyright 2014 Aleix Pol Gonzalez This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include #include #include #include #include #include #include #include #include EXPORT_SHARE_VERSION class KTpSendFileShareJob : public Purpose::Job { Q_OBJECT public: KTpSendFileShareJob(QObject* parent) : Purpose::Job(parent) {} QStringList arrayToList(const QJsonArray& array) { QStringList ret; foreach(const QJsonValue& val, array) { ret += val.toString(); } return ret; } - virtual void start() override + void start() override { QString executable = QStandardPaths::findExecutable(QStringLiteral("ktp-send-file")); if (executable.isEmpty()) { setError(1); setErrorText(i18n("Couldn't find 'ktp-send-file' executable.")); emitResult(); return; } QProcess* process = new QProcess(this); process->setProgram(executable); QJsonArray urlsJson = data().value(QStringLiteral("urls")).toArray(); process->setArguments(arrayToList(urlsJson)); connect(process, static_cast(&QProcess::finished), this, &KTpSendFileShareJob::jobFinished); process->start(); } Q_SLOT void jobFinished(int code, QProcess::ExitStatus /*status*/) { setError(code); setOutput( {{ QStringLiteral("url"), QString() }}); emitResult(); } }; class Q_DECL_EXPORT KTpSendFilePlugin : public Purpose::PluginBase { Q_OBJECT public: KTpSendFilePlugin(QObject* p, const QVariantList& ) : Purpose::PluginBase(p) {} - virtual Purpose::Job* createJob() const override + Purpose::Job* createJob() const override { return new KTpSendFileShareJob(nullptr); } }; K_PLUGIN_FACTORY_WITH_JSON(KTpSendFileShare, "ktpsendfileplugin.json", registerPlugin();) #include "ktpsendfileplugin.moc" diff --git a/src/plugins/pastebin/pastebinplugin.cpp b/src/plugins/pastebin/pastebinplugin.cpp index 5feda68..446599b 100644 --- a/src/plugins/pastebin/pastebinplugin.cpp +++ b/src/plugins/pastebin/pastebinplugin.cpp @@ -1,138 +1,138 @@ /* Copyright 2014 Aleix Pol Gonzalez This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include #include EXPORT_SHARE_VERSION // Taken from "share" Data Engine // key associated with plasma-devel@kde.org // thanks to Alan Schaaf of Pastebin (alan@pastebin.com) Q_GLOBAL_STATIC_WITH_ARGS(QByteArray, apiKey, ("0c8b6add8e0f6d53f61fe5ce870a1afa")) class PastebinJob : public Purpose::Job { Q_OBJECT public: PastebinJob(QObject* parent) : Purpose::Job(parent) , m_pendingJobs(0) {} - virtual void start() override + void start() override { QJsonArray urls = data().value(QStringLiteral("urls")).toArray(); if (urls.isEmpty()) { qWarning() << "no urls to share" << urls << data(); emitResult(); return; } m_pendingJobs = 0; foreach(const QJsonValue &val, urls) { QString u = val.toString(); KIO::StoredTransferJob* job = KIO::storedGet(QUrl(u)); connect(job, &KJob::finished, this, &PastebinJob::fileFetched); m_pendingJobs++; } Q_ASSERT(m_pendingJobs>0); } void fileFetched(KJob* j) { KIO::StoredTransferJob* job = qobject_cast(j); m_data += job->data(); --m_pendingJobs; if (job->error()) { setError(job->error()); setErrorText(job->errorString()); emitResult(); } else if (m_pendingJobs == 0) performUpload(); } void performUpload() { if (m_data.isEmpty()) { setError(1); setErrorText(i18n("No information to send")); emitResult(); return; } // qCDebug(PLUGIN_PASTEBIN) << "exporting patch to pastebin" << source->file(); QByteArray bytearray = "api_option=paste&api_paste_private=1&api_paste_name=kde-purpose-pastebin-plugin&api_paste_expire_date=1D&api_paste_format=diff&api_dev_key="+*apiKey+"&api_paste_code="; bytearray += QUrl::toPercentEncoding(QString::fromUtf8(m_data)); const QUrl url(QStringLiteral("http://pastebin.com/api/api_post.php")); KIO::TransferJob *tf = KIO::http_post(url, bytearray); tf->addMetaData(QStringLiteral("content-type"), QStringLiteral("Content-Type: application/x-www-form-urlencoded")); connect(tf, &KIO::TransferJob::data, this, [this](KIO::Job*, const QByteArray& data) { m_resultData += data; }); connect(tf, &KJob::result, this, &PastebinJob::textUploaded); m_resultData.clear(); } void textUploaded(KJob* job) { if (job->error()) { setError(error()); setErrorText(job->errorText()); } else if (!m_resultData.startsWith("http")) { setError(1); setErrorText(QString::fromUtf8(m_resultData)); } else setOutput( { { QStringLiteral("url"), QString::fromUtf8(m_resultData) } }); emitResult(); } private: int m_pendingJobs; QByteArray m_data; QByteArray m_resultData; }; class Q_DECL_EXPORT PastebinPlugin : public Purpose::PluginBase { Q_OBJECT public: PastebinPlugin(QObject* p, const QVariantList& ) : Purpose::PluginBase(p) {} - virtual Purpose::Job* createJob() const override + Purpose::Job* createJob() const override { return new PastebinJob(nullptr); } }; K_PLUGIN_FACTORY_WITH_JSON(Pastebin, "pastebinplugin.json", registerPlugin();) #include "pastebinplugin.moc" diff --git a/src/plugins/phabricator/phabricatorjobs.h b/src/plugins/phabricator/phabricatorjobs.h index de21b20..00ce63d 100644 --- a/src/plugins/phabricator/phabricatorjobs.h +++ b/src/plugins/phabricator/phabricatorjobs.h @@ -1,140 +1,140 @@ /* * This file is part of KDevelop * Copyright 2017 René J.V. Bertin * * This program 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 program 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 General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KDEVPLATFORM_PLUGIN_PHABRICATORJOBS_H #define KDEVPLATFORM_PLUGIN_PHABRICATORJOBS_H #include "phabricatorhelpers_export.h" #include #include #include #include #include #include class QNetworkReply; namespace Phabricator { class PHABRICATORHELPERS_EXPORT DifferentialRevision : public KJob { Q_OBJECT public: DifferentialRevision(const QString& id, QObject* parent) : KJob(parent), m_id(id), m_commit(QString()) { setPercent(0); } QString requestId() const { return m_id; } void setRequestId(const QString& id) { m_id = id; } QString commitRef() const { return m_commit; } void setCommitRef(const QString& commit) { m_commit = commit; } - virtual void start() override; - virtual QString errorString() const override + void start() override; + QString errorString() const override { return m_errorString; } void setErrorString(const QString& msg); QString scrubbedResult(); QStringList scrubbedResultList(); private Q_SLOTS: virtual void done(int exitCode, QProcess::ExitStatus exitStatus) = 0; protected: virtual bool buildArcCommand(const QString& workDir, const QString& patchFile=QString(), bool doBrowse=false); QProcess m_arcCmd; private: QString m_id; QString m_commit; QString m_errorString; QString m_arcInput; }; class PHABRICATORHELPERS_EXPORT NewDiffRev : public DifferentialRevision { Q_OBJECT public: NewDiffRev(const QUrl& patch, const QString& project, bool doBrowse = false, QObject* parent = nullptr); QString diffURI() const { return m_diffURI; } private Q_SLOTS: void done(int exitCode, QProcess::ExitStatus exitStatus) override; private: QUrl m_patch; QString m_project; QString m_diffURI; }; class PHABRICATORHELPERS_EXPORT UpdateDiffRev : public DifferentialRevision { Q_OBJECT public: UpdateDiffRev(const QUrl& patch, const QString& basedir, const QString& id, const QString& updateComment = QString(), bool doBrowse = false, QObject* parent = nullptr); QString diffURI() const { return m_diffURI; } private Q_SLOTS: void done(int exitCode, QProcess::ExitStatus exitStatus) override; private: QUrl m_patch; QString m_basedir; QString m_diffURI; }; class PHABRICATORHELPERS_EXPORT DiffRevList : public DifferentialRevision { Q_OBJECT public: DiffRevList(const QString& projectDir, QObject* parent = nullptr); // return the open diff. revisions as a list of pairs QList > reviews() const { return m_reviews; } // return the open diff. revisions as a map of diffDescription->diffID entries QHash reviewMap() const { return m_revMap; } private Q_SLOTS: void done(int exitCode, QProcess::ExitStatus exitStatus) override; protected: bool buildArcCommand(const QString& workDir, const QString& unused=QString(), bool ignored=false) override; private: QList > m_reviews; QHash m_revMap; QString m_projectDir; }; } #endif diff --git a/src/plugins/phabricator/phabricatorplugin.cpp b/src/plugins/phabricator/phabricatorplugin.cpp index 7b1b3be..6b7485a 100644 --- a/src/plugins/phabricator/phabricatorplugin.cpp +++ b/src/plugins/phabricator/phabricatorplugin.cpp @@ -1,168 +1,168 @@ /* * This file is part of KDevelop * Copyright 2017 René J.V. Bertin * * This program 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 program 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 General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include #include #include #include #include "phabricatorjobs.h" #include "debug.h" #include "purpose/job.h" #include "purpose/pluginbase.h" // FIXME: For some reason PLUGIN_PHABRICATOR isn't exported from the PhabricatorHelpers lib #undef qCDebug #define qCDebug(dum) qDebug() #undef qCWarning #define qCWarning(dum) qWarning() #undef qCCritical #define qCCritical(dum) qCritical() class PhabricatorJob : public Purpose::Job { Q_OBJECT public: PhabricatorJob(QObject* object = nullptr) : Purpose::Job(object) {} void start() override { const QString localBaseDir(data().value(QStringLiteral("localBaseDir")).toString()); const QUrl sourceFile(data().value(QStringLiteral("urls")).toArray().first().toString()); const QString updateDR = data().value(QStringLiteral("updateDR")).toString(); const bool doBrowse = data().value(QStringLiteral("doBrowse")).toBool(); const QString baseDir = QUrl(localBaseDir).toLocalFile(); if (QFileInfo(sourceFile.toLocalFile()).size() <= 0) { setError(KJob::UserDefinedError+1); setErrorText(i18n("Phabricator refuses empty patchfiles")); emit PhabricatorJob::warning(this, errorString(), QString()); qCCritical(PLUGIN_PHABRICATOR) << errorString(); emitResult(); return; } else if (updateDR.localeAwareCompare(i18n("unknown")) == 0) { setError(KJob::UserDefinedError+1); setErrorText(i18n("Please choose between creating a new revision or updating an existing one")); emit PhabricatorJob::warning(this, errorString(), QString()); qCCritical(PLUGIN_PHABRICATOR) << errorString(); emitResult(); return; } m_drTitle = data().value(QStringLiteral("drTitle")).toString(); KJob* job; if (!updateDR.isEmpty()) { // KDevelop could set an appropriate initial/default updateComment: // diff --git plugins/patchreview/patchreviewtoolview.cpp plugins/patchreview/patchreviewtoolview.cpp // index c088414..f59367f 100644 // --- plugins/patchreview/patchreviewtoolview.cpp // +++ plugins/patchreview/patchreviewtoolview.cpp // @@ -135,7 +135,8 @@ void PatchReviewToolView::patchChanged() { // m_exportMenu->model()->setInputData(QJsonObject { // { QStringLiteral("urls"), QJsonArray { p->file().toString() } }, // { QStringLiteral("mimeType"), { QStringLiteral("text/x-patch") } }, // - { QStringLiteral("localBaseDir"), { p->baseDir().toString() } } // + { QStringLiteral("localBaseDir"), { p->baseDir().toString() } }, // + { QStringLiteral("updateComment"), { QStringLiteral("patch updated through KDevelop's patchreview plugin") } } // }); // } // #endif const QString updateComment = data().value(QStringLiteral("updateComment")).toString(); job=new Phabricator::UpdateDiffRev(sourceFile, baseDir, updateDR, updateComment, doBrowse, this); connect(job, &KJob::finished, this, &PhabricatorJob::diffUpdated); } else { job=new Phabricator::NewDiffRev(sourceFile, baseDir, doBrowse, this); connect(job, &KJob::finished, this, &PhabricatorJob::diffCreated); if (!doBrowse) { QMessageBox::warning(nullptr, i18n("Please note"), i18n("Remember to complete the differential revision online!")); } } job->start(); emit PhabricatorJob::infoMessage(this, QStringLiteral("upload job started"), QString()); } void diffCreatedOrUpdated(KJob* j, bool created) { if(j->error()!=0) { setError(j->error()); setErrorText(j->errorString()); emit PhabricatorJob::warning(this, j->errorString(), QString()); qCCritical(PLUGIN_PHABRICATOR) << "Could not upload the patch" << j->errorString(); emitResult(); return; } if (created) { Phabricator::NewDiffRev const * job = qobject_cast(j); qCWarning(PLUGIN_PHABRICATOR) <<"new diff:" << job->diffURI(); setOutput({{ QStringLiteral("url"), job->diffURI() }}); } else { Phabricator::UpdateDiffRev const * job = qobject_cast(j); qCWarning(PLUGIN_PHABRICATOR) << "updated diff" << job->requestId() << ":" << job->diffURI(); setOutput({{ QStringLiteral("url"), job->diffURI() }}); emit PhabricatorJob::infoMessage(this, QStringLiteral("updated diff %1: %2").arg(job->requestId()).arg(job->diffURI()), QString()); } emitResult(); } void diffCreated(KJob* j) { diffCreatedOrUpdated(j, true); } void diffUpdated(KJob* j) { diffCreatedOrUpdated(j, false); } QString m_drTitle; }; class Q_DECL_EXPORT PhabricatorPlugin : public Purpose::PluginBase { Q_OBJECT public: PhabricatorPlugin(QObject* parent, const QList& /*args*/) : PluginBase(parent) {} - virtual ~PhabricatorPlugin() override {} + ~PhabricatorPlugin() override {} - virtual Purpose::Job* createJob() const override + Purpose::Job* createJob() const override { return new PhabricatorJob; } }; K_PLUGIN_FACTORY_WITH_JSON(PhabricatorPluginFactory, "phabricatorplugin.json", registerPlugin();) #include "phabricatorplugin.moc" diff --git a/src/plugins/phabricator/quick/phabricatorquickplugin.h b/src/plugins/phabricator/quick/phabricatorquickplugin.h index ac394f0..91d0b96 100644 --- a/src/plugins/phabricator/quick/phabricatorquickplugin.h +++ b/src/plugins/phabricator/quick/phabricatorquickplugin.h @@ -1,32 +1,32 @@ /* Copyright 2017 René J.V. Bertin This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef PHABRICATORPURPOSEQUICKPLUGIN_H #define PHABRICATORPURPOSEQUICKPLUGIN_H #include class PhabricatorPurposeQuickPlugin : public QQmlExtensionPlugin { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") public: - virtual void registerTypes(const char* uri) Q_DECL_OVERRIDE; + void registerTypes(const char* uri) Q_DECL_OVERRIDE; }; #endif // PHABRICATORPURPOSEQUICKPLUGIN_H diff --git a/src/plugins/reviewboard/quick/reviewboardquickplugin.h b/src/plugins/reviewboard/quick/reviewboardquickplugin.h index bae2768..b44c828 100644 --- a/src/plugins/reviewboard/quick/reviewboardquickplugin.h +++ b/src/plugins/reviewboard/quick/reviewboardquickplugin.h @@ -1,32 +1,32 @@ /* Copyright 2015 Aleix Pol Gonzalez This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef RBPURPOSEQUICKPLUGIN_H #define RBPURPOSEQUICKPLUGIN_H #include class RBPurposeQuickPlugin : public QQmlExtensionPlugin { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") public: - virtual void registerTypes(const char* uri) Q_DECL_OVERRIDE; + void registerTypes(const char* uri) Q_DECL_OVERRIDE; }; #endif // PURPOSEQUICKPLUGIN_H diff --git a/src/plugins/reviewboard/reviewboardjobs.h b/src/plugins/reviewboard/reviewboardjobs.h index ac45334..a665de8 100644 --- a/src/plugins/reviewboard/reviewboardjobs.h +++ b/src/plugins/reviewboard/reviewboardjobs.h @@ -1,171 +1,171 @@ /* * This file is part of KDevelop * Copyright 2010 Aleix Pol Gonzalez * * This program 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 program 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 General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KDEVPLATFORM_PLUGIN_REVIEWBOARDJOBS_H #define KDEVPLATFORM_PLUGIN_REVIEWBOARDJOBS_H #include "reviewboardhelpers_export.h" #include #include #include #include #include class QNetworkReply; namespace ReviewBoard { /** * Http call to the specified service. * Converts returned json data to a QVariant to be used from actual API calls * * @note It is reviewboard-agnostic. */ class REVIEWBOARDHELPERS_EXPORT HttpCall : public KJob { Q_OBJECT Q_PROPERTY(QVariant result READ result) public: enum Method { Get, Put, Post }; HttpCall(const QUrl& s, const QString& apiPath, const QList >& queryParameters, Method m, const QByteArray& post, bool multipart, QObject* parent); - virtual void start() override; + void start() override; QVariant result() const; private Q_SLOTS: void onFinished(); private: //TODO: change to QJsonObject QVariant m_result; QNetworkReply* m_reply; QUrl m_requrl; QByteArray m_post; QNetworkAccessManager m_manager; bool m_multipart; Method m_method; }; class REVIEWBOARDHELPERS_EXPORT ReviewRequest : public KJob { Q_OBJECT public: ReviewRequest(const QUrl& server, const QString& id, QObject* parent) : KJob(parent), m_server(server), m_id(id) {} QString requestId() const { return m_id; } void setRequestId(QString id) { m_id = id; } QUrl server() const { return m_server; } private: QUrl m_server; QString m_id; }; class REVIEWBOARDHELPERS_EXPORT NewRequest : public ReviewRequest { Q_OBJECT public: NewRequest(const QUrl& server, const QString& project, QObject* parent = nullptr); - virtual void start() override; + void start() override; private Q_SLOTS: void done(); private: HttpCall* m_newreq; QString m_project; }; class REVIEWBOARDHELPERS_EXPORT UpdateRequest : public ReviewRequest { Q_OBJECT public: UpdateRequest(const QUrl& server, const QString& id, const QVariantMap& newValues, QObject* parent = nullptr); - virtual void start() override; + void start() override; private Q_SLOTS: void done(); private: HttpCall* m_req; QString m_project; }; class REVIEWBOARDHELPERS_EXPORT SubmitPatchRequest : public ReviewRequest { Q_OBJECT public: SubmitPatchRequest(const QUrl &server, const QUrl& patch, const QString& basedir, const QString& id, QObject* parent = nullptr); - virtual void start() override; + void start() override; private Q_SLOTS: void done(); private: HttpCall* m_uploadpatch; QUrl m_patch; QString m_basedir; }; class REVIEWBOARDHELPERS_EXPORT ProjectsListRequest : public KJob { Q_OBJECT public: ProjectsListRequest(const QUrl &server, QObject* parent = nullptr); - virtual void start() override; + void start() override; QVariantList repositories() const; private Q_SLOTS: void requestRepositoryList(int startIndex); void done(KJob* done); private: QUrl m_server; QVariantList m_repositories; }; class REVIEWBOARDHELPERS_EXPORT ReviewListRequest : public KJob { Q_OBJECT public: ReviewListRequest(const QUrl& server, const QString& user, const QString& reviewStatus, QObject* parent = nullptr); - virtual void start() override; + void start() override; QVariantList reviews() const; private Q_SLOTS: void requestReviewList(int startIndex); void done(KJob* done); private: QUrl m_server; QString m_user; QString m_reviewStatus; QVariantList m_reviews; }; QByteArray urlToData(const QUrl&); } #endif diff --git a/src/plugins/reviewboard/reviewboardplugin.cpp b/src/plugins/reviewboard/reviewboardplugin.cpp index a059e5d..b87fda3 100644 --- a/src/plugins/reviewboard/reviewboardplugin.cpp +++ b/src/plugins/reviewboard/reviewboardplugin.cpp @@ -1,128 +1,128 @@ /* * This file is part of KDevelop * Copyright 2010 Aleix Pol Gonzalez * * This program 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 program 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 General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include #include #include "reviewboardjobs.h" #include "debug.h" #include "purpose/job.h" #include "purpose/pluginbase.h" class TheReviewboardJob : public Purpose::Job { Q_OBJECT public: TheReviewboardJob(QObject* object = nullptr) : Purpose::Job(object) {} void start() override { const QString baseDir(data().value(QStringLiteral("baseDir")).toString()); const QString repository(data().value(QStringLiteral("repository")).toString()); const QUrl sourceFile(data().value(QStringLiteral("urls")).toArray().first().toString()); const QString updateRR = data().value(QStringLiteral("updateRR")).toString(); const QJsonObject extraData = data().value(QStringLiteral("extraData")).toObject(); const QString username = data().value(QStringLiteral("username")).toString(); const QString password = data().value(QStringLiteral("password")).toString(); QUrl server(data().value(QStringLiteral("server")).toString()); server.setUserInfo(username + QLatin1Char(':') + password); KJob* job; if (!updateRR.isEmpty()) { job=new ReviewBoard::SubmitPatchRequest(server, sourceFile, baseDir, updateRR); connect(job, &KJob::finished, this, &TheReviewboardJob::reviewDone); } else { job=new ReviewBoard::NewRequest(server, repository); job->setProperty("extraData", extraData); connect(job, &KJob::finished, this, &TheReviewboardJob::reviewCreated); } job->setProperty("baseDir", baseDir); job->start(); } void reviewCreated(KJob* j) { if (j->error()!=0) { setError(j->error()); setErrorText(j->errorString()); emitResult(); return; } ReviewBoard::NewRequest const * job = qobject_cast(j); //This will provide things like groups and users for review from .reviewboardrc QVariantMap extraData = job->property("extraData").toMap(); if (!extraData.isEmpty()) { KJob* updateJob = new ReviewBoard::UpdateRequest(job->server(), job->requestId(), extraData); updateJob->start(); } // for git projects, m_source will be a VCSDiffPatchSource instance const QUrl sourceFile(data().value(QStringLiteral("urls")).toArray().first().toString()); ReviewBoard::SubmitPatchRequest* submitPatchJob=new ReviewBoard::SubmitPatchRequest(job->server(), sourceFile, j->property("baseDir").toString(), job->requestId()); connect(submitPatchJob, &ReviewBoard::SubmitPatchRequest::finished, this, &TheReviewboardJob::reviewDone); submitPatchJob->start(); } void reviewDone(KJob* j) { if(j->error()!=0) { setError(j->error()); setErrorText(j->errorString()); emitResult(); return; } ReviewBoard::SubmitPatchRequest const * job = qobject_cast(j); QUrl url = job->server(); url.setUserInfo(QString()); QString requrl = QStringLiteral("%1/r/%2/").arg(url.toDisplayString(QUrl::PreferLocalFile), job->requestId()); setOutput({{ QStringLiteral("url"), requrl }}); emitResult(); } }; class Q_DECL_EXPORT ReviewBoardPlugin : public Purpose::PluginBase { Q_OBJECT public: ReviewBoardPlugin(QObject* parent, const QList& /*args*/) : PluginBase(parent) {} - virtual ~ReviewBoardPlugin() override {} + ~ReviewBoardPlugin() override {} - virtual Purpose::Job* createJob() const override + Purpose::Job* createJob() const override { return new TheReviewboardJob; } }; K_PLUGIN_FACTORY_WITH_JSON(ReviewBoardPluginFactory, "reviewboardplugin.json", registerPlugin();) #include "reviewboardplugin.moc" diff --git a/src/plugins/saveas/saveasplugin.cpp b/src/plugins/saveas/saveasplugin.cpp index 4fb23d2..efa1914 100644 --- a/src/plugins/saveas/saveasplugin.cpp +++ b/src/plugins/saveas/saveasplugin.cpp @@ -1,127 +1,127 @@ /* Copyright 2014 Aleix Pol Gonzalez This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include EXPORT_SHARE_VERSION static QUrl addPathToUrl(const QUrl &url, const QString &relPath) { QString path = url.path(); if (!path.endsWith(QLatin1Char('/'))) { path += QLatin1Char('/'); } path += relPath; QUrl u(url); u.setPath(path); return u; } class SaveAsShareJob : public Purpose::Job { Q_OBJECT public: SaveAsShareJob(QObject* parent) : Purpose::Job(parent) { setCapabilities(Killable | Suspendable); } - virtual void start() override + void start() override { QJsonArray inputUrls = data().value(QStringLiteral("urls")).toArray(); if (inputUrls.isEmpty()) { setErrorText(i18n("No URLs to save")); setError(1); emitResult(); return; } QList urls; bool containsData = false; foreach(const QJsonValue &val, inputUrls) { urls.append(QUrl(val.toString())); containsData |= urls.last().scheme() == QLatin1String("data"); } m_dest = QUrl(data().value(QStringLiteral("destinationPath")).toString()); if (containsData && !(urls.count() == 1 && m_dest.isLocalFile() && !QFileInfo(m_dest.toLocalFile()).isDir())) { for(const QUrl& url: urls) { QUrl dest = addPathToUrl(m_dest, QStringLiteral("data")); auto job = KIO::copy(url, dest); connect(job, &KJob::finished, this, &SaveAsShareJob::fileCopied); m_jobs.insert(job); } } else { auto job = KIO::copy(urls, m_dest); connect(job, &KJob::finished, this, &SaveAsShareJob::fileCopied); m_jobs.insert(job); } } bool doKill() override { bool killed = true; for(KJob* job: m_jobs) killed &= job->kill(); return killed; } void fileCopied(KJob* job) { auto r = m_jobs.remove(job); Q_ASSERT(r); setError(error() + job->error()); setErrorText(errorText() + QLatin1Char(' ') + job->errorText()); if (job->error()==0 && m_jobs.isEmpty()) { setOutput({ { QStringLiteral("url"), m_dest.toString() } }); } emitResult(); } private: QUrl m_dest; QSet m_jobs; }; class Q_DECL_EXPORT SaveAsPlugin : public Purpose::PluginBase { Q_OBJECT public: SaveAsPlugin(QObject* p, const QVariantList& ) : Purpose::PluginBase(p) {} - virtual Purpose::Job* createJob() const override + Purpose::Job* createJob() const override { return new SaveAsShareJob(nullptr); } }; K_PLUGIN_FACTORY_WITH_JSON(SaveAsShare, "saveasplugin.json", registerPlugin();) #include "saveasplugin.moc" diff --git a/src/widgets/menu.cpp b/src/widgets/menu.cpp index 6a74688..4270501 100644 --- a/src/widgets/menu.cpp +++ b/src/widgets/menu.cpp @@ -1,97 +1,97 @@ /* Copyright 2015 Aleix Pol Gonzalez This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "menu.h" #include #include #include #include #include #include #include using namespace Purpose; class Purpose::MenuPrivate : public QObject { Q_OBJECT public: - ~MenuPrivate() { m_engine->deleteLater(); } + ~MenuPrivate() override { m_engine->deleteLater(); } MenuPrivate(Menu* q) : QObject(q) , m_engine(new QQmlApplicationEngine) , m_model(new AlternativesModel(q)) , q(q) { m_engine->rootContext()->setContextObject(new KLocalizedContext(this)); m_engine->load(QUrl(QStringLiteral("qrc:/JobDialog.qml"))); } void trigger(int row) { Q_ASSERT(!m_engine->rootObjects().isEmpty()); QObject* o = m_engine->rootObjects().at(0); if (!o) { qWarning() << Q_FUNC_INFO << "object is NULL at m_engine" << m_engine << "rootObjects=" << m_engine->rootObjects(); return; } o->setProperty("configuration", QVariant::fromValue(m_model->configureJob(row))); o->setProperty("q", QVariant::fromValue(q)); o->setProperty("visible", true); o->setParent(q); } public: QQmlApplicationEngine* m_engine; QPointer m_model; Purpose::Menu* q; }; Menu::Menu(QWidget* parent) : QMenu(parent) , d_ptr(new MenuPrivate(this)) { connect(d_ptr->m_model.data(), &AlternativesModel::inputDataChanged, this, &Menu::reload); connect(this, &QMenu::triggered, this, [this](QAction* action) { Q_D(Menu); d->trigger(action->property("row").toInt()); }); } void Menu::reload() { Q_D(Menu); clear(); for(int i=0, c=d->m_model->rowCount(); i != c; ++i) { QModelIndex idx = d->m_model->index(i); QAction* a = addAction(idx.data(Qt::DisplayRole).toString()); a->setToolTip(idx.data(Qt::ToolTipRole).toString()); a->setIcon(idx.data(Qt::DecorationRole).value()); a->setProperty("pluginId", idx.data(AlternativesModel::PluginIdRole)); a->setProperty("row", i); } setEnabled(!isEmpty()); } AlternativesModel* Menu::model() const { Q_D(const Menu); return d->m_model.data(); } #include "menu.moc"