1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
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.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
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 <Precision.hxx>
25 IMPLEMENT_STANDARD_RTTIEXT(Draw_ProgressIndicator,Message_ProgressIndicator)
27 //=======================================================================
28 //function : Draw_ProgressIndicator
30 //=======================================================================
31 Draw_ProgressIndicator::Draw_ProgressIndicator (const Draw_Interpretor &di, Standard_Real theUpdateThreshold)
32 : myTextMode ( DefaultTextMode() ),
33 myGraphMode ( DefaultGraphMode() ),
34 myTclOutput ( DefaultTclOutput() ),
35 myDraw ( (Draw_Interpretor*)&di ),
36 myShown ( Standard_False ),
37 myBreak ( Standard_False ),
38 myUpdateThreshold ( 0.01 * theUpdateThreshold ),
39 myLastPosition ( -1. ),
44 //=======================================================================
45 //function : ~Draw_ProgressIndicator
47 //=======================================================================
49 Draw_ProgressIndicator::~Draw_ProgressIndicator()
54 //=======================================================================
57 //=======================================================================
59 void Draw_ProgressIndicator::Reset()
61 Message_ProgressIndicator::Reset();
63 myDraw->Eval ( "destroy .xprogress" );
64 myShown = Standard_False;
66 myBreak = Standard_False;
71 //=======================================================================
74 //=======================================================================
76 Standard_Boolean Draw_ProgressIndicator::Show(const Standard_Boolean force)
78 if ( ! myGraphMode && ! myTextMode )
79 return Standard_False;
81 // remember time of the first call to Show as process start time
86 myStartTime = (Standard_Size)aTimeT;
89 // unless show is forced, show updated state only if at least 1% progress has been reached since the last update
90 Standard_Real aPosition = GetPosition();
91 if ( ! force && aPosition < 1. && Abs (aPosition - myLastPosition) < myUpdateThreshold)
92 return Standard_False; // return if update interval has not elapsed
93 myLastPosition = aPosition;
95 // Prepare textual progress info
96 std::stringstream aText;
97 aText.setf (std::ios::fixed, std:: ios::floatfield);
99 aText << "Progress: " << 100. * GetPosition() << "%";
100 for ( Standard_Integer i=GetNbScopes(); i >=1; i-- ) {
101 const Message_ProgressScale &scale = GetScope ( i );
102 if ( scale.GetName().IsNull() ) continue; // skip unnamed scopes
103 aText << " " << scale.GetName()->ToCString() << ": ";
105 // if scope has subscopes, print end of subscope as it s current position
106 Standard_Real locPos = ( (i >1 && GetPosition()!=0) ? GetScope ( i-1 ).GetLast() : GetPosition() );
107 // print progress info differently for finite and infinite scopes
108 if ( scale.GetInfinite() )
110 Standard_Real aVal = scale.BaseToLocal(locPos);
111 if (Precision::IsInfinite(aVal))
122 aText << scale.BaseToLocal ( locPos ) << " / " << scale.GetMax();
126 // Show graphic progress bar
129 // In addition, write elapsed/estimated/remaining time
130 if ( GetPosition() > 0.01 ) {
133 Standard_Size aTime = (Standard_Size)aTimeT;
134 aText << "\nElapsed/estimated time: " << (long)(aTime - myStartTime) <<
135 "/" << ( aTime - myStartTime ) / GetPosition() << " sec";
140 Sprintf ( command, "toplevel .xprogress -height 100 -width 410;"
141 "wm title .xprogress \"Progress\";"
142 "set xprogress_stop 0;"
143 "canvas .xprogress.bar -width 402 -height 22;"
144 ".xprogress.bar create rectangle 2 2 2 21 -fill blue -tags progress;"
145 ".xprogress.bar create rectangle 2 2 2 21 -outline black -tags progress_next;"
146 "message .xprogress.text -width 400 -text \"Progress 0%%\";"
147 "button .xprogress.stop -text \"Break\" -relief groove -width 9 -command {XProgress -stop %p};"
148 "pack .xprogress.bar .xprogress.text .xprogress.stop -side top;", this );
149 myDraw->Eval ( command );
150 myShown = Standard_True;
152 std::stringstream aCommand;
153 aCommand.setf(std::ios::fixed, std::ios::floatfield);
154 aCommand.precision(0);
155 aCommand << ".xprogress.bar coords progress 2 2 " << (1 + 400 * GetPosition()) << " 21;";
156 aCommand << ".xprogress.bar coords progress_next 2 2 " << (1 + 400 * GetScope(1).GetLast()) << " 21;";
157 aCommand << ".xprogress.text configure -text \"" << aText.str() << "\";";
158 aCommand << "update";
159 myDraw->Eval (aCommand.str().c_str());
162 // Print textual progress info
165 if (myTclOutput && myDraw)
167 *myDraw << aText.str().c_str() << "\n";
171 std::cout << aText.str().c_str() << "\n";
174 return Standard_True;
177 //=======================================================================
178 //function : UserBreak
180 //=======================================================================
182 Standard_Boolean Draw_ProgressIndicator::UserBreak()
184 if ( StopIndicator() == this ) {
185 // std::cout << "Progress Indicator - User Break: " << StopIndicator() << ", " << (void*)this << std::endl;
186 myBreak = Standard_True;
187 myDraw->Eval ( "XProgress -stop 0" );
192 //=======================================================================
193 //function : SetTextMode
194 //purpose : Sets text output mode (on/off)
195 //=======================================================================
197 void Draw_ProgressIndicator::SetTextMode(const Standard_Boolean theTextMode)
199 myTextMode = theTextMode;
202 //=======================================================================
203 //function : GetTextMode
204 //purpose : Returns text output mode (on/off)
205 //=======================================================================
207 Standard_Boolean Draw_ProgressIndicator::GetTextMode() const
212 //=======================================================================
213 //function : SetGraphMode
214 //purpose : Sets graphical output mode (on/off)
215 //=======================================================================
217 void Draw_ProgressIndicator::SetGraphMode(const Standard_Boolean theGraphMode)
219 myGraphMode = theGraphMode;
222 //=======================================================================
223 //function : GetGraphMode
224 //purpose : Returns graphical output mode (on/off)
225 //=======================================================================
227 Standard_Boolean Draw_ProgressIndicator::GetGraphMode() const
232 //=======================================================================
233 //function : DefaultTextMode
235 //=======================================================================
237 Standard_Boolean &Draw_ProgressIndicator::DefaultTextMode()
239 static Standard_Boolean defTextMode = Standard_False;
243 //=======================================================================
244 //function : DefaultGraphMode
246 //=======================================================================
248 Standard_Boolean &Draw_ProgressIndicator::DefaultGraphMode()
250 static Standard_Boolean defGraphMode = Standard_False;
254 //=======================================================================
255 //function : DefaultTclOutput
257 //=======================================================================
259 Standard_Boolean &Draw_ProgressIndicator::DefaultTclOutput()
261 static Standard_Boolean defTclOutput = Standard_False;
265 //=======================================================================
266 //function : StopIndicator
268 //=======================================================================
270 Standard_Address &Draw_ProgressIndicator::StopIndicator()
272 static Standard_Address stopIndicator = 0;
273 return stopIndicator;