From d6c9c1b71e069396bbe3850862de9aa10e6812e0 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 3 Nov 2000 20:52:17 +0000 Subject: [PATCH] added wxGetMultiChoice() (which refuses to work for some reason - will fix a.s.a.p.) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@8676 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/latex/wx/function.tex | 109 ++++++++-- include/wx/generic/choicdgg.h | 294 ++++++++++++++++++++------ samples/console/console.cpp | 54 ++++- samples/dialogs/dialogs.cpp | 26 +++ samples/dialogs/dialogs.h | 2 + samples/minimal/minimal.cpp | 11 + src/generic/choicdgg.cpp | 375 ++++++++++++++++++++++++---------- 7 files changed, 689 insertions(+), 182 deletions(-) diff --git a/docs/latex/wx/function.tex b/docs/latex/wx/function.tex index c48237402e..0b116e9eae 100644 --- a/docs/latex/wx/function.tex +++ b/docs/latex/wx/function.tex @@ -630,6 +630,45 @@ is valid) if the dialog was cancelled. +\membersection{::wxGetMultipleChoices}\label{wxgetmultiplechoices} + +\func{size\_t}{wxGetMultipleChoices}{\\ + \param{wxArrayInt\& }{selections},\\ + \param{const wxString\& }{message},\\ + \param{const wxString\& }{caption},\\ + \param{const wxArrayString\& }{aChoices},\\ + \param{wxWindow *}{parent = NULL},\\ + \param{int}{ x = -1}, \param{int}{ y = -1},\\ + \param{bool}{ centre = TRUE},\\ + \param{int }{width=150}, \param{int }{height=200}} + +\func{size\_t}{wxGetMultipleChoices}{\\ + \param{wxArrayInt\& }{selections},\\ + \param{const wxString\& }{message},\\ + \param{const wxString\& }{caption},\\ + \param{int}{ n}, \param{const wxString\& }{choices[]},\\ + \param{wxWindow *}{parent = NULL},\\ + \param{int}{ x = -1}, \param{int}{ y = -1},\\ + \param{bool}{ centre = TRUE},\\ + \param{int }{width=150}, \param{int }{height=200}} + +Pops up a dialog box containing a message, OK/Cancel buttons and a +multiple-selection listbox. The user may choose an arbitrary (including 0) +number of items in the listbox whose indices will be returned in +{\it selection} array. The initial contents of this array will be used to +select the items when the dialog is shown. + +You may pass the list of strings to choose from either using {\it choices} +which is an array of {\it n} strings for the listbox or by using a single +{\it aChoices} parameter of type \helpref{wxArrayString}{wxarraystring}. + +If {\it centre} is TRUE, the message text (which may include new line +characters) is centred; if FALSE, the message is left-justified. + +\wxheading{Include files} + + + \membersection{::wxGetNumberFromUser}\label{wxgetnumberfromuser} \func{long}{wxGetNumberFromUser}{ @@ -715,18 +754,34 @@ is centred; if FALSE, the message is left-justified. \membersection{::wxGetSingleChoice}\label{wxgetsinglechoice} -\func{wxString}{wxGetSingleChoice}{\param{const wxString\& }{message}, \param{const wxString\& }{caption}, \param{int}{ n}, \param{const wxString\& }{choices[]},\\ - \param{wxWindow *}{parent = NULL}, \param{int}{ x = -1}, \param{int}{ y = -1},\\ - \param{bool}{ centre = TRUE}, \param{int }{width=150}, \param{int }{height=200}} +\func{wxString}{wxGetSingleChoice}{\param{const wxString\& }{message},\\ + \param{const wxString\& }{caption},\\ + \param{const wxArrayString\& }{aChoices},\\ + \param{wxWindow *}{parent = NULL},\\ + \param{int}{ x = -1}, \param{int}{ y = -1},\\ + \param{bool}{ centre = TRUE},\\ + \param{int }{width=150}, \param{int }{height=200}} -Pops up a dialog box containing a message, OK/Cancel buttons and a single-selection -listbox. The user may choose an item and press OK to return a string or -Cancel to return the empty string. +\func{wxString}{wxGetSingleChoice}{\param{const wxString\& }{message},\\ + \param{const wxString\& }{caption},\\ + \param{int}{ n}, \param{const wxString\& }{choices[]},\\ + \param{wxWindow *}{parent = NULL},\\ + \param{int}{ x = -1}, \param{int}{ y = -1},\\ + \param{bool}{ centre = TRUE},\\ + \param{int }{width=150}, \param{int }{height=200}} -{\it choices} is an array of {\it n} strings for the listbox. +Pops up a dialog box containing a message, OK/Cancel buttons and a +single-selection listbox. The user may choose an item and press OK to return a +string or Cancel to return the empty string. Use +\helpref{wxGetSingleChoiceIndex}{wxgetsinglechoiceindex} if empty string is a +valid choice and if you want to be able to detect pressing Cancel reliably. -If {\it centre} is TRUE, the message text (which may include new line characters) -is centred; if FALSE, the message is left-justified. +You may pass the list of strings to choose from either using {\it choices} +which is an array of {\it n} strings for the listbox or by using a single +{\it aChoices} parameter of type \helpref{wxArrayString}{wxarraystring}. + +If {\it centre} is TRUE, the message text (which may include new line +characters) is centred; if FALSE, the message is left-justified. \wxheading{Include files} @@ -734,12 +789,20 @@ is centred; if FALSE, the message is left-justified. \membersection{::wxGetSingleChoiceIndex}\label{wxgetsinglechoiceindex} -\func{int}{wxGetSingleChoiceIndex}{\param{const wxString\& }{message}, \param{const wxString\& }{caption}, \param{int}{ n}, \param{const wxString\& }{choices[]},\\ +\func{int}{wxGetSingleChoiceIndex}{\param{const wxString\& }{message},\\ + \param{const wxString\& }{caption},\\ + \param{const wxArrayString\& }{aChoices},\\ + \param{wxWindow *}{parent = NULL}, \param{int}{ x = -1}, \param{int}{ y = -1},\\ + \param{bool}{ centre = TRUE}, \param{int }{width=150}, \param{int }{height=200}} + +\func{int}{wxGetSingleChoiceIndex}{\param{const wxString\& }{message},\\ + \param{const wxString\& }{caption},\\ + \param{int}{ n}, \param{const wxString\& }{choices[]},\\ \param{wxWindow *}{parent = NULL}, \param{int}{ x = -1}, \param{int}{ y = -1},\\ \param{bool}{ centre = TRUE}, \param{int }{width=150}, \param{int }{height=200}} -As {\bf wxGetSingleChoice} but returns the index representing the selected string. -If the user pressed cancel, -1 is returned. +As {\bf wxGetSingleChoice} but returns the index representing the selected +string. If the user pressed cancel, -1 is returned. \wxheading{Include files} @@ -747,12 +810,26 @@ If the user pressed cancel, -1 is returned. \membersection{::wxGetSingleChoiceData}\label{wxgetsinglechoicedata} -\func{wxString}{wxGetSingleChoiceData}{\param{const wxString\& }{message}, \param{const wxString\& }{caption}, \param{int}{ n}, \param{const wxString\& }{choices[]},\\ - \param{const wxString\& }{client\_data[]}, \param{wxWindow *}{parent = NULL}, \param{int}{ x = -1},\\ - \param{int}{ y = -1}, \param{bool}{ centre = TRUE}, \param{int }{width=150}, \param{int }{height=200}} +\func{wxString}{wxGetSingleChoiceData}{\param{const wxString\& }{message},\\ + \param{const wxString\& }{caption},\\ + \param{const wxArrayString\& }{aChoices},\\ + \param{const wxString\& }{client\_data[]},\\ + \param{wxWindow *}{parent = NULL},\\ + \param{int}{ x = -1}, \param{int}{ y = -1},\\ + \param{bool}{ centre = TRUE}, \param{int }{width=150}, \param{int }{height=200}} + +\func{wxString}{wxGetSingleChoiceData}{\param{const wxString\& }{message},\\ + \param{const wxString\& }{caption},\\ + \param{int}{ n}, \param{const wxString\& }{choices[]},\\ + \param{const wxString\& }{client\_data[]},\\ + \param{wxWindow *}{parent = NULL},\\ + \param{int}{ x = -1}, \param{int}{ y = -1},\\ + \param{bool}{ centre = TRUE}, \param{int }{width=150}, \param{int }{height=200}} As {\bf wxGetSingleChoice} but takes an array of client data pointers -corresponding to the strings, and returns one of these pointers. +corresponding to the strings, and returns one of these pointers or NULL if +Cancel was pressed. The {\it client\_data} array must have the same number of +elements as {\it choices} or {\it aChoices}! \wxheading{Include files} diff --git a/include/wx/generic/choicdgg.h b/include/wx/generic/choicdgg.h index bd0b45d7a0..ff12c18d92 100644 --- a/include/wx/generic/choicdgg.h +++ b/include/wx/generic/choicdgg.h @@ -1,11 +1,11 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: choicdgg.h +// Name: wx/generic/choicdgg.h // Purpose: Generic choice dialogs // Author: Julian Smart -// Modified by: +// Modified by: 03.11.00: VZ to add wxArrayString and multiple sel functions // Created: 01/02/97 // RCS-ID: $Id$ -// Copyright: (c) +// Copyright: (c) wxWindows team // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -16,20 +16,65 @@ #pragma interface "choicdgg.h" #endif +#include "wx/dynarray.h" #include "wx/dialog.h" class WXDLLEXPORT wxListBox; +// ---------------------------------------------------------------------------- +// some (ugly...) constants +// ---------------------------------------------------------------------------- + #define wxCHOICE_HEIGHT 150 #define wxCHOICE_WIDTH 200 #define wxCHOICEDLG_STYLE (wxDEFAULT_DIALOG_STYLE|wxOK | wxCANCEL | wxCENTRE) -class WXDLLEXPORT wxSingleChoiceDialog: public wxDialog +// ---------------------------------------------------------------------------- +// wxAnyChoiceDialog: a base class for dialogs containing a listbox +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxAnyChoiceDialog : public wxDialog { - DECLARE_DYNAMIC_CLASS(wxSingleChoiceDialog) +public: + wxAnyChoiceDialog() { } + + wxAnyChoiceDialog(wxWindow *parent, + const wxString& message, + const wxString& caption, + int n, const wxString *choices, + long styleDlg = wxCHOICEDLG_STYLE, + const wxPoint& pos = wxDefaultPosition, + long styleLbox = wxLB_ALWAYS_SB) + { + (void)Create(parent, message, caption, n, choices, + styleDlg, pos, styleLbox); + } + + bool Create(wxWindow *parent, + const wxString& message, + const wxString& caption, + int n, const wxString *choices, + long styleDlg = wxCHOICEDLG_STYLE, + const wxPoint& pos = wxDefaultPosition, + long styleLbox = wxLB_ALWAYS_SB); + +protected: + wxListBox *m_listbox; +}; +// ---------------------------------------------------------------------------- +// wxSingleChoiceDialog: a dialog with single selection listbox +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxSingleChoiceDialog : public wxAnyChoiceDialog +{ public: + wxSingleChoiceDialog() + { + m_selection = -1; + } + wxSingleChoiceDialog(wxWindow *parent, const wxString& message, const wxString& caption, @@ -39,6 +84,28 @@ public: long style = wxCHOICEDLG_STYLE, const wxPoint& pos = wxDefaultPosition); + bool Create(wxWindow *parent, + const wxString& message, + const wxString& caption, + int n, + const wxString *choices, + char **clientData = (char **)NULL, + long style = wxCHOICEDLG_STYLE, + const wxPoint& pos = wxDefaultPosition); + + void SetSelection(int sel); + int GetSelection() const { return m_selection; } + wxString GetStringSelection() const { return m_stringSelection; } + + // obsolete function (NB: no need to make it return wxChar, it's untyped) + char *GetSelectionClientData() const { return (char *)m_clientData; } + + // implementation from now on + void OnOK(wxCommandEvent& event); + void OnListBoxDClick(wxCommandEvent& event); + + // old, deprecated methods +#ifdef WXWIN_COMPATIBILITY_2 wxSingleChoiceDialog(wxWindow *parent, const wxString& message, const wxString& caption, @@ -50,82 +117,191 @@ public: bool Create(wxWindow *parent, const wxString& message, const wxString& caption, - int n, - const wxString *choices, + const wxStringList& choices, char **clientData = (char **)NULL, long style = wxCHOICEDLG_STYLE, const wxPoint& pos = wxDefaultPosition); +#endif // WXWIN_COMPATIBILITY_2 + +protected: + int m_selection; + wxString m_stringSelection; + +private: + DECLARE_DYNAMIC_CLASS(wxSingleChoiceDialog) + DECLARE_EVENT_TABLE() +}; + +// ---------------------------------------------------------------------------- +// wxMultiChoiceDialog: a dialog with multi selection listbox +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxMultiChoiceDialog : public wxAnyChoiceDialog +{ +public: + wxMultiChoiceDialog() { } + + wxMultiChoiceDialog(wxWindow *parent, + const wxString& message, + const wxString& caption, + int n, + const wxString *choices, + long style = wxCHOICEDLG_STYLE, + const wxPoint& pos = wxDefaultPosition) + { + (void)Create(parent, message, caption, n, choices, style, pos); + } bool Create(wxWindow *parent, const wxString& message, const wxString& caption, - const wxStringList& choices, - char **clientData = (char **)NULL, + int n, + const wxString *choices, long style = wxCHOICEDLG_STYLE, const wxPoint& pos = wxDefaultPosition); - void SetSelection(int sel); - int GetSelection() const { return m_selection; } - wxString GetStringSelection() const { return m_stringSelection; } - - // obsolete function (NB: no need to make it return wxChar, it's untyped) - char *GetSelectionClientData() const { return (char *)m_clientData; } + void SetSelections(const wxArrayInt& selections); + wxArrayInt GetSelections() const { return m_selections; } // implementation from now on void OnOK(wxCommandEvent& event); - void OnListBoxDClick(wxCommandEvent& event); protected: - int m_selection; - long m_dialogStyle; - wxString m_stringSelection; - wxListBox *m_listbox; + wxArrayInt m_selections; private: + DECLARE_DYNAMIC_CLASS(wxMultiChoiceDialog) DECLARE_EVENT_TABLE() }; -WXDLLEXPORT wxString wxGetSingleChoice(const wxString& message, const wxString& caption, - int n, const wxString *choices, wxWindow *parent = (wxWindow *) NULL, - int x = -1, int y = -1, bool centre = TRUE, - int width = wxCHOICE_WIDTH, int height = wxCHOICE_HEIGHT); +// ---------------------------------------------------------------------------- +// wrapper functions which can be used to get selection(s) from the user +// ---------------------------------------------------------------------------- + +// get the user selection as a string +WXDLLEXPORT wxString wxGetSingleChoice(const wxString& message, + const wxString& caption, + const wxArrayString& choices, + wxWindow *parent = (wxWindow *) NULL, + int x = -1, + int y = -1, + bool centre = TRUE, + int width = wxCHOICE_WIDTH, + int height = wxCHOICE_HEIGHT); -WXDLLEXPORT wxString wxGetSingleChoice(const wxString& message, const wxString& caption, - int n, wxChar *choices[], wxWindow *parent = (wxWindow *) NULL, - int x = -1, int y = -1, bool centre = TRUE, - int width = wxCHOICE_WIDTH, int height = wxCHOICE_HEIGHT); +WXDLLEXPORT wxString wxGetSingleChoice(const wxString& message, + const wxString& caption, + int n, const wxString *choices, + wxWindow *parent = (wxWindow *) NULL, + int x = -1, + int y = -1, + bool centre = TRUE, + int width = wxCHOICE_WIDTH, + int height = wxCHOICE_HEIGHT); // Same as above but gets position in list of strings, instead of string, // or -1 if no selection -WXDLLEXPORT int wxGetSingleChoiceIndex(const wxString& message, const wxString& caption, - int n, const wxString *choices, wxWindow *parent = (wxWindow *) NULL, - int x = -1, int y = -1, bool centre = TRUE, - int width = wxCHOICE_WIDTH, int height = wxCHOICE_HEIGHT); - -WXDLLEXPORT int wxGetSingleChoiceIndex(const wxString& message, const wxString& caption, - int n, wxChar *choices[], wxWindow *parent = (wxWindow *) NULL, - int x = -1, int y = -1, bool centre = TRUE, - int width = wxCHOICE_WIDTH, int height = wxCHOICE_HEIGHT); - -// Return client data instead -WXDLLEXPORT void* wxGetSingleChoiceData(const wxString& message, const wxString& caption, - int n, const wxString *choices, void **client_data, - wxWindow *parent = (wxWindow *) NULL, int x = -1, int y = -1, - bool centre = TRUE, - int width = wxCHOICE_WIDTH, int height = wxCHOICE_HEIGHT); - -WXDLLEXPORT void* wxGetSingleChoiceData(const wxString& message, const wxString& caption, - int n, wxChar *choices[], void **client_data, - wxWindow *parent = (wxWindow *) NULL, int x = -1, int y = -1, - bool centre = TRUE, - int width = wxCHOICE_WIDTH, int height = wxCHOICE_HEIGHT); - -/* -WXDLLEXPORT int wxGetMultipleChoice(const wxString& message, const wxString& caption, - int n, const wxString *choices, - int nsel, int * selection, - wxWindow *parent = NULL, int x = -1 , int y = -1, bool centre = TRUE, - int width = wxCHOICE_WIDTH, int height = wxCHOICE_HEIGHT); -*/ +WXDLLEXPORT int wxGetSingleChoiceIndex(const wxString& message, + const wxString& caption, + const wxArrayString& choices, + wxWindow *parent = (wxWindow *) NULL, + int x = -1, + int y = -1, + bool centre = TRUE, + int width = wxCHOICE_WIDTH, + int height = wxCHOICE_HEIGHT); + +WXDLLEXPORT int wxGetSingleChoiceIndex(const wxString& message, + const wxString& caption, + int n, const wxString *choices, + wxWindow *parent = (wxWindow *) NULL, + int x = -1, + int y = -1, + bool centre = TRUE, + int width = wxCHOICE_WIDTH, + int height = wxCHOICE_HEIGHT); + +// Return client data instead or NULL if cancelled +WXDLLEXPORT void* wxGetSingleChoiceData(const wxString& message, + const wxString& caption, + const wxArrayString& choices, + void **client_data, + wxWindow *parent = (wxWindow *) NULL, + int x = -1, int y = -1, + bool centre = TRUE, + int width = wxCHOICE_WIDTH, + int height = wxCHOICE_HEIGHT); + +WXDLLEXPORT void* wxGetSingleChoiceData(const wxString& message, + const wxString& caption, + int n, const wxString *choices, + void **client_data, + wxWindow *parent = (wxWindow *) NULL, + int x = -1, int y = -1, + bool centre = TRUE, + int width = wxCHOICE_WIDTH, + int height = wxCHOICE_HEIGHT); + +// fill the array with the indices of the chosen items, it will be empty +// if no items were selected or Cancel was pressed - return the number of +// selections +WXDLLEXPORT size_t wxGetMultipleChoices(wxArrayInt& selections, + const wxString& message, + const wxString& caption, + int n, const wxString *choices, + wxWindow *parent = (wxWindow *) NULL, + int x = -1, + int y = -1, + bool centre = TRUE, + int width = wxCHOICE_WIDTH, + int height = wxCHOICE_HEIGHT); + +WXDLLEXPORT size_t wxGetMultipleChoices(wxArrayInt& selections, + const wxString& message, + const wxString& caption, + const wxArrayString& choices, + wxWindow *parent = (wxWindow *) NULL, + int x = -1, + int y = -1, + bool centre = TRUE, + int width = wxCHOICE_WIDTH, + int height = wxCHOICE_HEIGHT); + +// ---------------------------------------------------------------------------- +// these methods are for backwards compatibility only, not documented and +// deprecated +// ---------------------------------------------------------------------------- + +WXDLLEXPORT wxString wxGetSingleChoice(const wxString& message, + const wxString& caption, + int n, wxChar *choices[], + wxWindow *parent = (wxWindow *) NULL, + int x = -1, + int y = -1, + bool centre = TRUE, + int width = wxCHOICE_WIDTH, + int height = wxCHOICE_HEIGHT); + +WXDLLEXPORT int wxGetSingleChoiceIndex(const wxString& message, + const wxString& caption, + int n, wxChar *choices[], + wxWindow *parent = (wxWindow *) NULL, + int x = -1, + int y = -1, + bool centre = TRUE, + int width = wxCHOICE_WIDTH, + int height = wxCHOICE_HEIGHT); + +WXDLLEXPORT void* wxGetSingleChoiceData(const wxString& message, + const wxString& caption, + int n, wxChar **choices, + void **client_data, + wxWindow *parent = (wxWindow *) NULL, + int x = -1, int y = -1, + bool centre = TRUE, + int width = wxCHOICE_WIDTH, + int height = wxCHOICE_HEIGHT); + + +#endif // __CHOICEDLGH_G__ -#endif diff --git a/samples/console/console.cpp b/samples/console/console.cpp index 313907e968..0229dcb002 100644 --- a/samples/console/console.cpp +++ b/samples/console/console.cpp @@ -35,7 +35,7 @@ // what to test (in alphabetic order)? -//#define TEST_ARRAYS +#define TEST_ARRAYS //#define TEST_CMDLINE //#define TEST_DATETIME //#define TEST_DIR @@ -3117,11 +3117,57 @@ static void PrintArray(const char* name, const wxArrayString& array) } } -static int StringLenCompare(const wxString& first, const wxString& second) +static void PrintArray(const char* name, const wxArrayInt& array) +{ + printf("Dump of the array '%s'\n", name); + + size_t nCount = array.GetCount(); + for ( size_t n = 0; n < nCount; n++ ) + { + printf("\t%s[%u] = %d\n", name, n, array[n]); + } +} + +int wxCMPFUNC_CONV StringLenCompare(const wxString& first, + const wxString& second) { return first.length() - second.length(); } +int wxCMPFUNC_CONV IntCompare(int *first, + int *second) +{ + return *first - *second; +} + +int wxCMPFUNC_CONV IntRevCompare(int *first, + int *second) +{ + return *second - *first; +} + +static void TestArrayOfInts() +{ + puts("*** Testing wxArrayInt ***\n"); + + wxArrayInt a; + a.Add(1); + a.Add(17); + a.Add(5); + a.Add(3); + + puts("Initially:"); + PrintArray("a", a); + + puts("After sort:"); + a.Sort(IntCompare); + PrintArray("a", a); + + puts("After reverse sort:"); + a.Sort(IntRevCompare); + PrintArray("a", a); +} + #include "wx/dynarray.h" WX_DECLARE_OBJARRAY(Bar, ArrayBars); @@ -3581,6 +3627,8 @@ int main(int argc, char **argv) #endif // TEST_STRINGS #ifdef TEST_ARRAYS + if ( 0 ) + { wxArrayString a1; a1.Add("tiger"); a1.Add("cat"); @@ -3624,6 +3672,8 @@ int main(int argc, char **argv) PrintArray("a1", a1); TestArrayOfObjects(); + } + TestArrayOfInts(); #endif // TEST_ARRAYS #ifdef TEST_DIR diff --git a/samples/dialogs/dialogs.cpp b/samples/dialogs/dialogs.cpp index ff1975db03..cafe3bdf22 100644 --- a/samples/dialogs/dialogs.cpp +++ b/samples/dialogs/dialogs.cpp @@ -60,6 +60,7 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_MENU(DIALOGS_PASSWORD_ENTRY, MyFrame::PasswordEntry) EVT_MENU(DIALOGS_NUM_ENTRY, MyFrame::NumericEntry) EVT_MENU(DIALOGS_SINGLE_CHOICE, MyFrame::SingleChoice) + EVT_MENU(DIALOGS_MULTI_CHOICE, MyFrame::MultiChoice) EVT_MENU(DIALOGS_FILE_OPEN, MyFrame::FileOpen) EVT_MENU(DIALOGS_FILE_OPEN2, MyFrame::FileOpen2) EVT_MENU(DIALOGS_FILES_OPEN, MyFrame::FilesOpen) @@ -127,6 +128,7 @@ bool MyApp::OnInit() file_menu->Append(DIALOGS_PASSWORD_ENTRY, "&Password entry\tCtrl-P"); file_menu->Append(DIALOGS_NUM_ENTRY, "&Numeric entry\tCtrl-N"); file_menu->Append(DIALOGS_SINGLE_CHOICE, "&Single choice\tCtrl-C"); + file_menu->Append(DIALOGS_MULTI_CHOICE, "M&ultiple choice\tCtrl-U"); file_menu->AppendSeparator(); file_menu->Append(DIALOGS_TIP, "&Tip of the day\tCtrl-T"); file_menu->AppendSeparator(); @@ -349,6 +351,30 @@ void MyFrame::SingleChoice(wxCommandEvent& WXUNUSED(event) ) } } +void MyFrame::MultiChoice(wxCommandEvent& WXUNUSED(event) ) +{ + const wxString choices[] = { "One", "Two", "Three", "Four", "Five" } ; + int n = 5; + + wxArrayInt selections; + size_t count = wxGetMultipleChoices(selections, + "This is a small sample\n" + "A multi-choice convenience dialog", + "Please select a value", + n, (const wxString *)choices, + this); + if ( count ) + { + wxLogMessage("You selected %u items:", count); + for ( size_t n = 0; n < count; n++ ) + { + wxLogMessage("\t%u: %u (%s)", n, selections[n], + choices[selections[n]].c_str()); + } + } + //else: cancelled or nothing selected +} + void MyFrame::FileOpen(wxCommandEvent& WXUNUSED(event) ) { wxFileDialog dialog(this, "Testing open file dialog", "", "", "*.txt", 0); diff --git a/samples/dialogs/dialogs.h b/samples/dialogs/dialogs.h index 56493424e8..bcf6e2a083 100644 --- a/samples/dialogs/dialogs.h +++ b/samples/dialogs/dialogs.h @@ -61,6 +61,7 @@ public: void LogDialog(wxCommandEvent& event); void MessageBox(wxCommandEvent& event); void SingleChoice(wxCommandEvent& event); + void MultiChoice(wxCommandEvent& event); void TextEntry(wxCommandEvent& event); void PasswordEntry(wxCommandEvent& event); void NumericEntry(wxCommandEvent& event); @@ -110,6 +111,7 @@ enum DIALOGS_CHOOSE_FONT_GENERIC, DIALOGS_MESSAGE_BOX, DIALOGS_SINGLE_CHOICE, + DIALOGS_MULTI_CHOICE, DIALOGS_TEXT_ENTRY, DIALOGS_PASSWORD_ENTRY, DIALOGS_FILE_OPEN, diff --git a/samples/minimal/minimal.cpp b/samples/minimal/minimal.cpp index 300c169a78..7f1ab0047c 100644 --- a/samples/minimal/minimal.cpp +++ b/samples/minimal/minimal.cpp @@ -67,6 +67,16 @@ public: MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size); // event handlers (these functions should _not_ be virtual) + void OnPaint(wxPaintEvent& event) + { + wxPaintDC dc(this); + dc.DrawRectangle(20, 20, 100, 100); + dc.SetPen(*wxRED_PEN); + dc.SetDeviceOrigin(20, 20); + dc.SetClippingRegion(0, 0, 100, 100); + dc.DrawLine(0, 0, 1000, 1000); + } + void OnQuit(wxCommandEvent& event); void OnAbout(wxCommandEvent& event); @@ -95,6 +105,7 @@ enum // handlers) which process them. It can be also done at run-time, but for the // simple menu events like this the static method is much simpler. BEGIN_EVENT_TABLE(MyFrame, wxFrame) + EVT_PAINT(MyFrame::OnPaint) EVT_MENU(Minimal_Quit, MyFrame::OnQuit) EVT_MENU(Minimal_About, MyFrame::OnAbout) END_EVENT_TABLE() diff --git a/src/generic/choicdgg.cpp b/src/generic/choicdgg.cpp index f2c529666a..62a5371f15 100644 --- a/src/generic/choicdgg.cpp +++ b/src/generic/choicdgg.cpp @@ -2,17 +2,25 @@ // Name: choicdgg.cpp // Purpose: Choice dialogs // Author: Julian Smart -// Modified by: +// Modified by: 03.11.00: VZ to add wxArrayString and multiple sel functions // Created: 04/01/98 // RCS-ID: $Id$ -// Copyright: (c) Julian Smart and Markus Holzem +// Copyright: (c) wxWindows team // Licence: wxWindows license ///////////////////////////////////////////////////////////////////////////// +// ============================================================================ +// declarations +// ============================================================================ + #ifdef __GNUG__ #pragma implementation "choicdgg.h" #endif +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" @@ -37,11 +45,60 @@ #include "wx/generic/choicdgg.h" +// ---------------------------------------------------------------------------- +// constants +// ---------------------------------------------------------------------------- + #define wxID_LISTBOX 3000 -wxString wxGetSingleChoice( const wxString& message, const wxString& caption, int n, - const wxString *choices, wxWindow *parent, - int WXUNUSED(x), int WXUNUSED(y), bool WXUNUSED(centre), +#if defined(__WXMSW__) || defined(__WXMAC__) +#define wxCHOICEDLG_DIALOG_STYLE (wxDEFAULT_DIALOG_STYLE | \ + wxDIALOG_MODAL | \ + wxTAB_TRAVERSAL) +#else +#define wxCHOICEDLG_DIALOG_STYLE (wxDEFAULT_DIALOG_STYLE | \ + wxDIALOG_MODAL | \ + wxRESIZE_BORDER | \ + wxTAB_TRAVERSAL) +#endif + +// ---------------------------------------------------------------------------- +// private functions +// ---------------------------------------------------------------------------- + +// convert wxArrayString into a wxString[] which must be delete[]d by caller +static int ConvertWXArrayToC(const wxArrayString& aChoices, wxString **choices); + +// ============================================================================ +// implementation +// ============================================================================ + +// ---------------------------------------------------------------------------- +// helpers +// ---------------------------------------------------------------------------- + +int ConvertWXArrayToC(const wxArrayString& aChoices, wxString **choices) +{ + int n = aChoices.GetCount(); + *choices = new wxString[n]; + for ( int i = 0; i < n; i++ ) + { + *choices[i] = aChoices[i]; + } + + return n; +} + +// ---------------------------------------------------------------------------- +// wrapper functions +// ---------------------------------------------------------------------------- + +wxString wxGetSingleChoice( const wxString& message, + const wxString& caption, + int n, const wxString *choices, + wxWindow *parent, + int WXUNUSED(x), int WXUNUSED(y), + bool WXUNUSED(centre), int WXUNUSED(width), int WXUNUSED(height) ) { wxSingleChoiceDialog dialog(parent, message, caption, n, choices); @@ -52,9 +109,29 @@ wxString wxGetSingleChoice( const wxString& message, const wxString& caption, in return choice; } +wxString wxGetSingleChoice( const wxString& message, + const wxString& caption, + const wxArrayString& aChoices, + wxWindow *parent, + int x, int y, + bool centre, + int width, int height) +{ + wxString *choices; + int n = ConvertWXArrayToC(aChoices, &choices); + wxString res = wxGetSingleChoice(message, caption, n, choices, parent, + x, y, centre, width, height); + delete [] choices; + + return res; +} + +#ifdef WXWIN_COMPATIBILITY_2 // Overloaded for backward compatibility -wxString wxGetSingleChoice( const wxString& message, const wxString& caption, int n, - char *choices[], wxWindow *parent, +wxString wxGetSingleChoice( const wxString& message, + const wxString& caption, + int n, char *choices[], + wxWindow *parent, int x, int y, bool centre, int width, int height ) { @@ -69,11 +146,15 @@ wxString wxGetSingleChoice( const wxString& message, const wxString& caption, in delete[] strings; return ans; } - -int wxGetSingleChoiceIndex( const wxString& message, const wxString& caption, int n, - const wxString *choices, wxWindow *parent, - int WXUNUSED(x), int WXUNUSED(y), bool WXUNUSED(centre), - int WXUNUSED(width), int WXUNUSED(height) ) +#endif // WXWIN_COMPATIBILITY_2 + +int wxGetSingleChoiceIndex( const wxString& message, + const wxString& caption, + int n, const wxString *choices, + wxWindow *parent, + int WXUNUSED(x), int WXUNUSED(y), + bool WXUNUSED(centre), + int WXUNUSED(width), int WXUNUSED(height) ) { wxSingleChoiceDialog dialog(parent, message, caption, n, choices); int choice; @@ -85,11 +166,14 @@ int wxGetSingleChoiceIndex( const wxString& message, const wxString& caption, in return choice; } +#ifdef WXWIN_COMPATIBILITY_2 // Overloaded for backward compatibility -int wxGetSingleChoiceIndex( const wxString& message, const wxString& caption, int n, - wxChar *choices[], wxWindow *parent, - int x, int y, bool centre, - int width, int height ) +int wxGetSingleChoiceIndex( const wxString& message, + const wxString& caption, + int n, wxChar *choices[], + wxWindow *parent, + int x, int y, bool centre, + int width, int height ) { wxString *strings = new wxString[n]; for ( int i = 0; i < n; i++) @@ -99,11 +183,16 @@ int wxGetSingleChoiceIndex( const wxString& message, const wxString& caption, in delete[] strings; return ans; } - -void *wxGetSingleChoiceData( const wxString& message, const wxString& caption, int n, - const wxString *choices, void **client_data, wxWindow *parent, - int WXUNUSED(x), int WXUNUSED(y), bool WXUNUSED(centre), - int WXUNUSED(width), int WXUNUSED(height) ) +#endif // WXWIN_COMPATIBILITY_2 + +void *wxGetSingleChoiceData( const wxString& message, + const wxString& caption, + int n, const wxString *choices, + void **client_data, + wxWindow *parent, + int WXUNUSED(x), int WXUNUSED(y), + bool WXUNUSED(centre), + int WXUNUSED(width), int WXUNUSED(height) ) { wxSingleChoiceDialog dialog(parent, message, caption, n, choices, (char **)client_data); void *data; @@ -115,11 +204,14 @@ void *wxGetSingleChoiceData( const wxString& message, const wxString& caption, i return data; } +#ifdef WXWIN_COMPATIBILITY_2 // Overloaded for backward compatibility -void *wxGetSingleChoiceData( const wxString& message, const wxString& caption, int n, - wxChar *choices[], void **client_data, wxWindow *parent, - int x, int y, bool centre, - int width, int height ) +void *wxGetSingleChoiceData( const wxString& message, + const wxString& caption, + int n, wxChar *choices[], + void **client_data, + wxWindow *parent, + int x, int y, bool centre, int width, int height ) { wxString *strings = new wxString[n]; int i; @@ -127,60 +219,114 @@ void *wxGetSingleChoiceData( const wxString& message, const wxString& caption, i { strings[i] = choices[i]; } - void *data = wxGetSingleChoiceData(message, caption, n, (const wxString *)strings, client_data, parent, - x, y, centre, width, height); + void *data = wxGetSingleChoiceData(message, caption, + n, (const wxString *)strings, + client_data, parent, + x, y, centre, width, height); delete[] strings; return data; } +#endif // WXWIN_COMPATIBILITY_2 + +size_t wxGetMultipleChoices(wxArrayInt& selections, + const wxString& message, + const wxString& caption, + int n, const wxString *choices, + wxWindow *parent, + int WXUNUSED(x), int WXUNUSED(y), + bool WXUNUSED(centre), + int WXUNUSED(width), int WXUNUSED(height)) +{ + wxMultiChoiceDialog dialog(parent, message, caption, n, choices); + if ( dialog.ShowModal() == wxID_OK ) + selections = dialog.GetSelections(); + else + selections.Empty(); + return selections.GetCount(); +} -/* Multiple choice dialog contributed by Robert Cowell - * - -The new data passed are in the "int nsel" and "int * selection" - -The idea is to make a multiple selection from list of strings. -The returned value is the total number selected. initialily there -are nsel selected, with indices stored in -selection[0],...,selection[nsel-1] which appear highlighted to -begin with. On exit with value i -selection[0..i-1] contains the indices of the selected items. -(Some prior selectecions might be deselected.) -Thus selection must be as big as choices, in case all items are -selected. - -*/ -/* -int wxGetMultipleChoice(const wxString& message, const wxString& caption, - int n, const wxString *choices, - int nsel, int * selection, - wxWindow *parent , int x , int y, bool centre, - int width, int height) +size_t wxGetMultipleChoices(wxArrayInt selections, + const wxString& message, + const wxString& caption, + const wxArrayString& aChoices, + wxWindow *parent, + int x, int y, + bool centre, + int width, int height) { - return -1; + wxString *choices; + int n = ConvertWXArrayToC(aChoices, &choices); + size_t res = wxGetMultipleChoices(selections, message, caption, + n, choices, parent, + x, y, centre, width, height); + delete [] choices; + + return res; } -*/ +// ---------------------------------------------------------------------------- +// wxAnyChoiceDialog +// ---------------------------------------------------------------------------- + +bool wxAnyChoiceDialog::Create(wxWindow *parent, + const wxString& message, + const wxString& caption, + int n, const wxString *choices, + long styleDlg, + const wxPoint& pos, + long styleLbox) +{ + if ( !wxDialog::Create(parent, -1, caption, pos, wxDefaultSize, + wxCHOICEDLG_DIALOG_STYLE) ) + return FALSE; + + wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL ); + + // 1) text message + topsizer->Add( CreateTextSizer( message ), 0, wxALL, 10 ); + + // 2) list box + m_listbox = new wxListBox( this, wxID_LISTBOX, + wxDefaultPosition, wxDefaultSize, + n, choices, + styleLbox ); + if ( n > 0 ) + m_listbox->SetSelection(0); + + topsizer->Add( m_listbox, 1, wxEXPAND | wxLEFT|wxRIGHT, 15 ); + +#if wxUSE_STATLINE + // 3) static line + topsizer->Add( new wxStaticLine( this, -1 ), 0, wxEXPAND | wxLEFT|wxRIGHT|wxTOP, 10 ); +#endif + + // 4) buttons + topsizer->Add( CreateButtonSizer( wxOK|wxCANCEL ), 0, wxCENTRE | wxALL, 10 ); + + SetAutoLayout( TRUE ); + SetSizer( topsizer ); + + topsizer->SetSizeHints( this ); + topsizer->Fit( this ); + + Centre( wxBOTH ); + + m_listbox->SetFocus(); + + return TRUE; +} + +// ---------------------------------------------------------------------------- // wxSingleChoiceDialog +// ---------------------------------------------------------------------------- BEGIN_EVENT_TABLE(wxSingleChoiceDialog, wxDialog) EVT_BUTTON(wxID_OK, wxSingleChoiceDialog::OnOK) EVT_LISTBOX_DCLICK(wxID_LISTBOX, wxSingleChoiceDialog::OnListBoxDClick) END_EVENT_TABLE() -IMPLEMENT_CLASS(wxSingleChoiceDialog, wxDialog) - -#if defined(__WXMSW__) || defined(__WXMAC__) -#define wxCHOICEDLG_DIALOG_STYLE (wxDEFAULT_DIALOG_STYLE | \ - wxDIALOG_MODAL | \ - wxTAB_TRAVERSAL) -#else -#define wxCHOICEDLG_DIALOG_STYLE (wxDEFAULT_DIALOG_STYLE | \ - wxDIALOG_MODAL | \ - wxRESIZE_BORDER | \ - wxTAB_TRAVERSAL) -#endif - +IMPLEMENT_DYNAMIC_CLASS(wxSingleChoiceDialog, wxDialog) wxSingleChoiceDialog::wxSingleChoiceDialog(wxWindow *parent, const wxString& message, @@ -190,12 +336,12 @@ wxSingleChoiceDialog::wxSingleChoiceDialog(wxWindow *parent, char **clientData, long style, const wxPoint& pos) - : wxDialog(parent, -1, caption, pos, wxDefaultSize, - wxCHOICEDLG_DIALOG_STYLE) { Create(parent, message, caption, n, choices, clientData, style); } +#ifdef WXWIN_COMPATIBILITY_2 + wxSingleChoiceDialog::wxSingleChoiceDialog(wxWindow *parent, const wxString& message, const wxString& caption, @@ -203,8 +349,6 @@ wxSingleChoiceDialog::wxSingleChoiceDialog(wxWindow *parent, char **clientData, long style, const wxPoint& pos) - : wxDialog(parent, -1, caption, pos, wxDefaultSize, - wxCHOICEDLG_DIALOG_STYLE) { Create(parent, message, caption, choices, clientData, style); } @@ -228,56 +372,29 @@ bool wxSingleChoiceDialog::Create(wxWindow *parent, return ans; } -bool wxSingleChoiceDialog::Create( wxWindow *WXUNUSED(parent), +#endif // WXWIN_COMPATIBILITY_2 + +bool wxSingleChoiceDialog::Create( wxWindow *parent, const wxString& message, - const wxString& WXUNUSED(caption), + const wxString& caption, int n, const wxString *choices, char **clientData, long style, - const wxPoint& WXUNUSED(pos) ) + const wxPoint& pos ) { - m_selection = 0; + if ( !wxAnyChoiceDialog::Create(parent, message, caption, + n, choices, + style, pos) ) + return FALSE; - m_dialogStyle = style; + m_selection = n > 0 ? 0 : -1; - wxBeginBusyCursor(); - - wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL ); - - // 1) text message - topsizer->Add( CreateTextSizer( message ), 0, wxALL, 10 ); - - // 2) list box - m_listbox = new wxListBox( this, wxID_LISTBOX, wxDefaultPosition, wxSize(160,100) , - n, choices, wxLB_ALWAYS_SB ); - m_listbox->SetSelection( m_selection ); if (clientData) { for (int i = 0; i < n; i++) m_listbox->SetClientData(i, clientData[i]); } - topsizer->Add( m_listbox, 1, wxEXPAND | wxLEFT|wxRIGHT, 15 ); - -#if wxUSE_STATLINE - // 3) static line - topsizer->Add( new wxStaticLine( this, -1 ), 0, wxEXPAND | wxLEFT|wxRIGHT|wxTOP, 10 ); -#endif - - // 4) buttons - topsizer->Add( CreateButtonSizer( wxOK|wxCANCEL ), 0, wxCENTRE | wxALL, 10 ); - - SetAutoLayout( TRUE ); - SetSizer( topsizer ); - - topsizer->SetSizeHints( this ); - topsizer->Fit( this ); - - Centre( wxBOTH ); - - m_listbox->SetFocus(); - - wxEndBusyCursor(); return TRUE; } @@ -315,3 +432,51 @@ void wxSingleChoiceDialog::OnListBoxDClick(wxCommandEvent& WXUNUSED(event)) EndModal(wxID_OK); } +// ---------------------------------------------------------------------------- +// wxMultiChoiceDialog +// ---------------------------------------------------------------------------- + +BEGIN_EVENT_TABLE(wxMultiChoiceDialog, wxDialog) + EVT_BUTTON(wxID_OK, wxMultiChoiceDialog::OnOK) +END_EVENT_TABLE() + +IMPLEMENT_DYNAMIC_CLASS(wxMultiChoiceDialog, wxDialog) + +bool wxMultiChoiceDialog::Create( wxWindow *parent, + const wxString& message, + const wxString& caption, + int n, + const wxString *choices, + long style, + const wxPoint& pos ) +{ + if ( !wxAnyChoiceDialog::Create(parent, message, caption, + n, choices, + style, pos, + wxLB_ALWAYS_SB | wxLB_MULTIPLE) ) + return FALSE; + + return TRUE; +} + +void wxMultiChoiceDialog::SetSelections(const wxArrayInt& selections) +{ + size_t count = selections.GetCount(); + for ( size_t n = 0; n < count; n++ ) + { + m_listbox->Select(selections[n]); + } +} + +void wxMultiChoiceDialog::OnOK(wxCommandEvent& WXUNUSED(event)) +{ + m_selections.Empty(); + size_t count = m_listbox->GetCount(); + for ( size_t n = 0; n < count; n++ ) + { + if ( m_listbox->IsSelected(n) ) + m_selections.Add(n); + } + + EndModal(wxID_OK); +} -- 2.45.2