refs #855, timeout support in view

* clear also hides indicator
* standard functions use timeout to hide indicator just in case something goes wrong
This commit is contained in:
Klaus Basan
2017-01-07 02:57:53 +01:00
committed by Mathew Sutcliffe
parent 6a1130100e
commit 02cbd8e00d
2 changed files with 59 additions and 19 deletions

View File

@@ -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 <class ModelClass, class ContainerType, class ObjectType>
BlackMisc::CWorker *CViewBase<ModelClass, ContainerType, ObjectType>::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 <class ModelClass, class ContainerType, class ObjectType>
void CViewBase<ModelClass, ContainerType, ObjectType>::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 <class ModelClass, class ContainerType, class ObjectType>
ObjectType CViewBase<ModelClass, ContainerType, ObjectType>::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 <class ModelClass, class ContainerType, class ObjectType>
void CViewBase<ModelClass, ContainerType, ObjectType>::clear()
{
Q_ASSERT(this->m_model);
this->m_model->clear();
this->hideLoadIndicator();
}
template <class ModelClass, class ContainerType, class ObjectType>
int CViewBase<ModelClass, ContainerType, ObjectType>::rowCount() const
{

View File

@@ -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;