%% options %% wx-gui type = dialog contents = sDialog [wxBoxSizer sDialog] direction = horizontal grow = yes proportion = 1 contents = $space(10) contents = verticalSizer contents = $space(10) [wxBoxSizer verticalSizer] direction = vertical grow = yes proportion = 1 contents = $space(10) contents = sttInProgress contents = $space(10) contents = gaugeProgress centered-x contents = $space(10) contents = sttWait centered-x contents = $space(10) contents = bCancel centered-x contents = $space(10) [wxGauge gaugeProgress] range = 1000 value = 0 grow = yes proportion = 1 [wxStaticText sttInProgress] text = labelText text style = centered no-auto-resize [wxStaticText sttWait] text = wxT("") text style = centered no-auto-resize grow = yes proportion = 1 [wxButton bCancel] text = sText[0] tip = sText[1] id = wxID_CANCEL %% header start /** @file Dk4WxProgressDialog.h Progress dialog. */ #ifndef DK4CONF_H_INCLUDED #include "dk4conf.h" #endif #ifndef DK4TYPES_H_INCLUDED #include "dk4types.h" #endif #ifndef WX_WXPREC_H_INCLUDED #include #define WX_WXPREC_H_INCLUDED 1 #endif #ifdef __BORLANDC__ #pragma hdrstop #endif #ifndef WX_PRECOMP #ifndef WX_WX_H_INCLUDED #include #define WX_WX_H_INCLUDED 1 #endif #endif #ifndef DK4WXAPPLICATIONHELPER_H_INCLUDED #include "Dk4WxApplicationHelper.h" #endif #ifndef DK4WXPROGRESSCONTROLLERBASE_H_INCLUDED #include "Dk4WxProgressControllerBase.h" #endif %% class start /** Progress dialog (progress bar and cancel button). */ class Dk4WxProgressDialog : public wxDialog, public Dk4WxProgressControllerWorkerBase, Dk4WxProgressControllerOwnerBase { private: /** Event table. */ DECLARE_EVENT_TABLE() protected: /** Synchronize access from multiple threads. */ wxCriticalSection csProtect; /** Text for dialog title. */ wxString sDialogTitle; /** Text for dialog box. */ wxString sDialogText; /** Three text strings shown in the dialog. */ const wxChar *sText[3]; /** Current gauge value. */ int iOld; /** New gauge value, set by worker thread. */ int iNew; /** Dialog box style. */ int iDialogStyle; /** Flag: Aborted via Cancel button. */ bool bAborted; /** Worker thread finished. */ bool bFinished; /** Success indicator from worker thread. */ bool bSuccess; /** Flag: Still active, not yet closed. */ bool bActive; /** Flag: Data to show a message box is available. */ bool bHaveDialog; public: /** Constructor. */ Dk4WxProgressDialog( wxFrame *parent, Dk4WxApplicationHelper *pAppHelp ); /** Handler for idle events. @param event Event to process. */ void OnIdle(wxIdleEvent & event); /** Handler for cancel button. @param event Event to process. */ void OnCancel(wxCommandEvent & WXUNUSED(event)); /** Set new gauge value, called from worker thread. */ void SetGauge(int value); /** Indicate that a dialog box should be shown by the main thread after the worker thread has finished. @param title Message box title. @param msg Message box text. @param st Message box style. */ void SetDialogData( const wxString & title, const wxString & msg, int st = wxID_OK ); /** Start processing. Does nothing, just implement the Dk4WxProgressControllerBase interface. */ void StartProcessing(void); /** Indicate end of processing, called from worker thread. @param success Flag: Successful processing. */ void EndProcessing(bool success = true); /** Check whether we can continue. */ bool CanContinue(void); /** Check whether the worker thread is finished. @return True if the worker thread is finished, false while running. */ bool IsFinished(void); /** Retrieve gauge value. @return Current value for progress gauge. */ int GetGauge(void); /** Abort processing. Called from the progress dialogs Cancel button. */ void AbortProcessing(void); /** Check whether the worker thread finished successfully. @return True to indicate success, false otherwise. */ bool GetSuccess(void); /** Check whether a dialog should be shown. @param title Result variable for message box title. @param msg Result variable for message text. @param style Result variable for dialog box style. @return True to show a dialog, false otherwise. */ bool GetDialogData(wxString & title, wxString & msg, int & style); %% class end }; %% header end %% module start #include "Dk4WxProgressDialog.h" $!trace-include BEGIN_EVENT_TABLE(Dk4WxProgressDialog,wxDialog) EVT_IDLE( Dk4WxProgressDialog::OnIdle) EVT_BUTTON(wxID_CANCEL, Dk4WxProgressDialog::OnCancel) END_EVENT_TABLE() static const wxChar * dk4wx_progress_kw_wx[] = { $!string-table macro=wxT # # 0 Default title # Operation in progress Cancel Abort operation Abortion scheduled, please wait. $!end }; /** Integer preference names. */ static const wxChar * const names[] = { $!string-table macro=wxT progress.min-width $!end }; %% constructor start Dk4WxProgressDialog::Dk4WxProgressDialog( wxFrame *parent, Dk4WxApplicationHelper *pAppHelp ) : wxDialog( parent, wxID_ANY, ( (NULL != pAppHelp) ? (pAppHelp->GetBasicString(2)) : (dk4wx_progress_kw_wx[0]) ), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE ) { const wxChar *labelText = NULL; int minWidth = 300; labelText = dk4wx_progress_kw_wx[0]; if (NULL != pAppHelp) { labelText = pAppHelp->GetBasicString(2); pAppHelp->GetMultiple(names, &minWidth, 1); if (0 > minWidth) { minWidth = 300; } } iOld = 0; iNew = 0; bActive = true; bAborted = false; bFinished = false; bSuccess = false; bHaveDialog = false; sDialogTitle = wxEmptyString; sDialogText = wxEmptyString; iDialogStyle = wxID_OK; if (NULL != pAppHelp) { sText[0] = pAppHelp->GetBasicString(3); // Button label sText[1] = pAppHelp->GetBasicString(4); // Button tooltip sText[2] = pAppHelp->GetBasicString(5); // Text hint } else { sText[0] = dk4wx_progress_kw_wx[1]; sText[1] = dk4wx_progress_kw_wx[2]; sText[2] = dk4wx_progress_kw_wx[3]; } %% constructor end if (dkctGUILayoutOK) { wxSize gaugeSize = gaugeProgress->GetMinSize(); if (300 > gaugeSize.GetWidth()) { gaugeSize.SetWidth(300); gaugeProgress->SetMinSize(gaugeSize); } sDialog->Fit(this); sDialog->SetSizeHints(this); } } %% module end void Dk4WxProgressDialog::OnIdle(wxIdleEvent & event) { int result; { wxCriticalSectionLocker lock(csProtect); if (bActive) { if (bFinished) { bActive = false; result = wxID_OK; if ((bAborted) || (!(bSuccess))) { result = wxID_CANCEL; } if (IsModal()) { EndModal(result); } else { SetReturnCode((bSuccess) && (!(bAborted))); Show(false); } } else { if (iNew != iOld) { iOld = iNew; gaugeProgress->SetValue(iNew); Refresh(); Update(); } event.RequestMore(); } } } event.Skip(); } void Dk4WxProgressDialog::OnCancel(wxCommandEvent & WXUNUSED(event)) { bCancel->Enable(false); bCancel->SetToolTip(sText[2]); Refresh(); Update(); { wxCriticalSectionLocker lock(csProtect); if (!(bFinished)) { bAborted = true; } } } void Dk4WxProgressDialog::SetGauge(int value) { wxCriticalSectionLocker lock(csProtect); iNew = value; } void Dk4WxProgressDialog::SetDialogData( const wxString & title, const wxString & msg, int st ) { wxCriticalSectionLocker lock(csProtect); bHaveDialog = true; sDialogTitle = title; sDialogText = msg; iDialogStyle = st; } void Dk4WxProgressDialog::StartProcessing(void) { wxCriticalSectionLocker lock(csProtect); bActive = true; sDialogTitle = wxEmptyString; sDialogText = wxEmptyString; iOld = 0; iNew = 0; bAborted = false; bFinished = false; bSuccess = true; bActive = true; bHaveDialog = false; } void Dk4WxProgressDialog::EndProcessing(bool success) { wxCriticalSectionLocker lock(csProtect); bFinished = true; if (!(bAborted)) { bSuccess = success; } } bool Dk4WxProgressDialog::CanContinue(void) { bool back = true; { wxCriticalSectionLocker lock(csProtect); if ((bAborted) || (bFinished)) { back = false; } } return back; } bool Dk4WxProgressDialog::IsFinished(void) { bool back = false; { wxCriticalSectionLocker lock(csProtect); back = bFinished; } return back; } int Dk4WxProgressDialog::GetGauge(void) { int back = 0; { wxCriticalSectionLocker lock(csProtect); back = iNew; } return back; } void Dk4WxProgressDialog::AbortProcessing(void) { wxCriticalSectionLocker lock(csProtect); if (!(bFinished)) { bAborted = true; } } bool Dk4WxProgressDialog::GetSuccess(void) { bool back = false; { wxCriticalSectionLocker lock(csProtect); if (bFinished) { back = true; if ((bAborted) || (!(bSuccess))) { back = false; } } } return back; } bool Dk4WxProgressDialog::GetDialogData( wxString & title, wxString & msg, int & style ) { bool back = false; { wxCriticalSectionLocker lock(csProtect); if (bHaveDialog) { title = sDialogTitle; msg = sDialogText; style = iDialogStyle; back = true; } } return back; }