\twocolitem{{\bf wxPD\_AUTO\_HIDE}}{Causes the progress dialog to disappear
from screen as soon as the maximum value of the progress meter has been
reached.}
+\twocolitem{{\bf wxPD\_SMOOTH}}{Causes smooth progress of the gauge control.}
\twocolitem{{\bf wxPD\_CAN\_ABORT}}{This flag tells the dialog that it should have a
"Cancel" button which the user may press. If this happens, the next call to
\helpref{Update()}{wxprogressdialogupdate} will return false.}
+\twocolitem{{\bf wxPD\_CAN\_SKIP}}{This flag tells the dialog that it should have a
+"Skip" button which the user may press. If this happens, the next call to
+ \helpref{Update()}{wxprogressdialogupdate} will return true in its skip parameter.}
\twocolitem{{\bf wxPD\_ELAPSED\_TIME}}{This flag tells the dialog that it should show elapsed time (since creating the dialog).}
\twocolitem{{\bf wxPD\_ESTIMATED\_TIME}}{This flag tells the dialog that it should show estimated time.}
\twocolitem{{\bf wxPD\_REMAINING\_TIME}}{This flag tells the dialog that it should show remaining time.}
\func{virtual bool}{Update}{
\param{int }{value},\rtfsp
- \param{const wxString\& }{newmsg = ""}}
+ \param{const wxString\& }{newmsg = ""},\rtfsp
+ \param{bool *}{skip = NULL}}
Updates the dialog, setting the progress bar to the new value and, if
given changes the message above it. Returns true unless the Cancel button
it is equal to the maximum.}
\docparam{newmsg}{The new messages for the progress dialog text, if it is
empty (which is the default) the message is not changed.}
+\docparam{skip}{If "Skip" button was pressed since last
+\helpref{Update}{wxprogressdialogupdate} call the skip is true.}
#pragma interface "progdlgg.h"
#endif
-#include "wx/setup.h"
+#include "wx/defs.h"
#if wxUSE_PROGRESSDLG
@param newmsg if used, new message to display
@returns true if ABORT button has not been pressed
*/
- virtual bool Update(int value, const wxString& newmsg = wxEmptyString);
+ virtual bool Update(int value, const wxString& newmsg = wxEmptyString, bool *skip = NULL);
/* Can be called to continue after the cancel button has been pressed, but
the program decided to continue the operation (e.g., user didn't
// callback for optional abort button
void OnCancel(wxCommandEvent& event);
+ // callback for optional skip button
+ void OnSkip(wxCommandEvent& event);
+
// callback to disable "hard" window closing
void OnClose(wxCloseEvent& event);
Finished // finished, waiting to be removed from screen
} m_state;
- // the abort button (or NULL if none)
+ // skip some portion
+ bool m_skip;
+
+#if !defined(__SMARTPHONE__)
+ // the abort and skip buttons (or NULL if none)
wxButton *m_btnAbort;
+ wxButton *m_btnSkip;
+#endif
// the maximum value
int m_maximum;
_T("Password entry dialog"),
wxEmptyString,
this);
- if ( !!pwd )
+ if ( !pwd.empty() )
{
wxMessageBox(wxString::Format(wxT("Your password is '%s'"), pwd.c_str()),
_T("Got password"), wxOK | wxICON_INFORMATION, this);
max, // range
this, // parent
wxPD_CAN_ABORT |
+ wxPD_CAN_SKIP |
wxPD_APP_MODAL |
// wxPD_AUTO_HIDE | -- try this as well
wxPD_ELAPSED_TIME |
wxPD_ESTIMATED_TIME |
- wxPD_REMAINING_TIME);
+ wxPD_REMAINING_TIME |
+ wxPD_SMOOTH);
bool cont = true;
- for ( int i = 0; i <= max; i++ )
+ bool skip = false;
+ // each skip will move progress about quarter forward
+ for ( int i = 0; i <= max; i = wxMin(i+(skip?int(max/4):1), max+1), skip = false )
{
#if wxUSE_STOPWATCH && wxUSE_LONGLONG
// do (almost) the same operations as we did for the performance test
#else
wxSleep(1);
#endif
+
+ wxString msg;
+
if ( i == max )
{
- cont = dialog.Update(i, _T("That's all, folks!"));
+ msg = _T("That's all, folks!");
}
- else if ( i == max / 2 )
+ else if ( i > max / 2 )
{
- cont = dialog.Update(i, _T("Only a half left (very long message)!"));
+ msg = _T("Only a half left (very long message)!");
}
- else
+
+#if wxUSE_STOPWATCH && wxUSE_LONGLONG
+ if ( (i % (max/100)) == 0 ) // // only 100 updates, this makes it much faster
{
- #if wxUSE_STOPWATCH && wxUSE_LONGLONG
- if ( (i % (max/100)) == 0 ) // // only 100 updates, this makes it much faster
- {
- cont = dialog.Update(i);
- }
- #else
- cont = dialog.Update(i);
- #endif
+ cont = dialog.Update(i, msg, &skip);
}
+#else
+ cont = dialog.Update(i, msg, &skip);
+#endif
+
if ( !cont )
{
if ( wxMessageBox(_T("Do you really want to cancel?"),
#define LAYOUT_MARGIN wxLARGESMALL(8,2)
+static const int wxID_SKIP = 32000; // whatever
+
// ----------------------------------------------------------------------------
// private functions
// ----------------------------------------------------------------------------
BEGIN_EVENT_TABLE(wxProgressDialog, wxDialog)
EVT_BUTTON(wxID_CANCEL, wxProgressDialog::OnCancel)
+ EVT_BUTTON(wxID_SKIP, wxProgressDialog::OnSkip)
EVT_CLOSE(wxProgressDialog::OnClose)
END_EVENT_TABLE()
wxWindow *parent,
int style)
: wxDialog(parent, wxID_ANY, title),
- m_delay(3)
+ m_delay(3),
+ m_skip(false)
{
// we may disappear at any moment, let the others know about it
SetExtraStyle(GetExtraStyle() | wxWS_EX_TRANSIENT);
-
m_windowStyle |= style;
bool hasAbortButton = (style & wxPD_CAN_ABORT) != 0;
+ bool hasSkipButton = (style & wxPD_CAN_SKIP) != 0;
#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
// we have to remove the "Close" button from the title bar then as it is
if ( maximum > 0 )
{
- // note that we can't use wxGA_SMOOTH because it happens to
- // cause the dialog to be modal. Have an extra
- // style argument to wxProgressDialog, perhaps.
+ int gauge_style = wxGA_HORIZONTAL;
+ if ( ( style & wxPD_SMOOTH ) == wxPD_SMOOTH )
+ gauge_style |= wxGA_SMOOTH;
m_gauge = new wxGauge(this, wxID_ANY, m_maximum,
wxDefaultPosition, wxDefaultSize,
- wxGA_HORIZONTAL);
+ gauge_style );
sizer->Add(m_gauge, 0, wxLEFT | wxRIGHT | wxTOP | wxEXPAND, 2*LAYOUT_MARGIN);
m_gauge->SetValue(0);
sizeDlg.y += nTimeLabels * (label->GetSize().y + LAYOUT_MARGIN);
}
- if ( hasAbortButton )
- {
#if defined(__SMARTPHONE__)
- SetLeftMenu(wxID_CANCEL, _("Cancel"));
- }
+ if ( hasSkipButton )
+ SetRightMenu(wxID_SKIP, _("Skip"));
+ if ( hasAbortButton )
+ SetLeftMenu(wxID_CANCEL);
#else
- m_btnAbort = new wxButton(this, wxID_CANCEL);
+ m_btnAbort = m_btnSkip = (wxButton *)NULL;
+ bool sizeDlgModified = false;
+ wxBoxSizer *buttonSizer = new wxBoxSizer(wxHORIZONTAL);
- // Windows dialogs usually have buttons in the lower right corner
+ const int sizerFlags =
#if defined(__WXMSW__) || defined(__WXPM__)
- sizer->Add(m_btnAbort, 0, wxALIGN_RIGHT | wxALL, 2*LAYOUT_MARGIN);
+ wxALIGN_RIGHT | wxALL
#else // !MSW
- sizer->Add(m_btnAbort, 0, wxALIGN_CENTER_HORIZONTAL | wxBOTTOM | wxTOP, 2*LAYOUT_MARGIN);
+ wxALIGN_CENTER_HORIZONTAL | wxBOTTOM | wxTOP
#endif // MSW/!MSW
+ ;
+
+ if ( hasSkipButton )
+ {
+ m_btnSkip = new wxButton(this, wxID_SKIP, _("Skip"));
+
+ // Windows dialogs usually have buttons in the lower right corner
+ buttonSizer->Add(m_btnSkip, 0, sizerFlags, LAYOUT_MARGIN);
sizeDlg.y += 2*LAYOUT_MARGIN + wxButton::GetDefaultSize().y;
+ sizeDlgModified = true;
}
- else // no "Cancel" button
-#endif // __SMARTPHONE__/!__SMARTPHONE__
+
+ if ( hasAbortButton )
{
- m_btnAbort = (wxButton *)NULL;
+ m_btnAbort = new wxButton(this, wxID_CANCEL);
+
+ // Windows dialogs usually have buttons in the lower right corner
+ buttonSizer->Add(m_btnAbort, 0, sizerFlags, LAYOUT_MARGIN);
+ if(!sizeDlgModified)
+ sizeDlg.y += 2*LAYOUT_MARGIN + wxButton::GetDefaultSize().y;
}
+ sizer->Add(buttonSizer, 0, sizerFlags, LAYOUT_MARGIN );
+#endif // __SMARTPHONE__/!__SMARTPHONE__
+
SetSizerAndFit(sizer);
sizeDlg.y += 2*LAYOUT_MARGIN;
// ----------------------------------------------------------------------------
bool
-wxProgressDialog::Update(int value, const wxString& newmsg)
+wxProgressDialog::Update(int value, const wxString& newmsg, bool *skip)
{
wxASSERT_MSG( value == -1 || m_gauge, wxT("cannot update non existent dialog") );
m_gauge->SetValue(value == m_maximum ? value : value + 1);
}
- if ( !newmsg.IsEmpty() )
+ if ( !newmsg.empty() && newmsg != m_msg->GetLabel() )
{
m_msg->SetLabel(newmsg);
{
#if defined(__SMARTPHONE__)
SetLeftMenu(wxID_CANCEL, _("Close"));
+ SetRightMenu();
#endif
+ if ( m_btnSkip )
+ {
+ // tell the user what he should do...
+ m_btnSkip->Disable();
+ }
+
if ( m_btnAbort )
{
// tell the user what he should do...
}
#endif // __WXMSW__
- if ( !newmsg )
+ if ( !newmsg.empty() )
{
// also provide the finishing message if the application didn't
m_msg->SetLabel(_("Done."));
else
{
// we have to yield because not only we want to update the display but
- // also to process the clicks on the cancel button
+ // also to process the clicks on the cancel and skip buttons
wxYieldIfNeeded() ;
+
+ if ( (m_skip) && (skip != NULL) && (*skip == false) )
+ {
+ *skip = true;
+ m_skip = false;
+ if(m_btnSkip)
+ m_btnSkip->Enable();
+ }
}
// update the display in case yielding above didn't do it
// user interrupt us again if needed
if(m_btnAbort)
m_btnAbort->Enable();
+
+ // enable skipping because the one before OnCancel() is no more valid
+ m_skip = false;
+ if(m_btnSkip)
+ m_btnSkip->Enable();
+
#if defined(__SMARTPHONE__)
SetLeftMenu(wxID_CANCEL, _("Cancel"));
#endif
// request has been noticed
if(m_btnAbort)
m_btnAbort->Disable();
+ if(m_btnSkip)
+ m_btnSkip->Disable();
#if defined(__SMARTPHONE__)
SetLeftMenu();
}
}
+void wxProgressDialog::OnSkip(wxCommandEvent& WXUNUSED(event))
+{
+ if(m_btnSkip)
+ m_btnSkip->Disable();
+ m_skip = true;
+}
+
void wxProgressDialog::OnClose(wxCloseEvent& event)
{
if ( m_state == Uncancelable )
m_state = Canceled;
if(m_btnAbort)
m_btnAbort->Disable();
+ if(m_btnSkip)
+ m_btnSkip->Disable();
+
#if defined(__SMARTPHONE__)
SetLeftMenu();
#endif