diff --git a/src/service/plugins/gtk-eventspy/GtkEventSpy.cpp b/src/service/plugins/gtk-eventspy/GtkEventSpy.cpp
index 2eb7d70..38250fc 100644
--- a/src/service/plugins/gtk-eventspy/GtkEventSpy.cpp
+++ b/src/service/plugins/gtk-eventspy/GtkEventSpy.cpp
@@ -1,230 +1,239 @@
/*
* Copyright (C) 2019 Méven Car (meven.car@kdemail.net)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU 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, see .
*/
#include "GtkEventSpy.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "DebugPluginGtkEventSpy.h"
KAMD_EXPORT_PLUGIN(GtkEventSpyPlugin, GtkEventSpyPlugin,
"kactivitymanagerd-plugin-gtk-eventspy.json")
GtkEventSpyPlugin::GtkEventSpyPlugin(QObject *parent, const QVariantList &args)
: Plugin(parent)
, m_resources(nullptr)
, m_dirWatcher(new KDirWatch(this))
, m_lastUpdate(QDateTime::currentDateTime())
{
Q_UNUSED(args);
// gtk xml history file
// usually $HOME/.local/share/recently-used.xbel
QString filename = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)
+ QLatin1String("/recently-used.xbel");
m_dirWatcher->addFile(filename);
connect(m_dirWatcher.get(), &KDirWatch::dirty,
this, &GtkEventSpyPlugin::fileUpdated);
connect(m_dirWatcher.get(), &KDirWatch::created,
this, &GtkEventSpyPlugin::fileUpdated);
}
struct Application {
QString name;
QDateTime modified;
};
class Bookmark
{
public:
QUrl href;
QDateTime added;
QDateTime modified;
QDateTime visited;
+ QString mimetype;
QList applications;
QString latestApplication() const;
};
QString Bookmark::latestApplication() const
{
Application current = applications.first();
for (const Application &app : applications) {
if (app.modified > current.modified) {
current = app;
}
}
return current.name;
}
class BookmarkHandler : public QXmlDefaultHandler
{
public:
bool startElement(const QString &namespaceURI, const QString &localName, const QString &qName,
const QXmlAttributes &attributes) override;
bool endElement(const QString &namespaceURI, const QString &localName,
const QString &qName) override;
QList bookmarks() const;
private:
QList marks;
Bookmark current;
};
QList BookmarkHandler::bookmarks() const
{
return marks;
}
bool BookmarkHandler::startElement(const QString & /*namespaceURI*/, const QString & /*localName*/,
const QString &qName, const QXmlAttributes &attributes)
{
// new bookmark
if (qName == QStringLiteral("bookmark")) {
current = Bookmark();
current.href = QUrl(attributes.value("href"));
QString added = attributes.value("added");
QString modified = attributes.value("modified");
QString visited = attributes.value("visited");
current.added = QDateTime::fromString(added, Qt::ISODate);
current.modified = QDateTime::fromString(modified, Qt::ISODate);
current.visited = QDateTime::fromString(visited, Qt::ISODate);
// application for the current bookmark
} else if (qName == QStringLiteral("bookmark:application")) {
Application app;
QString exec = attributes.value("exec");
if (exec.startsWith(QLatin1Char('\'')) && exec.endsWith(QLatin1Char('\''))) {
// remove "'" caracters wrapping the command
exec = exec.mid(1, exec.size() -2);
}
// Search for applications which are executable and case-insensitively match the search term
// See https://techbase.kde.org/Development/Tutorials/Services/Traders#The_KTrader_Query_Language
const auto query = QString("exist Exec and Exec ~~ '%1'").arg(exec);
const KService::List services
= KServiceTypeTrader::self()->query(QStringLiteral("Application"), query);
if (!services.isEmpty()) {
// use the first item matching
const auto service = services.first();
app.name = service->desktopEntryName();
} else {
// when no services are found, sanitize a little the exec
// remove space and any caracter after
const int spaceIndex = exec.indexOf(" ");
if (spaceIndex != -1) {
exec = exec.mid(0, spaceIndex);
}
app.name = exec;
}
app.modified = QDateTime::fromString(attributes.value("modified"), Qt::ISODate);
current.applications.append(app);
+ } else if (qName == QStringLiteral("mime:mime-type")) {
+ current.mimetype = attributes.value("type");
}
return true;
}
bool BookmarkHandler::endElement(const QString &namespaceURI, const QString &localName,
const QString &qName)
{
Q_UNUSED(namespaceURI);
Q_UNUSED(localName);
if (qName == QStringLiteral("bookmark")) {
// keep track of the finished parsed bookmark
marks << current;
}
return true;
}
void GtkEventSpyPlugin::fileUpdated(const QString &filename)
{
QFile file(filename);
if (!file.open(QFile::ReadOnly | QFile::Text)) {
qCWarning(KAMD_LOG_PLUGIN_GTK_EVENTSPY) << "Could not read" << filename;
return;
}
// must parse the xbel xml file
BookmarkHandler bookmarkHandler;
QXmlSimpleReader reader;
reader.setContentHandler(&bookmarkHandler);
reader.setErrorHandler(&bookmarkHandler);
QXmlInputSource source(&file);
if (!reader.parse(source)) {
qCWarning(KAMD_LOG_PLUGIN_GTK_EVENTSPY) << "could not parse" << file << "error was "
<< bookmarkHandler.errorString();
return;
}
// then find the files that were accessed since last run
const QList bookmarks = bookmarkHandler.bookmarks();
for (const Bookmark &mark : bookmarks) {
if (mark.added > m_lastUpdate || mark.modified > m_lastUpdate
|| mark.visited > m_lastUpdate) {
- addDocument(mark.href, mark.latestApplication());
+ addDocument(mark.href, mark.latestApplication(), mark.mimetype);
}
}
m_lastUpdate = QDateTime::currentDateTime();
}
-void GtkEventSpyPlugin::addDocument(const QUrl &url, const QString &application)
+void GtkEventSpyPlugin::addDocument(const QUrl &url, const QString &application, const QString &mimetype)
{
const QString name = url.fileName();
Plugin::invoke(
m_resources, "RegisterResourceEvent",
Q_ARG(QString, application), // Application
Q_ARG(uint, 0), // Window ID
Q_ARG(QString, url.toString()), // URI
Q_ARG(uint, 0) // Event Activities::Accessed
);
+
+ Plugin::invoke(
+ m_resources, "RegisteredResourceMimetype",
+ Q_ARG(QString, url.toString()), // uri
+ Q_ARG(QString, mimetype) // mimetype
+ );
}
GtkEventSpyPlugin::~GtkEventSpyPlugin()
{
}
bool GtkEventSpyPlugin::init(QHash &modules)
{
Plugin::init(modules);
m_resources = modules["resources"];
return true;
}
#include "GtkEventSpy.moc"
diff --git a/src/service/plugins/gtk-eventspy/GtkEventSpy.h b/src/service/plugins/gtk-eventspy/GtkEventSpy.h
index 863ba5f..88d47a1 100644
--- a/src/service/plugins/gtk-eventspy/GtkEventSpy.h
+++ b/src/service/plugins/gtk-eventspy/GtkEventSpy.h
@@ -1,49 +1,49 @@
/*
* Copyright (C) 2019 Méven Car (meven.car@kdemail.net)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU 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, see .
*/
#ifndef PLUGINS_EVENT_SPY_PLUGIN_H
#define PLUGINS_EVENT_SPY_PLUGIN_H
#include
#include
#include
class KDirWatch;
class GtkEventSpyPlugin : public Plugin
{
Q_OBJECT
public:
explicit GtkEventSpyPlugin(QObject *parent = nullptr,
const QVariantList &args = QVariantList());
~GtkEventSpyPlugin() override;
bool init(QHash &modules) override;
private Q_SLOTS:
void fileUpdated(const QString &file);
- void addDocument(const QUrl &url, const QString &application);
+ void addDocument(const QUrl &url, const QString &application, const QString &mimetype);
private:
QObject *m_resources;
std::unique_ptr m_dirWatcher;
QDateTime m_lastUpdate;
};
#endif // PLUGINS_EVENT_SPY_PLUGIN_H