Commit 9eda8853 authored by David Faure's avatar David Faure
Browse files

StandardActionManager: compress updates and emit useful signal

When deleting 5000 emails, KMail uses 100% CPU for a long time.
This is because the messagelib code (due to threading etc.) removes
rows one by one from the model. As a result
- StandardActionManager was recalculating selection (slowly, see
safeSelectedRows()) after every item
- StandardMailActionManager was doing the same again
- QSortFilterProxyModel updates its internal mapping at every step.
I can't fix the last one, but I fixed the first two:

1) compress changes with a 0s timer, so we only update the actions
when going back to the event loop
2) emit signal for StandardMailActionManager to use the computed
lists, and more importantly so that it doesn't need its own timer.
StandardActionManager is now the one which decides when StandardMailActionManager
should update.
parent be65c229
Pipeline #30655 passed with stage
in 41 minutes and 39 seconds
......@@ -46,6 +46,7 @@
#include <QPointer>
#include <QInputDialog>
#include <QRegularExpression>
#include <QTimer>
using namespace Akonadi;
......@@ -271,6 +272,9 @@ public:
setContextText(StandardActionManager::Paste, StandardActionManager::ErrorMessageTitle,
i18n("Paste failed"));
mDelayedUpdateTimer.setSingleShot(true);
connect(&mDelayedUpdateTimer, &QTimer::timeout, q, [this]() { updateActions(); });
qRegisterMetaType<Akonadi::Item::List>("Akonadi::Item::List");
}
......@@ -460,6 +464,12 @@ public:
return collectionList;
}
void delayedUpdateActions()
{
// Compress changes (e.g. when deleting many rows, do this only once)
mDelayedUpdateTimer.start(0);
}
void updateActions()
{
// favorite collections
......@@ -497,6 +507,7 @@ public:
if (favoritesModel) {
enableAction(StandardActionManager::SynchronizeFavoriteCollections, (favoritesModel->rowCount() > 0));
}
Q_EMIT q->selectionsChanged(selectedCollectionsList, selectedFavoriteCollectionsList, selectedItems);
Q_EMIT q->actionStateUpdated();
}
......@@ -1556,6 +1567,7 @@ public:
QVector<QAction *> actions;
QHash<StandardActionManager::Type, KLocalizedString> pluralLabels;
QHash<StandardActionManager::Type, KLocalizedString> pluralIconLabels;
QTimer mDelayedUpdateTimer;
struct ContextTextEntry {
QString text;
......@@ -1604,7 +1616,7 @@ void StandardActionManager::setCollectionSelectionModel(QItemSelectionModel *sel
void StandardActionManager::setItemSelectionModel(QItemSelectionModel *selectionModel)
{
d->itemSelectionModel = selectionModel;
connect(selectionModel, &QItemSelectionModel::selectionChanged, this, [this]() { d->updateActions(); });
connect(selectionModel, &QItemSelectionModel::selectionChanged, this, [this]() { d->delayedUpdateActions(); });
}
void StandardActionManager::setFavoriteCollectionsModel(FavoriteCollectionsModel *favoritesModel)
......
......@@ -342,6 +342,17 @@ public:
void createActionFolderMenu(QMenu *menu, Type type);
Q_SIGNALS:
/**
* This signal is emitted whenever one of the selections has changed
* (selected collections, selected favorites collections, selected items)
* This allows other action managers to update their actions accordingly
* (see e.g. StandardMailActionManager)
*/
void selectionsChanged(const Collection::List &selectedCollectionsList,
const Collection::List &selectedFavoriteCollectionsList,
const Item::List &selectedItems);
/**
* This signal is emitted whenever the action state has been updated.
* In case you have special needs for changing the state of some actions,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment