]> git.saurik.com Git - apt.git/blame - apt-pkg/contrib/progress.cc
* merged from apt--mvo
[apt.git] / apt-pkg / contrib / progress.cc
CommitLineData
404ec98e
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
82c6b98d 3// $Id: progress.cc,v 1.12 2003/01/11 07:17:04 jgg Exp $
404ec98e
AL
4/* ######################################################################
5
6 OpProgress - Operation Progress
7
8 ##################################################################### */
9 /*}}}*/
10// Include Files /*{{{*/
404ec98e 11#include <apt-pkg/progress.h>
6f4f200a 12#include <apt-pkg/error.h>
0a8e3465 13#include <apt-pkg/configuration.h>
b2e465d6
AL
14
15#include <apti18n.h>
4d055c05
AL
16
17#include <iostream>
404ec98e
AL
18#include <stdio.h>
19 /*}}}*/
20
4d055c05
AL
21using namespace std;
22
404ec98e
AL
23// OpProgress::OpProgress - Constructor /*{{{*/
24// ---------------------------------------------------------------------
25/* */
26OpProgress::OpProgress() : Current(0), Total(0), Size(0), SubTotal(1),
27 LastPercent(0), Percent(0)
28{
29 memset(&LastTime,0,sizeof(LastTime));
30}
31 /*}}}*/
32// OpProgress::Progress - Sub progress with no state change /*{{{*/
33// ---------------------------------------------------------------------
a246f2dc
AL
34/* Current is the Base Overall progress in units of Total. Cur is the sub
35 progress in units of SubTotal. Size is a scaling factor that says what
36 percent of Total SubTotal is. */
404ec98e
AL
37void OpProgress::Progress(unsigned long Cur)
38{
77b9dbc2
AL
39 if (Total == 0 || Size == 0 || SubTotal == 0)
40 Percent = 0;
41 else
42 Percent = (Current + Cur/((float)SubTotal)*Size)*100.0/Total;
404ec98e
AL
43 Update();
44}
45 /*}}}*/
46// OpProgress::OverallProgress - Set the overall progress /*{{{*/
47// ---------------------------------------------------------------------
48/* */
49void OpProgress::OverallProgress(unsigned long Current, unsigned long Total,
171c75f1 50 unsigned long Size,const string &Op)
404ec98e
AL
51{
52 this->Current = Current;
53 this->Total = Total;
54 this->Size = Size;
55 this->Op = Op;
56 SubOp = string();
77b9dbc2
AL
57 if (Total == 0)
58 Percent = 0;
59 else
60 Percent = Current*100.0/Total;
404ec98e
AL
61 Update();
62}
63 /*}}}*/
64// OpProgress::SubProgress - Set the sub progress state /*{{{*/
65// ---------------------------------------------------------------------
66/* */
171c75f1 67void OpProgress::SubProgress(unsigned long SubTotal,const string &Op)
404ec98e
AL
68{
69 this->SubTotal = SubTotal;
70 SubOp = Op;
77b9dbc2
AL
71 if (Total == 0)
72 Percent = 0;
73 else
74 Percent = Current*100.0/Total;
404ec98e
AL
75 Update();
76}
77 /*}}}*/
8ce4327b
AL
78// OpProgress::SubProgress - Set the sub progress state /*{{{*/
79// ---------------------------------------------------------------------
80/* */
81void OpProgress::SubProgress(unsigned long SubTotal)
82{
83 this->SubTotal = SubTotal;
77b9dbc2
AL
84 if (Total == 0)
85 Percent = 0;
86 else
87 Percent = Current*100.0/Total;
8ce4327b
AL
88 Update();
89}
90 /*}}}*/
404ec98e
AL
91// OpProgress::CheckChange - See if the display should be updated /*{{{*/
92// ---------------------------------------------------------------------
93/* Progress calls are made so frequently that if every one resulted in
94 an update the display would be swamped and the system much slower.
95 This provides an upper bound on the update rate. */
96bool OpProgress::CheckChange(float Interval)
97{
98 // New major progress indication
99 if (Op != LastOp)
100 {
101 MajorChange = true;
102 LastOp = Op;
103 return true;
104 }
105 MajorChange = false;
106
1a7c9eba
AL
107 if (SubOp != LastSubOp)
108 {
109 LastSubOp = SubOp;
110 return true;
111 }
112
404ec98e
AL
113 if ((int)LastPercent == (int)Percent)
114 return false;
61ec2779
MV
115
116 LastPercent = Percent;
404ec98e 117
b2e465d6
AL
118 if (Interval == 0)
119 return false;
120
404ec98e
AL
121 // Check time delta
122 struct timeval Now;
123 gettimeofday(&Now,0);
124 double Diff = Now.tv_sec - LastTime.tv_sec + (Now.tv_usec - LastTime.tv_usec)/1000000.0;
125 if (Diff < Interval)
126 return false;
127 LastTime = Now;
128 return true;
129}
130 /*}}}*/
0a8e3465
AL
131// OpTextProgress::OpTextProgress - Constructor /*{{{*/
132// ---------------------------------------------------------------------
133/* */
134OpTextProgress::OpTextProgress(Configuration &Config) :
135 NoUpdate(false), NoDisplay(false), LastLen(0)
136{
137 if (Config.FindI("quiet",0) >= 1)
138 NoUpdate = true;
139 if (Config.FindI("quiet",0) >= 2)
140 NoDisplay = true;
141};
142 /*}}}*/
404ec98e
AL
143// OpTextProgress::Done - Clean up the display /*{{{*/
144// ---------------------------------------------------------------------
145/* */
146void OpTextProgress::Done()
147{
148 if (NoUpdate == false && OldOp.empty() == false)
149 {
150 char S[300];
6f4f200a 151 if (_error->PendingError() == true)
82c6b98d 152 snprintf(S,sizeof(S),_("%c%s... Error!"),'\r',OldOp.c_str());
b35d2f5f 153 else
82c6b98d 154 snprintf(S,sizeof(S),_("%c%s... Done"),'\r',OldOp.c_str());
404ec98e
AL
155 Write(S);
156 cout << endl;
157 OldOp = string();
0a8e3465
AL
158 }
159
160 if (NoUpdate == true && NoDisplay == false && OldOp.empty() == false)
161 {
162 OldOp = string();
163 cout << endl;
164 }
404ec98e
AL
165}
166 /*}}}*/
167// OpTextProgress::Update - Simple text spinner /*{{{*/
168// ---------------------------------------------------------------------
169/* */
170void OpTextProgress::Update()
171{
b2e465d6 172 if (CheckChange((NoUpdate == true?0:0.7)) == false)
404ec98e
AL
173 return;
174
175 // No percent spinner
176 if (NoUpdate == true)
177 {
178 if (MajorChange == false)
179 return;
0a8e3465
AL
180 if (NoDisplay == false)
181 {
182 if (OldOp.empty() == false)
183 cout << endl;
184 OldOp = "a";
185 cout << Op << "..." << flush;
186 }
187
404ec98e
AL
188 return;
189 }
190
191 // Erase the old text and 'log' the event
192 char S[300];
193 if (MajorChange == true && OldOp.empty() == false)
194 {
195 snprintf(S,sizeof(S),"\r%s",OldOp.c_str());
196 Write(S);
197 cout << endl;
198 }
199
200 // Print the spinner
201 snprintf(S,sizeof(S),"\r%s... %u%%",Op.c_str(),(unsigned int)Percent);
202 Write(S);
203
204 OldOp = Op;
205}
206 /*}}}*/
207// OpTextProgress::Write - Write the progress string /*{{{*/
208// ---------------------------------------------------------------------
209/* This space fills the end to overwrite the previous text */
210void OpTextProgress::Write(const char *S)
211{
212 cout << S;
213 for (unsigned int I = strlen(S); I < LastLen; I++)
214 cout << ' ';
215 cout << '\r' << flush;
216 LastLen = strlen(S);
217}
218 /*}}}*/