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