diff --git a/common/confirm.cpp b/common/confirm.cpp index 9c3ab3dfed..bd0f99d736 100644 --- a/common/confirm.cpp +++ b/common/confirm.cpp @@ -34,6 +34,8 @@ #include #include +#include + class DIALOG_EXIT: public DIALOG_EXIT_BASE { @@ -175,3 +177,156 @@ int YesNoCancelDialog( wxWindow* aParent, return dlg.ShowModal(); } + + +int SelectSingleOption( wxWindow* aParent, const wxString& aTitle, const wxString& aMessage, const wxArrayString& aOptions ) +{ + int ret = -1; + wxDialog* dlg = new DIALOG_SHIM( aParent, wxID_ANY, aTitle ); + dlg->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* boxSizer = new wxBoxSizer( wxVERTICAL ); + + if( !aMessage.IsEmpty() ) + boxSizer->Add( new wxStaticText( dlg, wxID_ANY, aMessage ), 0, wxEXPAND | wxALL, 5 ); + + std::vector radioButtons; + radioButtons.reserve( aOptions.Count() ); + + for( const wxString& option : aOptions ) + { + radioButtons.emplace_back( new wxRadioButton( dlg, wxID_ANY, _( option ) ) ); + boxSizer->Add( radioButtons.back(), 0, wxEXPAND | wxALL, 5 ); + } + + wxStdDialogButtonSizer* m_sdboxSizer = new wxStdDialogButtonSizer(); + m_sdboxSizer->AddButton( new wxButton( dlg, wxID_OK ) ); + m_sdboxSizer->AddButton( new wxButton( dlg, wxID_CANCEL ) ); + m_sdboxSizer->Realize(); + boxSizer->Add( m_sdboxSizer, 1, wxEXPAND | wxALL, 5 ); + + dlg->SetSizer( boxSizer ); + dlg->Layout(); + boxSizer->Fit( dlg ); + dlg->Centre( wxBOTH ); + + if( dlg->ShowModal() == wxID_OK ) + { + for( int i = 0; i < radioButtons.size(); ++i ) + { + if( radioButtons[i]->GetValue() ) + { + ret = i; + break; + } + } + } + else + { + ret = -1; + } + + dlg->Destroy(); + + return ret; +} + + +class DIALOG_MULTI_OPTIONS : public DIALOG_SHIM +{ +public: + DIALOG_MULTI_OPTIONS( wxWindow* aParent, const wxString& aTitle, const wxString& aMessage, + const wxArrayString& aOptions ) + : DIALOG_SHIM( aParent, wxID_ANY, aTitle ) + { + SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* boxSizer = new wxBoxSizer( wxVERTICAL ); + + if( !aMessage.IsEmpty() ) + boxSizer->Add( new wxStaticText( this, wxID_ANY, aMessage ), 0, wxEXPAND | wxALL, 5 ); + + m_checkBoxes.reserve( aOptions.Count() ); + + for( const wxString& option : aOptions ) + { + m_checkBoxes.emplace_back( new wxCheckBox( this, wxID_ANY, _( option ) ) ); + boxSizer->Add( m_checkBoxes.back(), 0, wxEXPAND | wxALL, 5 ); + } + + wxBoxSizer* btnSizer = new wxBoxSizer( wxHORIZONTAL ); + wxButton* selectAll = new wxButton( this, wxID_ANY, "Select All" ); + btnSizer->Add( selectAll, 0, wxEXPAND | wxALL, 5 ); + wxButton* unselectAll = new wxButton( this, wxID_ANY, "Unselect All" ); + btnSizer->Add( unselectAll, 0, wxEXPAND | wxALL, 5 ); + boxSizer->Add( btnSizer, 0, wxEXPAND | wxALL, 5 ); + + wxStdDialogButtonSizer* m_sdboxSizer = new wxStdDialogButtonSizer(); + m_sdboxSizer->AddButton( new wxButton( this, wxID_OK ) ); + m_sdboxSizer->AddButton( new wxButton( this, wxID_CANCEL ) ); + m_sdboxSizer->Realize(); + boxSizer->Add( m_sdboxSizer, 0, wxEXPAND | wxALL, 5 ); + + SetSizer( boxSizer ); + Layout(); + boxSizer->Fit( this ); + Centre( wxBOTH ); + + selectAll->Bind( wxEVT_COMMAND_BUTTON_CLICKED, &DIALOG_MULTI_OPTIONS::selectAll, this ); + unselectAll->Bind( wxEVT_COMMAND_BUTTON_CLICKED, &DIALOG_MULTI_OPTIONS::unselectAll, this ); + } + + std::vector GetSelection() const + { + std::vector ret; + + for( int i = 0; i < m_checkBoxes.size(); ++i ) + { + if( m_checkBoxes[i]->IsChecked() ) + ret.push_back( i ); + } + + return ret; + } + + void SetCheckboxes( bool aValue ) + { + for( auto& cb : m_checkBoxes ) + cb->SetValue( aValue ); + } + +protected: + std::vector m_checkBoxes; + + void selectAll( wxCommandEvent& aEvent ) + { + SetCheckboxes( true ); + } + + void unselectAll( wxCommandEvent& aEvent ) + { + SetCheckboxes( false ); + } +}; + + +std::pair> SelectMultipleOptions( wxWindow* aParent, const wxString& aTitle, + const wxString& aMessage, const wxArrayString& aOptions, bool aDefaultState ) +{ + std::vector ret; + bool clickedOk; + DIALOG_MULTI_OPTIONS dlg( aParent, aTitle, aMessage, aOptions ); + dlg.SetCheckboxes( aDefaultState ); + + if( dlg.ShowModal() == wxID_OK ) + { + ret = dlg.GetSelection(); + clickedOk = true; + } + else + { + clickedOk = false; + } + + return std::make_pair( clickedOk, ret ); +} diff --git a/include/confirm.h b/include/confirm.h index 6dab366cf6..47a6ef4d57 100644 --- a/include/confirm.h +++ b/include/confirm.h @@ -32,6 +32,7 @@ #define __INCLUDE__CONFIRM_H__ #include +#include /** * Function DisplayExitDialog @@ -121,4 +122,27 @@ void DisplayHtmlInfoMessage( wxWindow* parent, const wxString& title, const wxSize& size = wxDefaultSize ); +/** + * Displays a dialog with radioboxes asking the user to select an option. + * @param aParent is the parent window. + * @param aTitle is the dialog title. + * @param aMessage is a text label displayed in the first row of the dialog. + * @param aOptions is a vector of possible options. + * @return Index of the selected option or -1 when the dialog has been cancelled. + */ +int SelectSingleOption( wxWindow* aParent, const wxString& aTitle, const wxString& aMessage, + const wxArrayString& aOptions ); + +/** + * Displays a dialog with checkboxes asking the user to select one or more options. + * @param aParent is the parent window. + * @param aTitle is the dialog title. + * @param aMessage is a text label displayed in the first row of the dialog. + * @param aOptions is a vector of possible options. + * @param aDefaultState is the default state for the checkboxes. + * @return Vector containing indices of the selected option. + */ +std::pair> SelectMultipleOptions( wxWindow* aParent, const wxString& aTitle, + const wxString& aMessage, const wxArrayString& aOptions, bool aDefaultState = false ); + #endif /* __INCLUDE__CONFIRM_H__ */