#include "wx/dcclient.h"
#include "wx/timer.h"
#include "wx/settings.h"
+ #include "wx/app.h"
#endif
#include "wx/progdlg.h"
+#include "wx/evtloop.h"
// ---------------------------------------------------------------------------
// macros
m_msg = new wxStaticText(this, wxID_ANY, message);
sizerTop->Add(m_msg, 0, wxLEFT | wxTOP, 2*LAYOUT_MARGIN);
- wxSize sizeLabel = m_msg->GetSize();
if ( maximum > 0 )
{
int gauge_style = wxGA_HORIZONTAL;
m_break = 0;
m_ctdelay = 0;
- // if we are going to have at least one label, remember it in this var
- wxStaticText *label = NULL;
-
// also count how many labels we really have
size_t nTimeLabels = 0;
{
nTimeLabels++;
- label =
m_elapsed = CreateLabel(_("Elapsed time:"), sizerLabels);
}
{
nTimeLabels++;
- label =
m_estimated = CreateLabel(_("Estimated time:"), sizerLabels);
}
{
nTimeLabels++;
- label =
m_remaining = CreateLabel(_("Remaining time:"), sizerLabels);
}
sizerTop->Add(sizerLabels, 0, wxALIGN_CENTER_HORIZONTAL | wxTOP, LAYOUT_MARGIN);
// so that we return true below and that out [Cancel] handler knew what
// to do
m_state = Finished;
- if( !(GetWindowStyle() & wxPD_AUTO_HIDE) )
+ if( !HasFlag(wxPD_AUTO_HIDE) )
{
EnableClose();
DisableSkip();
m_msg->SetLabel(_("Done."));
}
- wxYieldIfNeeded() ;
+ 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
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
- wxYieldIfNeeded();
+ // 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();
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::ReenableOtherWindows()
{
- if ( GetWindowStyle() & wxPD_APP_MODAL )
+ if ( HasFlag(wxPD_APP_MODAL) )
{
delete m_winDisabler;
- m_winDisabler = (wxWindowDisabler *)NULL;
+ m_winDisabler = NULL;
}
else
{
if (val != (unsigned long)-1)
{
- unsigned long hours = val / 3600;
- unsigned long minutes = (val % 3600) / 60;
- unsigned long seconds = val % 60;
- s.Printf(wxT("%lu:%02lu:%02lu"), hours, minutes, seconds);
+ unsigned long hours = val / 3600;
+ unsigned long minutes = (val % 3600) / 60;
+ unsigned long seconds = val % 60;
+ s.Printf(wxT("%lu:%02lu:%02lu"), hours, minutes, seconds);
}
else
{
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);
- wxYieldIfNeeded() ;
+ // 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);
}
}