]> git.saurik.com Git - wxWidgets.git/blame - src/generic/progdlgg.cpp
use wxWANTS_CHARS to allow arrows to work inside the control
[wxWidgets.git] / src / generic / progdlgg.cpp
CommitLineData
8fa2e6a2 1/////////////////////////////////////////////////////////////////////////////
9eddec69 2// Name: src/generic/progdlgg.cpp
8fa2e6a2 3// Purpose: wxProgressDialog class
9d55bfef 4// Author: Karsten Ballueder
8fa2e6a2
KB
5// Modified by:
6// Created: 09.05.1999
7// RCS-ID: $Id$
9d55bfef 8// Copyright: (c) Karsten Ballueder
65571936 9// Licence: wxWindows licence
8fa2e6a2
KB
10/////////////////////////////////////////////////////////////////////////////
11
0655ad29
VZ
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
8fa2e6a2
KB
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
f81a6620 24 #pragma hdrstop
8fa2e6a2
KB
25#endif
26
0655ad29
VZ
27#if wxUSE_PROGRESSDLG
28
8fa2e6a2 29#ifndef WX_PRECOMP
f81a6620
VZ
30 #include "wx/utils.h"
31 #include "wx/frame.h"
32 #include "wx/button.h"
33 #include "wx/stattext.h"
0ca3b64f 34 #include "wx/sizer.h"
f81a6620
VZ
35 #include "wx/event.h"
36 #include "wx/gauge.h"
37 #include "wx/intl.h"
720dcba6 38 #include "wx/dcclient.h"
9b61f868 39 #include "wx/timer.h"
9eddec69 40 #include "wx/settings.h"
8fa2e6a2
KB
41#endif
42
fe8635a7 43#include "wx/progdlg.h"
8fa2e6a2 44
d2cdad17
WS
45// ---------------------------------------------------------------------------
46// macros
47// ---------------------------------------------------------------------------
48
49/* Macro for avoiding #ifdefs when value have to be different depending on size of
9a357011 50 device we display on - take it from something like wxDesktopPolicy in the future
d2cdad17
WS
51 */
52
53#if defined(__SMARTPHONE__)
54 #define wxLARGESMALL(large,small) small
55#else
56 #define wxLARGESMALL(large,small) large
57#endif
58
0655ad29
VZ
59// ----------------------------------------------------------------------------
60// constants
61// ----------------------------------------------------------------------------
62
d2cdad17 63#define LAYOUT_MARGIN wxLARGESMALL(8,2)
8fa2e6a2 64
ecda9475
WS
65static const int wxID_SKIP = 32000; // whatever
66
0655ad29
VZ
67// ----------------------------------------------------------------------------
68// private functions
69// ----------------------------------------------------------------------------
70
71// update the label to show the given time (in seconds)
72static void SetTimeLabel(unsigned long val, wxStaticText *label);
73
74// ----------------------------------------------------------------------------
75// event tables
76// ----------------------------------------------------------------------------
8fa2e6a2 77
1b6452df 78BEGIN_EVENT_TABLE(wxProgressDialog, wxDialog)
ef8698d6 79 EVT_BUTTON(wxID_CANCEL, wxProgressDialog::OnCancel)
ecda9475 80 EVT_BUTTON(wxID_SKIP, wxProgressDialog::OnSkip)
ef8698d6 81
ef8698d6 82 EVT_CLOSE(wxProgressDialog::OnClose)
1b6452df 83END_EVENT_TABLE()
8fa2e6a2 84
1b6452df 85IMPLEMENT_CLASS(wxProgressDialog, wxDialog)
8fa2e6a2 86
0655ad29 87// ============================================================================
db1a42b8 88// wxProgressDialog implementation
0655ad29 89// ============================================================================
8fa2e6a2 90
0655ad29 91// ----------------------------------------------------------------------------
db1a42b8 92// wxProgressDialog creation
0655ad29 93// ----------------------------------------------------------------------------
f81a6620 94
695f550b
VZ
95wxProgressDialog::wxProgressDialog(const wxString& title,
96 const wxString& message,
0655ad29
VZ
97 int maximum,
98 wxWindow *parent,
99 int style)
2229243b 100 : wxDialog(GetParentForModalDialog(parent), wxID_ANY, title),
3786ce5a 101 m_skip(false),
69c69546
WS
102 m_delay(3),
103 m_hasAbortButton(false),
104 m_hasSkipButton(false)
0655ad29 105{
39cc7a0b
VZ
106 // we may disappear at any moment, let the others know about it
107 SetExtraStyle(GetExtraStyle() | wxWS_EX_TRANSIENT);
96becbd8
VS
108 m_windowStyle |= style;
109
69c69546
WS
110 m_hasAbortButton = (style & wxPD_CAN_ABORT) != 0;
111 m_hasSkipButton = (style & wxPD_CAN_SKIP) != 0;
c4d305b7 112
cff7ef89 113#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
c4d305b7
VZ
114 // we have to remove the "Close" button from the title bar then as it is
115 // confusing to have it - it doesn't work anyhow
116 //
117 // FIXME: should probably have a (extended?) window style for this
69c69546 118 if ( !m_hasAbortButton )
c4d305b7 119 {
dabbc6a5 120 EnableCloseButton(false);
c4d305b7
VZ
121 }
122#endif // wxMSW
123
d2cdad17
WS
124#if defined(__SMARTPHONE__)
125 SetLeftMenu();
126#endif
127
69c69546 128 m_state = m_hasAbortButton ? Continue : Uncancelable;
0655ad29
VZ
129 m_maximum = maximum;
130
94640e04 131#if defined(__WXMSW__) || defined(__WXPM__)
7c349adb
VZ
132 // we can't have values > 65,536 in the progress control under Windows, so
133 // scale everything down
134 m_factor = m_maximum / 65536 + 1;
135 m_maximum /= m_factor;
136#endif // __WXMSW__
137
6258e418 138 m_parentTop = wxGetTopLevelParent(parent);
abceee76 139
0655ad29 140 wxClientDC dc(this);
a756f210 141 dc.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
e8a301af 142 wxCoord widthText = 0;
f1415824 143 dc.GetTextExtent(message, &widthText, NULL, NULL, NULL, NULL);
0655ad29 144
695f550b
VZ
145 // top-level sizerTop
146 wxSizer * const sizerTop = new wxBoxSizer(wxVERTICAL);
d2cdad17 147
dabbc6a5 148 m_msg = new wxStaticText(this, wxID_ANY, message);
695f550b 149 sizerTop->Add(m_msg, 0, wxLEFT | wxTOP, 2*LAYOUT_MARGIN);
0655ad29 150
695f550b 151 wxSize sizeLabel = m_msg->GetSize();
0655ad29
VZ
152 if ( maximum > 0 )
153 {
ecda9475 154 int gauge_style = wxGA_HORIZONTAL;
695f550b 155 if ( style & wxPD_SMOOTH )
ecda9475 156 gauge_style |= wxGA_SMOOTH;
695f550b
VZ
157 m_gauge = new wxGauge
158 (
159 this,
160 wxID_ANY,
161 m_maximum,
162 wxDefaultPosition,
163 // make the progress bar sufficiently long
164 wxSize(wxMin(wxGetClientDisplayRect().width/3, 300), -1),
165 gauge_style
166 );
167
168 sizerTop->Add(m_gauge, 0, wxLEFT | wxRIGHT | wxTOP | wxEXPAND, 2*LAYOUT_MARGIN);
0655ad29 169 m_gauge->SetValue(0);
0655ad29
VZ
170 }
171 else
695f550b
VZ
172 {
173 m_gauge = NULL;
174 }
0655ad29
VZ
175
176 // create the estimated/remaining/total time zones if requested
695f550b
VZ
177 m_elapsed =
178 m_estimated =
179 m_remaining = NULL;
180 m_display_estimated =
181 m_last_timeupdate =
182 m_break = 0;
2c5ef4e2 183 m_ctdelay = 0;
0655ad29 184
6f457a77 185 // if we are going to have at least one label, remember it in this var
8d6854a6
VZ
186 wxStaticText *label = NULL;
187
188 // also count how many labels we really have
189 size_t nTimeLabels = 0;
190
695f550b
VZ
191 wxSizer * const sizerLabels = new wxFlexGridSizer(2);
192
0655ad29
VZ
193 if ( style & wxPD_ELAPSED_TIME )
194 {
195 nTimeLabels++;
196
8d6854a6 197 label =
695f550b 198 m_elapsed = CreateLabel(_("Elapsed time:"), sizerLabels);
0655ad29
VZ
199 }
200
201 if ( style & wxPD_ESTIMATED_TIME )
202 {
203 nTimeLabels++;
204
8d6854a6 205 label =
695f550b 206 m_estimated = CreateLabel(_("Estimated time:"), sizerLabels);
0655ad29
VZ
207 }
208
209 if ( style & wxPD_REMAINING_TIME )
210 {
211 nTimeLabels++;
212
8d6854a6 213 label =
695f550b 214 m_remaining = CreateLabel(_("Remaining time:"), sizerLabels);
0655ad29 215 }
695f550b 216 sizerTop->Add(sizerLabels, 0, wxALIGN_CENTER_HORIZONTAL | wxTOP, LAYOUT_MARGIN);
0655ad29
VZ
217
218 if ( nTimeLabels > 0 )
219 {
220 // set it to the current time
221 m_timeStart = wxGetCurrentTime();
0655ad29
VZ
222 }
223
d2cdad17 224#if defined(__SMARTPHONE__)
69c69546 225 if ( m_hasSkipButton )
ecda9475 226 SetRightMenu(wxID_SKIP, _("Skip"));
69c69546 227 if ( m_hasAbortButton )
ecda9475 228 SetLeftMenu(wxID_CANCEL);
d2cdad17 229#else
695f550b
VZ
230 m_btnAbort =
231 m_btnSkip = NULL;
232
ecda9475 233 wxBoxSizer *buttonSizer = new wxBoxSizer(wxHORIZONTAL);
0655ad29 234
695f550b 235 // Windows dialogs usually have buttons in the lower right corner
3786ce5a 236 const int sizerFlags =
94640e04 237#if defined(__WXMSW__) || defined(__WXPM__)
ecda9475 238 wxALIGN_RIGHT | wxALL
0655ad29 239#else // !MSW
ecda9475 240 wxALIGN_CENTER_HORIZONTAL | wxBOTTOM | wxTOP
0655ad29 241#endif // MSW/!MSW
ecda9475
WS
242 ;
243
69c69546 244 if ( m_hasSkipButton )
ecda9475 245 {
695f550b 246 m_btnSkip = new wxButton(this, wxID_SKIP, _("&Skip"));
ecda9475 247
ecda9475 248 buttonSizer->Add(m_btnSkip, 0, sizerFlags, LAYOUT_MARGIN);
0655ad29 249 }
ecda9475 250
69c69546 251 if ( m_hasAbortButton )
e269a9be 252 {
ecda9475
WS
253 m_btnAbort = new wxButton(this, wxID_CANCEL);
254
ecda9475 255 buttonSizer->Add(m_btnAbort, 0, sizerFlags, LAYOUT_MARGIN);
e269a9be 256 }
0655ad29 257
695f550b 258 sizerTop->Add(buttonSizer, 0, sizerFlags, LAYOUT_MARGIN );
ecda9475
WS
259#endif // __SMARTPHONE__/!__SMARTPHONE__
260
695f550b 261 SetSizerAndFit(sizerTop);
0655ad29
VZ
262
263 Centre(wxCENTER_FRAME | wxBOTH);
264
cbc66a27 265 if ( style & wxPD_APP_MODAL )
0655ad29 266 {
cbc66a27 267 m_winDisabler = new wxWindowDisabler(this);
0655ad29
VZ
268 }
269 else
270 {
cbc66a27 271 if ( m_parentTop )
dabbc6a5 272 m_parentTop->Disable();
cbc66a27 273 m_winDisabler = NULL;
0655ad29
VZ
274 }
275
dabbc6a5
DS
276 Show();
277 Enable();
33961d59 278
70f3fad6
VZ
279 // this one can be initialized even if the others are unknown for now
280 //
281 // NB: do it after calling Layout() to keep the labels correctly aligned
282 if ( m_elapsed )
283 {
284 SetTimeLabel(0, m_elapsed);
285 }
286
f89d65ea 287 Update();
8fa2e6a2
KB
288}
289
695f550b
VZ
290wxStaticText *
291wxProgressDialog::CreateLabel(const wxString& text, wxSizer *sizer)
0655ad29 292{
695f550b
VZ
293 wxStaticText *label = new wxStaticText(this, wxID_ANY, text);
294 wxStaticText *value = new wxStaticText(this, wxID_ANY, _("unknown"));
0655ad29 295
d2cdad17
WS
296 // select placement most native or nice on target GUI
297#if defined(__SMARTPHONE__)
695f550b
VZ
298 // value and time to the left in two rows
299 sizer->Add(label, 1, wxALIGN_LEFT);
300 sizer->Add(value, 1, wxALIGN_LEFT);
fe8635a7 301#elif defined(__WXMSW__) || defined(__WXPM__) || defined(__WXMAC__) || defined(__WXGTK20__)
695f550b
VZ
302 // value and time centered in one row
303 sizer->Add(label, 1, wxLARGESMALL(wxALIGN_RIGHT,wxALIGN_LEFT) | wxTOP | wxRIGHT, LAYOUT_MARGIN);
304 sizer->Add(value, 1, wxALIGN_LEFT | wxTOP, LAYOUT_MARGIN);
d2cdad17 305#else
695f550b
VZ
306 // value and time to the right in one row
307 sizer->Add(label);
308 sizer->Add(value, 0, wxLEFT, LAYOUT_MARGIN);
d2cdad17 309#endif
0655ad29 310
695f550b 311 return value;
0655ad29 312}
8fa2e6a2 313
db1a42b8
VZ
314// ----------------------------------------------------------------------------
315// wxProgressDialog operations
316// ----------------------------------------------------------------------------
317
8fa2e6a2 318bool
ecda9475 319wxProgressDialog::Update(int value, const wxString& newmsg, bool *skip)
8fa2e6a2 320{
abceee76 321 wxASSERT_MSG( value == -1 || m_gauge, wxT("cannot update non existent dialog") );
7c349adb
VZ
322
323#ifdef __WXMSW__
324 value /= m_factor;
325#endif // __WXMSW__
326
abceee76
VZ
327 wxASSERT_MSG( value <= m_maximum, wxT("invalid progress value") );
328
c4c6ada9
VZ
329 if ( m_gauge )
330 m_gauge->SetValue(value);
abceee76 331
fe8635a7 332 UpdateMessage(newmsg);
abceee76
VZ
333
334 if ( (m_elapsed || m_remaining || m_estimated) && (value != 0) )
335 {
336 unsigned long elapsed = wxGetCurrentTime() - m_timeStart;
2c5ef4e2
VZ
337 if ( m_last_timeupdate < elapsed
338 || value == m_maximum
339 )
340 {
341 m_last_timeupdate = elapsed;
342 unsigned long estimated = m_break +
343 (unsigned long)(( (double) (elapsed-m_break) * m_maximum ) / ((double)value)) ;
344 if ( estimated > m_display_estimated
345 && m_ctdelay >= 0
346 )
347 {
348 ++m_ctdelay;
349 }
350 else if ( estimated < m_display_estimated
351 && m_ctdelay <= 0
352 )
353 {
354 --m_ctdelay;
355 }
356 else
357 {
358 m_ctdelay = 0;
359 }
360 if ( m_ctdelay >= m_delay // enough confirmations for a higher value
361 || m_ctdelay <= (m_delay*-1) // enough confirmations for a lower value
362 || value == m_maximum // to stay consistent
363 || elapsed > m_display_estimated // to stay consistent
364 || ( elapsed > 0 && elapsed < 4 ) // additional updates in the beginning
365 )
366 {
367 m_display_estimated = estimated;
368 m_ctdelay = 0;
369 }
370 }
371
ce07cd8a 372 long display_remaining = m_display_estimated - elapsed;
2c5ef4e2
VZ
373 if ( display_remaining < 0 )
374 {
375 display_remaining = 0;
376 }
abceee76
VZ
377
378 SetTimeLabel(elapsed, m_elapsed);
2c5ef4e2
VZ
379 SetTimeLabel(m_display_estimated, m_estimated);
380 SetTimeLabel(display_remaining, m_remaining);
abceee76
VZ
381 }
382
ff095200 383 if ( value == m_maximum )
abceee76 384 {
837adaa9
VZ
385 if ( m_state == Finished )
386 {
387 // ignore multiple calls to Update(m_maximum): it may sometimes be
388 // troublesome to ensure that Update() is not called twice with the
389 // same value (e.g. because of the rounding errors) and if we don't
390 // return now we're going to generate asserts below
391 return true;
392 }
393
dabbc6a5 394 // so that we return true below and that out [Cancel] handler knew what
1c79904b
MB
395 // to do
396 m_state = Finished;
397 if( !(GetWindowStyle() & wxPD_AUTO_HIDE) )
abceee76 398 {
69c69546
WS
399 EnableClose();
400 DisableSkip();
cff7ef89 401#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
69c69546 402 EnableCloseButton();
c4d305b7 403#endif // __WXMSW__
abceee76 404
60ad766e 405 if ( newmsg.empty() )
1c79904b
MB
406 {
407 // also provide the finishing message if the application didn't
408 m_msg->SetLabel(_("Done."));
409 }
abceee76 410
822fc380 411 wxYieldIfNeeded() ;
ff095200 412
1c79904b
MB
413 (void)ShowModal();
414 }
ff095200 415 else // auto hide
1c79904b 416 {
ff095200
VZ
417 // reenable other windows before hiding this one because otherwise
418 // Windows wouldn't give the focus back to the window which had
419 // been previously focused because it would still be disabled
1c79904b 420 ReenableOtherWindows();
ff095200
VZ
421
422 Hide();
1c79904b 423 }
abceee76 424 }
f4aa7ec3 425 else // not at maximum yet
abceee76 426 {
f4aa7ec3 427 return DoAfterUpdate(skip);
abceee76 428 }
1b6452df 429
1d1c3a9f 430 // update the display in case yielding above didn't do it
f89d65ea 431 Update();
0655ad29 432
abceee76 433 return m_state != Canceled;
8fa2e6a2
KB
434}
435
f4aa7ec3 436bool wxProgressDialog::Pulse(const wxString& newmsg, bool *skip)
fe8635a7
RR
437{
438 wxASSERT_MSG( m_gauge, wxT("cannot update non existent dialog") );
439
440 // show a bit of progress
441 m_gauge->Pulse();
442
443 UpdateMessage(newmsg);
444
445 if (m_elapsed || m_remaining || m_estimated)
446 {
447 unsigned long elapsed = wxGetCurrentTime() - m_timeStart;
448
449 SetTimeLabel(elapsed, m_elapsed);
450 SetTimeLabel((unsigned long)-1, m_estimated);
451 SetTimeLabel((unsigned long)-1, m_remaining);
452 }
453
f4aa7ec3
VZ
454 return DoAfterUpdate(skip);
455}
456
457bool wxProgressDialog::DoAfterUpdate(bool *skip)
458{
fe8635a7
RR
459 // we have to yield because not only we want to update the display but
460 // also to process the clicks on the cancel and skip buttons
f4aa7ec3
VZ
461 wxYieldIfNeeded();
462
463 Update();
fe8635a7 464
f4aa7ec3 465 if ( m_skip && skip && !*skip )
fe8635a7
RR
466 {
467 *skip = true;
468 m_skip = false;
469 EnableSkip();
470 }
471
472 return m_state != Canceled;
473}
474
db1a42b8
VZ
475void wxProgressDialog::Resume()
476{
477 m_state = Continue;
2c5ef4e2
VZ
478 m_ctdelay = m_delay; // force an update of the elapsed/estimated/remaining time
479 m_break += wxGetCurrentTime()-m_timeStop;
db1a42b8 480
69c69546
WS
481 EnableAbort();
482 EnableSkip();
ecda9475 483 m_skip = false;
db1a42b8
VZ
484}
485
7d1dcec2
JS
486bool wxProgressDialog::Show( bool show )
487{
488 // reenable other windows before hiding this one because otherwise
489 // Windows wouldn't give the focus back to the window which had
490 // been previously focused because it would still be disabled
491 if(!show)
492 ReenableOtherWindows();
493
494 return wxDialog::Show(show);
495}
496
0655ad29
VZ
497// ----------------------------------------------------------------------------
498// event handlers
499// ----------------------------------------------------------------------------
500
501void wxProgressDialog::OnCancel(wxCommandEvent& event)
502{
503 if ( m_state == Finished )
504 {
505 // this means that the count down is already finished and we're being
506 // shown as a modal dialog - so just let the default handler do the job
507 event.Skip();
508 }
509 else
510 {
511 // request to cancel was received, the next time Update() is called we
512 // will handle it
513 m_state = Canceled;
1b6452df 514
69c69546 515 // update the buttons state immediately so that the user knows that the
1b6452df 516 // request has been noticed
69c69546
WS
517 DisableAbort();
518 DisableSkip();
2c5ef4e2
VZ
519
520 // save the time when the dialog was stopped
521 m_timeStop = wxGetCurrentTime();
0655ad29
VZ
522 }
523}
524
ecda9475
WS
525void wxProgressDialog::OnSkip(wxCommandEvent& WXUNUSED(event))
526{
69c69546 527 DisableSkip();
ecda9475
WS
528 m_skip = true;
529}
530
8fa2e6a2
KB
531void wxProgressDialog::OnClose(wxCloseEvent& event)
532{
0655ad29 533 if ( m_state == Uncancelable )
abceee76
VZ
534 {
535 // can't close this dialog
dabbc6a5 536 event.Veto();
abceee76
VZ
537 }
538 else if ( m_state == Finished )
539 {
540 // let the default handler close the window as we already terminated
541 event.Skip();
542 }
0655ad29 543 else
abceee76
VZ
544 {
545 // next Update() will notice it
0655ad29 546 m_state = Canceled;
69c69546
WS
547 DisableAbort();
548 DisableSkip();
ecda9475 549
2c5ef4e2 550 m_timeStop = wxGetCurrentTime();
abceee76 551 }
8fa2e6a2
KB
552}
553
0655ad29
VZ
554// ----------------------------------------------------------------------------
555// destruction
556// ----------------------------------------------------------------------------
8fa2e6a2
KB
557
558wxProgressDialog::~wxProgressDialog()
ef8698d6
VZ
559{
560 // normally this should have been already done, but just in case
561 ReenableOtherWindows();
562}
563
564void wxProgressDialog::ReenableOtherWindows()
8fa2e6a2 565{
cbc66a27 566 if ( GetWindowStyle() & wxPD_APP_MODAL )
0655ad29 567 {
cbc66a27 568 delete m_winDisabler;
ef8698d6 569 m_winDisabler = (wxWindowDisabler *)NULL;
0655ad29
VZ
570 }
571 else
572 {
cbc66a27 573 if ( m_parentTop )
dabbc6a5 574 m_parentTop->Enable();
0655ad29 575 }
8fa2e6a2 576}
ce4169a4 577
0655ad29
VZ
578// ----------------------------------------------------------------------------
579// private functions
580// ----------------------------------------------------------------------------
581
582static void SetTimeLabel(unsigned long val, wxStaticText *label)
583{
584 if ( label )
585 {
586 wxString s;
fe8635a7
RR
587
588 if (val != (unsigned long)-1)
589 {
0655ad29
VZ
590 unsigned long hours = val / 3600;
591 unsigned long minutes = (val % 3600) / 60;
592 unsigned long seconds = val % 60;
223d09f6 593 s.Printf(wxT("%lu:%02lu:%02lu"), hours, minutes, seconds);
fe8635a7
RR
594 }
595 else
596 {
597 s = _("Unknown");
598 }
0655ad29
VZ
599
600 if ( s != label->GetLabel() )
601 label->SetLabel(s);
602 }
603}
604
69c69546
WS
605void wxProgressDialog::EnableSkip(bool enable)
606{
607 if(m_hasSkipButton)
608 {
609#ifdef __SMARTPHONE__
610 if(enable)
611 SetRightMenu(wxID_SKIP, _("Skip"));
612 else
613 SetRightMenu();
614#else
615 if(m_btnSkip)
616 m_btnSkip->Enable(enable);
617#endif
618 }
619}
620
621void wxProgressDialog::EnableAbort(bool enable)
622{
623 if(m_hasAbortButton)
624 {
625#ifdef __SMARTPHONE__
626 if(enable)
9a2256da 627 SetLeftMenu(wxID_CANCEL); // stock buttons makes Cancel label
69c69546
WS
628 else
629 SetLeftMenu();
630#else
631 if(m_btnAbort)
632 m_btnAbort->Enable(enable);
633#endif
634 }
635}
636
637void wxProgressDialog::EnableClose()
638{
639 if(m_hasAbortButton)
640 {
641#ifdef __SMARTPHONE__
642 SetLeftMenu(wxID_CANCEL, _("Close"));
643#else
644 if(m_btnAbort)
645 {
646 m_btnAbort->Enable();
647 m_btnAbort->SetLabel(_("Close"));
648 }
649#endif
650 }
651}
652
fe8635a7
RR
653void wxProgressDialog::UpdateMessage(const wxString &newmsg)
654{
655 if ( !newmsg.empty() && newmsg != m_msg->GetLabel() )
656 {
657 m_msg->SetLabel(newmsg);
658
659 wxYieldIfNeeded() ;
660 }
661}
662
0655ad29 663#endif // wxUSE_PROGRESSDLG