]> git.saurik.com Git - wxWidgets.git/blob - src/generic/progdlgg.cpp
1. more wxMotif fixes
[wxWidgets.git] / src / generic / progdlgg.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: progdlgg.h
3 // Purpose: wxProgressDialog class
4 // Author: Karsten Ballüder
5 // Modified by:
6 // Created: 09.05.1999
7 // RCS-ID: $Id$
8 // Copyright: (c) Karsten Ballüder
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "progdlgg.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #ifndef WX_PRECOMP
24 #include "wx/utils.h"
25 #include "wx/frame.h"
26 #include "wx/button.h"
27 #include "wx/stattext.h"
28 #include "wx/layout.h"
29 #include "wx/event.h"
30 #include "wx/gauge.h"
31 #include "wx/intl.h"
32 #include "wx/settings.h"
33 #include "wx/dcclient.h"
34 #endif
35
36 #if wxUSE_PROGRESSDLG
37
38 #include "wx/generic/progdlgg.h"
39
40 #define LAYOUT_X_MARGIN 8
41 #define LAYOUT_Y_MARGIN 8
42
43 // wxTextEntryDialog
44
45 #if !USE_SHARED_LIBRARY
46 BEGIN_EVENT_TABLE(wxProgressDialog, wxFrame)
47 EVT_BUTTON(-1, wxProgressDialog::OnCancel)
48 EVT_CLOSE(wxProgressDialog::OnClose)
49 END_EVENT_TABLE()
50
51 IMPLEMENT_CLASS(wxProgressDialog, wxFrame)
52 #endif
53
54 wxProgressDialog::wxProgressDialog(wxString const &title,
55 wxString const &message,
56 int maximum,
57 wxWindow *parent,
58 int style)
59 {
60 wxWindow *lastWindow = NULL;
61 bool hasAbortButton = (style & wxPD_CAN_ABORT) != 0;
62 m_state = hasAbortButton ? Continue : Uncancelable;
63 m_disableParentOnly = (style & wxPD_APP_MODAL) == 0;
64 m_parent = parent;
65 m_maximum = maximum;
66
67 m_elapsed = m_estimated = m_remaining = NULL;
68 if ((style & (wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME | wxPD_REMAINING_TIME)) != 0) m_time = new wxTime;
69 else m_time = NULL;
70
71 wxFrame::Create(m_parent, -1, title, wxDefaultPosition,
72 wxDefaultSize, wxDEFAULT_DIALOG_STYLE);
73 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE));
74
75 wxLayoutConstraints *c;
76
77 wxClientDC dc(this);
78 dc.SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT));
79 long widthText;
80 dc.GetTextExtent(message, &widthText, NULL);
81
82 m_msg = new wxStaticText(this, -1, message);
83 c = new wxLayoutConstraints;
84 c->left.SameAs(this, wxLeft, 2*LAYOUT_X_MARGIN);
85 c->top.SameAs(this, wxTop, 2*LAYOUT_Y_MARGIN);
86 c->width.AsIs();
87 c->height.AsIs();
88 m_msg->SetConstraints(c);
89 lastWindow = m_msg;
90
91 if ( maximum > 0 )
92 {
93 m_gauge = new wxGauge(this, -1, maximum,
94 wxDefaultPosition, wxDefaultSize,
95 wxGA_HORIZONTAL | wxRAISED_BORDER);
96 c = new wxLayoutConstraints;
97 c->left.SameAs(this, wxLeft, 2*LAYOUT_X_MARGIN);
98 c->top.Below(m_msg, 2*LAYOUT_Y_MARGIN);
99 c->right.SameAs(this, wxRight, 2*LAYOUT_X_MARGIN);
100 c->height.AsIs();
101 m_gauge->SetConstraints(c);
102 m_gauge->SetValue(0);
103 lastWindow = m_gauge;
104 }
105 else
106 m_gauge = (wxGauge *)NULL;
107
108
109 if ( style & wxPD_ELAPSED_TIME )
110 {
111 m_elapsed = new wxStaticText(this, -1, "");
112 c = new wxLayoutConstraints;
113 c->right.SameAs(this, wxRight, 2*LAYOUT_X_MARGIN);
114 c->top.Below(lastWindow, LAYOUT_Y_MARGIN);
115 c->width.Absolute(60);
116 c->height.AsIs();
117 m_elapsed->SetConstraints(c);
118
119 wxStaticText *dummy = new wxStaticText(this, -1, _T("Elapsed time : "));
120 c = new wxLayoutConstraints;
121 c->right.LeftOf(m_elapsed);
122 c->top.SameAs(m_elapsed, wxTop, 0);
123 c->width.AsIs();
124 c->height.AsIs();
125 dummy->SetConstraints(c);
126
127 lastWindow = m_elapsed;
128 }
129
130 if ( style & wxPD_ESTIMATED_TIME )
131 {
132 m_estimated = new wxStaticText(this, -1, "");
133 c = new wxLayoutConstraints;
134 c->right.SameAs(this, wxRight, 2*LAYOUT_X_MARGIN);
135 c->top.Below(lastWindow, 0);
136 c->width.Absolute(60);
137 c->height.AsIs();
138 m_estimated->SetConstraints(c);
139
140 wxStaticText *dummy = new wxStaticText(this, -1, _T("Estimated time : "));
141 c = new wxLayoutConstraints;
142 c->right.LeftOf(m_estimated);
143 c->top.SameAs(m_estimated, wxTop, 0);
144 c->width.AsIs();
145 c->height.AsIs();
146 dummy->SetConstraints(c);
147
148 lastWindow = m_estimated;
149 }
150
151 if ( style & wxPD_REMAINING_TIME )
152 {
153 m_remaining = new wxStaticText(this, -1, "");
154 c = new wxLayoutConstraints;
155 c->right.SameAs(this, wxRight, 2*LAYOUT_X_MARGIN);
156 c->top.Below(lastWindow, 0);
157 c->width.Absolute(60);
158 c->height.AsIs();
159 m_remaining->SetConstraints(c);
160
161 wxStaticText *dummy = new wxStaticText(this, -1, _T("Remaining time : "));
162 c = new wxLayoutConstraints;
163 c->right.LeftOf(m_remaining);
164 c->top.SameAs(m_remaining, wxTop, 0);
165 c->width.AsIs();
166 c->height.AsIs();
167 dummy->SetConstraints(c);
168
169 lastWindow = m_remaining;
170 }
171
172 if ( hasAbortButton )
173 {
174 m_btnAbort = new wxButton(this, -1, _("Cancel"));
175 c = new wxLayoutConstraints;
176 c->centreX.SameAs(this, wxCentreX);
177 c->top.Below(lastWindow, 2*LAYOUT_Y_MARGIN);
178 c->width.AsIs();
179 c->height.AsIs();
180 m_btnAbort->SetConstraints(c);
181 }
182 else
183 m_btnAbort = (wxButton *)NULL;
184
185 SetAutoLayout(TRUE);
186 Layout();
187
188 // calc the height of the dialog
189 Fit();
190 // and set the width from it - unfortunately, Fit() makes the dialog way too
191 // wide under Windows, so try to find a reasonable value for the width, not
192 // too big and not too small
193 wxSize size = GetClientSize();
194 size.x = wxMax(3*widthText/2, 2*size.y);
195 SetClientSize(size);
196
197 Show(TRUE);
198 Centre(wxCENTER_FRAME | wxBOTH);
199
200 if(m_disableParentOnly)
201 {
202 if(m_parent) m_parent->Enable(FALSE);
203 }
204 else
205 wxEnableTopLevelWindows(FALSE);
206
207 Enable(TRUE); // enable this window
208 wxYield();
209 }
210
211
212 bool
213 wxProgressDialog::Update(int value, const wxString& newmsg)
214 {
215 wxASSERT_MSG( value == -1 || m_gauge, _T("cannot update non existent dialog") );
216 wxASSERT_MSG( value <= m_maximum, _T("invalid progress value") );
217
218
219 if( m_gauge )
220 m_gauge->SetValue(value + 1);
221
222 if( !newmsg.IsEmpty() )
223 m_msg->SetLabel(newmsg);
224
225 if ( (m_elapsed || m_remaining || m_estimated) && (value != 0) )
226 {
227 wxTime timenow;
228 wxTime diff = timenow - *m_time;
229 unsigned long secs = diff.GetSecond() + 60 * diff.GetMinute() + 60 * 60 * diff.GetHour();
230 unsigned long estim = secs * m_maximum / value;
231 unsigned long remai = estim - secs;
232 wxString s;
233
234 if (m_elapsed)
235 {
236 s.Printf(_T("%i:%02i:%02i"), diff.GetHour(), diff.GetMinute(), diff.GetSecond());
237 if (s != m_elapsed->GetLabel()) m_elapsed->SetLabel(s);
238 }
239 if (m_estimated)
240 {
241 s.Printf(_T("%i:%02i:%02i"), estim / (60 * 60), (estim / 60) % 60, estim % 60);
242 if (s != m_estimated->GetLabel()) m_estimated->SetLabel(s);
243 }
244 if (m_remaining)
245 {
246 s.Printf(_T("%i:%02i:%02i"), remai / (60 * 60), (remai / 60) % 60, remai % 60);
247 if (s != m_remaining->GetLabel()) m_remaining->SetLabel(s);
248 }
249 }
250
251 if ( (value == m_maximum - 1) && !(GetWindowStyleFlag() & wxPD_AUTO_HIDE) )
252 {
253 if ( m_btnAbort )
254 {
255 // tell the user what he should do...
256 m_btnAbort->SetLabel(_("Close"));
257 }
258
259 /*I think the default should be the other way round. If the
260 application wants to set a "Done." message at the end, it should
261 supply it. Any serious objections to this change? Makes the
262 application programmers' work a little easier.
263 if ( !newmsg )
264 {
265 // also provide the finishing message if the application didn't
266 m_msg->SetLabel(_("Done."));
267 }
268 */
269 m_state = Finished;
270
271 // so that we return TRUE below
272 m_state = Finished;
273 }
274 wxYield();
275 return m_state != Canceled;
276 }
277
278 void wxProgressDialog::OnClose(wxCloseEvent& event)
279 {
280 if ( m_state == Uncancelable )
281 event.Veto(TRUE);
282 else
283 m_state = Canceled;
284 }
285
286
287 wxProgressDialog::~wxProgressDialog()
288 {
289 if ( m_disableParentOnly )
290 {
291 if(m_parent) m_parent->Enable(TRUE);
292 }
293 else
294 wxEnableTopLevelWindows(TRUE);
295 if (m_time) delete m_time;
296 }
297
298 #endif