X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/dde19c2180ef8d6415af7bb2492bfcb0a2d5c7e4..b35549525f2a8dd584fdda158829e8406da0541e:/src/generic/progdlgg.cpp diff --git a/src/generic/progdlgg.cpp b/src/generic/progdlgg.cpp index 6677a2ea33..3c962a0f2e 100644 --- a/src/generic/progdlgg.cpp +++ b/src/generic/progdlgg.cpp @@ -99,7 +99,7 @@ wxProgressDialog::wxProgressDialog(const wxString& title, int maximum, wxWindow *parent, int style) - : wxDialog(GetParentForModalDialog(parent), wxID_ANY, title), + : wxDialog(GetParentForModalDialog(parent, style), wxID_ANY, title), m_skip(false), m_delay(3), m_hasAbortButton(false), @@ -139,11 +139,6 @@ wxProgressDialog::wxProgressDialog(const wxString& title, m_parentTop = wxGetTopLevelParent(parent); - wxClientDC dc(this); - dc.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); - wxCoord widthText = 0; - dc.GetTextExtent(message, &widthText, NULL, NULL, NULL, NULL); - // top-level sizerTop wxSizer * const sizerTop = new wxBoxSizer(wxVERTICAL); @@ -313,6 +308,9 @@ wxProgressDialog::CreateLabel(const wxString& text, wxSizer *sizer) bool wxProgressDialog::Update(int value, const wxString& newmsg, bool *skip) { + if ( !DoBeforeUpdate(skip) ) + return false; + wxASSERT_MSG( value == -1 || m_gauge, wxT("cannot update non existent dialog") ); #ifdef __WXMSW__ @@ -403,8 +401,17 @@ wxProgressDialog::Update(int value, const wxString& newmsg, bool *skip) m_msg->SetLabel(_("Done.")); } + 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 @@ -419,7 +426,7 @@ wxProgressDialog::Update(int value, const wxString& newmsg, bool *skip) } else // not at maximum yet { - return DoAfterUpdate(skip); + DoAfterUpdate(); } // update the display in case yielding above didn't do it @@ -430,6 +437,9 @@ wxProgressDialog::Update(int value, const wxString& newmsg, bool *skip) bool wxProgressDialog::Pulse(const wxString& newmsg, bool *skip) { + if ( !DoBeforeUpdate(skip) ) + return false; + wxASSERT_MSG( m_gauge, wxT("cannot update non existent dialog") ); // show a bit of progress @@ -446,13 +456,20 @@ bool wxProgressDialog::Pulse(const wxString& newmsg, bool *skip) SetTimeLabel((unsigned long)-1, m_remaining); } - return DoAfterUpdate(skip); + DoAfterUpdate(); + + return m_state != Canceled; } -bool wxProgressDialog::DoAfterUpdate(bool *skip) +bool wxProgressDialog::DoBeforeUpdate(bool *skip) { + wxCHECK_MSG(wxEventLoopBase::GetActive(), false, + "wxProgressDialog::DoBeforeUpdate 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(); @@ -467,6 +484,17 @@ bool wxProgressDialog::DoAfterUpdate(bool *skip) return m_state != Canceled; } +void wxProgressDialog::DoAfterUpdate() +{ + wxCHECK_RET(wxEventLoopBase::GetActive(), + "wxProgressDialog::DoAfterUpdate 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); +} + void wxProgressDialog::Resume() { m_state = Continue; @@ -508,6 +536,34 @@ 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__ +} + + +bool wxProgressDialog::WasCancelled() const +{ + return m_hasAbortButton && m_state == Canceled; +} + +bool wxProgressDialog::WasSkipped() const +{ + return m_hasSkipButton && m_skip; +} + + // ---------------------------------------------------------------------------- // event handlers // ---------------------------------------------------------------------------- @@ -579,8 +635,7 @@ void wxProgressDialog::ReenableOtherWindows() { if ( HasFlag(wxPD_APP_MODAL) ) { - delete m_winDisabler; - m_winDisabler = NULL; + wxDELETE(m_winDisabler); } else { @@ -666,12 +721,16 @@ void wxProgressDialog::EnableClose() void wxProgressDialog::UpdateMessage(const wxString &newmsg) { + wxCHECK_RET(wxEventLoopBase::GetActive(), + "wxProgressDialog::UpdateMessage needs a running event loop"); + if ( !newmsg.empty() && newmsg != m_msg->GetLabel() ) { m_msg->SetLabel(newmsg); - Fit(); // adapt to the new label size - + // 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); } }