File indexing completed on 2025-02-02 05:17:48

0001 /*
0002  *   SPDX-FileCopyrightText: 2023 Méven Car (meven@kde.org)
0003  *
0004  *   SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "LibreOfficeEventSpy.h"
0008 
0009 #include "DebugLibreOfficeEventSpy.h"
0010 
0011 #include <QFile>
0012 #include <QFileInfo>
0013 #include <QMimeDatabase>
0014 #include <QStandardPaths>
0015 #include <QString>
0016 #include <QUrl>
0017 #include <QXmlStreamReader>
0018 
0019 #include <KApplicationTrader>
0020 #include <KDirWatch>
0021 #include <KService>
0022 
0023 K_PLUGIN_CLASS(LibreOfficeEventSpyPlugin)
0024 
0025 LibreOfficeEventSpyPlugin::LibreOfficeEventSpyPlugin(QObject *parent)
0026     : Plugin(parent)
0027     , m_resources(nullptr)
0028     , m_dirWatcher(new KDirWatch(this))
0029 {
0030     // libreoffice config file
0031     // usually $HOME/.config/libreoffice/4/user/registrymodifications.xcu
0032     QString filename = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1String("/libreoffice/4/user/registrymodifications.xcu");
0033 
0034     QFileInfo stat(filename);
0035     if (stat.exists()) {
0036         m_dirWatcher->addFile(filename);
0037         connect(m_dirWatcher.get(), &KDirWatch::dirty, this, &LibreOfficeEventSpyPlugin::fileUpdated);
0038         connect(m_dirWatcher.get(), &KDirWatch::created, this, &LibreOfficeEventSpyPlugin::fileUpdated);
0039 
0040         // call to initialize m_previousUrls
0041         fileUpdated(filename);
0042     } else {
0043         qCDebug(KAMD_LOG_PLUGIN_LIBREOFFICE_EVENTSPY) << "Could not read libreoffice config file: " << filename;
0044     }
0045 }
0046 
0047 void LibreOfficeEventSpyPlugin::fileUpdated(const QString &filename)
0048 {
0049     QFile file(filename);
0050     if (!file.open(QFile::ReadOnly | QFile::Text)) {
0051         qCWarning(KAMD_LOG_PLUGIN_LIBREOFFICE_EVENTSPY) << "Could not read" << filename;
0052         return;
0053     }
0054 
0055     QUrl fileUrl;
0056     const static QString historyItemListAttr =
0057         QStringLiteral("/org.openoffice.Office.Histories/Histories/org.openoffice.Office.Histories:HistoryInfo['PickList']/OrderList");
0058 
0059     QXmlStreamReader reader(&file);
0060     bool m_item_is_history = false;
0061     while (!reader.atEnd()) {
0062         const auto token = reader.readNext();
0063         if (token == QXmlStreamReader::StartElement) {
0064             if (reader.qualifiedName() == QLatin1String("item")) {
0065                 if (reader.attributes().value("oor:path") == historyItemListAttr) {
0066                     m_item_is_history = true;
0067                 }
0068             } else if (reader.qualifiedName() == QLatin1String("value") && m_item_is_history) {
0069                 // found first history value
0070                 fileUrl = QUrl(reader.readElementText());
0071                 break;
0072             }
0073         } else if (token == QXmlStreamReader::EndElement) {
0074             if (reader.qualifiedName() == QLatin1String("node")) {
0075                 m_item_is_history = false;
0076             }
0077         }
0078     }
0079 
0080     if (reader.hasError()) {
0081         qCWarning(KAMD_LOG_PLUGIN_LIBREOFFICE_EVENTSPY) << "could not parse" << file.fileName() << "error was " << reader.errorString();
0082         return;
0083     }
0084 
0085     if (m_init && m_lastUrl != fileUrl) {
0086 
0087         m_lastUrl = fileUrl;
0088 
0089         QMimeDatabase db;
0090         const auto mimeType = db.mimeTypeForUrl(fileUrl).name();
0091         auto app = KApplicationTrader::preferredService(mimeType);
0092         if (app) {
0093             addDocument(fileUrl, app->desktopEntryName(), mimeType);
0094         }
0095     }
0096 
0097     m_lastUrl = fileUrl;
0098     m_init = true;
0099 }
0100 
0101 void LibreOfficeEventSpyPlugin::addDocument(const QUrl &url, const QString &application, const QString &mimetype)
0102 {
0103     const auto urlString = url.toString(QUrl::PreferLocalFile);
0104     Plugin::invoke<Qt::QueuedConnection>(m_resources,
0105                                          "RegisterResourceEvent",
0106                                          Q_ARG(QString, application), // Application
0107                                          Q_ARG(uint, 0), // Window ID
0108                                          Q_ARG(QString, urlString), // URI
0109                                          Q_ARG(uint, 0) // Event Activities::Accessed
0110     );
0111 
0112     Plugin::invoke<Qt::QueuedConnection>(m_resources,
0113                                          "RegisteredResourceMimetype",
0114                                          Q_ARG(QString, urlString), // uri
0115                                          Q_ARG(QString, mimetype) // mimetype
0116     );
0117 
0118     Plugin::invoke<Qt::QueuedConnection>(m_resources,
0119                                          "RegisterResourceTitle",
0120                                          Q_ARG(QString, urlString), // uri
0121                                          Q_ARG(QString, url.fileName()) // title
0122     );
0123 }
0124 
0125 LibreOfficeEventSpyPlugin::~LibreOfficeEventSpyPlugin()
0126 {
0127 }
0128 
0129 bool LibreOfficeEventSpyPlugin::init(QHash<QString, QObject *> &modules)
0130 {
0131     Plugin::init(modules);
0132 
0133     m_resources = modules["resources"];
0134 
0135     return true;
0136 }
0137 
0138 #include "LibreOfficeEventSpy.moc"