changeset 555:3f698e237585

* Pop view progress bars back into "indeterminate" mode if they are not updated for a couple of seconds (useful for plugins with very active getRemainingFeatures())
author Chris Cannam
date Fri, 12 Mar 2010 15:34:18 +0000
parents ffeafe09c8d9
children eabefd562995
files view/View.cpp view/View.h
diffstat 2 files changed, 78 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/view/View.cpp	Fri Jan 29 13:54:25 2010 +0000
+++ b/view/View.cpp	Fri Mar 12 15:34:18 2010 +0000
@@ -531,22 +531,27 @@
 
     m_layers.push_back(layer);
 
-//    m_progressBars[layer] = new LayerProgressBar(this);
-    m_progressBars[layer] = new QProgressBar(this);
-    m_progressBars[layer]->setMinimum(0);
-    m_progressBars[layer]->setMaximum(0);
-//    m_progressBars[layer]->setMaximum(100);
-//    m_progressBars[layer]->setMinimumWidth(80);
-    m_progressBars[layer]->setFixedWidth(80);
-//    m_progressBars[layer]->setText(""); //!!!
-    m_progressBars[layer]->setTextVisible(false);
-
-    QFont f(m_progressBars[layer]->font());
+    QProgressBar *pb = new QProgressBar(this);
+    pb->setMinimum(0);
+    pb->setMaximum(0);
+    pb->setFixedWidth(80);
+    pb->setTextVisible(false);
+
+    ProgressBarRec pbr;
+    pbr.bar = pb;
+    pbr.lastCheck = 0;
+    pbr.checkTimer = new QTimer();
+    connect(pbr.checkTimer, SIGNAL(timeout()), this,
+            SLOT(progressCheckStalledTimerElapsed()));
+
+    m_progressBars[layer] = pbr;
+
+    QFont f(pb->font());
     int fs = Preferences::getInstance()->getViewFontSize();
     f.setPointSize(std::min(fs, int(ceil(fs * 0.85))));
 
-    m_progressBars[layer]->setFont(f);
-    m_progressBars[layer]->hide();
+    pb->setFont(f);
+    pb->hide();
     
     connect(layer, SIGNAL(layerParametersChanged()),
 	    this,    SLOT(layerParametersChanged()));
@@ -586,7 +591,8 @@
 	if (*i == layer) {
 	    m_layers.erase(i);
 	    if (m_progressBars.find(layer) != m_progressBars.end()) {
-		delete m_progressBars[layer];
+		delete m_progressBars[layer].bar;
+		delete m_progressBars[layer].checkTimer;
 		m_progressBars.erase(layer);
 	    }
 	    break;
@@ -1406,11 +1412,18 @@
 
     int ph = height();
 
-    for (ProgressMap::const_iterator i = m_progressBars.begin();
+    for (ProgressMap::iterator i = m_progressBars.begin();
 	 i != m_progressBars.end(); ++i) {
 
+        QProgressBar *pb = i->second.bar;
+
 	if (i->first == object) {
 
+            // The timer is used to test for stalls.  If the progress
+            // bar does not get updated for some length of time, the
+            // timer prompts it to go back into "indeterminate" mode
+            QTimer *timer = i->second.checkTimer;
+
 	    int completion = i->first->getCompletion(this);
             QString text = i->first->getPropertyContainerName();
 
@@ -1419,7 +1432,7 @@
                 dynamic_cast<RangeSummarisableTimeValueModel *>(model);
 
             if (completion > 0) {
-                i->second->setMaximum(100); // was 0, for indeterminate start
+                pb->setMaximum(100); // was 0, for indeterminate start
             }
 
             if (completion >= 100) {
@@ -1441,34 +1454,62 @@
 
 	    if (completion >= 100) {
 
-		i->second->hide();
+		pb->hide();
+                timer->stop();
 
 	    } else {
 
-//		i->second->setText(text);
-
-		i->second->setValue(completion);
-		i->second->move(0, ph - i->second->height());
-
-		i->second->show();
-		i->second->update();
-
-		ph -= i->second->height();
+//                std::cerr << "progress = " << completion << std::endl;
+
+                if (!pb->isVisible()) {
+                    i->second.lastCheck = 0;
+                    timer->setInterval(2000);
+                    timer->start();
+                }
+
+		pb->setValue(completion);
+		pb->move(0, ph - pb->height());
+
+		pb->show();
+		pb->update();
+
+		ph -= pb->height();
 	    }
 	} else {
-	    if (i->second->isVisible()) {
-		ph -= i->second->height();
+	    if (pb->isVisible()) {
+		ph -= pb->height();
 	    }
 	}
     }
 }
 
+void
+View::progressCheckStalledTimerElapsed()
+{
+    QObject *s = sender();
+    QTimer *t = qobject_cast<QTimer *>(s);
+    if (!t) return;
+    for (ProgressMap::iterator i =  m_progressBars.begin();
+         i != m_progressBars.end(); ++i) {
+        if (i->second.checkTimer == t) {
+            int value = i->second.bar->value();
+            if (value > 0 && value == i->second.lastCheck) {
+                i->second.bar->setMaximum(0); // indeterminate
+            }
+            i->second.lastCheck = value;
+            return;
+        }
+    }
+}
+
 int
 View::getProgressBarWidth() const
 {
     for (ProgressMap::const_iterator i = m_progressBars.begin();
 	 i != m_progressBars.end(); ++i) {
-        if (i->second && i->second->isVisible()) return i->second->width();
+        if (i->second.bar && i->second.bar->isVisible()) {
+            return i->second.bar->width();
+        }
     }
 
     return 0;
--- a/view/View.h	Fri Jan 29 13:54:25 2010 +0000
+++ b/view/View.h	Fri Mar 12 15:34:18 2010 +0000
@@ -305,6 +305,8 @@
     virtual void overlayModeChanged();
     virtual void zoomWheelsEnabledChanged();
 
+    virtual void progressCheckStalledTimerElapsed();
+
 protected:
     View(QWidget *, bool showProgress);
     virtual void paintEvent(QPaintEvent *e);
@@ -373,8 +375,12 @@
 	QString m_text;
     };
 
-//    typedef std::map<Layer *, LayerProgressBar *> ProgressMap;
-    typedef std::map<Layer *, QProgressBar *> ProgressMap;
+    struct ProgressBarRec {
+        QProgressBar *bar;
+        int lastCheck;
+        QTimer *checkTimer;
+    };
+    typedef std::map<Layer *, ProgressBarRec> ProgressMap;
     ProgressMap m_progressBars; // I own the ProgressBars
 
     ViewManager *m_manager; // I don't own this