Files
qelectrotech-source-mirror/sources/ElementsCollection/elementcollectionitem.h
T
ispyisail 79e87cb3b8 Set up the elements collection's items on the GUI thread
ElementsCollectionModel::loadCollections() runs setUpData() for every
item on worker threads (QtConcurrent::map), and setUpData() calls
setText(), setFlags(), setData() and setToolTip() on items that are
already in the model. Each of these changes the model and emits its
dataChanged() signal from a worker thread, which QAbstractItemModel
does not allow. Loading the shipped collection (8838 elements) emitted
dataChanged() 38958 times, all from worker threads.

The expensive part (reading every element file) stays on the worker
threads. Only the result is moved: ElementCollectionItem::setData()
keeps a value set from a worker thread on the item, data() returns it
to the same worker so setUpData() still reads back what it has set,
and the model applies the kept values on the GUI thread when the map
is finished, before emitting loadingFinished(). setUpData() called on
the GUI thread (macros collection, a single added or changed element)
is unchanged.

With this change the same load emits dataChanged() 38958 times, all on
the GUI thread.

Revives the still-needed part of #516, closed only to clear a review
backlog. Its other two changes are left out: the wait in
loadMacrosCollection() guarded a model shared with a running map,
which no longer happens (the macros always get a model of their own),
and qetinformation.h's static QString constants are a size clean-up,
not a bug.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 10:35:19 +13:00

75 lines
2.7 KiB
C++

/*
Copyright 2006-2026 The QElectroTech Team
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
QElectroTech is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ELEMENTCOLLECTIONITEM2_H
#define ELEMENTCOLLECTIONITEM2_H
#include <QHash>
#include <QStandardItem>
/**
@brief The ElementCollectionItem class
This class represent a item (a directory or an element) in a element collection.
This class must be herited for specialisation.
This item is used by ElementsCollectionModel for manage the elements collection
*/
class ElementCollectionItem : public QStandardItem
{
public:
ElementCollectionItem();
enum {Type = UserType+1};
int type() const override { return Type; }
virtual bool isDir() const = 0;
virtual bool isElement() const = 0;
virtual QString localName() = 0;
virtual QString name() const = 0;
virtual QString collectionPath() const = 0;
virtual bool isCollectionRoot() const = 0;
virtual void addChildAtPath(const QString &collection_name) = 0;
virtual void setUpData() = 0;
virtual void setUpIcon() = 0;
virtual void clearData();
ElementCollectionItem *lastItemForPath(const QString &path, QString &no_found_path);
ElementCollectionItem *childWithCollectionName(const QString& name) const;
QList<QStandardItem *> directChilds() const;
int rowForInsertItem(const QString &name);
ElementCollectionItem *itemAtPath(const QString &path);
QList<ElementCollectionItem *> elementsDirectChild() const;
QList<ElementCollectionItem *> directoriesDirectChild() const;
QList<ElementCollectionItem *> elementsChild() const;
QList<ElementCollectionItem *> directoriesChild() const;
QList<ElementCollectionItem *> items() const;
QVariant data(int role = Qt::UserRole + 1) const override;
void setData(const QVariant &value, int role = Qt::UserRole + 1) override;
void applyDeferredData();
private:
/// Values set by setUpData() while it runs on a worker thread,
/// see setData(). Only ever touched by that one worker thread,
/// until applyDeferredData() empties it on the GUI thread.
QHash<int, QVariant> m_deferred_data;
};
void setUpData(ElementCollectionItem *eci);
#endif // ELEMENTCOLLECTIONITEM2_H