diff --git a/src/core/engine.h b/src/core/engine.h --- a/src/core/engine.h +++ b/src/core/engine.h @@ -133,6 +133,9 @@ QList categoriesMetadata(); + QString adoptionCommand(const KNSCore::EntryInternal &entry) const; + bool hasAdoptionCommand() const; + Q_SIGNALS: /** * Indicates a message to be added to the ui's log, or sent to a messagebox @@ -217,8 +220,7 @@ QHash > m_providers; - // TODO KF6: remove - QString m_unused; + QString m_adoptionCommand; // the current request from providers Provider::SearchRequest m_currentRequest; diff --git a/src/core/engine.cpp b/src/core/engine.cpp --- a/src/core/engine.cpp +++ b/src/core/engine.cpp @@ -135,6 +135,7 @@ } m_categories = group.readEntry("Categories", QStringList()); + m_adoptionCommand = group.readEntry("AdoptionCommand", QString()); qCDebug(KNEWSTUFFCORE) << "Categories: " << m_categories; m_providerFileUrl = group.readEntry("ProvidersUrl", QString()); @@ -604,3 +605,57 @@ p->loadEntries(request); } } + +/** + * we look for the directory where all the resources got installed. + * assuming it was extracted into a directory + */ +static QDir sharedDir(QStringList dirs, const QString &rootPath) +{ + while(!dirs.isEmpty()) { + const QString currentPath = QDir::cleanPath(dirs.takeLast()); + if (!currentPath.startsWith(rootPath)) + continue; + + const QFileInfo current(currentPath); + if (!current.isDir()) + continue; + + const QDir dir = current.dir(); + if (dir.path()==(rootPath+dir.dirName())) { + return dir; + } + } + return {}; +} + +QString Engine::adoptionCommand(const KNSCore::EntryInternal& entry) const +{ + auto adoption = m_adoptionCommand; + if(adoption.isEmpty()) + return {}; + + const QLatin1String dirReplace("%d"); + if (adoption.contains(dirReplace)) { + QString installPath = sharedDir(entry.installedFiles(), m_installation->targetInstallationPath()).path(); + adoption.replace(dirReplace, installPath); + } + + const QLatin1String fileReplace("%f"); + QStringList ret; + if (adoption.contains(fileReplace)) { + if (entry.installedFiles().isEmpty()) { + qCWarning(KNEWSTUFFCORE) << "no installed files to adopt"; + } else if (entry.installedFiles().count() != 1) { + qCWarning(KNEWSTUFFCORE) << "can only adopt one file, will be using the first" << entry.installedFiles().at(0); + } + + adoption.replace(fileReplace, entry.installedFiles().at(0)); + } + return adoption; +} + +bool KNSCore::Engine::hasAdoptionCommand() const +{ + return !m_adoptionCommand.isEmpty(); +} diff --git a/src/core/installation.h b/src/core/installation.h --- a/src/core/installation.h +++ b/src/core/installation.h @@ -121,6 +121,13 @@ void slotPayloadResult(KJob *job); + /** + * @returns the installation path + * + * @since 5.31 + */ + QString targetInstallationPath() const; + Q_SIGNALS: void signalEntryChanged(const KNSCore::EntryInternal &entry); void signalInstallationFinished(); @@ -135,7 +142,6 @@ private: void install(KNSCore::EntryInternal entry, const QString &downloadedFile); - QString targetInstallationPath(); QStringList installDownloadedFileAndUncompress(const KNSCore::EntryInternal &entry, const QString &payloadfile, const QString installdir); QProcess* runPostInstallationCommand(const QString &installPath); diff --git a/src/core/installation.cpp b/src/core/installation.cpp --- a/src/core/installation.cpp +++ b/src/core/installation.cpp @@ -334,7 +334,7 @@ } } -QString Installation::targetInstallationPath() +QString Installation::targetInstallationPath() const { QString installdir; diff --git a/src/ui/itemsviewbasedelegate.cpp b/src/ui/itemsviewbasedelegate.cpp --- a/src/ui/itemsviewbasedelegate.cpp +++ b/src/ui/itemsviewbasedelegate.cpp @@ -86,6 +86,9 @@ void ItemsViewBaseDelegate::slotInstallActionTriggered(QAction *action) { + if (action->data().isNull()) + return; + QPoint rowDownload = action->data().toPoint(); int row = rowDownload.x(); QModelIndex index = m_itemView->model()->index(row, 0); diff --git a/src/ui/itemsviewdelegate.cpp b/src/ui/itemsviewdelegate.cpp --- a/src/ui/itemsviewdelegate.cpp +++ b/src/ui/itemsviewdelegate.cpp @@ -25,10 +25,12 @@ #include #include #include +#include #include #include #include +#include #include "core/itemsmodel.h" @@ -61,7 +63,6 @@ QToolButton *installButton = new QToolButton(); installButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); - installButton->setPopupMode(QToolButton::InstantPopup); list << installButton; setBlockedEventTypes(installButton, QList() << QEvent::MouseButtonPress << QEvent::MouseButtonRelease << QEvent::MouseButtonDblClick); @@ -152,6 +153,8 @@ installButton->setText(text); installButton->setEnabled(enabled); installButton->setIcon(icon); + installButton->setPopupMode(QToolButton::InstantPopup); + if (installable && entry.downloadLinkCount() > 1) { QMenu *installMenu = new QMenu(installButton); foreach (const KNSCore::EntryInternal::DownloadLinkInformation &info, entry.downloadLinkInformationList()) { @@ -163,6 +166,15 @@ installAction->setData(QPoint(index.row(), info.id)); } installButton->setMenu(installMenu); + } else if (entry.status() == Entry::Installed && m_engine->hasAdoptionCommand()) { + QMenu* m = new QMenu(installButton); + m->addAction(i18n("Use"), m, [this, entry](){ + QStringList args = KShell::splitArgs(m_engine->adoptionCommand(entry)); + qCDebug(KNEWSTUFF) << "executing AdoptionCommand" << args; + QProcess::startDetached(args.takeFirst(), args); + }); + installButton->setPopupMode(QToolButton::MenuButtonPopup); + installButton->setMenu(m); } }