0026936: Drawbacks of inlining in new type system in OCCT 7.0 -- automatic
[occt.git] / src / Draw / Draw_ProgressIndicator.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14
15 #include <Draw.hxx>
16 #include <Draw_Interpretor.hxx>
17 #include <Draw_ProgressIndicator.hxx>
18 #include <Message.hxx>
19 #include <Message_Messenger.hxx>
20 #include <Message_ProgressScale.hxx>
21 #include <Standard_Type.hxx>
22
23 #include <stdio.h>
24 #include <time.h>
25 IMPLEMENT_STANDARD_RTTIEXT(Draw_ProgressIndicator,Message_ProgressIndicator)
26
27 //=======================================================================
28 //function : Draw_ProgressIndicator
29 //purpose  : 
30 //=======================================================================
31 Draw_ProgressIndicator::Draw_ProgressIndicator(const Draw_Interpretor &di,
32                                                    const Standard_Integer updateTime) :
33        myTextMode ( DefaultTextMode() ),
34        myGraphMode ( DefaultGraphMode() ),
35        myDraw ( (Standard_Address)&di ),
36        myShown ( Standard_False ),
37        myBreak ( Standard_False ),
38        myUpdateTime ( updateTime ),
39        myLastUpdate ( 0 ), myStartTime ( 0 )
40 {
41 }
42
43 //=======================================================================
44 //function : Destroy
45 //purpose  : 
46 //=======================================================================
47
48 void Draw_ProgressIndicator::Destroy()
49 {
50   Reset();
51 }
52
53 //=======================================================================
54 //function : Reset
55 //purpose  : 
56 //=======================================================================
57
58 void Draw_ProgressIndicator::Reset()
59 {
60   Message_ProgressIndicator::Reset();
61   if ( myShown ) {
62     ((Draw_Interpretor*)myDraw)->Eval ( "destroy .xprogress" );
63     myShown = Standard_False;
64   }
65   myBreak = Standard_False;
66   myLastUpdate = myStartTime = 0;
67 }
68
69 //=======================================================================
70 //function : Show
71 //purpose  : 
72 //=======================================================================
73
74 Standard_Boolean Draw_ProgressIndicator::Show(const Standard_Boolean force)
75 {
76   if ( ! myGraphMode && ! myTextMode ) return Standard_False;
77   time_t aTimeT;
78   time ( &aTimeT );
79   Standard_Size aTime = (Standard_Size)aTimeT;
80   if ( ! myStartTime ) myStartTime = aTime;
81   if ( ! force && myUpdateTime >0 && aTime < myLastUpdate + myUpdateTime && GetPosition() < 1. )
82     return Standard_False; // return if update interval has not elapsed
83   myLastUpdate = aTime;
84   
85   // Prepare textual progress info
86   char text[2048];
87   Standard_Integer n = 0;
88   n += Sprintf ( &text[n], "Progress: %.0f%%", 100. * GetPosition() );
89   for ( Standard_Integer i=GetNbScopes(); i >=1; i-- ) {
90     const Message_ProgressScale &scale = GetScope ( i );
91     if ( scale.GetName().IsNull() ) continue; // skip unnamed scopes
92     // if scope has subscopes, print end of subscope as its current position
93     Standard_Real locPos = ( i >1 ? GetScope ( i-1 ).GetLast() : GetPosition() );
94     // print progress info differently for finite and infinite scopes
95     if ( scale.GetInfinite() )
96       n += Sprintf ( &text[n], " %s: %.0f", scale.GetName()->ToCString(), 
97                      scale.BaseToLocal ( locPos ) );
98     else 
99       n += Sprintf ( &text[n], " %s: %.0f / %.0f", scale.GetName()->ToCString(), 
100                      scale.BaseToLocal ( locPos ), scale.GetMax() );
101   }
102
103   // In addition, write elapsed/estimated/remaining time
104   if ( GetPosition() > 0.01 ) {
105     n += Sprintf ( &text[n], "\nElapsed/estimated time: %ld/%.0f sec", 
106                    (long)(aTime - myStartTime), ( aTime - myStartTime ) / GetPosition() );
107   }
108   
109   // Show graphic progress bar
110   if ( myGraphMode ) {
111     if ( ! myShown ) {
112       char command[1024];
113       Sprintf ( command, "toplevel .xprogress -height 100 -width 410;"
114                          "wm title .xprogress \"Progress\";"
115                          "set xprogress_stop 0;"
116                          "canvas .xprogress.bar -width 402 -height 22;"
117                          ".xprogress.bar create rectangle 2 2 2 21 -fill blue -tags progress;"
118                          ".xprogress.bar create rectangle 2 2 2 21 -outline black -tags progress_next;"
119                          "message .xprogress.text -width 400 -text \"Progress 0%%\";"
120                          "button .xprogress.stop -text \"Break\" -relief groove -width 9 -command {XProgress -stop %p};"
121                          "pack .xprogress.bar .xprogress.text .xprogress.stop -side top;", this );
122       ((Draw_Interpretor*)myDraw)->Eval ( command );
123       myShown = Standard_True;
124     }
125     char command[1024];
126     Standard_Integer num = 0;
127     num += Sprintf ( &command[num], ".xprogress.bar coords progress 2 2 %.0f 21;", 
128                   1+400*GetPosition() );
129     num += Sprintf ( &command[num], ".xprogress.bar coords progress_next 2 2 %.0f 21;", 
130                   1+400*GetScope(1).GetLast() );
131     num += Sprintf ( &command[num], ".xprogress.text configure -text \"%s\";", text );
132     num += Sprintf ( &command[num], "update" );
133     ((Draw_Interpretor*)myDraw)->Eval ( command );
134   }
135
136   // Print textual progress info
137   if ( myTextMode )
138     Message::DefaultMessenger()->Send (text, Message_Info);
139   
140   return Standard_True;
141 }
142        
143 //=======================================================================
144 //function : UserBreak
145 //purpose  : 
146 //=======================================================================
147
148 Standard_Boolean Draw_ProgressIndicator::UserBreak()
149 {
150   if ( StopIndicator() == this ) {
151 //    cout << "Progress Indicator - User Break: " << StopIndicator() << ", " << (void*)this << endl;
152     myBreak = Standard_True;
153     ((Draw_Interpretor*)myDraw)->Eval ( "XProgress -stop 0" );
154   }
155   return myBreak;
156 }
157        
158 //=======================================================================
159 //function : SetTextMode
160 //purpose  : Sets text output mode (on/off)
161 //=======================================================================
162
163 void Draw_ProgressIndicator::SetTextMode(const Standard_Boolean theTextMode)
164 {
165   myTextMode = theTextMode;
166 }
167
168 //=======================================================================
169 //function : GetTextMode
170 //purpose  : Returns text output mode (on/off)
171 //=======================================================================
172
173 Standard_Boolean Draw_ProgressIndicator::GetTextMode() const
174 {
175   return myTextMode;
176 }
177
178 //=======================================================================
179 //function : SetGraphMode
180 //purpose  : Sets graphical output mode (on/off)
181 //=======================================================================
182
183 void Draw_ProgressIndicator::SetGraphMode(const Standard_Boolean theGraphMode)
184 {
185   myGraphMode = theGraphMode;
186 }
187
188 //=======================================================================
189 //function : GetGraphMode
190 //purpose  : Returns graphical output mode (on/off)
191 //=======================================================================
192
193 Standard_Boolean Draw_ProgressIndicator::GetGraphMode() const
194 {
195   return myGraphMode;
196 }
197
198 //=======================================================================
199 //function : DefaultTextMode
200 //purpose  : 
201 //=======================================================================
202
203 Standard_Boolean &Draw_ProgressIndicator::DefaultTextMode () 
204 {
205   static Standard_Boolean defTextMode = Standard_False;
206   return defTextMode;
207 }
208     
209 //=======================================================================
210 //function : DefaultGraphMode
211 //purpose  : 
212 //=======================================================================
213
214 Standard_Boolean &Draw_ProgressIndicator::DefaultGraphMode () 
215 {
216   static Standard_Boolean defGraphMode = Standard_False;
217   return defGraphMode;
218 }
219     
220 //=======================================================================
221 //function : StopIndicator
222 //purpose  : 
223 //=======================================================================
224
225 Standard_Address &Draw_ProgressIndicator::StopIndicator ()
226 {
227   static Standard_Address stopIndicator = 0;
228   return stopIndicator;
229 }
230
231