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_ProgressScope.hxx>
21 #include <NCollection_List.hxx>
22 #include <Precision.hxx>
24 #include <OSD_Exception_CTRL_BREAK.hxx>
25 #include <OSD_Thread.hxx>
29 IMPLEMENT_STANDARD_RTTIEXT(Draw_ProgressIndicator,Message_ProgressIndicator)
31 //=======================================================================
32 //function : Draw_ProgressIndicator
34 //=======================================================================
35 Draw_ProgressIndicator::Draw_ProgressIndicator (const Draw_Interpretor &di, Standard_Real theUpdateThreshold)
36 : myTclMode ( DefaultTclMode() ),
37 myConsoleMode ( DefaultConsoleMode() ),
38 myGraphMode ( DefaultGraphMode() ),
39 myDraw ( (Draw_Interpretor*)&di ),
40 myShown ( Standard_False ),
41 myBreak ( Standard_False ),
42 myUpdateThreshold ( 0.01 * theUpdateThreshold ),
43 myLastPosition ( -1. ),
45 myGuiThreadId (OSD_Thread::Current())
49 //=======================================================================
50 //function : ~Draw_ProgressIndicator
52 //=======================================================================
54 Draw_ProgressIndicator::~Draw_ProgressIndicator()
59 //=======================================================================
62 //=======================================================================
64 void Draw_ProgressIndicator::Reset()
66 Message_ProgressIndicator::Reset();
68 myDraw->Eval ( "destroy .xprogress" );
69 myShown = Standard_False;
71 myBreak = Standard_False;
76 //=======================================================================
79 //=======================================================================
81 void Draw_ProgressIndicator::Show (const Message_ProgressScope& theScope, const Standard_Boolean force)
83 if (!myGraphMode && !myTclMode && !myConsoleMode)
86 // remember time of the first call to Show as process start time
93 myStartTime = (Standard_Size)aTimeT;
97 // unless show is forced, show updated state only if at least 1% progress has been reached since the last update
98 Standard_Real aPosition = GetPosition();
99 if ( ! force && aPosition < 1. && Abs (aPosition - myLastPosition) < myUpdateThreshold)
100 return; // return if update interval has not elapsed
102 myLastPosition = aPosition;
104 // Prepare textual progress info
105 std::stringstream aText;
106 aText.setf (std::ios::fixed, std:: ios::floatfield);
108 aText << "Progress: " << 100. * GetPosition() << "%";
109 NCollection_List<const Message_ProgressScope*> aScopes;
110 for (const Message_ProgressScope* aPS = &theScope; aPS; aPS = aPS->Parent())
111 aScopes.Prepend(aPS);
112 for (NCollection_List<const Message_ProgressScope*>::Iterator it(aScopes); it.More(); it.Next())
114 const Message_ProgressScope* aPS = it.Value();
115 if (!aPS->Name()) continue; // skip unnamed scopes
116 aText << " " << aPS->Name() << ": ";
118 // print progress info differently for finite and infinite scopes
119 Standard_Real aVal = aPS->Value();
120 if (aPS->IsInfinite())
122 if (Precision::IsInfinite(aVal))
133 aText << aVal << " / " << aPS->MaxValue();
137 // Show graphic progress bar.
138 // It will be updated only within GUI thread.
139 if (myGraphMode && myGuiThreadId == OSD_Thread::Current())
141 // In addition, write elapsed/estimated/remaining time
142 if ( GetPosition() > 0.01 ) {
145 Standard_Size aTime = (Standard_Size)aTimeT;
146 aText << "\nElapsed/estimated time: " << (long)(aTime - myStartTime) <<
147 "/" << ( aTime - myStartTime ) / GetPosition() << " sec";
152 Sprintf ( command, "toplevel .xprogress -height 100 -width 410;"
153 "wm title .xprogress \"Progress\";"
154 "set xprogress_stop 0;"
155 "canvas .xprogress.bar -width 402 -height 22;"
156 ".xprogress.bar create rectangle 2 2 2 21 -fill blue -tags progress;"
157 ".xprogress.bar create rectangle 2 2 2 21 -outline black -tags progress_next;"
158 "message .xprogress.text -width 400 -text \"Progress 0%%\";"
159 "button .xprogress.stop -text \"Break\" -relief groove -width 9 -command {XProgress -stop %p};"
160 "pack .xprogress.bar .xprogress.text .xprogress.stop -side top;", this );
161 myDraw->Eval ( command );
162 myShown = Standard_True;
164 std::stringstream aCommand;
165 aCommand.setf(std::ios::fixed, std::ios::floatfield);
166 aCommand.precision(0);
167 aCommand << ".xprogress.bar coords progress 2 2 " << (1 + 400 * GetPosition()) << " 21;";
168 aCommand << ".xprogress.bar coords progress_next 2 2 " << (1 + 400 * theScope.GetPortion()) << " 21;";
169 aCommand << ".xprogress.text configure -text \"" << aText.str() << "\";";
170 aCommand << "update";
171 myDraw->Eval (aCommand.str().c_str());
174 // Print textual progress info
175 if (myTclMode && myDraw)
177 *myDraw << aText.str().c_str() << "\n";
181 std::cout << aText.str().c_str() << "\n";
185 //=======================================================================
186 //function : UserBreak
188 //=======================================================================
190 Standard_Boolean Draw_ProgressIndicator::UserBreak()
192 if ( StopIndicator() == this )
194 // std::cout << "Progress Indicator - User Break: " << StopIndicator() << ", " << (void*)this << std::endl;
195 myBreak = Standard_True;
196 myDraw->Eval ( "XProgress -stop 0" );
200 // treatment of Ctrl-Break signal
205 catch (OSD_Exception_CTRL_BREAK)
207 myBreak = Standard_True;
213 //=======================================================================
214 //function : SetTclMode
215 //purpose : Sets Tcl output mode (on/off)
216 //=======================================================================
218 void Draw_ProgressIndicator::SetTclMode(const Standard_Boolean theTclMode)
220 myTclMode = theTclMode;
223 //=======================================================================
224 //function : GetTclMode
225 //purpose : Returns Tcl output mode (on/off)
226 //=======================================================================
228 Standard_Boolean Draw_ProgressIndicator::GetTclMode() const
233 //=======================================================================
234 //function : SetConsoleMode
235 //purpose : Sets Console output mode (on/off)
236 //=======================================================================
238 void Draw_ProgressIndicator::SetConsoleMode(const Standard_Boolean theMode)
240 myConsoleMode = theMode;
243 //=======================================================================
244 //function : GetConsoleMode
245 //purpose : Returns Console output mode (on/off)
246 //=======================================================================
248 Standard_Boolean Draw_ProgressIndicator::GetConsoleMode() const
250 return myConsoleMode;
253 //=======================================================================
254 //function : SetGraphMode
255 //purpose : Sets graphical output mode (on/off)
256 //=======================================================================
258 void Draw_ProgressIndicator::SetGraphMode(const Standard_Boolean theGraphMode)
260 myGraphMode = theGraphMode;
263 //=======================================================================
264 //function : GetGraphMode
265 //purpose : Returns graphical output mode (on/off)
266 //=======================================================================
268 Standard_Boolean Draw_ProgressIndicator::GetGraphMode() const
273 //=======================================================================
274 //function : DefaultTclMode
276 //=======================================================================
278 Standard_Boolean &Draw_ProgressIndicator::DefaultTclMode()
280 static Standard_Boolean defTclMode = Standard_False;
284 //=======================================================================
285 //function : DefaultConsoleMode
287 //=======================================================================
289 Standard_Boolean &Draw_ProgressIndicator::DefaultConsoleMode()
291 static Standard_Boolean defConsoleMode = Standard_False;
292 return defConsoleMode;
295 //=======================================================================
296 //function : DefaultGraphMode
298 //=======================================================================
300 Standard_Boolean &Draw_ProgressIndicator::DefaultGraphMode()
302 static Standard_Boolean defGraphMode = Standard_False;
306 //=======================================================================
307 //function : StopIndicator
309 //=======================================================================
311 Standard_Address &Draw_ProgressIndicator::StopIndicator()
313 static Standard_Address stopIndicator = 0;
314 return stopIndicator;