0031171: Draw - support Unicode input / output in console on Windows
[occt.git] / src / Draw / Draw_ProgressIndicator.cxx
CommitLineData
973c2be1 1// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 2//
973c2be1 3// This file is part of Open CASCADE Technology software library.
b311480e 4//
d5f74e42 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
973c2be1 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.
b311480e 10//
973c2be1 11// Alternatively, this file may be used under the terms of Open CASCADE
12// commercial license or contractual agreement.
b311480e 13
42cf5bc1 14
7fd59977 15#include <Draw.hxx>
42cf5bc1 16#include <Draw_Interpretor.hxx>
17#include <Draw_ProgressIndicator.hxx>
7fd59977 18#include <Message.hxx>
42cf5bc1 19#include <Message_Messenger.hxx>
20#include <Message_ProgressScale.hxx>
53d770b3 21#include <Precision.hxx>
b311480e 22
7fd59977 23#include <stdio.h>
42cf5bc1 24#include <time.h>
92efcf78 25IMPLEMENT_STANDARD_RTTIEXT(Draw_ProgressIndicator,Message_ProgressIndicator)
26
7fd59977 27//=======================================================================
28//function : Draw_ProgressIndicator
29//purpose :
30//=======================================================================
6b55f8e3 31Draw_ProgressIndicator::Draw_ProgressIndicator (const Draw_Interpretor &di, Standard_Real theUpdateThreshold)
32: myTextMode ( DefaultTextMode() ),
33 myGraphMode ( DefaultGraphMode() ),
34 myDraw ( (Standard_Address)&di ),
35 myShown ( Standard_False ),
36 myBreak ( Standard_False ),
37 myUpdateThreshold ( 0.01 * theUpdateThreshold ),
38 myLastPosition ( -1. ),
39 myStartTime ( 0 )
7fd59977 40{
41}
42
43//=======================================================================
6b55f8e3 44//function : ~Draw_ProgressIndicator
7fd59977 45//purpose :
46//=======================================================================
47
6b55f8e3 48Draw_ProgressIndicator::~Draw_ProgressIndicator()
7fd59977 49{
50 Reset();
51}
52
53//=======================================================================
54//function : Reset
55//purpose :
56//=======================================================================
57
58void 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;
6b55f8e3 66 myLastPosition = -1.;
67 myStartTime = 0;
7fd59977 68}
69
70//=======================================================================
71//function : Show
72//purpose :
73//=======================================================================
74
75Standard_Boolean Draw_ProgressIndicator::Show(const Standard_Boolean force)
76{
6b55f8e3 77 if ( ! myGraphMode && ! myTextMode )
78 return Standard_False;
79
80 // remember time of the first call to Show as process start time
81 if ( ! myStartTime )
82 {
83 time_t aTimeT;
84 time ( &aTimeT );
85 myStartTime = (Standard_Size)aTimeT;
86 }
87
88 // unless show is forced, show updated state only if at least 1% progress has been reached since the last update
89 Standard_Real aPosition = GetPosition();
90 if ( ! force && aPosition < 1. && Abs (aPosition - myLastPosition) < myUpdateThreshold)
7fd59977 91 return Standard_False; // return if update interval has not elapsed
6b55f8e3 92 myLastPosition = aPosition;
7fd59977 93
94 // Prepare textual progress info
53d770b3 95 std::stringstream aText;
96 aText.setf (std::ios::fixed, std:: ios::floatfield);
97 aText.precision(0);
98 aText << "Progress: " << 100. * GetPosition() << "%";
7fd59977 99 for ( Standard_Integer i=GetNbScopes(); i >=1; i-- ) {
100 const Message_ProgressScale &scale = GetScope ( i );
101 if ( scale.GetName().IsNull() ) continue; // skip unnamed scopes
53d770b3 102 aText << " " << scale.GetName()->ToCString() << ": ";
103
7fd59977 104 // if scope has subscopes, print end of subscope as its current position
105 Standard_Real locPos = ( i >1 ? GetScope ( i-1 ).GetLast() : GetPosition() );
106 // print progress info differently for finite and infinite scopes
107 if ( scale.GetInfinite() )
53d770b3 108 {
109 Standard_Real aVal = scale.BaseToLocal(locPos);
110 if (Precision::IsInfinite(aVal))
111 {
112 aText << "finished";
113 }
114 else
115 {
116 aText << aVal;
117 }
118 }
119 else
120 {
121 aText << scale.BaseToLocal ( locPos ) << " / " << scale.GetMax();
122 }
7fd59977 123 }
124
7fd59977 125 // Show graphic progress bar
126 if ( myGraphMode ) {
6b55f8e3 127
128 // In addition, write elapsed/estimated/remaining time
129 if ( GetPosition() > 0.01 ) {
130 time_t aTimeT;
131 time ( &aTimeT );
132 Standard_Size aTime = (Standard_Size)aTimeT;
53d770b3 133 aText << "\nElapsed/estimated time: " << (long)(aTime - myStartTime) <<
134 "/" << ( aTime - myStartTime ) / GetPosition() << " sec";
6b55f8e3 135 }
136
7fd59977 137 if ( ! myShown ) {
138 char command[1024];
91322f44 139 Sprintf ( command, "toplevel .xprogress -height 100 -width 410;"
7fd59977 140 "wm title .xprogress \"Progress\";"
141 "set xprogress_stop 0;"
142 "canvas .xprogress.bar -width 402 -height 22;"
143 ".xprogress.bar create rectangle 2 2 2 21 -fill blue -tags progress;"
144 ".xprogress.bar create rectangle 2 2 2 21 -outline black -tags progress_next;"
145 "message .xprogress.text -width 400 -text \"Progress 0%%\";"
68299304 146 "button .xprogress.stop -text \"Break\" -relief groove -width 9 -command {XProgress -stop %p};"
147 "pack .xprogress.bar .xprogress.text .xprogress.stop -side top;", this );
7fd59977 148 ((Draw_Interpretor*)myDraw)->Eval ( command );
149 myShown = Standard_True;
150 }
53d770b3 151 std::stringstream aCommand;
152 aCommand.setf(std::ios::fixed, std::ios::floatfield);
153 aCommand.precision(0);
154 aCommand << ".xprogress.bar coords progress 2 2 " << (1 + 400 * GetPosition()) << " 21;";
155 aCommand << ".xprogress.bar coords progress_next 2 2 " << (1 + 400 * GetScope(1).GetLast()) << " 21;";
156 aCommand << ".xprogress.text configure -text \"" << aText.str() << "\";";
157 aCommand << "update";
158 ((Draw_Interpretor*)myDraw)->Eval (aCommand.str().c_str());
7fd59977 159 }
160
161 // Print textual progress info
162 if ( myTextMode )
53d770b3 163 Message::DefaultMessenger()->Send (aText.str().c_str(), Message_Info);
7fd59977 164
165 return Standard_True;
166}
167
168//=======================================================================
169//function : UserBreak
170//purpose :
171//=======================================================================
172
173Standard_Boolean Draw_ProgressIndicator::UserBreak()
174{
68299304 175 if ( StopIndicator() == this ) {
04232180 176// std::cout << "Progress Indicator - User Break: " << StopIndicator() << ", " << (void*)this << std::endl;
7fd59977 177 myBreak = Standard_True;
178 ((Draw_Interpretor*)myDraw)->Eval ( "XProgress -stop 0" );
179 }
180 return myBreak;
181}
182
183//=======================================================================
184//function : SetTextMode
185//purpose : Sets text output mode (on/off)
186//=======================================================================
187
188void Draw_ProgressIndicator::SetTextMode(const Standard_Boolean theTextMode)
189{
190 myTextMode = theTextMode;
191}
192
193//=======================================================================
194//function : GetTextMode
195//purpose : Returns text output mode (on/off)
196//=======================================================================
197
198Standard_Boolean Draw_ProgressIndicator::GetTextMode() const
199{
200 return myTextMode;
201}
202
203//=======================================================================
204//function : SetGraphMode
205//purpose : Sets graphical output mode (on/off)
206//=======================================================================
207
208void Draw_ProgressIndicator::SetGraphMode(const Standard_Boolean theGraphMode)
209{
210 myGraphMode = theGraphMode;
211}
212
213//=======================================================================
214//function : GetGraphMode
215//purpose : Returns graphical output mode (on/off)
216//=======================================================================
217
218Standard_Boolean Draw_ProgressIndicator::GetGraphMode() const
219{
220 return myGraphMode;
221}
222
223//=======================================================================
224//function : DefaultTextMode
225//purpose :
226//=======================================================================
227
228Standard_Boolean &Draw_ProgressIndicator::DefaultTextMode ()
229{
230 static Standard_Boolean defTextMode = Standard_False;
231 return defTextMode;
232}
233
234//=======================================================================
235//function : DefaultGraphMode
236//purpose :
237//=======================================================================
238
239Standard_Boolean &Draw_ProgressIndicator::DefaultGraphMode ()
240{
241 static Standard_Boolean defGraphMode = Standard_False;
242 return defGraphMode;
243}
244
245//=======================================================================
246//function : StopIndicator
247//purpose :
248//=======================================================================
249
68299304 250Standard_Address &Draw_ProgressIndicator::StopIndicator ()
7fd59977 251{
68299304 252 static Standard_Address stopIndicator = 0;
7fd59977 253 return stopIndicator;
254}
255
256