]> git.saurik.com Git - apt.git/blob - apt-pkg/contrib/progress.cc
* merged from dpkg-log
[apt.git] / apt-pkg / contrib / progress.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 // $Id: progress.cc,v 1.12 2003/01/11 07:17:04 jgg Exp $
4 /* ######################################################################
5
6 OpProgress - Operation Progress
7
8 ##################################################################### */
9 /*}}}*/
10 // Include Files /*{{{*/
11 #include <apt-pkg/progress.h>
12 #include <apt-pkg/error.h>
13 #include <apt-pkg/configuration.h>
14
15 #include <apti18n.h>
16
17 #include <iostream>
18 #include <stdio.h>
19 /*}}}*/
20
21 using namespace std;
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,const 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,const 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 LastPercent = Percent;
117
118 if (Interval == 0)
119 return false;
120
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 /*}}}*/
131 // OpTextProgress::OpTextProgress - Constructor /*{{{*/
132 // ---------------------------------------------------------------------
133 /* */
134 OpTextProgress::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 /*}}}*/
143 // OpTextProgress::Done - Clean up the display /*{{{*/
144 // ---------------------------------------------------------------------
145 /* */
146 void OpTextProgress::Done()
147 {
148 if (NoUpdate == false && OldOp.empty() == false)
149 {
150 char S[300];
151 if (_error->PendingError() == true)
152 snprintf(S,sizeof(S),_("%c%s... Error!"),'\r',OldOp.c_str());
153 else
154 snprintf(S,sizeof(S),_("%c%s... Done"),'\r',OldOp.c_str());
155 Write(S);
156 cout << endl;
157 OldOp = string();
158 }
159
160 if (NoUpdate == true && NoDisplay == false && OldOp.empty() == false)
161 {
162 OldOp = string();
163 cout << endl;
164 }
165 }
166 /*}}}*/
167 // OpTextProgress::Update - Simple text spinner /*{{{*/
168 // ---------------------------------------------------------------------
169 /* */
170 void OpTextProgress::Update()
171 {
172 if (CheckChange((NoUpdate == true?0:0.7)) == false)
173 return;
174
175 // No percent spinner
176 if (NoUpdate == true)
177 {
178 if (MajorChange == false)
179 return;
180 if (NoDisplay == false)
181 {
182 if (OldOp.empty() == false)
183 cout << endl;
184 OldOp = "a";
185 cout << Op << "..." << flush;
186 }
187
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 */
210 void 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 /*}}}*/