plugin/fsm: incremental updates
This commit is contained in:
parent
2d7d01354a
commit
7b35c23bd0
3 changed files with 121 additions and 31 deletions
|
|
@ -179,13 +179,38 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
populate: Transition {
|
add: Transition {
|
||||||
|
Anim {
|
||||||
|
properties: "opacity,scale"
|
||||||
|
from: 0
|
||||||
|
to: 1
|
||||||
|
duration: Appearance.anim.durations.expressiveDefaultSpatial
|
||||||
|
easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
remove: Transition {
|
||||||
|
Anim {
|
||||||
|
property: "opacity"
|
||||||
|
to: 0
|
||||||
|
}
|
||||||
Anim {
|
Anim {
|
||||||
property: "scale"
|
property: "scale"
|
||||||
from: 0.7
|
to: 0.5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
displaced: Transition {
|
||||||
|
Anim {
|
||||||
|
properties: "opacity,scale"
|
||||||
to: 1
|
to: 1
|
||||||
easing.bezierCurve: Appearance.anim.curves.standardDecel
|
easing.bezierCurve: Appearance.anim.curves.standardDecel
|
||||||
}
|
}
|
||||||
|
Anim {
|
||||||
|
properties: "x,y"
|
||||||
|
duration: Appearance.anim.durations.expressiveDefaultSpatial
|
||||||
|
easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -266,38 +266,101 @@ void FileSystemModel::updateEntriesForDir(const QString& dir) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto result = watcher->result();
|
const auto result = watcher->result();
|
||||||
const auto removedPaths = result.first;
|
applyChanges(result.first, result.second);
|
||||||
const auto addedPaths = result.second;
|
|
||||||
|
|
||||||
beginResetModel();
|
|
||||||
|
|
||||||
const int numEntries = static_cast<int>(m_entries.size());
|
|
||||||
for (int i = numEntries - 1; i >= 0; --i) {
|
|
||||||
if (removedPaths.contains(m_entries[i]->path())) {
|
|
||||||
emit removed(m_entries[i]->path());
|
|
||||||
delete m_entries.takeAt(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& path : addedPaths) {
|
|
||||||
const auto entry = new FileSystemEntry(path, m_dir.relativeFilePath(path), this);
|
|
||||||
emit added(entry);
|
|
||||||
m_entries << entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
});
|
|
||||||
|
|
||||||
emit entriesChanged();
|
|
||||||
|
|
||||||
endResetModel();
|
|
||||||
|
|
||||||
watcher->deleteLater();
|
watcher->deleteLater();
|
||||||
});
|
});
|
||||||
|
|
||||||
watcher->setFuture(future);
|
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>());
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
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());
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FileSystemModel::compareEntries(const FileSystemEntry* a, const FileSystemEntry* b) {
|
||||||
|
if (a->isDir() != b->isDir()) {
|
||||||
|
return a->isDir();
|
||||||
|
}
|
||||||
|
return a->relativePath().localeAwareCompare(b->relativePath()) < 0;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -154,4 +154,6 @@ private:
|
||||||
void updateWatcher();
|
void updateWatcher();
|
||||||
void updateEntries();
|
void updateEntries();
|
||||||
void updateEntriesForDir(const QString& dir);
|
void updateEntriesForDir(const QString& dir);
|
||||||
|
void applyChanges(const QSet<QString>& removedPaths, const QSet<QString>& addedPaths);
|
||||||
|
static bool compareEntries(const FileSystemEntry* a, const FileSystemEntry* b);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue