mirror of
https://github.com/Qortal/Brooklyn.git
synced 2025-02-14 11:15:54 +00:00
197 lines
6.4 KiB
C++
197 lines
6.4 KiB
C++
/*
|
|
SPDX-FileCopyrightText: 2003 Joseph Wenninger <jowenn@kde.org>
|
|
|
|
SPDX-License-Identifier: LGPL-2.0-or-later
|
|
*/
|
|
|
|
#include <KLocalizedString>
|
|
#include <kio/slavebase.h>
|
|
#include <kservice.h>
|
|
#include <kservicegroup.h>
|
|
#include <sys/stat.h>
|
|
#include <time.h>
|
|
|
|
#include <QStandardPaths>
|
|
#include <QUrl>
|
|
|
|
// Pseudo plugin class to embed meta data
|
|
class KIOPluginForMetaData : public QObject
|
|
{
|
|
Q_OBJECT
|
|
Q_PLUGIN_METADATA(IID "org.kde.kio.slave.applications" FILE "applications.json")
|
|
};
|
|
|
|
class ApplicationsProtocol : public KIO::SlaveBase
|
|
{
|
|
public:
|
|
enum RunMode {
|
|
ProgramsMode,
|
|
ApplicationsMode,
|
|
};
|
|
ApplicationsProtocol(const QByteArray &protocol, const QByteArray &pool, const QByteArray &app);
|
|
~ApplicationsProtocol() override;
|
|
void get(const QUrl &url) override;
|
|
void stat(const QUrl &url) override;
|
|
void listDir(const QUrl &url) override;
|
|
|
|
private:
|
|
RunMode m_runMode;
|
|
};
|
|
|
|
extern "C" {
|
|
Q_DECL_EXPORT int kdemain(int argc, char **argv)
|
|
{
|
|
QCoreApplication app(argc, argv);
|
|
app.setApplicationName("kio_applications");
|
|
|
|
ApplicationsProtocol slave(argv[1], argv[2], argv[3]);
|
|
slave.dispatchLoop();
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
static void createFileEntry(KIO::UDSEntry &entry, const KService::Ptr &service, const QUrl &parentUrl)
|
|
{
|
|
entry.clear();
|
|
entry.fastInsert(KIO::UDSEntry::UDS_NAME, KIO::encodeFileName(service->name()));
|
|
entry.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFREG);
|
|
const QString fileUrl = parentUrl.url() + '/' + service->desktopEntryName();
|
|
entry.fastInsert(KIO::UDSEntry::UDS_URL, fileUrl);
|
|
entry.fastInsert(KIO::UDSEntry::UDS_ACCESS, 0500);
|
|
entry.fastInsert(KIO::UDSEntry::UDS_MIME_TYPE, QStringLiteral("application/x-desktop"));
|
|
entry.fastInsert(KIO::UDSEntry::UDS_SIZE, 0);
|
|
const QString localPath = QStandardPaths::locate(QStandardPaths::ApplicationsLocation, QStringLiteral("%1.desktop").arg(service->desktopEntryName()));
|
|
entry.fastInsert(KIO::UDSEntry::UDS_LOCAL_PATH, localPath);
|
|
entry.fastInsert(KIO::UDSEntry::UDS_MODIFICATION_TIME, time(nullptr));
|
|
entry.fastInsert(KIO::UDSEntry::UDS_ICON_NAME, service->icon());
|
|
}
|
|
|
|
static void createDirEntry(KIO::UDSEntry &entry, const QString &name, const QString &url, const QString &mime, const QString &iconName)
|
|
{
|
|
entry.clear();
|
|
entry.fastInsert(KIO::UDSEntry::UDS_NAME, name);
|
|
entry.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR);
|
|
entry.fastInsert(KIO::UDSEntry::UDS_ACCESS, 0500);
|
|
entry.fastInsert(KIO::UDSEntry::UDS_MIME_TYPE, mime);
|
|
if (!url.isEmpty())
|
|
entry.fastInsert(KIO::UDSEntry::UDS_URL, url);
|
|
entry.fastInsert(KIO::UDSEntry::UDS_ICON_NAME, iconName);
|
|
}
|
|
|
|
ApplicationsProtocol::ApplicationsProtocol(const QByteArray &protocol, const QByteArray &pool, const QByteArray &app)
|
|
: SlaveBase(protocol, pool, app)
|
|
{
|
|
// Adjusts which part of the K Menu to virtualize.
|
|
if (protocol == "programs")
|
|
m_runMode = ProgramsMode;
|
|
else // if (protocol == "applications")
|
|
m_runMode = ApplicationsMode;
|
|
}
|
|
|
|
ApplicationsProtocol::~ApplicationsProtocol()
|
|
{
|
|
}
|
|
|
|
void ApplicationsProtocol::get(const QUrl &url)
|
|
{
|
|
KService::Ptr service = KService::serviceByDesktopName(url.fileName());
|
|
if (service && service->isValid()) {
|
|
const QString localPath = QStandardPaths::locate(QStandardPaths::ApplicationsLocation, QStringLiteral("%1.desktop").arg(service->desktopEntryName()));
|
|
QUrl redirUrl(QUrl::fromLocalFile(localPath));
|
|
redirection(redirUrl);
|
|
finished();
|
|
} else {
|
|
error(KIO::ERR_IS_DIRECTORY, url.toDisplayString());
|
|
}
|
|
}
|
|
|
|
void ApplicationsProtocol::stat(const QUrl &url)
|
|
{
|
|
KIO::UDSEntry entry;
|
|
|
|
QString servicePath(url.path());
|
|
if (!servicePath.endsWith('/'))
|
|
servicePath.append('/');
|
|
servicePath.remove(0, 1); // remove starting '/'
|
|
|
|
KServiceGroup::Ptr grp = KServiceGroup::group(servicePath);
|
|
|
|
if (grp && grp->isValid()) {
|
|
createDirEntry(entry,
|
|
((m_runMode == ApplicationsMode) ? i18n("Applications") : i18n("Programs")),
|
|
url.url(),
|
|
QStringLiteral("inode/directory"),
|
|
grp->icon());
|
|
} else {
|
|
KService::Ptr service = KService::serviceByDesktopName(url.fileName());
|
|
if (service && service->isValid()) {
|
|
createFileEntry(entry, service, url);
|
|
} else {
|
|
error(KIO::ERR_SLAVE_DEFINED, i18n("Unknown application folder"));
|
|
return;
|
|
}
|
|
}
|
|
|
|
statEntry(entry);
|
|
finished();
|
|
}
|
|
|
|
void ApplicationsProtocol::listDir(const QUrl &url)
|
|
{
|
|
QString groupPath = url.path();
|
|
if (!groupPath.endsWith('/'))
|
|
groupPath.append('/');
|
|
groupPath.remove(0, 1); // remove starting '/'
|
|
|
|
KServiceGroup::Ptr grp = KServiceGroup::group(groupPath);
|
|
|
|
if (!grp || !grp->isValid()) {
|
|
error(KIO::ERR_DOES_NOT_EXIST, groupPath);
|
|
return;
|
|
}
|
|
|
|
unsigned int count = 0;
|
|
KIO::UDSEntry entry;
|
|
|
|
foreach (const KSycocaEntry::Ptr &e, grp->entries(true, true)) {
|
|
if (e->isType(KST_KServiceGroup)) {
|
|
KServiceGroup::Ptr g(static_cast<KServiceGroup *>(e.data()));
|
|
|
|
// qDebug() << "ADDING SERVICE GROUP WITH PATH " << g->relPath();
|
|
|
|
// Avoid adding empty groups.
|
|
KServiceGroup::Ptr subMenuRoot = KServiceGroup::group(g->relPath());
|
|
if (subMenuRoot->childCount() == 0)
|
|
continue;
|
|
|
|
// Ignore dotfiles.
|
|
if (g->name().startsWith('.'))
|
|
continue;
|
|
|
|
QString relPath = g->relPath();
|
|
QUrl dirUrl = url; // preserve protocol, whether that's programs:/ or applications:/
|
|
dirUrl.setPath('/' + relPath);
|
|
dirUrl = dirUrl.adjusted(QUrl::StripTrailingSlash);
|
|
// qDebug() << "ApplicationsProtocol: adding entry" << dirUrl;
|
|
createDirEntry(entry, g->caption(), dirUrl.url(), QStringLiteral("inode/directory"), g->icon());
|
|
} else {
|
|
KService::Ptr service(static_cast<KService *>(e.data()));
|
|
|
|
// qDebug() << "the entry name is" << service->desktopEntryName()
|
|
// << "with path" << service->entryPath();
|
|
|
|
if (!service->isApplication()) // how could this happen?
|
|
continue;
|
|
createFileEntry(entry, service, url);
|
|
}
|
|
|
|
listEntry(entry);
|
|
count++;
|
|
}
|
|
|
|
totalSize(count);
|
|
finished();
|
|
}
|
|
|
|
#include "kio_applications.moc"
|