AutoTest: Cache expanded state as well

Parsing may end up with incomplete information when parsing documents
that are currently edited and contain syntax errors due to
incomplete changes.
This resulted in not re-adding all items which in turn led to lose
also its expanded state when re-adding it in a later successful parse.
Avoid the need to expand manually again and again by caching the
expanded state for a couple of re-parses.

Change-Id: I2994b9c7ab56c0c76f416d10247e68dea271cd10
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Christian Stenger
2020-06-17 13:04:44 +02:00
parent ad5443395d
commit b402215daf
3 changed files with 52 additions and 2 deletions

View File

@@ -43,6 +43,7 @@
#include <utils/utilsicons.h>
#include <coreplugin/actionmanager/actionmanager.h>
#include <projectexplorer/buildmanager.h>
#include <projectexplorer/session.h>
#include <QAction>
#include <QMenu>
@@ -106,6 +107,14 @@ TestNavigationWidget::TestNavigationWidget(QWidget *parent) :
this, [this] (int numberOfActive) {
m_missingFrameworksWidget->setVisible(numberOfActive == 0);
});
ProjectExplorer::SessionManager *sm = ProjectExplorer::SessionManager::instance();
connect(sm, &ProjectExplorer::SessionManager::startupProjectChanged,
[this](ProjectExplorer::Project * /*project*/) {
m_expandedStateCache.clear();
m_itemUseCache.clear();
});
connect(m_model, &TestTreeModel::testTreeModelChanged,
this, &TestNavigationWidget::reapplyCachedExpandedState);
connect(m_progressTimer, &QTimer::timeout,
m_progressIndicator, &Utils::ProgressIndicator::show);
}
@@ -226,6 +235,28 @@ QList<QToolButton *> TestNavigationWidget::createToolButtons()
return list;
}
void TestNavigationWidget::updateExpandedStateCache()
{
// raise generation for cached items and drop anything reaching 10th generation
const QList<QString> cachedNames = m_itemUseCache.keys();
for (const QString &cachedName : cachedNames) {
auto it = m_itemUseCache.find(cachedName);
if (it.value()++ >= 10) {
m_itemUseCache.erase(it);
m_expandedStateCache.remove(cachedName);
}
}
for (Utils::TreeItem *rootNode : *m_model->rootItem()) {
rootNode->forAllChildren([this](Utils::TreeItem *child) {
auto childItem = static_cast<TestTreeItem *>(child);
const QString cacheName = childItem->cacheName();
m_expandedStateCache.insert(cacheName, m_view->isExpanded(childItem->index()));
m_itemUseCache[cacheName] = 0; // explicitly mark as 0-generation
});
}
}
void TestNavigationWidget::onItemActivated(const QModelIndex &index)
{
const Utils::Link link = index.data(LinkRole).value<Utils::Link>();
@@ -295,6 +326,22 @@ void TestNavigationWidget::onRunThisTestTriggered(TestRunMode runMode)
TestRunner::instance()->runTest(runMode, item);
}
void TestNavigationWidget::reapplyCachedExpandedState()
{
for (Utils::TreeItem *rootNode : *m_model->rootItem()) {
rootNode->forAllChildren([this](Utils::TreeItem *child) {
auto childItem = static_cast<TestTreeItem *>(child);
const QString cacheName = childItem->cacheName();
const auto it = m_expandedStateCache.find(cacheName);
if (it == m_expandedStateCache.end())
return;
QModelIndex index = child->index();
if (m_view->isExpanded(index) != it.value())
m_view->setExpanded(index, it.value());
});
}
}
TestNavigationWidgetFactory::TestNavigationWidgetFactory()
{
setDisplayName(tr("Tests"));

View File

@@ -64,7 +64,7 @@ public:
void contextMenuEvent(QContextMenuEvent *event) override;
QList<QToolButton *> createToolButtons();
signals:
void updateExpandedStateCache();
private:
void onItemActivated(const QModelIndex &index);
@@ -74,6 +74,7 @@ private:
void onParsingFinished();
void initializeFilterMenu();
void onRunThisTestTriggered(TestRunMode runMode);
void reapplyCachedExpandedState();
TestTreeModel *m_model;
TestTreeSortFilterModel *m_sortFilterModel;
@@ -85,6 +86,8 @@ private:
Utils::ProgressIndicator *m_progressIndicator;
QTimer *m_progressTimer;
QFrame *m_missingFrameworksWidget;
QHash<QString, bool> m_expandedStateCache;
QHash<QString, int> m_itemUseCache;
};
class TestNavigationWidgetFactory : public Core::INavigationWidgetFactory

View File

@@ -104,7 +104,7 @@ private:
QList<TestTreeItem *> testItemsByName(TestTreeItem *root, const QString &testName);
Internal::TestCodeParser *m_parser = nullptr;
QHash<QString, Qt::CheckState> m_checkStateCache; // could be enhanced to store expanded as well
QHash<QString, Qt::CheckState> m_checkStateCache;
QHash<QString, int> m_itemUseCache;
};