+ wxCHECK_MSG(wxEventLoopBase::GetActive(), false,
+ "wxProgressDialog::Update needs a running event loop");
+
+ // allow the window to repaint:
+ // NOTE: since we yield only for UI events with this call, there
+ // should be no side-effects
+ wxEventLoopBase::GetActive()->YieldFor(wxEVT_CATEGORY_UI);
+
+ // NOTE: this call results in a new event loop being created
+ // and to a call to ProcessPendingEvents() (which may generate
+ // unwanted re-entrancies).
+ (void)ShowModal();
+ }
+ else // auto hide
+ {
+ // reenable other windows before hiding this one because otherwise
+ // Windows wouldn't give the focus back to the window which had
+ // been previously focused because it would still be disabled
+ ReenableOtherWindows();
+
+ Hide();
+ }
+ }
+ else // not at maximum yet
+ {
+ return DoAfterUpdate(skip);
+ }
+
+ // update the display in case yielding above didn't do it
+ Update();
+
+ return m_state != Canceled;
+}
+
+bool wxProgressDialog::Pulse(const wxString& newmsg, bool *skip)
+{
+ wxASSERT_MSG( m_gauge, wxT("cannot update non existent dialog") );
+
+ // show a bit of progress
+ m_gauge->Pulse();
+
+ UpdateMessage(newmsg);
+
+ if (m_elapsed || m_remaining || m_estimated)
+ {
+ unsigned long elapsed = wxGetCurrentTime() - m_timeStart;
+
+ SetTimeLabel(elapsed, m_elapsed);
+ SetTimeLabel((unsigned long)-1, m_estimated);
+ SetTimeLabel((unsigned long)-1, m_remaining);
+ }
+
+ return DoAfterUpdate(skip);
+}
+
+bool wxProgressDialog::DoAfterUpdate(bool *skip)
+{
+ wxCHECK_MSG(wxEventLoopBase::GetActive(), false,
+ "wxProgressDialog::DoAfterUpdate needs a running event loop");
+
+ // we have to yield because not only we want to update the display but
+ // also to process the clicks on the cancel and skip buttons
+ // NOTE: using YieldFor() this call shouldn't give re-entrancy problems
+ // for event handlers not interested to UI/user-input events.
+ wxEventLoopBase::GetActive()->YieldFor(wxEVT_CATEGORY_UI|wxEVT_CATEGORY_USER_INPUT);
+
+ Update();
+
+ if ( m_skip && skip && !*skip )
+ {
+ *skip = true;
+ m_skip = false;
+ EnableSkip();
+ }
+
+ return m_state != Canceled;
+}
+
+void wxProgressDialog::Resume()
+{
+ m_state = Continue;
+ m_ctdelay = m_delay; // force an update of the elapsed/estimated/remaining time
+ m_break += wxGetCurrentTime()-m_timeStop;
+
+ EnableAbort();
+ EnableSkip();
+ m_skip = false;
+}
+
+bool wxProgressDialog::Show( bool show )
+{
+ // reenable other windows before hiding this one because otherwise
+ // Windows wouldn't give the focus back to the window which had
+ // been previously focused because it would still be disabled
+ if(!show)
+ ReenableOtherWindows();
+
+ return wxDialog::Show(show);
+}
+
+int wxProgressDialog::GetValue() const
+{
+ if (m_gauge)
+ return m_gauge->GetValue();
+ return wxNOT_FOUND;
+}
+
+int wxProgressDialog::GetRange() const
+{
+ if (m_gauge)
+ return m_gauge->GetRange();
+ return wxNOT_FOUND;
+}
+
+wxString wxProgressDialog::GetMessage() const
+{
+ return m_msg->GetLabel();
+}
+
+void wxProgressDialog::SetRange(int maximum)
+{
+ wxASSERT_MSG(m_gauge, "The dialog should have been constructed with a range > 0");
+ wxASSERT_MSG(maximum > 0, "Invalid range");
+
+ m_gauge->SetRange(maximum);
+ m_maximum = maximum;
+
+#if defined(__WXMSW__) || defined(__WXPM__)
+ // we can't have values > 65,536 in the progress control under Windows, so
+ // scale everything down
+ m_factor = m_maximum / 65536 + 1;
+ m_maximum /= m_factor;
+#endif // __WXMSW__
+}
+
+// ----------------------------------------------------------------------------
+// event handlers
+// ----------------------------------------------------------------------------
+
+void wxProgressDialog::OnCancel(wxCommandEvent& event)
+{
+ if ( m_state == Finished )
+ {
+ // this means that the count down is already finished and we're being
+ // shown as a modal dialog - so just let the default handler do the job
+ event.Skip();
+ }
+ else
+ {
+ // request to cancel was received, the next time Update() is called we
+ // will handle it
+ m_state = Canceled;
+
+ // update the buttons state immediately so that the user knows that the
+ // request has been noticed
+ DisableAbort();
+ DisableSkip();
+
+ // save the time when the dialog was stopped
+ m_timeStop = wxGetCurrentTime();
+ }
+}
+
+void wxProgressDialog::OnSkip(wxCommandEvent& WXUNUSED(event))
+{
+ DisableSkip();
+ m_skip = true;