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