Loading elements collections doesn't freeze gui anymore.

This commit is contained in:
Claveau Joshua 2020-01-19 11:53:40 +01:00
parent ed2e72e995
commit f297e28b64
7 changed files with 64 additions and 52 deletions

View File

@ -240,7 +240,6 @@ QList<ElementCollectionItem *> ElementCollectionItem::items() const
return list; return list;
} }
void setUpData(ElementCollectionItem *eci) void setUpData(ElementCollectionItem *eci) {
{
eci->setUpData(); eci->setUpData();
} }

View File

@ -24,8 +24,8 @@
#include "qetproject.h" #include "qetproject.h"
#include "elementcollectionhandler.h" #include "elementcollectionhandler.h"
#include <QFutureWatcher>
#include <QtConcurrent> #include <QtConcurrent>
#include <QMessageBox>
/** /**
* @brief ElementsCollectionModel::ElementsCollectionModel * @brief ElementsCollectionModel::ElementsCollectionModel
@ -218,15 +218,16 @@ bool ElementsCollectionModel::dropMimeData(const QMimeData *data, Qt::DropAction
* Load the several collections in this model. * Load the several collections in this model.
* Prefer use this method instead of addCommonCollection, addCustomCollection and addProject, * Prefer use this method instead of addCommonCollection, addCustomCollection and addProject,
* because it use multithreading to speed up the loading. * because it use multithreading to speed up the loading.
* This method emit loadingMaxValue(int) for know the maximum progress value * This method emit loadingProgressRangeChanged(int, int) for know the minimu and maximum progress value
* This method emit loadingProgressValue(int) for know the current progress value * This method emit loadingProgressValueChanged(int) for know the current progress value
* This method emit loadingFinished for know when loading finished.
* @param common_collection : true for load the common collection * @param common_collection : true for load the common collection
* @param custom_collection : true for load the custom collection * @param custom_collection : true for load the custom collection
* @param projects : list of projects to load * @param projects : list of projects to load
*/ */
void ElementsCollectionModel::loadCollections(bool common_collection, bool custom_collection, QList<QETProject *> projects) void ElementsCollectionModel::loadCollections(bool common_collection, bool custom_collection, QList<QETProject *> projects)
{ {
QList <ElementCollectionItem *> list; m_items_list_to_setUp.clear();
if (common_collection) if (common_collection)
addCommonCollection(false); addCommonCollection(false);
@ -234,20 +235,21 @@ void ElementsCollectionModel::loadCollections(bool common_collection, bool custo
addCustomCollection(false); addCustomCollection(false);
if (common_collection || custom_collection) if (common_collection || custom_collection)
list.append(items()); m_items_list_to_setUp.append(items());
for (QETProject *project : projects) for (QETProject *project : projects)
{ {
addProject(project, false); addProject(project, false);
list.append(projectItems(project)); m_items_list_to_setUp.append(projectItems(project));
}
emit loadingMaxValue(list.size());
QFuture<void> future = QtConcurrent::map(list, setUpData);
while (future.isRunning()) {
emit loadingProgressValue(future.progressValue());
} }
auto *watcher = new QFutureWatcher<void>();
connect(watcher, &QFutureWatcher<void>::progressValueChanged, this, &ElementsCollectionModel::loadingProgressValueChanged);
connect(watcher, &QFutureWatcher<void>::progressRangeChanged, this, &ElementsCollectionModel::loadingProgressRangeChanged);
connect(watcher, &QFutureWatcher<void>::finished, this, &ElementsCollectionModel::loadingFinished);
connect(watcher, &QFutureWatcher<void>::finished, watcher, &QFutureWatcher<void>::deleteLater);
m_future = QtConcurrent::map(m_items_list_to_setUp, setUpData);
watcher->setFuture(m_future);
} }
/** /**

View File

@ -60,8 +60,9 @@ class ElementsCollectionModel : public QStandardItemModel
QModelIndex indexFromLocation(const ElementsLocation &location); QModelIndex indexFromLocation(const ElementsLocation &location);
signals: signals:
void loadingMaxValue(int); void loadingProgressValueChanged(int);
void loadingProgressValue(int); void loadingProgressRangeChanged(int, int);
void loadingFinished();
private: private:
void elementIntegratedToCollection (const QString& path); void elementIntegratedToCollection (const QString& path);
@ -72,6 +73,8 @@ class ElementsCollectionModel : public QStandardItemModel
QList <QETProject *> m_project_list; QList <QETProject *> m_project_list;
QHash <QETProject *, XmlProjectElementCollectionItem *> m_project_hash; QHash <QETProject *, XmlProjectElementCollectionItem *> m_project_hash;
bool m_hide_element = false; bool m_hide_element = false;
QFuture<void> m_future;
QList <ElementCollectionItem *> m_items_list_to_setUp;
}; };
#endif // ELEMENTSCOLLECTIONMODEL2_H #endif // ELEMENTSCOLLECTIONMODEL2_H

View File

@ -83,20 +83,18 @@ void ElementsCollectionWidget::expandFirstItems()
* Add @project to be displayed * Add @project to be displayed
* @param project * @param project
*/ */
void ElementsCollectionWidget::addProject(QETProject *project) { void ElementsCollectionWidget::addProject(QETProject *project)
if (m_model) { {
QList <QETProject *> prj; prj.append(project); if (m_model)
{
m_progress_bar->show(); m_progress_bar->show();
connect(m_model, &ElementsCollectionModel::loadingMaxValue, m_progress_bar, &QProgressBar::setMaximum); m_tree_view->setDisabled(true);
connect(m_model, &ElementsCollectionModel::loadingProgressValue, m_progress_bar, &QProgressBar::setValue); QList <QETProject *> prj; prj.append(project);
m_model->loadCollections(false,false, prj); m_model->loadCollections(false,false, prj);
disconnect(m_model, &ElementsCollectionModel::loadingMaxValue, m_progress_bar, &QProgressBar::setMaximum);
disconnect(m_model, &ElementsCollectionModel::loadingProgressValue, m_progress_bar, &QProgressBar::setValue);
m_progress_bar->hide();
m_model->highlightUnusedElement();
} }
else else {
m_waiting_project.append(project); m_waiting_project.append(project);
}
} }
void ElementsCollectionWidget::removeProject(QETProject *project) { void ElementsCollectionWidget::removeProject(QETProject *project) {
@ -533,7 +531,9 @@ void ElementsCollectionWidget::dirProperties()
void ElementsCollectionWidget::reload() void ElementsCollectionWidget::reload()
{ {
m_progress_bar->show(); m_progress_bar->show();
ElementsCollectionModel *new_model = new ElementsCollectionModel(m_tree_view); m_progress_bar->setValue(1); //Force to repaint now, else progress bar will be not displayed immediately
m_tree_view->setDisabled(true);
m_tree_view->repaint(); //Force to repaint now, else tree view will be not disabled immediately
QList <QETProject *> project_list; QList <QETProject *> project_list;
project_list.append(m_waiting_project); project_list.append(m_waiting_project);
@ -541,23 +541,40 @@ void ElementsCollectionWidget::reload()
if (m_model) if (m_model)
project_list.append(m_model->project()); project_list.append(m_model->project());
if(m_new_model) {
m_new_model->deleteLater();
}
m_new_model = new ElementsCollectionModel(m_tree_view);
connect(m_new_model, &ElementsCollectionModel::loadingProgressRangeChanged, m_progress_bar, &QProgressBar::setRange);
connect(m_new_model, &ElementsCollectionModel::loadingProgressValueChanged, m_progress_bar, &QProgressBar::setValue);
connect(m_new_model, &ElementsCollectionModel::loadingFinished, this, &ElementsCollectionWidget::loadingFinished);
connect(new_model, &ElementsCollectionModel::loadingMaxValue, m_progress_bar, &QProgressBar::setMaximum); m_new_model->loadCollections(true, true, project_list);
connect(new_model, &ElementsCollectionModel::loadingProgressValue, m_progress_bar, &QProgressBar::setValue); }
new_model->loadCollections(true, true, project_list); /**
* @brief ElementsCollectionWidget::loadingFinished
* Process when collection finished to be loaded
*/
void ElementsCollectionWidget::loadingFinished()
{
if (m_new_model)
{
m_new_model->highlightUnusedElement();
m_tree_view->setModel(m_new_model);
m_index_at_context_menu = QModelIndex();
m_showed_index = QModelIndex();
if (m_model) delete m_model;
m_model = m_new_model;
m_new_model = nullptr;
expandFirstItems();
}
else {
m_model->highlightUnusedElement();
}
disconnect(new_model, &ElementsCollectionModel::loadingMaxValue, m_progress_bar, &QProgressBar::setMaximum);
disconnect(new_model, &ElementsCollectionModel::loadingProgressValue, m_progress_bar, &QProgressBar::setValue);
new_model->highlightUnusedElement();
m_tree_view->setModel(new_model);
m_index_at_context_menu = QModelIndex();
m_showed_index = QModelIndex();
if (m_model) delete m_model;
m_model = new_model;
expandFirstItems();
m_progress_bar->hide(); m_progress_bar->hide();
m_tree_view->setEnabled(true);
} }
/** /**

View File

@ -79,13 +79,15 @@ class ElementsCollectionWidget : public QWidget
public slots: public slots:
void reload(); void reload();
void loadingFinished();
private: private:
void locationWasSaved(const ElementsLocation& location); void locationWasSaved(const ElementsLocation& location);
private: private:
ElementsCollectionModel *m_model; ElementsCollectionModel *m_model = nullptr;
ElementsCollectionModel *m_new_model = nullptr;
QLineEdit *m_search_field; QLineEdit *m_search_field;
QTimer m_search_timer; QTimer m_search_timer;
ElementsTreeView *m_tree_view; ElementsTreeView *m_tree_view;

View File

@ -125,16 +125,6 @@ QString ElementsLocation::baseName() const {
return(QString()); return(QString());
} }
/**
* @brief ElementsLocation::projectId
* This method is used to know if an element belongs to
* a project or not.
* @return Element Project Id
*/
int ElementsLocation::projectId() const {
return QETApp::projectId(m_project);
}
/** /**
* @brief ElementsLocation::collectionPath * @brief ElementsLocation::collectionPath
* Return the path of the represented element relative to collection * Return the path of the represented element relative to collection

View File

@ -50,7 +50,6 @@ class ElementsLocation
public: public:
QString baseName() const; QString baseName() const;
int projectId() const;
QString collectionPath(bool protocol = true) const; QString collectionPath(bool protocol = true) const;
QString projectCollectionPath() const; QString projectCollectionPath() const;