diff --git a/sources/TerminalStrip/ui/terminalstripeditorwindow.cpp b/sources/TerminalStrip/ui/terminalstripeditorwindow.cpp index cc1d86a94..ef7538c49 100644 --- a/sources/TerminalStrip/ui/terminalstripeditorwindow.cpp +++ b/sources/TerminalStrip/ui/terminalstripeditorwindow.cpp @@ -52,6 +52,8 @@ TerminalStripEditorWindow *TerminalStripEditorWindow::instance(QETProject *proje { QProgressDialog busy_(tr("Opening the terminal block manager..."), QString(), 0, 0, parent); busy_.setWindowTitle(tr("Terminal block manager")); + //Only a title : nothing to minimize, maximize or close + busy_.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint); busy_.setWindowModality(Qt::ApplicationModal); busy_.setCancelButton(nullptr); busy_.setMinimumDuration(0); @@ -74,6 +76,23 @@ TerminalStripEditorWindow *TerminalStripEditorWindow::instance(QETProject *proje QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents); QApplication::setOverrideCursor(Qt::WaitCursor); + //The folios not built yet (lazy folios) are built now : show the + //progress, and run the event loop between two folios, so that the + //window system still gets answers (else the message is said + //"not responding") + if (project) + { + project->setFolioBuildObserver([&busy_](int built, int total) + { + if (busy_.maximum() != total) { + busy_.setMaximum(total); + } + busy_.setLabelText(tr("Reading folio %1 of %2...").arg(built).arg(total)); + busy_.setValue(built); + QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents); + }); + } + static QMutex mutex_; if (!window_) { mutex_.lock(); @@ -84,6 +103,9 @@ TerminalStripEditorWindow *TerminalStripEditorWindow::instance(QETProject *proje window_->setProject(project); } + if (project) { + project->setFolioBuildObserver({}); + } QApplication::restoreOverrideCursor(); return window_; } diff --git a/sources/qetproject.cpp b/sources/qetproject.cpp index c63d09602..23034f30e 100644 --- a/sources/qetproject.cpp +++ b/sources/qetproject.cpp @@ -407,6 +407,11 @@ void QETProject::init() m_autosave_timer.setInterval(ms); connect(&m_autosave_timer, &QTimer::timeout, this, [this]() { + //Not while folios are being built (the event loop can run + //then, see setFolioBuildObserver()) : the next time + if (this->m_state == ProjectParsingRunning) { + return; + } if(!this->m_file_path.isEmpty()) { //No one is there to ask: a file changed behind this @@ -762,6 +767,18 @@ void QETProject::loadFolios() const buildFolios(m_diagrams_list); } +/** + @brief QETProject::setFolioBuildObserver + @p observer is called after each folio built by buildFolios(), with the + number of folios built so far and the number to build : a long build + can show its progress, and keep the window system answered by running + the event loop (without the user input) in @p observer. The autosave + waits meanwhile. An empty function removes the observer. +*/ +void QETProject::setFolioBuildObserver(std::function observer) { + m_folio_build_observer = std::move(observer); +} + /** @brief QETProject::buildFolios Build those of @p folios still waiting, as opening builds them: all @@ -785,8 +802,23 @@ void QETProject::buildFolios(const QList &folios) const const bool signals_were_blocked = self->m_data_base.signalsBlocked(); self->m_data_base.blockSignals(true); QList built; + int waiting_ = 0; + if (m_folio_build_observer) { + for (Diagram *d : folios) + if (!d->isLoaded()) ++waiting_; + } for (Diagram *d : folios) - if (d->buildDeferred()) built << d; + { + if (d->buildDeferred()) + { + built << d; + //Someone shows the progress (a long build, opening the + //terminal block manager...) + if (m_folio_build_observer) { + m_folio_build_observer(built.size(), waiting_); + } + } + } for (Diagram *d : std::as_const(built)) self->folioLoaded(d); self->m_data_base.blockSignals(signals_were_blocked); diff --git a/sources/qetproject.h b/sources/qetproject.h index aeb87a1b5..437112fcf 100644 --- a/sources/qetproject.h +++ b/sources/qetproject.h @@ -18,6 +18,7 @@ #ifndef QET_PROJECT_H #define QET_PROJECT_H +#include #include "ElementsCollection/elementslocation.h" #include "NameList/nameslist.h" #include "project/projectpropertieshandler.h" @@ -150,6 +151,7 @@ class QETProject : public QObject QSet tableChainFolios(Diagram *folio) const; void loadFolios() const; void buildFolios(const QList &folios) const; + void setFolioBuildObserver(std::function observer); void folioLoaded(Diagram *folio); int folioIndex(const Diagram *) const; XmlElementCollection *embeddedElementCollection()const; @@ -625,6 +627,8 @@ class QETProject : public QObject QHash> m_shared_uuid_keepers; //symbol and wire uuids the file carries, see derivedItemUuid() projectDataBase m_data_base; QVector m_terminal_strip_vector; + //Called after each folio built, see setFolioBuildObserver() + std::function m_folio_build_observer; QVector m_cables; ProjectPropertiesHandler m_project_properties_handler;