summaryrefslogtreecommitdiff
path: root/plugin
diff options
context:
space:
mode:
Diffstat (limited to 'plugin')
-rw-r--r--plugin/src/Caelestia/filesystemmodel.cpp107
-rw-r--r--plugin/src/Caelestia/filesystemmodel.hpp2
2 files changed, 87 insertions, 22 deletions
diff --git a/plugin/src/Caelestia/filesystemmodel.cpp b/plugin/src/Caelestia/filesystemmodel.cpp
index 3f75303..7f973a0 100644
--- a/plugin/src/Caelestia/filesystemmodel.cpp
+++ b/plugin/src/Caelestia/filesystemmodel.cpp
@@ -266,38 +266,101 @@ void FileSystemModel::updateEntriesForDir(const QString& dir) {
}
const auto result = watcher->result();
- const auto removedPaths = result.first;
- const auto addedPaths = result.second;
+ applyChanges(result.first, result.second);
- beginResetModel();
+ watcher->deleteLater();
+ });
+
+ watcher->setFuture(future);
+}
+
+void FileSystemModel::applyChanges(const QSet<QString>& removedPaths, const QSet<QString>& addedPaths) {
+ QList<int> removedIndices;
+ for (int i = 0; i < m_entries.size(); ++i) {
+ if (removedPaths.contains(m_entries[i]->path())) {
+ removedIndices << i;
+ }
+ }
+ std::sort(removedIndices.begin(), removedIndices.end(), std::greater<int>());
- const int numEntries = static_cast<int>(m_entries.size());
- for (int i = numEntries - 1; i >= 0; --i) {
- if (removedPaths.contains(m_entries[i]->path())) {
+ int start = -1;
+ int end = -1;
+ for (int idx : removedIndices) {
+ if (start == -1) {
+ start = idx;
+ end = idx;
+ } else if (idx == end - 1) {
+ end = idx;
+ } else {
+ beginRemoveRows(QModelIndex(), end, start);
+ for (int i = start; i >= end; --i) {
emit removed(m_entries[i]->path());
delete m_entries.takeAt(i);
}
- }
+ endRemoveRows();
- for (const auto& path : addedPaths) {
- const auto entry = new FileSystemEntry(path, m_dir.relativeFilePath(path), this);
- emit added(entry);
- m_entries << entry;
+ start = idx;
+ end = idx;
}
+ }
+ if (start != -1) {
+ beginRemoveRows(QModelIndex(), end, start);
+ for (int i = start; i >= end; --i) {
+ emit removed(m_entries[i]->path());
+ delete m_entries.takeAt(i);
+ }
+ endRemoveRows();
+ }
- std::sort(m_entries.begin(), m_entries.end(), [](const FileSystemEntry* a, const FileSystemEntry* b) {
- if (a->isDir() != b->isDir()) {
- return a->isDir();
- }
- return a->relativePath().localeAwareCompare(b->relativePath()) < 0;
- });
+ QList<FileSystemEntry*> newEntries;
+ for (const auto& path : addedPaths) {
+ newEntries << new FileSystemEntry(path, m_dir.relativeFilePath(path), this);
+ }
+ std::sort(newEntries.begin(), newEntries.end(), &FileSystemModel::compareEntries);
- emit entriesChanged();
+ int insertStart = -1;
+ int prevRow = -1;
+ QList<FileSystemEntry*> batchItems;
+ for (const auto& entry : newEntries) {
+ const auto it = std::lower_bound(m_entries.begin(), m_entries.end(), entry, &FileSystemModel::compareEntries);
+ int row = static_cast<int>(it - m_entries.begin());
- endResetModel();
+ if (insertStart == -1) {
+ insertStart = row;
+ prevRow = row;
+ batchItems.clear();
+ batchItems << entry;
+ } else if (row == prevRow + 1) {
+ prevRow = row;
+ batchItems << entry;
+ } else {
+ beginInsertRows(QModelIndex(), insertStart, static_cast<int>(insertStart + batchItems.size() - 1));
+ for (int i = 0; i < batchItems.size(); ++i) {
+ m_entries.insert(insertStart + i, batchItems[i]);
+ emit added(batchItems[i]);
+ }
+ endInsertRows();
- watcher->deleteLater();
- });
+ insertStart = row;
+ prevRow = row;
+ batchItems.clear();
+ batchItems << entry;
+ }
+ prevRow = static_cast<int>(m_entries.indexOf(entry));
+ }
+ if (!batchItems.isEmpty()) {
+ beginInsertRows(QModelIndex(), insertStart, static_cast<int>(insertStart + batchItems.size() - 1));
+ for (int i = 0; i < batchItems.size(); ++i) {
+ m_entries.insert(insertStart + i, batchItems[i]);
+ emit added(batchItems[i]);
+ }
+ endInsertRows();
+ }
+}
- watcher->setFuture(future);
+bool FileSystemModel::compareEntries(const FileSystemEntry* a, const FileSystemEntry* b) {
+ if (a->isDir() != b->isDir()) {
+ return a->isDir();
+ }
+ return a->relativePath().localeAwareCompare(b->relativePath()) < 0;
}
diff --git a/plugin/src/Caelestia/filesystemmodel.hpp b/plugin/src/Caelestia/filesystemmodel.hpp
index fdcd6c1..2e3bf93 100644
--- a/plugin/src/Caelestia/filesystemmodel.hpp
+++ b/plugin/src/Caelestia/filesystemmodel.hpp
@@ -154,4 +154,6 @@ private:
void updateWatcher();
void updateEntries();
void updateEntriesForDir(const QString& dir);
+ void applyChanges(const QSet<QString>& removedPaths, const QSet<QString>& addedPaths);
+ static bool compareEntries(const FileSystemEntry* a, const FileSystemEntry* b);
};