From 02cbd8e00de273fee51e9604c28bf84f1352a155 Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Sat, 7 Jan 2017 02:57:53 +0100 Subject: [PATCH] refs #855, timeout support in view * clear also hides indicator * standard functions use timeout to hide indicator just in case something goes wrong --- src/blackgui/views/viewbase.cpp | 61 ++++++++++++++++++++++++--------- src/blackgui/views/viewbase.h | 17 +++++++-- 2 files changed, 59 insertions(+), 19 deletions(-) diff --git a/src/blackgui/views/viewbase.cpp b/src/blackgui/views/viewbase.cpp index a28c49f46..c429dc6b0 100644 --- a/src/blackgui/views/viewbase.cpp +++ b/src/blackgui/views/viewbase.cpp @@ -289,7 +289,7 @@ namespace BlackGui if (m_showingLoadIndicator) { // just in case, if this ever will be dangling - menuActions.addAction(BlackMisc::CIcons::preloader16(), "Hide load indicator", CMenuAction::pathViewUpdates(), nullptr, { this, &CViewBaseNonTemplate::hideLoadIndicator }); + menuActions.addAction(BlackMisc::CIcons::preloader16(), "Hide load indicator", CMenuAction::pathViewUpdates(), nullptr, { this, &CViewBaseNonTemplate::ps_hideLoadIndicator }); } if (this->m_menus.testFlag(MenuClear)) { menuActions.addActions(this->initMenuActions(MenuClear)); } @@ -537,16 +537,21 @@ namespace BlackGui void CViewBaseNonTemplate::ps_triggerReload() { - this->showLoadIndicator(); + this->showLoadIndicatorWithTimeout(this->m_loadIndicatorTimeoutMsDefault); emit this->requestUpdate(); } void CViewBaseNonTemplate::ps_triggerReloadFromBackend() { - this->showLoadIndicator(); + this->showLoadIndicatorWithTimeout(this->m_loadIndicatorTimeoutMsDefault); emit this->requestNewBackendData(); } + void CViewBaseNonTemplate::ps_hideLoadIndicator() + { + this->hideLoadIndicator(); + } + void CViewBaseNonTemplate::onModelChanged() { this->updateSortIndicator(); @@ -570,19 +575,19 @@ namespace BlackGui this->m_rowResizeMode = Content; } - void CViewBaseNonTemplate::showLoadIndicator(int containerSizeDependent, bool processEvents) + int CViewBaseNonTemplate::showLoadIndicator(int containerSizeDependent, int timeoutMs, bool processEvents) { - if (!m_enabledLoadIndicator) { return; } - if (this->m_showingLoadIndicator) { return; } + if (!this->m_enabledLoadIndicator) { return -1; } + if (this->m_showingLoadIndicator) { return -1; } if (this->hasDockWidgetArea()) { - if (!this->isVisibleWidget()) { return; } + if (!this->isVisibleWidget()) { return -1; } } if (containerSizeDependent >= 0) { // really with indicator? - if (containerSizeDependent < ResizeSubsetThreshold) { return; } + if (containerSizeDependent < ResizeSubsetThreshold) { return -1; } } this->m_showingLoadIndicator = true; emit loadIndicatorVisibilityChanged(this->m_showingLoadIndicator); @@ -592,7 +597,12 @@ namespace BlackGui this->m_loadIndicator = new CLoadIndicator(64, 64, this); } this->centerLoadIndicator(); - this->m_loadIndicator->startAnimation(processEvents); + return this->m_loadIndicator->startAnimation(timeoutMs > 0 ? timeoutMs : this->m_loadIndicatorTimeoutMsDefault, processEvents); + } + + int CViewBaseNonTemplate::showLoadIndicatorWithTimeout(int timeoutMs, bool processEvents) + { + return this->showLoadIndicator(-1, timeoutMs, processEvents); } void CViewBaseNonTemplate::centerLoadIndicator() @@ -602,13 +612,13 @@ namespace BlackGui this->m_loadIndicator->centerLoadIndicator(middle); } - void CViewBaseNonTemplate::hideLoadIndicator() + void CViewBaseNonTemplate::hideLoadIndicator(int loadingId) { if (!this->m_showingLoadIndicator) { return; } this->m_showingLoadIndicator = false; emit loadIndicatorVisibilityChanged(this->m_showingLoadIndicator); if (!this->m_loadIndicator) { return; } - this->m_loadIndicator->stopAnimation(); + this->m_loadIndicator->stopAnimation(loadingId); } bool CViewBaseNonTemplate::isResizeConditionMet(int containerSize) const @@ -824,6 +834,13 @@ namespace BlackGui template BlackMisc::CWorker *CViewBase::updateContainerAsync(const ContainerType &container, bool sort, bool resize) { + // avoid unnecessary effort when empty + if (container.isEmpty()) + { + this->clear(); + return nullptr; + } + Q_UNUSED(sort); ModelClass *model = this->derivedModel(); auto sortColumn = model->getSortColumn(); @@ -844,7 +861,11 @@ namespace BlackGui template void CViewBase::updateContainerMaybeAsync(const ContainerType &container, bool sort, bool resize) { - if (container.size() > ASyncRowsCountThreshold && sort) + if (container.isEmpty()) + { + this->clear(); + } + else if (container.size() > ASyncRowsCountThreshold && sort) { // larger container with sorting this->updateContainerAsync(container, sort, resize); @@ -986,7 +1007,7 @@ namespace BlackGui template ObjectType CViewBase::selectedObject() const { - ContainerType c = this->selectedObjects(); + const ContainerType c = this->selectedObjects(); return c.frontOrDefault(); } @@ -996,21 +1017,21 @@ namespace BlackGui if (!this->hasSelection()) { return 0; } if (this->isEmpty()) { return 0; } - int currentRows = this->rowCount(); + const int currentRows = this->rowCount(); if (currentRows == selectedRowCount()) { this->clear(); return currentRows; } - ContainerType selected(selectedObjects()); + const ContainerType selected(selectedObjects()); ContainerType newObjects(container()); for (const ObjectType &obj : selected) { newObjects.remove(obj); } - int delta = currentRows - newObjects.size(); + const int delta = currentRows - newObjects.size(); this->updateContainerMaybeAsync(newObjects); return delta; } @@ -1054,6 +1075,14 @@ namespace BlackGui this->updateContainerMaybeAsync(filtered); } + template + void CViewBase::clear() + { + Q_ASSERT(this->m_model); + this->m_model->clear(); + this->hideLoadIndicator(); + } + template int CViewBase::rowCount() const { diff --git a/src/blackgui/views/viewbase.h b/src/blackgui/views/viewbase.h index 0bab2e5a6..bdcb464eb 100644 --- a/src/blackgui/views/viewbase.h +++ b/src/blackgui/views/viewbase.h @@ -313,14 +313,21 @@ namespace BlackGui //! Show loading indicator //! \param containerSizeDependent check against resize threshold if indicator makes sense + //! \param timeoutMs timeout the loading indicator //! \param processEvents force event processing to display indicator by updating GUI - void showLoadIndicator(int containerSizeDependent = -1, bool processEvents = true); + int showLoadIndicator(int containerSizeDependent = -1, int timeoutMs = -1, bool processEvents = true); + + //! Show loading indicator which can time out + int showLoadIndicatorWithTimeout(int timeoutMs = -1, bool processEvents = true); + + //! Load indicator's default time (ms) + void setLoadIndicatorTimeoutDefaultTime(int timeoutMs) { m_loadIndicatorTimeoutMsDefault = timeoutMs; } //! Underlying model changed void onModelChanged(); //! Hide loading indicator - void hideLoadIndicator(); + void hideLoadIndicator(int loadingId = -1); //! Remove selected rows virtual int removeSelectedRows() = 0; @@ -399,6 +406,7 @@ namespace BlackGui int m_resizeCount = 0; //!< flag / counter, how many resize activities int m_skipResizeThreshold = 40; //!< when to skip resize (rows count) int m_resizeAutoNthTime = 1; //!< with ResizeAuto, resize every n-th time + int m_loadIndicatorTimeoutMsDefault = 30 * 1000; //!< default time for timeout bool m_forceStretchLastColumnWhenResized = false; //!< a small table might (few columns) might to fail stretching, force again bool m_showingLoadIndicator = false; //!< showing loading indicator bool m_enabledLoadIndicator = true; //!< loading indicator enabled/disabled @@ -458,6 +466,9 @@ namespace BlackGui //! Trigger reload from backend by signal requestNewBackendData() void ps_triggerReloadFromBackend(); + //! Hide load indicator (no parameters) + void ps_hideLoadIndicator(); + // ------------ slots of CViewDbObjects ---------------- // need to be declared here and overridden, as this is the only part with valid Q_OBJECT @@ -589,7 +600,7 @@ namespace BlackGui //! \name BlackGui::Views::CViewBaseNonTemplate implementations //! @{ - virtual void clear() override { Q_ASSERT(this->m_model); this->m_model->clear(); } + virtual void clear() override; virtual int rowCount() const override; virtual bool isEmpty() const override; virtual bool isOrderable() const override;