00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
#include <wx/wxprec.h>
00032
00033
#ifdef __BORLANDC__
00034
#pragma hdrstop
00035
#endif
00036
00037
#ifndef WX_PRECOMP
00038
00039
#include <wx/wx.h>
00040
#endif
00041
00042
#include "dlgProgress.hpp"
00043
#include "comdefs.hpp"
00044
00045
#include "compat.hpp"
00046
00047
00048
00049
00050
using namespace std;
00051
00052
00053 IMPLEMENT_DYNAMIC_CLASS(
dlgProgress, wxDialog)
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 dlgProgress::
dlgProgress(const wxString& title, const wxString& message,
00067
int maximum, wxWindow* parent,
int style)
00068 : wxDialog(parent, -1, title)
00069 {
00070
00071 SetExtraStyle(GetExtraStyle() | wxWS_EX_TRANSIENT);
00072
00073 m_windowStyle |= style;
00074
00075
bool hasAbortButton = (style & wxPD_CAN_ABORT) != 0;
00076
00077
#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
00078
00079
00080
00081
00082
if (!hasAbortButton)
00083 EnableCloseButton(FALSE);
00084
#endif // wxMSW
00085
00086 state = hasAbortButton ? Continue : Uncancelable;
00087 this->maximum = maximum;
00088
00089
#if defined(__WXMSW__) || defined(__WXPM__)
00090
00091
00092 factor = this->maximum / SHRT_MAX + 1;
00093 this->maximum /= factor;
00094
#endif // __WXMSW__
00095
00096
00097 ctrParentTop = parent;
00098
while (ctrParentTop && ctrParentTop->GetParent())
00099 ctrParentTop = ctrParentTop->GetParent();
00100
00101
00102 createControls();
00103
00104 this->Centre(wxBOTH);
00105
00106
if (style & wxPD_APP_MODAL)
00107 winDisabler =
new wxWindowDisabler(
this);
00108
else
00109
if (ctrParentTop)
00110 {
00111 ctrParentTop->Enable(FALSE);
00112 winDisabler = (wxWindowDisabler*)NULL;
00113 }
00114
00115 this->Show(
true);
00116 this->Enable(
true);
00117
00118
00119 timeStart = ::wxGetCurrentTime();
00120
00121
00122
if (lblElapsed)
00123 SetTimeLabel(0, lblElapsed);
00124
00125
00126 wxYield();
00127
00128
#ifdef __WXMAC__
00129
MacUpdateImmediately();
00130
#endif
00131
}
00132
00133
00134
00135
00136
00137
00138 void dlgProgress::createControls(
const wxString& message)
00139 {
00140
00141 wxClientDC dc(
this);
00142 wxSize size = wxDefaultSize;
00143 size.SetHeight(GetCharHeight() * 2);
00144
lblMessage =
new wxStaticText(
this, -1, message, wxDefaultPosition, size);
00145
00146
if (
maximum > 0)
00147
00148
00149
00150
gauProgress =
new wxGauge(
this, -1,
maximum, wxDefaultPosition,
00151 wxDefaultSize, wxGA_HORIZONTAL);
00152
else
00153
gauProgress = (wxGauge*)NULL;
00154
00155
00156 size_t nTimeLabels = 0;
00157
00158
00159 wxStaticText* lblElapsedTxt;
00160
if (GetWindowStyle() & wxPD_ELAPSED_TIME)
00161 {
00162 lblElapsedTxt =
new wxStaticText(
this, -1, _(
"Elapsed time:"));
00163
lblElapsed =
new wxStaticText(
this, -1, _(
"unknown"));
00164 nTimeLabels++;
00165 }
00166
else
00167 {
00168 lblElapsedTxt = (wxStaticText*)NULL;
00169
lblElapsed = (wxStaticText*)NULL;
00170 }
00171
00172
00173 wxStaticText* lblEstimatedTxt;
00174
if (GetWindowStyle() & wxPD_ESTIMATED_TIME)
00175 {
00176 lblEstimatedTxt =
new wxStaticText(
this, -1, _(
"Estimated time:"));
00177
lblEstimated =
new wxStaticText(
this, -1, _(
"unknown"));
00178 nTimeLabels++;
00179 }
00180
else
00181 {
00182 lblEstimatedTxt = (wxStaticText*)NULL;
00183
lblEstimated = (wxStaticText*)NULL;
00184 }
00185
00186
00187 wxStaticText* lblRemainingTxt;
00188
if (GetWindowStyle() & wxPD_REMAINING_TIME)
00189 {
00190 lblRemainingTxt =
new wxStaticText(
this, -1, _(
"Remaining time:"));
00191
lblRemaining =
new wxStaticText(
this, -1, _(
"unknown"));
00192 nTimeLabels++;
00193 }
00194
else
00195 {
00196 lblRemainingTxt = (wxStaticText*)NULL;
00197
lblRemaining = (wxStaticText*)NULL;
00198 }
00199
00200
00201
btnPause =
new wxButton(
this, BTN_PAUSE, _(
"&Pause"));
00202
btnPause->SetDefault();
00203
bool hasAbortButton = (GetWindowStyle() & wxPD_CAN_ABORT) != 0;
00204
btnCancel =
new wxButton(
this, wxID_CANCEL, _(
"&Cancel"));
00205
if (!hasAbortButton)
00206
btnCancel->Enable(
false);
00207
00208
00209
00210
int clientHeight = 0;
00211
00212
00213 wxBoxSizer* dlgProgressSizer2 =
new wxBoxSizer(wxVERTICAL);
00214 this->SetSizer(dlgProgressSizer2);
00215 wxBoxSizer* dlgProgressSizer =
new wxBoxSizer(wxVERTICAL);
00216 dlgProgressSizer2->Add(dlgProgressSizer, 1, wxALL | wxGROW,
CONTROL_SPACE);
00217 clientHeight +=
CONTROL_SPACE * 2;
00218
00219
00220 dlgProgressSizer->Add(
lblMessage, 0, wxGROW | wxALIGN_LEFT);
00221 clientHeight +=
lblMessage->GetSize().GetHeight();
00222
00223
00224
if (
maximum > 0)
00225 {
00226 dlgProgressSizer->Add(
gauProgress, 0, wxGROW | wxTOP | wxALIGN_LEFT,
CONTROL_SPACE / 2);
00227 clientHeight +=
gauProgress->GetSize().GetHeight() +
CONTROL_SPACE / 2;
00228 }
00229
00230
00231
if (nTimeLabels > 0)
00232 {
00233 clientHeight +=
CONTROL_SPACE;
00234 wxBoxSizer* timeSizerRight =
new wxBoxSizer(wxHORIZONTAL);
00235 dlgProgressSizer->Add(timeSizerRight, 0, wxTOP | wxALIGN_CENTER_HORIZONTAL,
CONTROL_SPACE);
00236 wxFlexGridSizer* timeSizer =
new wxFlexGridSizer(2,
CONTROL_SPACE / 2,
CONTROL_SPACE);
00237 timeSizerRight->Add(timeSizer, 0, wxALIGN_RIGHT);
00238 timeSizer->AddGrowableCol(1);
00239
if (
lblElapsed)
00240 {
00241 timeSizer->Add(lblElapsedTxt, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT);
00242 timeSizer->Add(
lblElapsed, 1, wxALIGN_CENTER_VERTICAL | wxGROW);
00243 clientHeight +=
lblElapsed->GetSize().GetHeight() +
CONTROL_SPACE / 2;
00244 }
00245
if (
lblEstimated)
00246 {
00247 timeSizer->Add(lblEstimatedTxt, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT);
00248 timeSizer->Add(
lblEstimated, 1, wxALIGN_CENTER_VERTICAL | wxGROW);
00249 clientHeight +=
lblEstimated->GetSize().GetHeight() +
CONTROL_SPACE / 2;
00250 }
00251
if (
lblRemaining)
00252 {
00253 timeSizer->Add(lblRemainingTxt, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT);
00254 timeSizer->Add(
lblRemaining, 1, wxALIGN_CENTER_VERTICAL | wxGROW);
00255 clientHeight +=
lblRemaining->GetSize().GetHeight() +
CONTROL_SPACE / 2;
00256 }
00257 }
00258
00259
00260 wxGridSizer* buttonsSizer =
new wxGridSizer(2, 0, 2 *
CONTROL_SPACE);
00261 buttonsSizer->Add(
btnPause);
00262 buttonsSizer->Add(
btnCancel);
00263 dlgProgressSizer->Add(buttonsSizer, 0, wxTOP | wxALIGN_RIGHT,
CONTROL_SPACE);
00264 clientHeight +=
CONTROL_SPACE + wxMax(
btnPause->GetSize().GetHeight(),
btnCancel->GetSize().GetHeight());
00265
00266
00267 this->SetAutoLayout(
true);
00268 this->Layout();
00269
00270
00271 size.SetHeight(clientHeight);
00272 size.SetWidth((16 * size.GetHeight()) / 7);
00273 SetClientSize(size);
00274 }
00275
00276
00277
00278
00279
00280
00281 dlgProgress::~dlgProgress()
00282 {
00283
00284
ReenableOtherWindows();
00285 }
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295 void dlgProgress::ReenableOtherWindows()
00296 {
00297
if (GetWindowStyle() & wxPD_APP_MODAL)
00298 {
00299
delete winDisabler;
00300
winDisabler = (wxWindowDisabler*)NULL;
00301 }
00302
else
00303
if (
ctrParentTop)
00304
ctrParentTop->Enable(
true);
00305 }
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316 bool dlgProgress::Update(
int value,
const wxString& newmsg)
00317 {
00318 wxASSERT_MSG(
state != paused, wxT(
"paused state isn't handled correctly"));
00319 wxASSERT_MSG(value == -1 ||
gauProgress, wxT(
"cannot update non existent dialog"));
00320
00321
#ifdef __WXMSW__
00322
value /= factor;
00323
#endif // __WXMSW__
00324
00325 wxASSERT_MSG(value <=
maximum, wxT(
"invalid progress value"));
00326
00327
if (gauProgress && value < maximum)
00328 gauProgress->SetValue(value + 1);
00329
00330
if (!newmsg.IsEmpty())
00331 {
00332
lblMessage->SetLabel(newmsg);
00333 wxYield();
00334 }
00335
00336
if ((
lblElapsed ||
lblRemaining ||
lblEstimated) && (value != 0))
00337 {
00338
unsigned long elapsed = wxGetCurrentTime() -
timeStart;
00339
unsigned long estimated = (
unsigned long)(((
double)elapsed * maximum) / ((
double)value));
00340
unsigned long remaining = estimated - elapsed;
00341
00342
SetTimeLabel(elapsed,
lblElapsed);
00343
SetTimeLabel(estimated,
lblEstimated);
00344
SetTimeLabel(remaining,
lblRemaining);
00345 }
00346
00347
if (value == maximum)
00348 {
00349
00350
00351
state = Finished;
00352
if (!(GetWindowStyle() & wxPD_AUTO_HIDE))
00353 {
00354
00355
if (gauProgress != NULL)
00356 gauProgress->SetValue(maximum);
00357
00358
00359
btnPause->Disable();
00360
00361
00362
btnCancel->SetLabel(_(
"&Close"));
00363
btnCancel->Enable(
true);
00364
btnCancel->SetFocus();
00365
00366
bool hasAbortButton = (GetWindowStyle() & wxPD_CAN_ABORT) != 0;
00367
#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
00368
if (!hasAbortButton)
00369 {
00370
00371 EnableCloseButton(TRUE);
00372 }
00373
#endif // __WXMSW__
00374
00375
if (!newmsg)
00376
00377
lblMessage->SetLabel(_(
"Done."));
00378
00379 wxYield();
00380 (
void)ShowModal();
00381 }
00382
else
00383 {
00384
00385
00386
00387
ReenableOtherWindows();
00388
00389 Hide();
00390 }
00391 }
00392
else
00393 {
00394
00395 wxYield();
00396 }
00397
00398
#ifdef __WXMAC__
00399
MacUpdateImmediately();
00400
#endif
00401
00402
return state != Canceled;
00403 }
00404
00405
00406
00407
00408
00409
00410 void dlgProgress::Resume()
00411 {
00412
if (
state == Canceled)
00413 {
00414
state = Continue;
00415
00416
00417
00418
if ((GetWindowStyle() & wxPD_CAN_ABORT) != 0)
00419
btnCancel->Enable();
00420
btnPause->Enable();
00421 }
00422 }
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434 bool dlgProgress::Show(
bool show)
00435 {
00436
00437
00438
00439
if (!show)
00440
ReenableOtherWindows();
00441
00442
return wxDialog::Show(show);
00443 }
00444
00445
00446
00447
00448
00449
00450
00451
00452 void dlgProgress::btnCancelClick(wxCommandEvent& event)
00453 {
00454
if (
state == Finished)
00455 {
00456
00457
00458 event.Skip();
00459 }
00460
else
00461 {
00462
00463
00464
state = Canceled;
00465
00466
00467
00468
btnCancel->Disable();
00469
btnPause->Disable();
00470 }
00471 }
00472
00473
00474
00475
00476
00477
00478
00479
00480 void dlgProgress::btnPauseClick(wxCommandEvent& event)
00481 {
00482
switch (
state)
00483 {
00484
case Continue :
00485
case Uncancelable :
00486
btnPause->SetLabel(_(
"C&ontinue"));
00487
state = Paused;
00488
break;
00489
case Paused :
00490
btnPause->SetLabel(_(
"&Pause"));
00491
if ((GetWindowStyle() & wxPD_CAN_ABORT) != 0)
00492
state = Continue;
00493
else
00494
state = Uncancelable;
00495
break;
00496 }
00497 wxYield();
00498
#ifdef __WXMAC__
00499
MacUpdateImmediately();
00500
#endif
00501
}
00502
00503
00504
00505
00506
00507
00508
00509
00510 void dlgProgress::FrameClose(wxCloseEvent& event)
00511 {
00512
if (
state == Uncancelable)
00513 {
00514
00515 event.Veto(
true);
00516 }
00517
else if (
state == Finished)
00518 {
00519
00520 event.Skip();
00521 }
00522
else
00523 {
00524
00525
if ((GetWindowStyle() & wxPD_CAN_ABORT) != 0)
00526
00527
state = Canceled;
00528 }
00529 }
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539 bool dlgProgress::isPaused()
const
00540
{
00541
return state == Paused;
00542 }
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552 void dlgProgress::SetTimeLabel(
unsigned long val, wxStaticText* label)
00553 {
00554
if (label != NULL)
00555 {
00556 wxString s;
00557
unsigned long hours = val / 3600;
00558
unsigned long minutes = (val % 3600) / 60;
00559
unsigned long seconds = val % 60;
00560 s.Printf(wxT(
"%lu:%02lu:%02lu"), hours, minutes, seconds);
00561
00562
if (s != label->GetLabel())
00563 label->SetLabel(s);
00564 }
00565 }
00566
00567
00568
00569
00570 BEGIN_EVENT_TABLE(
dlgProgress, wxDialog)
00571 EVT_BUTTON(wxID_CANCEL,
dlgProgress::btnCancelClick)
00572 EVT_BUTTON(BTN_PAUSE,
dlgProgress::btnPauseClick)
00573 EVT_CLOSE(
dlgProgress::FrameClose)
00574 END_EVENT_TABLE()
00575