mirror of
https://invent.kde.org/plasma/plasma-desktop.git
synced 2026-11-03 14:49:44 -09:00
Positioner: Remove invalid or nonexistant files
Adds a signal so that whenever a file is deleted/moved to trash, we know to remove it from positioner configuration. On listing completion, we now get a list of items that actually exist, so that positioner can remove the extraneous files. Iterate over all resolutions and skip files that do not exist in our position array during saving. BUG: 469445 CCBUG: 507079 FIXED-IN: 6.8.3
This commit is contained in:
parent
761476d81b
commit
a2a72d5e13
4 changed files with 56 additions and 15 deletions
|
|
@ -227,9 +227,9 @@ FolderModel::FolderModel(QObject *parent)
|
|||
|
||||
connect(dirLister, &KCoreDirLister::started, this, std::bind(&FolderModel::setStatus, this, Status::Listing));
|
||||
|
||||
QObject::connect(dirLister, &KCoreDirLister::completed, this, [this] {
|
||||
QObject::connect(dirLister, &KCoreDirLister::completed, this, [this, dirLister] {
|
||||
setStatus(Status::Ready);
|
||||
Q_EMIT listingCompleted();
|
||||
Q_EMIT listingCompleted(dirLister->items().urlList());
|
||||
});
|
||||
|
||||
QObject::connect(dirLister, &KCoreDirLister::canceled, this, [this] {
|
||||
|
|
@ -1662,6 +1662,7 @@ void FolderModel::evictFromIsDirCache(const KFileItemList &items)
|
|||
for (const KFileItem &item : items) {
|
||||
m_screenMapper->removeFromMap(item.url(), m_currentActivity);
|
||||
m_isDirCache.remove(item.url());
|
||||
Q_EMIT itemDeleted(item.url());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -292,7 +292,7 @@ public:
|
|||
|
||||
Q_SIGNALS:
|
||||
void urlChanged() const;
|
||||
void listingCompleted() const;
|
||||
void listingCompleted(const QList<QUrl> &items) const;
|
||||
void listingCanceled() const;
|
||||
void iconNameChanged() const;
|
||||
void resolvedUrlChanged() const;
|
||||
|
|
@ -324,6 +324,7 @@ Q_SIGNALS:
|
|||
void selectionDone();
|
||||
void creatingNewItemsChanged() const;
|
||||
void selectionCountChanged() const;
|
||||
void itemDeleted(const QUrl &url);
|
||||
|
||||
protected:
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||
|
|
|
|||
|
|
@ -1061,13 +1061,33 @@ void Positioner::savePositionsConfig()
|
|||
auto doc = QJsonDocument::fromJson(confdata.toUtf8());
|
||||
QJsonObject root;
|
||||
// Iterate over the old data
|
||||
for (const auto &item : doc.toVariant().toMap().asKeyValueRange()) {
|
||||
if (item.first != m_resolution) {
|
||||
root.insert(item.first, QJsonValue::fromVariant(item.second));
|
||||
// Positions are serialized like this: [stripes, itemsPerStripe, filename, stripe, position]
|
||||
const auto currentPositions = positions();
|
||||
for (const auto &[resolution, itemList] : doc.toVariant().toMap().asKeyValueRange()) {
|
||||
if (resolution != m_resolution) {
|
||||
QStringList newPositions;
|
||||
const QStringList positions = itemList.toStringList();
|
||||
if (positions.size() >= PositionsConstants::headerSize
|
||||
&& (positions.size() - PositionsConstants::headerSize) % PositionsConstants::bucketSize == 0) {
|
||||
newPositions.append(positions[0]);
|
||||
newPositions.append(positions[1]);
|
||||
|
||||
for (qsizetype offset = PositionsConstants::headerSize; offset < positions.size(); offset += PositionsConstants::bucketSize) {
|
||||
const auto name = positions[offset + PositionsConstants::filenameOffset];
|
||||
const auto stripe = positions[offset + PositionsConstants::stripeOffset];
|
||||
const auto pos = positions[offset + PositionsConstants::posOffset];
|
||||
if (currentPositions.contains(name)) {
|
||||
newPositions.append(name);
|
||||
newPositions.append(stripe);
|
||||
newPositions.append(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
root.insert(resolution, QJsonValue::fromVariant(newPositions));
|
||||
}
|
||||
}
|
||||
// Append our new item
|
||||
root.insert(m_resolution, QJsonArray::fromStringList(positions()));
|
||||
root.insert(m_resolution, QJsonArray::fromStringList(currentPositions));
|
||||
|
||||
const QByteArray data = QJsonDocument(root).toJson(QJsonDocument::Compact);
|
||||
auto config = m_applet->config().group(QStringLiteral("General"));
|
||||
|
|
@ -1125,13 +1145,14 @@ void Positioner::loadChangedPositions()
|
|||
m_changedPositions.clear();
|
||||
m_changedPositions.reserve(jsonArr.size());
|
||||
|
||||
for (auto it = jsonArr.begin(), itEnd = jsonArr.end(); it != itEnd; ++it) {
|
||||
const auto filename = it.key();
|
||||
for (const auto &key : jsonArr.keys()) {
|
||||
const auto filename = key;
|
||||
|
||||
if (filename.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto values = it.value().toVariant().toStringList();
|
||||
const auto values = jsonArr[key].toVariant().toStringList();
|
||||
if (values.size() != 3) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1287,11 +1308,26 @@ void Positioner::onItemRenamed(const QString &filename, const QString &newFilena
|
|||
savePositionsConfig();
|
||||
}
|
||||
|
||||
// Save positions only when listing is done, so we
|
||||
// do not save them during they're being moved due to
|
||||
// geometry changes
|
||||
void Positioner::onListingCompleted()
|
||||
void Positioner::onItemDeleted(const QUrl &url)
|
||||
{
|
||||
updatePositionsList();
|
||||
m_positions.remove(url.toString());
|
||||
convertFolderModelData();
|
||||
savePositionsConfig();
|
||||
}
|
||||
|
||||
void Positioner::onListingCompleted(const QList<QUrl> &urls)
|
||||
{
|
||||
QHash<QString, GridPosition> newPositions;
|
||||
|
||||
for (const auto &url : urls) {
|
||||
if (m_positions.contains(url.toString())) {
|
||||
newPositions[url.toString()] = m_positions[url.toString()];
|
||||
}
|
||||
}
|
||||
|
||||
m_positions = newPositions;
|
||||
|
||||
savePositionsConfig();
|
||||
}
|
||||
|
||||
|
|
@ -1310,6 +1346,7 @@ void Positioner::connectSignals(FolderModel *model)
|
|||
connect(m_folderModel, &FolderModel::statusChanged, this, &Positioner::sourceStatusChanged, Qt::UniqueConnection);
|
||||
connect(m_folderModel, &FolderModel::itemRenamed, this, &Positioner::onItemRenamed, Qt::UniqueConnection);
|
||||
connect(m_folderModel, &FolderModel::listingCompleted, this, &Positioner::onListingCompleted, Qt::UniqueConnection);
|
||||
connect(m_folderModel, &FolderModel::itemDeleted, this, &Positioner::onItemDeleted, Qt::UniqueConnection);
|
||||
}
|
||||
|
||||
void Positioner::disconnectSignals(FolderModel *model)
|
||||
|
|
@ -1327,6 +1364,7 @@ void Positioner::disconnectSignals(FolderModel *model)
|
|||
disconnect(m_folderModel, &FolderModel::statusChanged, this, &Positioner::sourceStatusChanged);
|
||||
disconnect(m_folderModel, &FolderModel::itemRenamed, this, &Positioner::onItemRenamed);
|
||||
disconnect(m_folderModel, &FolderModel::listingCompleted, this, &Positioner::onListingCompleted);
|
||||
disconnect(m_folderModel, &FolderModel::itemDeleted, this, &Positioner::onItemDeleted);
|
||||
}
|
||||
|
||||
#include "moc_positioner.cpp"
|
||||
|
|
|
|||
|
|
@ -142,7 +142,8 @@ private Q_SLOTS:
|
|||
void sourceRowsRemoved(const QModelIndex &parent, int first, int last);
|
||||
void sourceLayoutChanged(const QList<QPersistentModelIndex> &parents, QAbstractItemModel::LayoutChangeHint hint);
|
||||
void onItemRenamed(const QString &filename, const QString &newFilename);
|
||||
void onListingCompleted();
|
||||
void onItemDeleted(const QUrl &url);
|
||||
void onListingCompleted(const QList<QUrl> &urls);
|
||||
|
||||
private:
|
||||
void initMaps(int size = -1);
|
||||
|
|
|
|||
Loading…
Reference in a new issue