]> git.saurik.com Git - apt.git/blob - apt-pkg/contrib/progress.cc
fixed typo in fileutl.cc (damn you, studly caps...)
[apt.git] / apt-pkg / contrib / progress.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 // $Id: progress.cc,v 1.10 2001/02/20 07:03:17 jgg Exp $
4 /* ######################################################################
5
6 OpProgress - Operation Progress
7
8 ##################################################################### */
9 /*}}}*/
10 // Include Files /*{{{*/
11 #ifdef __GNUG__
12 #pragma implementation "apt-pkg/progress.h"
13 #endif
14 #include <apt-pkg/progress.h>
15 #include <apt-pkg/error.h>
16 #include <apt-pkg/configuration.h>
17
18 #include <apti18n.h>
19
20 #include <stdio.h>
21 /*}}}*/
22
23 // OpProgress::OpProgress - Constructor /*{{{*/
24 // ---------------------------------------------------------------------
25 /* */
26 OpProgress::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 // ---------------------------------------------------------------------
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. */
37 void OpProgress::Progress(unsigned long Cur)
38 {
39 if (Total == 0 || Size == 0 || SubTotal == 0)
40 Percent = 0;
41 else
42 Percent = (Current + Cur/((float)SubTotal)*Size)*100.0/Total;
43 Update();
44 }
45 /*}}}*/
46 // OpProgress::OverallProgress - Set the overall progress /*{{{*/
47 // ---------------------------------------------------------------------
48 /* */
49 void OpProgress::OverallProgress(unsigned long Current, unsigned long Total,
50 unsigned long Size,string Op)
51 {
52 this->Current = Current;
53 this->Total = Total;
54 this->Size = Size;
55 this->Op = Op;
56 SubOp = string();
57 if (Total == 0)
58 Percent = 0;
59 else
60 Percent = Current*100.0/Total;
61 Update();
62 }
63 /*}}}*/
64 // OpProgress::SubProgress - Set the sub progress state /*{{{*/
65 // ---------------------------------------------------------------------
66 /* */
67 void OpProgress::SubProgress(unsigned long SubTotal,string Op)
68 {
69 this->SubTotal = SubTotal;
70 SubOp = Op;
71 if (Total == 0)
72 Percent = 0;
73 else
74 Percent = Current*100.0/Total;
75 Update();
76 }
77 /*}}}*/
78 // OpProgress::SubProgress - Set the sub progress state /*{{{*/
79 // ---------------------------------------------------------------------
80 /* */
81 void OpProgress::SubProgress(unsigned long SubTotal)
82 {
83 this->SubTotal = SubTotal;
84 if (Total == 0)
85 Percent = 0;
86 else
87 Percent = Current*100.0/Total;
88 Update();
89 }
90 /*}}}*/
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. */
96 bool 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
107 if (SubOp != LastSubOp)
108 {
109 LastSubOp = SubOp;
110 return true;
111 }
112
113 if ((int)LastPercent == (int)Percent)
114 return false;
115
116 if (Interval == 0)
117 return false;
118
119 // Check time delta
120 struct timeval Now;
121 gettimeofday(&Now,0);
122 double Diff = Now.tv_sec - LastTime.tv_sec + (Now.tv_usec - LastTime.tv_usec)/1000000.0;
123 if (Diff < Interval)
124 return false;
125 LastTime = Now;
126 LastPercent = Percent;
127 return true;
128 }
129 /*}}}*/
130 // OpTextProgress::OpTextProgress - Constructor /*{{{*/
131 // ---------------------------------------------------------------------
132 /* */
133 OpTextProgress::OpTextProgress(Configuration &Config) :
134 NoUpdate(false), NoDisplay(false), LastLen(0)
135 {
136 if (Config.FindI("quiet",0) >= 1)
137 NoUpdate = true;
138 if (Config.FindI("quiet",0) >= 2)
139 NoDisplay = true;
140 };
141 /*}}}*/
142 // OpTextProgress::Done - Clean up the display /*{{{*/
143 // ---------------------------------------------------------------------
144 /* */
145 void OpTextProgress::Done()
146 {
147 if (NoUpdate == false && OldOp.empty() == false)
148 {
149 char S[300];
150 if (_error->PendingError() == true)
151 snprintf(S,sizeof(S),_("\r%s... Error!"),OldOp.c_str());
152 else
153 snprintf(S,sizeof(S),_("\r%s... Done"),OldOp.c_str());
154 Write(S);
155 cout << endl;
156 OldOp = string();
157 }
158
159 if (NoUpdate == true && NoDisplay == false && OldOp.empty() == false)
160 {
161 OldOp = string();
162 cout << endl;
163 }
164 }
165 /*}}}*/
166 // OpTextProgress::Update - Simple text spinner /*{{{*/
167 // ---------------------------------------------------------------------
168 /* */
169 void OpTextProgress::Update()
170 {
171 if (CheckChange((NoUpdate == true?0:0.7)) == false)
172 return;
173
174 // No percent spinner
175 if (NoUpdate == true)
176 {
177 if (MajorChange == false)
178 return;
179 if (NoDisplay == false)
180 {
181 if (OldOp.empty() == false)
182 cout << endl;
183 OldOp = "a";
184 cout << Op << "..." << flush;
185 }
186
187 return;
188 }
189
190 // Erase the old text and 'log' the event
191 char S[300];
192 if (MajorChange == true && OldOp.empty() == false)
193 {
194 snprintf(S,sizeof(S),"\r%s",OldOp.c_str());
195 Write(S);
196 cout << endl;
197 }
198
199 // Print the spinner
200 snprintf(S,sizeof(S),"\r%s... %u%%",Op.c_str(),(unsigned int)Percent);
201 Write(S);
202
203 OldOp = Op;
204 }
205 /*}}}*/
206 // OpTextProgress::Write - Write the progress string /*{{{*/
207 // ---------------------------------------------------------------------
208 /* This space fills the end to overwrite the previous text */
209 void OpTextProgress::Write(const char *S)
210 {
211 cout << S;
212 for (unsigned int I = strlen(S); I < LastLen; I++)
213 cout << ' ';
214 cout << '\r' << flush;
215 LastLen = strlen(S);
216 }
217 /*}}}*/