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>
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();
}
|