From f297e28b642fefc12924f7553670ba54eeb2f22e Mon Sep 17 00:00:00 2001 From: Claveau Joshua Date: Sun, 19 Jan 2020 11:53:40 +0100 Subject: [PATCH] Loading elements collections doesn't freeze gui anymore. --- .../elementcollectionitem.cpp | 3 +- .../elementscollectionmodel.cpp | 26 ++++---- .../elementscollectionmodel.h | 7 +- .../elementscollectionwidget.cpp | 65 ++++++++++++------- .../elementscollectionwidget.h | 4 +- .../ElementsCollection/elementslocation.cpp | 10 --- sources/ElementsCollection/elementslocation.h | 1 - 7 files changed, 64 insertions(+), 52 deletions(-) diff --git a/sources/ElementsCollection/elementcollectionitem.cpp b/sources/ElementsCollection/elementcollectionitem.cpp index f9599bd09..0293b36b3 100644 --- a/sources/ElementsCollection/elementcollectionitem.cpp +++ b/sources/ElementsCollection/elementcollectionitem.cpp @@ -240,7 +240,6 @@ QList ElementCollectionItem::items() const return list; } -void setUpData(ElementCollectionItem *eci) -{ +void setUpData(ElementCollectionItem *eci) { eci->setUpData(); } diff --git a/sources/ElementsCollection/elementscollectionmodel.cpp b/sources/ElementsCollection/elementscollectionmodel.cpp index b87d6575d..d8d09b94b 100644 --- a/sources/ElementsCollection/elementscollectionmodel.cpp +++ b/sources/ElementsCollection/elementscollectionmodel.cpp @@ -24,8 +24,8 @@ #include "qetproject.h" #include "elementcollectionhandler.h" +#include #include -#include /** * @brief ElementsCollectionModel::ElementsCollectionModel @@ -218,15 +218,16 @@ bool ElementsCollectionModel::dropMimeData(const QMimeData *data, Qt::DropAction * Load the several collections in this model. * Prefer use this method instead of addCommonCollection, addCustomCollection and addProject, * because it use multithreading to speed up the loading. - * This method emit loadingMaxValue(int) for know the maximum progress value - * This method emit loadingProgressValue(int) for know the current progress value + * This method emit loadingProgressRangeChanged(int, int) for know the minimu and maximum 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 custom_collection : true for load the custom collection * @param projects : list of projects to load */ void ElementsCollectionModel::loadCollections(bool common_collection, bool custom_collection, QList projects) { - QList list; + m_items_list_to_setUp.clear(); if (common_collection) addCommonCollection(false); @@ -234,20 +235,21 @@ void ElementsCollectionModel::loadCollections(bool common_collection, bool custo addCustomCollection(false); if (common_collection || custom_collection) - list.append(items()); + m_items_list_to_setUp.append(items()); for (QETProject *project : projects) { addProject(project, false); - list.append(projectItems(project)); - } - - emit loadingMaxValue(list.size()); - QFuture future = QtConcurrent::map(list, setUpData); - while (future.isRunning()) { - emit loadingProgressValue(future.progressValue()); + m_items_list_to_setUp.append(projectItems(project)); } + auto *watcher = new QFutureWatcher(); + connect(watcher, &QFutureWatcher::progressValueChanged, this, &ElementsCollectionModel::loadingProgressValueChanged); + connect(watcher, &QFutureWatcher::progressRangeChanged, this, &ElementsCollectionModel::loadingProgressRangeChanged); + connect(watcher, &QFutureWatcher::finished, this, &ElementsCollectionModel::loadingFinished); + connect(watcher, &QFutureWatcher::finished, watcher, &QFutureWatcher::deleteLater); + m_future = QtConcurrent::map(m_items_list_to_setUp, setUpData); + watcher->setFuture(m_future); } /** diff --git a/sources/ElementsCollection/elementscollectionmodel.h b/sources/ElementsCollection/elementscollectionmodel.h index deda87cce..266405e43 100644 --- a/sources/ElementsCollection/elementscollectionmodel.h +++ b/sources/ElementsCollection/elementscollectionmodel.h @@ -60,8 +60,9 @@ class ElementsCollectionModel : public QStandardItemModel QModelIndex indexFromLocation(const ElementsLocation &location); signals: - void loadingMaxValue(int); - void loadingProgressValue(int); + void loadingProgressValueChanged(int); + void loadingProgressRangeChanged(int, int); + void loadingFinished(); private: void elementIntegratedToCollection (const QString& path); @@ -72,6 +73,8 @@ class ElementsCollectionModel : public QStandardItemModel QList m_project_list; QHash m_project_hash; bool m_hide_element = false; + QFuture m_future; + QList m_items_list_to_setUp; }; #endif // ELEMENTSCOLLECTIONMODEL2_H diff --git a/sources/ElementsCollection/elementscollectionwidget.cpp b/sources/ElementsCollection/elementscollectionwidget.cpp index 1feac7981..05db3446f 100644 --- a/sources/ElementsCollection/elementscollectionwidget.cpp +++ b/sources/ElementsCollection/elementscollectionwidget.cpp @@ -83,20 +83,18 @@ void ElementsCollectionWidget::expandFirstItems() * Add @project to be displayed * @param project */ -void ElementsCollectionWidget::addProject(QETProject *project) { - if (m_model) { - QList prj; prj.append(project); +void ElementsCollectionWidget::addProject(QETProject *project) +{ + if (m_model) + { m_progress_bar->show(); - connect(m_model, &ElementsCollectionModel::loadingMaxValue, m_progress_bar, &QProgressBar::setMaximum); - connect(m_model, &ElementsCollectionModel::loadingProgressValue, m_progress_bar, &QProgressBar::setValue); + m_tree_view->setDisabled(true); + QList prj; prj.append(project); 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); + } } void ElementsCollectionWidget::removeProject(QETProject *project) { @@ -533,7 +531,9 @@ void ElementsCollectionWidget::dirProperties() void ElementsCollectionWidget::reload() { 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 project_list; project_list.append(m_waiting_project); @@ -541,23 +541,40 @@ void ElementsCollectionWidget::reload() if (m_model) 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); - connect(new_model, &ElementsCollectionModel::loadingProgressValue, m_progress_bar, &QProgressBar::setValue); + m_new_model->loadCollections(true, true, project_list); +} - 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_tree_view->setEnabled(true); } /** diff --git a/sources/ElementsCollection/elementscollectionwidget.h b/sources/ElementsCollection/elementscollectionwidget.h index 8b6ec8f20..3c9125eba 100644 --- a/sources/ElementsCollection/elementscollectionwidget.h +++ b/sources/ElementsCollection/elementscollectionwidget.h @@ -79,13 +79,15 @@ class ElementsCollectionWidget : public QWidget public slots: void reload(); + void loadingFinished(); private: void locationWasSaved(const ElementsLocation& location); private: - ElementsCollectionModel *m_model; + ElementsCollectionModel *m_model = nullptr; + ElementsCollectionModel *m_new_model = nullptr; QLineEdit *m_search_field; QTimer m_search_timer; ElementsTreeView *m_tree_view; diff --git a/sources/ElementsCollection/elementslocation.cpp b/sources/ElementsCollection/elementslocation.cpp index b77da5b60..517cd226c 100644 --- a/sources/ElementsCollection/elementslocation.cpp +++ b/sources/ElementsCollection/elementslocation.cpp @@ -125,16 +125,6 @@ QString ElementsLocation::baseName() const { 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 * Return the path of the represented element relative to collection diff --git a/sources/ElementsCollection/elementslocation.h b/sources/ElementsCollection/elementslocation.h index 2e2425c40..a3ca160ac 100644 --- a/sources/ElementsCollection/elementslocation.h +++ b/sources/ElementsCollection/elementslocation.h @@ -50,7 +50,6 @@ class ElementsLocation public: QString baseName() const; - int projectId() const; QString collectionPath(bool protocol = true) const; QString projectCollectionPath() const;