1 
2 #include "progressindicator.h"
3 #include "global.h"
4 
5 #include <QApplication>
6 #include <QLayout>
7 #include <QBoxLayout>
8 #include <QLabel>
9 #include <QProgressBar>
10 #include <QToolTip>
11 
12 #include <KLocale>
13 
14 
TrailingAverage()15 TrailingAverage::TrailingAverage()
16 {
17     count = 10;
18 }
19 
~TrailingAverage()20 TrailingAverage::~TrailingAverage()
21 {}
22 
setCount(int _count)23 void TrailingAverage::setCount( int _count )
24 {
25     count = _count;
26 
27     while( deltaTime.count() > count )
28         deltaTime.removeFirst();
29 
30     while( deltaValue.count() > count )
31         deltaValue.removeFirst();
32 }
33 
addData(float _deltaTime,float _deltaValue)34 void TrailingAverage::addData( float _deltaTime, float _deltaValue )
35 {
36     while( deltaTime.count() > count )
37         deltaTime.removeFirst();
38 
39     while( deltaValue.count() > count )
40         deltaValue.removeFirst();
41 
42     deltaTime.append( _deltaTime );
43     deltaValue.append( _deltaValue );
44 }
45 
average()46 float TrailingAverage::average()
47 {
48     float _deltaTime = 0;
49     foreach( const float time, deltaTime )
50         _deltaTime += time;
51 
52     float _deltaValue = 0;
53     foreach( const float value, deltaValue )
54         _deltaValue += value;
55 
56     return _deltaValue / _deltaTime;
57 }
58 
59 
ProgressIndicator(QWidget * parent,Feature features)60 ProgressIndicator::ProgressIndicator( QWidget *parent, Feature features )
61     : QWidget( parent ),
62     lSpeed( 0 ),
63     lTime( 0 )
64 {
65     const int fontHeight = QFontMetrics(QApplication::font()).boundingRect("M").size().height();
66 
67     totalTime = processedTime = 0;
68 
69     QHBoxLayout *box = new QHBoxLayout( this );
70     box->setContentsMargins( 0, 0, 0, 0 );
71 
72     pBar = new QProgressBar( this );
73     box->addWidget( pBar, 0, Qt::AlignVCenter );
74     pBar->setRange( 0, 1 );
75     pBar->setValue( 0 );
76 
77     if( features != 0 )
78     {
79         box->addSpacing( 0.4*fontHeight );
80 
81         QGridLayout *statusChildGrid = new QGridLayout();
82         statusChildGrid->setContentsMargins( 0, 0, 0, 0 );
83         box->addLayout( statusChildGrid );
84         box->setAlignment( statusChildGrid, Qt::AlignVCenter );
85 
86         if( features & FeatureSpeed )
87         {
88             QLabel *lSpeedText = new QLabel( i18n("Speed:"), this );
89             statusChildGrid->addWidget( lSpeedText, 0, 0, Qt::AlignVCenter );
90 
91             QString actSpeed = "  0x";
92 
93             lSpeed = new QLabel( "<pre>" + actSpeed + "</pre>", this );
94             statusChildGrid->addWidget( lSpeed, 0, 1, Qt::AlignVCenter | Qt::AlignRight );
95 
96             speedAverage.setCount( 10 );
97         }
98 
99         if( features & FeatureTime )
100         {
101             QLabel *lTimeText = new QLabel( i18n("Remaining time:"), this );
102             statusChildGrid->addWidget( lTimeText, 1, 0, Qt::AlignVCenter );
103 
104             lTime = new QLabel( "<pre> 0s</pre>", this );
105             lTime->setFont( QFont( "Courier" ) );
106             statusChildGrid->addWidget( lTime, 1, 1, Qt::AlignVCenter | Qt::AlignRight );
107 
108             timeAverage.setCount( 60 );
109         }
110 
111         updateTime.setHMS( 24, 0, 0 );
112     }
113 }
114 
~ProgressIndicator()115 ProgressIndicator::~ProgressIndicator()
116 {}
117 
timeChanged(float timeDelta)118 void ProgressIndicator::timeChanged( float timeDelta )
119 {
120     totalTime += timeDelta;
121 
122     if( totalTime > 0 )
123         pBar->setRange( 0, (int)totalTime );
124     else
125         pBar->setRange( 0, 1 );
126 }
127 
timeFinished(float timeDelta)128 void ProgressIndicator::timeFinished( float timeDelta )
129 {
130     processedTime += timeDelta;
131 }
132 
finished(bool reset)133 void ProgressIndicator::finished( bool reset )
134 {
135     if( reset )
136     {
137         totalTime -= processedTime;
138         if( totalTime < 0 )
139             totalTime = 0.0f;
140     }
141 
142     processedTime = 0.0f;
143 
144     pBar->setRange( 0, totalTime > 0 ? (int)totalTime : 1 );
145     if( reset )
146         pBar->setValue( totalTime > 0 ? 0 : 1 );
147     else
148         pBar->setValue( pBar->maximum() );
149 
150     updateTime.setHMS( 24, 0, 0 );
151 
152     if( lTime )
153     {
154         lTime->setText( "<pre> 0s</pre>" );
155     }
156 
157     if( lSpeed )
158     {
159         QString actSpeed = "  0x";
160 
161         lSpeed->setText( "<pre>" + actSpeed + "</pre>" );
162     }
163 
164     emit progressChanged( i18n("Finished") );
165 }
166 
update(float timeProgress)167 void ProgressIndicator::update( float timeProgress )
168 {
169     const float currentProcessedTime = processedTime + timeProgress;
170 
171     pBar->setValue( (int)currentProcessedTime );
172 
173     const int iPercent = ( pBar->maximum() > 0 ) ? pBar->value() * 100 / pBar->maximum() : 0;
174 
175     if( lTime || lSpeed )
176     {
177         if( !updateTime.isValid() )
178             updateTime.start();
179 
180         if( updateTime.elapsed() >= 1000 )
181         {
182             const float deltaTime = updateTime.restart() / 1000;
183 
184             if( lTime )
185             {
186                 timeAverage.addData( deltaTime, currentProcessedTime - lastProcessedTime );
187                 const float remainingProcessTime = totalTime - currentProcessedTime;
188                 const float remainingTime = remainingProcessTime / timeAverage.average() + 1;
189 
190                 lTime->setText( "<pre>" + Global::prettyNumber(remainingTime,"s") + "</pre>" );
191             }
192 
193             if( lSpeed )
194             {
195                 speedAverage.addData( deltaTime, currentProcessedTime - lastProcessedTime );
196                 const float speed = speedAverage.average();
197 
198                 if( speed >= 0.0f && speed < 100000.0f )
199                 {
200                     QString speedString = QString::number(qRound(speed)) + "x";
201 
202                     if( speed < 10 )
203                         speedString = " " + speedString;
204 
205                     if( speed < 100 )
206                         speedString = " " + speedString;
207 
208                     lSpeed->setText( "<pre>" + speedString + "</pre>" );
209                 }
210             }
211 
212             lastProcessedTime = currentProcessedTime;
213         }
214     }
215 
216     emit progressChanged( QString::number(iPercent) + "%" );
217 }
218 
219