diff options
author | Fabien Proriol <fabien.proriol@kazoe.org> | 2025-05-25 12:13:31 +0200 |
---|---|---|
committer | Fabien Proriol <fabien.proriol@kazoe.org> | 2025-05-25 12:13:31 +0200 |
commit | 1dbc0e3c88ba271ba35bc3f82e7864c4f35e1236 (patch) | |
tree | 8c491cd196e2eff4c59f8c23f566f7ff26981586 /src/lib/xdgentries.cpp |
Initial Commit
Diffstat (limited to 'src/lib/xdgentries.cpp')
-rw-r--r-- | src/lib/xdgentries.cpp | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/src/lib/xdgentries.cpp b/src/lib/xdgentries.cpp new file mode 100644 index 0000000..790e472 --- /dev/null +++ b/src/lib/xdgentries.cpp @@ -0,0 +1,128 @@ +#include "xdgentries.h" +#include "xdgentry.h" +#include <QDebug> +#include <QDir> +#include <QFileInfo> +#include <set> +#include <algorithm> + +xdg::Entries::Entries(QObject *parent) + : QObject(parent) +{ + QObject::connect(&m_watcher, &QFileSystemWatcher::directoryChanged, this, &Entries::_directoryChanged, Qt::QueuedConnection); +} + +void xdg::Entries::_directoryChanged(const QString &path) +{ + QDir directory(path); + QStringList old, now, removed, added; + for(xdg::Entry *entry: m_entries) + { + if(entry->path().startsWith(directory.absolutePath())) + { + old.append(entry->path()); + } + } + for(const QString &item: directory.entryList(QStringList() << "*.desktop", QDir::Files)) + { + QString current = directory.absoluteFilePath(item); + if(current.startsWith(directory.absolutePath())) + { + now.append(current); + } + } + std::set_difference(old.begin(), old.end(), now.begin(), now.end(), std::inserter(removed, removed.begin())); + std::set_difference(now.begin(), now.end(), old.begin(), old.end(), std::inserter(added, added.begin())); + for(const QString &item: removed) + { + unregister(item); + } + for(const QString &item: added) + { + add(item, true); + } +} + +void xdg::Entries::_entryDataChanged(const QString key, const QString value) +{ + xdg::Entry* ent = qobject_cast<xdg::Entry*>(QObject::sender()); + emit entryDataChanged(ent->appId(), key, value); +} + +void xdg::Entries::unregister(const QString &path) +{ + QFileInfo info(path); + QString id = info.completeBaseName(); + int oldid = m_entries.keys().indexOf(id); + emit startRemoveEntry(oldid); + xdg::Entry* old = m_entries[id]; + m_watcher.removePath(old->path()); + m_entries.remove(id); + emit endRemoveEntry(oldid); +} + +int xdg::Entries::add(const QString &path, bool replace) +{ + QFileInfo info(path); + QString id = info.completeBaseName(); + if(!info.isFile() || info.suffix() != "desktop") + { + qWarning() << path << "is not a desktop entry"; + return -1; + } + + if(m_entries.contains(id)) + { + if(replace) + { + unregister(path); + } + else + { + return -1; + } + } + + xdg::Entry* entry = new xdg::Entry(path); + QObject::connect(entry, &xdg::Entry::dataChanged, this, &Entries::_entryDataChanged); + QObject::connect(entry, &xdg::Entry::raiseProcess, this, &Entries::raiseProcess); + + m_entries[id] = entry; + emit startCreateEntry(m_entries.keys().indexOf(id)); + emit endCreateEntry(m_entries.keys().indexOf(id)); + return 0; +} + +int xdg::Entries::addDirectory(const QString &path, bool replace) +{ + QFileInfo info(path.trimmed()); + if(!info.isDir()) + { + return -1; + } + + QDir directory(path.trimmed()); + QStringList items = directory.entryList(QStringList() << "*.desktop", QDir::Files); + for(QString &item: items) + { + add(directory.absoluteFilePath(item), replace); + } + + m_watcher.addPath(path.trimmed()); + return 0; +} + +qsizetype xdg::Entries::count() const +{ + return m_entries.count(); +} + +const xdg::Entry *xdg::Entries::getEntry(int i) const +{ + return m_entries[m_entries.keys()[i]]; +} + +QList<xdg::Entry *> xdg::Entries::getEntries() +{ + return m_entries.values(); +} |