validate.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name: validate.cpp
  3. // Purpose: wxWidgets validator sample
  4. // Author: Julian Smart
  5. // Modified by:
  6. // Created: 04/01/98
  7. // Copyright: (c) Julian Smart
  8. // Licence: wxWindows licence
  9. /////////////////////////////////////////////////////////////////////////////
  10. // See online help for an overview of validators. In general, a
  11. // validator transfers data between a control and a variable.
  12. // It may also test for validity of a string transferred to or
  13. // from a text control. All validators transfer data, but not
  14. // all test validity, so don't be confused by the name.
  15. // For compilers that support precompilation, includes "wx/wx.h".
  16. #include "wx/wxprec.h"
  17. #ifdef __BORLANDC__
  18. #pragma hdrstop
  19. #endif // __BORLANDC__
  20. #ifndef WX_PRECOMP
  21. #include "wx/wx.h"
  22. #endif // WX_PRECOMP
  23. #include "validate.h"
  24. #include "wx/sizer.h"
  25. #include "wx/valgen.h"
  26. #include "wx/valtext.h"
  27. #include "wx/valnum.h"
  28. #ifndef wxHAS_IMAGES_IN_RESOURCES
  29. #include "../sample.xpm"
  30. #endif
  31. // ----------------------------------------------------------------------------
  32. // Global data
  33. // ----------------------------------------------------------------------------
  34. MyData g_data;
  35. wxString g_listbox_choices[] =
  36. {wxT("one"), wxT("two"), wxT("three")};
  37. wxString g_combobox_choices[] =
  38. {wxT("yes"), wxT("no (doesn't validate)"), wxT("maybe (doesn't validate)")};
  39. wxString g_radiobox_choices[] =
  40. {wxT("green"), wxT("yellow"), wxT("red")};
  41. // ----------------------------------------------------------------------------
  42. // MyData
  43. // ----------------------------------------------------------------------------
  44. MyData::MyData()
  45. {
  46. // This string will be passed to an alpha-only validator, which
  47. // will complain because spaces aren't alpha. Note that validation
  48. // is performed only when 'OK' is pressed.
  49. m_string = wxT("Spaces are invalid here");
  50. m_string2 = "Valid text";
  51. m_listbox_choices.Add(0);
  52. m_intValue = 0;
  53. m_doubleValue = 12354.31;
  54. }
  55. // ----------------------------------------------------------------------------
  56. // MyComboBoxValidator
  57. // ----------------------------------------------------------------------------
  58. bool MyComboBoxValidator::Validate(wxWindow *WXUNUSED(parent))
  59. {
  60. wxASSERT(GetWindow()->IsKindOf(CLASSINFO(wxComboBox)));
  61. wxComboBox* cb = (wxComboBox*)GetWindow();
  62. if (cb->GetValue() == g_combobox_choices[1] ||
  63. cb->GetValue() == g_combobox_choices[2])
  64. {
  65. // we accept any string != g_combobox_choices[1|2] !
  66. wxLogError("Invalid combo box text!");
  67. return false;
  68. }
  69. if (m_var)
  70. *m_var = cb->GetValue();
  71. return true;
  72. }
  73. bool MyComboBoxValidator::TransferToWindow()
  74. {
  75. wxASSERT(GetWindow()->IsKindOf(CLASSINFO(wxComboBox)));
  76. if ( m_var )
  77. {
  78. wxComboBox* cb = (wxComboBox*)GetWindow();
  79. if ( !cb )
  80. return false;
  81. cb->SetValue(*m_var);
  82. }
  83. return true;
  84. }
  85. bool MyComboBoxValidator::TransferFromWindow()
  86. {
  87. wxASSERT(GetWindow()->IsKindOf(CLASSINFO(wxComboBox)));
  88. if ( m_var )
  89. {
  90. wxComboBox* cb = (wxComboBox*)GetWindow();
  91. if ( !cb )
  92. return false;
  93. *m_var = cb->GetValue();
  94. }
  95. return true;
  96. }
  97. // ----------------------------------------------------------------------------
  98. // MyApp
  99. // ----------------------------------------------------------------------------
  100. IMPLEMENT_APP(MyApp)
  101. bool MyApp::OnInit()
  102. {
  103. if ( !wxApp::OnInit() )
  104. return false;
  105. // Create and display the main frame window.
  106. MyFrame *frame = new MyFrame((wxFrame *) NULL, wxT("Validator Test"),
  107. 50, 50, 300, 250);
  108. frame->Show(true);
  109. return true;
  110. }
  111. // ----------------------------------------------------------------------------
  112. // MyFrame
  113. // ----------------------------------------------------------------------------
  114. wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
  115. EVT_MENU(wxID_EXIT, MyFrame::OnQuit)
  116. EVT_MENU(VALIDATE_TEST_DIALOG, MyFrame::OnTestDialog)
  117. EVT_MENU(VALIDATE_TOGGLE_BELL, MyFrame::OnToggleBell)
  118. wxEND_EVENT_TABLE()
  119. MyFrame::MyFrame(wxFrame *frame, const wxString&title, int x, int y, int w, int h)
  120. : wxFrame(frame, wxID_ANY, title, wxPoint(x, y), wxSize(w, h)),
  121. m_silent(true)
  122. {
  123. SetIcon(wxICON(sample));
  124. // Create a listbox to display the validated data.
  125. m_listbox = new wxListBox(this, wxID_ANY);
  126. m_listbox->Append(wxString(wxT("Try 'File|Test' to see how validators work.")));
  127. wxMenu *file_menu = new wxMenu;
  128. file_menu->Append(VALIDATE_TEST_DIALOG, wxT("&Test dialog..."), wxT("Demonstrate validators"));
  129. file_menu->AppendCheckItem(VALIDATE_TOGGLE_BELL, wxT("&Bell on error"), wxT("Toggle bell on error"));
  130. file_menu->AppendSeparator();
  131. file_menu->Append(wxID_EXIT, wxT("E&xit"));
  132. wxMenuBar *menu_bar = new wxMenuBar;
  133. menu_bar->Append(file_menu, wxT("&File"));
  134. SetMenuBar(menu_bar);
  135. // All validators share a common (static) flag that controls
  136. // whether they beep on error. Here we turn it off:
  137. wxValidator::SuppressBellOnError(m_silent);
  138. file_menu->Check(VALIDATE_TOGGLE_BELL, !wxValidator::IsSilent());
  139. #if wxUSE_STATUSBAR
  140. CreateStatusBar(1);
  141. #endif // wxUSE_STATUSBAR
  142. }
  143. void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
  144. {
  145. Close(true);
  146. }
  147. void MyFrame::OnTestDialog(wxCommandEvent& WXUNUSED(event))
  148. {
  149. // The validators defined in the dialog implementation bind controls
  150. // and variables together. Values are transferred between them behind
  151. // the scenes, so here we don't have to query the controls for their
  152. // values.
  153. MyDialog dialog(this, wxT("Validator demonstration"));
  154. // When the dialog is displayed, validators automatically transfer
  155. // data from variables to their corresponding controls.
  156. if ( dialog.ShowModal() == wxID_OK )
  157. {
  158. // 'OK' was pressed, so controls that have validators are
  159. // automatically transferred to the variables we specified
  160. // when we created the validators.
  161. m_listbox->Clear();
  162. m_listbox->Append(wxString(wxT("string: ")) + g_data.m_string);
  163. m_listbox->Append(wxString(wxT("string #2: ")) + g_data.m_string2);
  164. for(unsigned int i = 0; i < g_data.m_listbox_choices.GetCount(); ++i)
  165. {
  166. int j = g_data.m_listbox_choices[i];
  167. m_listbox->Append(wxString(wxT("listbox choice(s): ")) + g_listbox_choices[j]);
  168. }
  169. wxString checkbox_state(g_data.m_checkbox_state ? wxT("checked") : wxT("unchecked"));
  170. m_listbox->Append(wxString(wxT("checkbox: ")) + checkbox_state);
  171. m_listbox->Append(wxString(wxT("combobox: ")) + g_data.m_combobox_choice);
  172. m_listbox->Append(wxString(wxT("radiobox: ")) + g_radiobox_choices[g_data.m_radiobox_choice]);
  173. m_listbox->Append(wxString::Format("integer value: %d", g_data.m_intValue));
  174. m_listbox->Append(wxString::Format("double value: %.3f", g_data.m_doubleValue));
  175. }
  176. }
  177. void MyFrame::OnToggleBell(wxCommandEvent& event)
  178. {
  179. m_silent = !m_silent;
  180. wxValidator::SuppressBellOnError(m_silent);
  181. event.Skip();
  182. }
  183. // ----------------------------------------------------------------------------
  184. // MyDialog
  185. // ----------------------------------------------------------------------------
  186. MyDialog::MyDialog( wxWindow *parent, const wxString& title,
  187. const wxPoint& pos, const wxSize& size, const long WXUNUSED(style) ) :
  188. wxDialog(parent, VALIDATE_DIALOG_ID, title, pos, size, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
  189. {
  190. // setup the flex grid sizer
  191. // -------------------------
  192. wxFlexGridSizer *flexgridsizer = new wxFlexGridSizer(3, 2, 5, 5);
  193. // Create and add controls to sizers. Note that a member variable
  194. // of g_data is bound to each control upon construction. There is
  195. // currently no easy way to substitute a different validator or a
  196. // different transfer variable after a control has been constructed.
  197. // Pointers to some of these controls are saved in member variables
  198. // so that we can use them elsewhere, like this one.
  199. m_text = new wxTextCtrl(this, VALIDATE_TEXT, wxEmptyString,
  200. wxDefaultPosition, wxDefaultSize, 0,
  201. wxTextValidator(wxFILTER_ALPHA, &g_data.m_string));
  202. m_text->SetToolTip("uses wxTextValidator with wxFILTER_ALPHA");
  203. flexgridsizer->Add(m_text, 1, wxGROW);
  204. // Now set a wxTextValidator with an explicit list of characters NOT allowed:
  205. wxTextValidator textVal(wxFILTER_EMPTY|wxFILTER_EXCLUDE_LIST, &g_data.m_string2);
  206. textVal.SetCharExcludes("bcwyz");
  207. wxTextCtrl* txt2 =
  208. new wxTextCtrl(this, VALIDATE_TEXT2, wxEmptyString,
  209. wxDefaultPosition, wxDefaultSize, 0, textVal);
  210. txt2->SetToolTip("uses wxTextValidator with wxFILTER_EMPTY|wxFILTER_EXCLUDE_LIST (to exclude 'bcwyz')");
  211. flexgridsizer->Add(txt2, 1, wxGROW);
  212. flexgridsizer->Add(new wxListBox((wxWindow*)this, VALIDATE_LIST,
  213. wxDefaultPosition, wxDefaultSize,
  214. 3, g_listbox_choices, wxLB_MULTIPLE,
  215. wxGenericValidator(&g_data.m_listbox_choices)),
  216. 1, wxGROW);
  217. m_combobox = new wxComboBox(this, VALIDATE_COMBO, wxEmptyString,
  218. wxDefaultPosition, wxDefaultSize,
  219. 3, g_combobox_choices, 0L,
  220. MyComboBoxValidator(&g_data.m_combobox_choice));
  221. m_combobox->SetToolTip("uses a custom validator (MyComboBoxValidator)");
  222. flexgridsizer->Add(m_combobox, 1, wxALIGN_CENTER);
  223. // This wxCheckBox* doesn't need to be assigned to any pointer
  224. // because we don't use it elsewhere--it can be anonymous.
  225. // We don't need any such pointer to query its state, which
  226. // can be gotten directly from g_data.
  227. flexgridsizer->Add(new wxCheckBox(this, VALIDATE_CHECK, wxT("Sample checkbox"),
  228. wxDefaultPosition, wxDefaultSize, 0,
  229. wxGenericValidator(&g_data.m_checkbox_state)),
  230. 1, wxALIGN_CENTER|wxALL, 15);
  231. flexgridsizer->AddGrowableCol(0);
  232. flexgridsizer->AddGrowableCol(1);
  233. flexgridsizer->AddGrowableRow(1);
  234. // setup the button sizer
  235. // ----------------------
  236. wxStdDialogButtonSizer *btn = new wxStdDialogButtonSizer();
  237. btn->AddButton(new wxButton(this, wxID_OK));
  238. btn->AddButton(new wxButton(this, wxID_CANCEL));
  239. btn->Realize();
  240. // setup a sizer with the controls for numeric validators
  241. // ------------------------------------------------------
  242. wxIntegerValidator<int> valInt(&g_data.m_intValue,
  243. wxNUM_VAL_THOUSANDS_SEPARATOR |
  244. wxNUM_VAL_ZERO_AS_BLANK);
  245. valInt.SetMin(0); // Only allow positive numbers
  246. m_numericTextInt = new wxTextCtrl
  247. (
  248. this,
  249. wxID_ANY,
  250. "",
  251. wxDefaultPosition,
  252. wxDefaultSize,
  253. wxTE_RIGHT,
  254. valInt
  255. );
  256. m_numericTextInt->SetToolTip("uses wxIntegerValidator to accept positive "
  257. "integers only");
  258. m_numericTextDouble = new wxTextCtrl
  259. (
  260. this,
  261. wxID_ANY,
  262. "",
  263. wxDefaultPosition,
  264. wxDefaultSize,
  265. wxTE_RIGHT,
  266. wxMakeFloatingPointValidator
  267. (
  268. 3,
  269. &g_data.m_doubleValue,
  270. wxNUM_VAL_THOUSANDS_SEPARATOR |
  271. wxNUM_VAL_NO_TRAILING_ZEROES
  272. )
  273. );
  274. m_numericTextDouble->SetToolTip("uses wxFloatingPointValidator with 3 decimals");
  275. wxBoxSizer *numSizer = new wxBoxSizer( wxHORIZONTAL );
  276. numSizer->Add( m_numericTextInt, 1, wxALL, 10 );
  277. numSizer->Add( m_numericTextDouble, 1, wxALL, 10 );
  278. // setup the main sizer
  279. // --------------------
  280. wxBoxSizer *mainsizer = new wxBoxSizer( wxVERTICAL );
  281. mainsizer->Add(flexgridsizer, 1, wxGROW | wxALL, 10);
  282. mainsizer->Add(new wxRadioBox((wxWindow*)this, VALIDATE_RADIO, wxT("Pick a color"),
  283. wxDefaultPosition, wxDefaultSize,
  284. 3, g_radiobox_choices, 1, wxRA_SPECIFY_ROWS,
  285. wxGenericValidator(&g_data.m_radiobox_choice)),
  286. 0, wxGROW | wxLEFT|wxBOTTOM|wxRIGHT, 10);
  287. mainsizer->Add( numSizer, 0, wxGROW | wxALL );
  288. mainsizer->Add(btn, 0, wxGROW | wxALL, 10);
  289. SetSizer(mainsizer);
  290. mainsizer->SetSizeHints(this);
  291. // make the dialog a bit bigger than its minimal size:
  292. SetSize(GetBestSize()*1.5);
  293. }
  294. bool MyDialog::TransferDataToWindow()
  295. {
  296. bool r = wxDialog::TransferDataToWindow();
  297. // These function calls have to be made here, after the
  298. // dialog has been created.
  299. m_text->SetFocus();
  300. m_combobox->SetSelection(0);
  301. return r;
  302. }