summaryrefslogtreecommitdiff
path: root/src/lib/xdgentries.cpp
blob: 4be82511838a4afcb538f44601889881c264bc66 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include "xdgentries.h"
#include "xdgentry.h"
#include <QDebug>
#include <QDir>
#include <QFileInfo>
#include <set>
#include <algorithm>

KaZoe::Entries::Entries(QObject *parent)
    : QObject(parent)
{
    QObject::connect(&m_watcher, &QFileSystemWatcher::directoryChanged, this, &Entries::_directoryChanged, Qt::QueuedConnection);
}

void KaZoe::Entries::_directoryChanged(const QString &path)
{
    QDir directory(path);
    QStringList old, now, removed, added;
    for(KaZoe::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 KaZoe::Entries::_entryDataChanged(const QString key, const QString value)
{
    KaZoe::Entry* ent = qobject_cast<KaZoe::Entry*>(QObject::sender());
    emit entryDataChanged(ent->appId(), key, value);
}

void KaZoe::Entries::unregister(const QString &path)
{
    QFileInfo info(path);
    QString id = info.completeBaseName();
    int oldid = m_entries.keys().indexOf(id);
    emit startRemoveEntry(oldid);
    KaZoe::Entry* old = m_entries[id];
    m_watcher.removePath(old->path());
    m_entries.remove(id);
    emit endRemoveEntry(oldid);
}

int KaZoe::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;
        }
    }

    KaZoe::Entry* entry = new KaZoe::Entry(path);
    QObject::connect(entry, &KaZoe::Entry::dataChanged, this, &Entries::_entryDataChanged);
    QObject::connect(entry, &KaZoe::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 KaZoe::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 KaZoe::Entries::count() const
{
    return m_entries.count();
}

const KaZoe::Entry *KaZoe::Entries::getEntry(int i) const
{
    return m_entries[m_entries.keys()[i]];
}

QList<KaZoe::Entry *> KaZoe::Entries::getEntries()
{
    return m_entries.values();
}