diff options
author | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2017-09-12 12:25:54 +0200 |
---|---|---|
committer | Holger Freyther <holger+qt@freyther.de> | 2017-10-24 12:05:55 +0000 |
commit | f196da3aa5e15aeb95762ce4d97ec54269c16959 (patch) | |
tree | 23aaef778e6a338646bf4f62686b7badf9b1653e /wayland/democompositor/apps | |
parent | 444878981185912f88155f27635b509b613a48e8 (diff) |
democompositor: Remove deleted files from the model
In the previous code review Paul discovered the fact that files
would never be removed. Implement finding deleted files and emit
a signal per removed file. Consume the signal in QML and use the
new API to kill the process (one could close the wayland display
connection as well).
Emit the removed signals _after_ the model has been updated to
provide the QML code with an updated model during the signal
handling.
Change-Id: Ib3bb1bd953bfbf09d25c5e5822756a53b08fd797
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
Diffstat (limited to 'wayland/democompositor/apps')
-rw-r--r-- | wayland/democompositor/apps/applistmodel.cpp | 59 | ||||
-rw-r--r-- | wayland/democompositor/apps/applistmodel.h | 7 |
2 files changed, 60 insertions, 6 deletions
diff --git a/wayland/democompositor/apps/applistmodel.cpp b/wayland/democompositor/apps/applistmodel.cpp index 0b4d620..b0774f7 100644 --- a/wayland/democompositor/apps/applistmodel.cpp +++ b/wayland/democompositor/apps/applistmodel.cpp @@ -135,25 +135,74 @@ void AppListModel::addDir(const QString& dirName) { QDirIterator dirIt(dirName, QDir::Files | QDir::NoDotAndDotDot | QDir::Readable); + // We want to deal with the corner case of some files being + // removed. One option would have been to keep a marker bit + // inside the AppEntry but that might leak too much of the + // implementation to the outside. Let's keep a list of file + // names that came from the directory and remove items from + // the list as we re-parse them. Once we are done emit the + // signals. + QVector<QString> deletionCandidates = entriesWithPrefix(dirName); + beginResetModel(); - while (dirIt.hasNext()) - doAddFile(dirIt.next()); + while (dirIt.hasNext()) { + auto fileName = dirIt.next(); + if (!doAddFile(fileName)) + continue; + deletionCandidates.removeAll(fileName); + } + QVector<AppEntry> removedApps = removeEntries(deletionCandidates); endResetModel(); + + // Announce the apps we removed after the model has been updated + for (const auto& app : removedApps) { + qCDebug(apps) << "Going to remove entry for " << app.sourceFileName; + emit appRemoved(app); + } } -void AppListModel::doAddFile(const QString& fileName) +bool AppListModel::doAddFile(const QString& fileName) { bool ok; auto newEntry = AppParser::parseFile(fileName, &ok); if (!ok) - return; + return false; for (int i = 0; i < m_rows.count(); ++i) { if (m_rows[i].sourceFileName == fileName) { m_rows[i] = newEntry; - return; + return true; } } m_rows.push_back(newEntry); + return true; +} + +QVector<QString> AppListModel::entriesWithPrefix(const QString& prefix) const +{ + QVector<QString> entries; + + for (const AppEntry& entry : m_rows) + if (entry.sourceFileName.startsWith(prefix)) + entries.push_back(entry.sourceFileName); + return entries; +} + +QVector<AppEntry> AppListModel::removeEntries(const QVector<QString>& fileNames) +{ + QVector<AppEntry> removedEntries(fileNames.size()); + + // Rare but quadratic. The actual removal. + for (const auto &toRemoveFile: fileNames) { + for (int i = 0; i < m_rows.size(); ++i) { + if (m_rows[i].sourceFileName != toRemoveFile) + continue; + removedEntries.append(m_rows[i]); + m_rows.removeAt(i); + break; + } + } + + return removedEntries; } diff --git a/wayland/democompositor/apps/applistmodel.h b/wayland/democompositor/apps/applistmodel.h index 9147f54..4662e8f 100644 --- a/wayland/democompositor/apps/applistmodel.h +++ b/wayland/democompositor/apps/applistmodel.h @@ -76,6 +76,9 @@ public: QVariant data(const QModelIndex& index, int role) const Q_DECL_OVERRIDE; QHash<int, QByteArray> roleNames() const Q_DECL_OVERRIDE; +Q_SIGNALS: + void appRemoved(const AppEntry& appEntry); + public Q_SLOTS: bool addAndWatchDir(const QString& dirName); @@ -83,7 +86,9 @@ public Q_SLOTS: void addDir(const QString& dirName); private: - void doAddFile(const QString& fileName); + QVector<QString> entriesWithPrefix(const QString& prefix) const; + QVector<AppEntry> removeEntries(const QVector<QString>& sourceFileNames); + bool doAddFile(const QString& fileName); QVector<AppEntry> m_rows; static QHash<int, QByteArray> m_roles; |