Join with aliencode
[ntk/apt.git] / apt-pkg / contrib / progress.cc
CommitLineData
404ec98e
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
b2e465d6 3// $Id: progress.cc,v 1.10 2001/02/20 07:03:17 jgg Exp $
404ec98e
AL
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>
6f4f200a 15#include <apt-pkg/error.h>
0a8e3465 16#include <apt-pkg/configuration.h>
b2e465d6
AL
17
18#include <apti18n.h>
19
404ec98e
AL
20#include <stdio.h>
21 /*}}}*/
22
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,
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();
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/* */
67void OpProgress::SubProgress(unsigned long SubTotal,string Op)
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;
404ec98e 115
b2e465d6
AL
116 if (Interval == 0)
117 return false;
118
404ec98e
AL
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;
1a7c9eba 126 LastPercent = Percent;
404ec98e
AL
127 return true;
128}
129 /*}}}*/
0a8e3465
AL
130// OpTextProgress::OpTextProgress - Constructor /*{{{*/
131// ---------------------------------------------------------------------
132/* */
133OpTextProgress::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 /*}}}*/
404ec98e
AL
142// OpTextProgress::Done - Clean up the display /*{{{*/
143// ---------------------------------------------------------------------
144/* */
145void OpTextProgress::Done()
146{
147 if (NoUpdate == false && OldOp.empty() == false)
148 {
149 char S[300];
6f4f200a 150 if (_error->PendingError() == true)
b2e465d6 151 snprintf(S,sizeof(S),_("\r%s... Error!"),OldOp.c_str());
b35d2f5f 152 else
b2e465d6 153 snprintf(S,sizeof(S),_("\r%s... Done"),OldOp.c_str());
404ec98e
AL
154 Write(S);
155 cout << endl;
156 OldOp = string();
0a8e3465
AL
157 }
158
159 if (NoUpdate == true && NoDisplay == false && OldOp.empty() == false)
160 {
161 OldOp = string();
162 cout << endl;
163 }
404ec98e
AL
164}
165 /*}}}*/
166// OpTextProgress::Update - Simple text spinner /*{{{*/
167// ---------------------------------------------------------------------
168/* */
169void OpTextProgress::Update()
170{
b2e465d6 171 if (CheckChange((NoUpdate == true?0:0.7)) == false)
404ec98e
AL
172 return;
173
174 // No percent spinner
175 if (NoUpdate == true)
176 {
177 if (MajorChange == false)
178 return;
0a8e3465
AL
179 if (NoDisplay == false)
180 {
181 if (OldOp.empty() == false)
182 cout << endl;
183 OldOp = "a";
184 cout << Op << "..." << flush;
185 }
186
404ec98e
AL
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 */
209void 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 /*}}}*/