Removed wxLongStringProperty derived property creator macros (just subclass and imple...
[wxWidgets.git] / samples / propgrid / tests.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: samples/propgrid/tests.cpp
3 // Purpose: wxPropertyGrid tests
4 // Author: Jaakko Salli
5 // Modified by:
6 // Created: 2007-05-16
7 // RCS-ID: $Id$
8 // Copyright: (c) Jaakko Salli
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 #include "wx/wxprec.h"
13
14 #ifdef __BORLANDC__
15 #pragma hdrstop
16 #endif
17
18 #ifndef WX_PRECOMP
19 #include "wx/wx.h"
20 #endif
21
22 #include <wx/propgrid/propgrid.h>
23 #include <wx/propgrid/advprops.h>
24 #include <wx/propgrid/manager.h>
25
26 #include "propgrid.h"
27 #include "sampleprops.h"
28
29
30 // -----------------------------------------------------------------------
31 // wxTestCustomFlagsProperty
32 // -----------------------------------------------------------------------
33
34 //
35 // Constant definitions required by wxFlagsProperty examples.
36 //
37
38 static const wxChar* _fs_framestyle_labels[] = {
39 wxT("wxCAPTION"),
40 wxT("wxMINIMIZE"),
41 wxT("wxMAXIMIZE"),
42 wxT("wxCLOSE_BOX"),
43 wxT("wxSTAY_ON_TOP"),
44 wxT("wxSYSTEM_MENU"),
45 wxT("wxRESIZE_BORDER"),
46 wxT("wxFRAME_TOOL_WINDOW"),
47 wxT("wxFRAME_NO_TASKBAR"),
48 wxT("wxFRAME_FLOAT_ON_PARENT"),
49 wxT("wxFRAME_SHAPED"),
50 (const wxChar*) NULL
51 };
52
53 static const long _fs_framestyle_values[] = {
54 wxCAPTION,
55 wxMINIMIZE,
56 wxMAXIMIZE,
57 wxCLOSE_BOX,
58 wxSTAY_ON_TOP,
59 wxSYSTEM_MENU,
60 wxRESIZE_BORDER,
61 wxFRAME_TOOL_WINDOW,
62 wxFRAME_NO_TASKBAR,
63 wxFRAME_FLOAT_ON_PARENT,
64 wxFRAME_SHAPED
65 };
66
67 // Colour labels. Last (before NULL, if any) must be Custom.
68 static const wxChar* mycolprop_labels[] = {
69 wxT("Black"),
70 wxT("Blue"),
71 wxT("Brown"),
72 wxT("Custom"),
73 (const wxChar*) NULL
74 };
75
76 // Relevant colour values as unsigned longs.
77 static unsigned long mycolprop_colours[] = {
78 wxPG_COLOUR(0,0,0),
79 wxPG_COLOUR(0,0,255),
80 wxPG_COLOUR(166,124,81),
81 wxPG_COLOUR(0,0,0)
82 };
83
84 // Implement property class. Third argument is optional values array,
85 // but in this example we are only interested in creating a shortcut
86 // for user to access the colour values. Last arg is itemcount, but
87 // it will be deprecated in the future.
88 WX_PG_DECLARE_CUSTOM_COLOUR_PROPERTY_USES_WXCOLOUR(wxMyColourProperty)
89 WX_PG_IMPLEMENT_CUSTOM_COLOUR_PROPERTY_USES_WXCOLOUR(wxMyColourProperty,
90 mycolprop_labels,
91 (long*)NULL,
92 mycolprop_colours)
93
94
95 WX_PG_DECLARE_CUSTOM_COLOUR_PROPERTY(wxMyColour2Property)
96 WX_PG_IMPLEMENT_CUSTOM_COLOUR_PROPERTY(wxMyColour2Property,
97 mycolprop_labels,
98 (long*)NULL,
99 mycolprop_colours)
100
101 // -----------------------------------------------------------------------
102
103 //
104 // Test customizing wxColourProperty via subclassing
105 //
106 // * Includes custom colour entry.
107 // * Includes extra custom entry.
108 //
109 class MyColourProperty3 : public wxColourProperty
110 {
111 public:
112 MyColourProperty3( const wxString& label = wxPG_LABEL,
113 const wxString& name = wxPG_LABEL,
114 const wxColour& value = *wxWHITE )
115 : wxColourProperty(label, name, value)
116 {
117 wxPGChoices colours;
118 colours.Add(wxT("White"));
119 colours.Add(wxT("Black"));
120 colours.Add(wxT("Red"));
121 colours.Add(wxT("Green"));
122 colours.Add(wxT("Blue"));
123 colours.Add(wxT("Custom"));
124 colours.Add(wxT("None"));
125 m_choices = colours;
126 SetIndex(0);
127 wxVariant variant;
128 variant << value;
129 SetValue(variant);
130 }
131
132 virtual ~MyColourProperty3()
133 {
134 }
135
136 virtual wxColour GetColour( int index ) const
137 {
138 switch (index)
139 {
140 case 0: return *wxWHITE;
141 case 1: return *wxBLACK;
142 case 2: return *wxRED;
143 case 3: return *wxGREEN;
144 case 4: return *wxBLUE;
145 case 5:
146 // Return current colour for the custom entry
147 wxColour col;
148 if ( GetIndex() == GetCustomColourIndex() )
149 {
150 if ( m_value.IsNull() )
151 return col;
152 col << m_value;
153 return col;
154 }
155 return *wxWHITE;
156 };
157 return wxColour();
158 }
159
160 virtual wxString ColourToString( const wxColour& col, int index ) const
161 {
162 if ( index == (int)(m_choices.GetCount()-1) )
163 return wxT("");
164
165 return wxColourProperty::ColourToString(col, index);
166 }
167
168 virtual int GetCustomColourIndex() const
169 {
170 return m_choices.GetCount()-2;
171 }
172 };
173
174
175 void FormMain::AddTestProperties( wxPropertyGridPage* pg )
176 {
177 pg->Append( new wxMyColourProperty(wxT("CustomColourProperty1")) );
178
179 pg->SetPropertyHelpString(wxT("CustomColourProperty1"),
180 wxT("This is a wxMyColourProperty from the sample app. ")
181 wxT("It is built with WX_PG_IMPLEMENT_CUSTOM_COLOUR_PROPERTY_USES_WXCOLOUR macro ")
182 wxT("and has wxColour as its data type"));
183
184 pg->Append( new wxMyColour2Property(wxT("CustomColourProperty2")) );
185
186 pg->SetPropertyHelpString(wxT("CustomColourProperty2"),
187 wxT("This is a wxMyColour2Property from the sample app. ")
188 wxT("It is built with WX_PG_IMPLEMENT_CUSTOM_COLOUR_PROPERTY macro ")
189 wxT("and has wxColourPropertyValue as its data type"));
190
191 pg->Append( new MyColourProperty3(wxT("CustomColourProperty3"), wxPG_LABEL, *wxGREEN) );
192 pg->GetProperty(wxT("CustomColourProperty3"))->SetFlag(wxPG_PROP_AUTO_UNSPECIFIED);
193 pg->SetPropertyEditor( wxT("CustomColourProperty3"), wxPGEditor_ComboBox );
194
195 pg->SetPropertyHelpString(wxT("CustomColourProperty3"),
196 wxT("This is a MyColourProperty3 from the sample app. ")
197 wxT("It is built by subclassing wxColourProperty."));
198 }
199
200 // -----------------------------------------------------------------------
201
202 void FormMain::OnDumpList( wxCommandEvent& WXUNUSED(event) )
203 {
204 wxVariant values = m_pPropGridManager->GetPropertyValues(wxT("list"), wxNullProperty, wxPG_INC_ATTRIBUTES);
205 wxString text = wxT("This only tests that wxVariant related routines do not crash.");
206 wxString t;
207
208 wxDialog* dlg = new wxDialog(this,-1,wxT("wxVariant Test"),
209 wxDefaultPosition,wxDefaultSize,wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER);
210
211 unsigned int i;
212 for ( i = 0; i < (unsigned int)values.GetCount(); i++ )
213 {
214 wxVariant& v = values[i];
215
216 wxString strValue = v.GetString();
217
218 #if wxCHECK_VERSION(2,8,0)
219 if ( v.GetName().EndsWith(wxT("@attr")) )
220 #else
221 if ( v.GetName().Right(5) == wxT("@attr") )
222 #endif
223 {
224 text += wxString::Format(wxT("Attributes:\n"));
225
226 unsigned int n;
227 for ( n = 0; n < (unsigned int)v.GetCount(); n++ )
228 {
229 wxVariant& a = v[n];
230
231 t.Printf(wxT(" atribute %i: name=\"%s\" (type=\"%s\" value=\"%s\")\n"),(int)n,
232 a.GetName().c_str(),a.GetType().c_str(),a.GetString().c_str());
233 text += t;
234 }
235 }
236 else
237 {
238 t.Printf(wxT("%i: name=\"%s\" type=\"%s\" value=\"%s\"\n"),(int)i,
239 v.GetName().c_str(),v.GetType().c_str(),strValue.c_str());
240 text += t;
241 }
242 }
243
244 // multi-line text editor dialog
245 const int spacing = 8;
246 wxBoxSizer* topsizer = new wxBoxSizer( wxVERTICAL );
247 wxBoxSizer* rowsizer = new wxBoxSizer( wxHORIZONTAL );
248 wxTextCtrl* ed = new wxTextCtrl(dlg,11,text,
249 wxDefaultPosition,wxDefaultSize,wxTE_MULTILINE|wxTE_READONLY);
250 rowsizer->Add( ed, 1, wxEXPAND|wxALL, spacing );
251 topsizer->Add( rowsizer, 1, wxEXPAND, 0 );
252 rowsizer = new wxBoxSizer( wxHORIZONTAL );
253 const int butSzFlags =
254 wxALIGN_CENTRE_HORIZONTAL|wxALIGN_CENTRE_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT;
255 rowsizer->Add( new wxButton(dlg,wxID_OK,wxT("Ok")),
256 0, butSzFlags, spacing );
257 topsizer->Add( rowsizer, 0, wxALIGN_RIGHT|wxALIGN_CENTRE_VERTICAL, 0 );
258
259 dlg->SetSizer( topsizer );
260 topsizer->SetSizeHints( dlg );
261
262 dlg->SetSize(400,300);
263 dlg->Centre();
264 dlg->ShowModal();
265 }
266
267 // -----------------------------------------------------------------------
268
269 class TestRunner
270 {
271 public:
272
273 TestRunner( const wxString& name, wxPropertyGridManager* man, wxTextCtrl* ed, wxArrayString* errorMessages )
274 {
275 m_name = name;
276 m_man = man;
277 m_ed = ed;
278 m_errorMessages = errorMessages;
279 #ifdef __WXDEBUG__
280 m_preWarnings = wxPGGlobalVars->m_warnings;
281 #endif
282
283 if ( name != wxT("none") )
284 Msg(name+wxT("\n"));
285 }
286
287 ~TestRunner()
288 {
289 #ifdef __WXDEBUG__
290 int warningsOccurred = wxPGGlobalVars->m_warnings - m_preWarnings;
291 if ( warningsOccurred )
292 {
293 wxString s = wxString::Format(wxT("%i warnings occurred during test '%s'"), warningsOccurred, m_name.c_str());
294 m_errorMessages->push_back(s);
295 Msg(s);
296 }
297 #endif
298 }
299
300 void Msg( const wxString& text )
301 {
302 if ( m_ed )
303 {
304 m_ed->AppendText(text);
305 m_ed->AppendText(wxT("\n"));
306 }
307 wxLogDebug(text);
308 }
309
310 protected:
311 wxPropertyGridManager* m_man;
312 wxTextCtrl* m_ed;
313 wxArrayString* m_errorMessages;
314 wxString m_name;
315 #ifdef __WXDEBUG__
316 int m_preWarnings;
317 #endif
318 };
319
320
321 #define RT_START_TEST(TESTNAME) \
322 TestRunner tr(wxT(#TESTNAME), pgman, ed, &errorMessages);
323
324 #define RT_MSG(S) \
325 tr.Msg(S);
326
327 #define RT_FAILURE() \
328 { \
329 wxString s1 = wxString::Format(wxT("Test failure in tests.cpp, line %i."),__LINE__-1); \
330 errorMessages.push_back(s1); \
331 wxLogDebug(s1); \
332 failures++; \
333 }
334
335 #define RT_FAILURE_MSG(MSG) \
336 { \
337 wxString s1 = wxString::Format(wxT("Test failure in tests.cpp, line %i."),__LINE__-1); \
338 errorMessages.push_back(s1); \
339 wxLogDebug(s1); \
340 wxString s2 = wxString::Format(wxT("Message: %s"),MSG); \
341 errorMessages.push_back(s2); \
342 wxLogDebug(s2); \
343 failures++; \
344 }
345
346 #define RT_VALIDATE_VIRTUAL_HEIGHT(PROPS, EXTRATEXT) \
347 { \
348 unsigned int h1_ = PROPS->GetVirtualHeight(); \
349 unsigned int h2_ = PROPS->GetActualVirtualHeight(); \
350 if ( h1_ != h2_ ) \
351 { \
352 wxString s_ = wxString::Format(wxT("VirtualHeight = %i, should be %i (%s)"), h1_, h2_, EXTRATEXT.c_str()); \
353 RT_FAILURE_MSG(s_.c_str()); \
354 _failed_ = true; \
355 } \
356 else \
357 { \
358 _failed_ = false; \
359 } \
360 }
361
362
363 int gpiro_cmpfunc(const void* a, const void* b)
364 {
365 const wxPGProperty* p1 = (const wxPGProperty*) a;
366 const wxPGProperty* p2 = (const wxPGProperty*) b;
367 return (int) (((size_t)p1->GetClientData()) - ((size_t)p2->GetClientData()));
368 }
369
370 wxArrayPGProperty GetPropertiesInRandomOrder( wxPropertyGridInterface* props, int iterationFlags = wxPG_ITERATE_ALL )
371 {
372 wxArrayPGProperty arr;
373
374 wxPropertyGridIterator it;
375
376 for ( it = props->GetIterator(iterationFlags);
377 !it.AtEnd();
378 it++ )
379 {
380 wxPGProperty* p = *it;
381 size_t randomNumber = rand();
382 p->SetClientData(reinterpret_cast<void*>(randomNumber));
383 arr.push_back(p);
384 }
385
386 wxPGProperty** firstEntry = &arr[0];
387 qsort(firstEntry, arr.size(), sizeof(wxPGProperty*), gpiro_cmpfunc);
388
389 return arr;
390 }
391
392 bool FormMain::RunTests( bool fullTest, bool interactive )
393 {
394 wxString t;
395
396 wxPropertyGridManager* pgman = m_pPropGridManager;
397 wxPropertyGrid* pg;
398
399 size_t i;
400
401 pgman->ClearSelection();
402
403 int failures = 0;
404 bool _failed_ = false;
405 wxArrayString errorMessages;
406 wxDialog* dlg = NULL;
407
408 dlg = new wxDialog(this,-1,wxT("wxPropertyGrid Regression Tests"),
409 wxDefaultPosition,wxDefaultSize,wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER);
410
411 // multi-line text editor dialog
412 const int spacing = 8;
413 wxBoxSizer* topsizer = new wxBoxSizer( wxVERTICAL );
414 wxBoxSizer* rowsizer = new wxBoxSizer( wxHORIZONTAL );
415 wxTextCtrl* ed = new wxTextCtrl(dlg,11,wxEmptyString,
416 wxDefaultPosition,wxDefaultSize,wxTE_MULTILINE|wxTE_READONLY);
417 rowsizer->Add( ed, 1, wxEXPAND|wxALL, spacing );
418 topsizer->Add( rowsizer, 1, wxEXPAND, 0 );
419 rowsizer = new wxBoxSizer( wxHORIZONTAL );
420 const int butSzFlags =
421 wxALIGN_CENTRE_HORIZONTAL|wxALIGN_CENTRE_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT;
422 rowsizer->Add( new wxButton(dlg,wxID_OK,wxT("Ok")),
423 0, butSzFlags, spacing );
424 topsizer->Add( rowsizer, 0, wxALIGN_RIGHT|wxALIGN_CENTRE_VERTICAL, 0 );
425
426 dlg->SetSizer( topsizer );
427 topsizer->SetSizeHints( dlg );
428
429 dlg->SetSize(400,300);
430 dlg->Move(wxSystemSettings::GetMetric(wxSYS_SCREEN_X)-dlg->GetSize().x,
431 wxSystemSettings::GetMetric(wxSYS_SCREEN_Y)-dlg->GetSize().y);
432 dlg->Show();
433
434 {
435 //
436 // Basic iterator tests
437 RT_START_TEST(GetIterator)
438
439 wxPGVIterator it;
440 int count;
441
442 count = 0;
443 for ( it = pgman->GetVIterator(wxPG_ITERATE_PROPERTIES);
444 !it.AtEnd();
445 it.Next() )
446 {
447 wxPGProperty* p = it.GetProperty();
448 if ( p->IsCategory() )
449 RT_FAILURE_MSG(wxString::Format(wxT("'%s' is a category (non-private child property expected)"),p->GetLabel().c_str()).c_str())
450 else if ( p->GetParent()->HasFlag(wxPG_PROP_AGGREGATE) )
451 RT_FAILURE_MSG(wxString::Format(wxT("'%s' is a private child (non-private child property expected)"),p->GetLabel().c_str()).c_str())
452 count++;
453 }
454
455 RT_MSG(wxString::Format(wxT("GetVIterator(wxPG_ITERATE_PROPERTIES) -> %i entries"), count));
456
457 count = 0;
458 for ( it = pgman->GetVIterator(wxPG_ITERATE_CATEGORIES);
459 !it.AtEnd();
460 it.Next() )
461 {
462 wxPGProperty* p = it.GetProperty();
463 if ( !p->IsCategory() )
464 RT_FAILURE_MSG(wxString::Format(wxT("'%s' is not a category (only category was expected)"),p->GetLabel().c_str()).c_str())
465 count++;
466 }
467
468 RT_MSG(wxString::Format(wxT("GetVIterator(wxPG_ITERATE_CATEGORIES) -> %i entries"), count));
469
470 count = 0;
471 for ( it = pgman->GetVIterator(wxPG_ITERATE_PROPERTIES|wxPG_ITERATE_CATEGORIES);
472 !it.AtEnd();
473 it.Next() )
474 {
475 wxPGProperty* p = it.GetProperty();
476 if ( p->GetParent()->HasFlag(wxPG_PROP_AGGREGATE) )
477 RT_FAILURE_MSG(wxString::Format(wxT("'%s' is a private child (non-private child property or category expected)"),p->GetLabel().c_str()).c_str())
478 count++;
479 }
480
481 RT_MSG(wxString::Format(wxT("GetVIterator(wxPG_ITERATE_PROPERTIES|wxPG_ITERATE_CATEGORIES) -> %i entries"), count));
482
483 count = 0;
484 for ( it = pgman->GetVIterator(wxPG_ITERATE_VISIBLE);
485 !it.AtEnd();
486 it.Next() )
487 {
488 wxPGProperty* p = it.GetProperty();
489 if ( (p->GetParent() != p->GetParentState()->DoGetRoot() && !p->GetParent()->IsExpanded()) )
490 RT_FAILURE_MSG(wxString::Format(wxT("'%s' had collapsed parent (only visible properties expected)"),p->GetLabel().c_str()).c_str())
491 else if ( p->HasFlag(wxPG_PROP_HIDDEN) )
492 RT_FAILURE_MSG(wxString::Format(wxT("'%s' was hidden (only visible properties expected)"),p->GetLabel().c_str()).c_str())
493 count++;
494 }
495
496 RT_MSG(wxString::Format(wxT("GetVIterator(wxPG_ITERATE_VISIBLE) -> %i entries"), count));
497 }
498
499 if ( fullTest )
500 {
501 // Test that setting focus to properties does not crash things
502 RT_START_TEST(SelectProperty)
503
504 wxPropertyGridIterator it;
505 size_t ind;
506
507 for ( ind=0; ind<pgman->GetPageCount(); ind++ )
508 {
509 wxPropertyGridPage* page = pgman->GetPage(ind);
510 pgman->SelectPage(page);
511
512 for ( it = page->GetIterator(wxPG_ITERATE_VISIBLE);
513 !it.AtEnd();
514 it++ )
515 {
516 wxPGProperty* p = *it;
517 RT_MSG(p->GetLabel());
518 pgman->GetGrid()->SelectProperty(p, true);
519 ::wxMilliSleep(150);
520 Update();
521 }
522 }
523 }
524
525 {
526 //
527 // Delete everything in reverse order
528 RT_START_TEST(DeleteProperty)
529
530 wxPGVIterator it;
531 wxArrayPGProperty array;
532
533 for ( it = pgman->GetVIterator(wxPG_ITERATE_ALL&~(wxPG_IT_CHILDREN(wxPG_PROP_AGGREGATE)));
534 !it.AtEnd();
535 it.Next() )
536 array.push_back(it.GetProperty());
537
538 wxArrayPGProperty::reverse_iterator it2;
539
540 for ( it2 = array.rbegin(); it2 != array.rend(); it2++ )
541 {
542 wxPGProperty* p = (wxPGProperty*)*it2;
543 RT_MSG(wxString::Format(wxT("Deleting '%s' ('%s')"),p->GetLabel().c_str(),p->GetName().c_str()));
544 pgman->DeleteProperty(p);
545 }
546
547 // Recreate grid
548 CreateGrid( -1, -1 );
549 pgman = m_pPropGridManager;
550 }
551
552 {
553 //
554 // Test property default values
555 RT_START_TEST(Default_Values)
556
557 wxPGVIterator it;
558
559 for ( it = pgman->GetVIterator(wxPG_ITERATE_PROPERTIES);
560 !it.AtEnd();
561 it.Next() )
562 {
563 wxPGProperty* p = it.GetProperty();
564 pgman->SetPropertyValue(p, p->GetDefaultValue());
565 }
566
567 // Recreate grid
568 CreateGrid( -1, -1 );
569 pgman = m_pPropGridManager;
570 }
571
572 {
573 RT_START_TEST(GetPropertyValues)
574
575 for ( i=0; i<3; i++ )
576 {
577 wxString text;
578
579 wxPropertyGridPage* page = pgman->GetPage(i);
580
581 wxVariant values = page->GetPropertyValues();
582
583 unsigned int i;
584 for ( i = 0; i < (unsigned int)values.GetCount(); i++ )
585 {
586 wxVariant& v = values[i];
587
588 t.Printf(wxT("%i: name=\"%s\" type=\"%s\"\n"),(int)i,
589 v.GetName().c_str(),v.GetType().c_str());
590
591 text += t;
592 }
593 ed->AppendText(text);
594 }
595 }
596
597 {
598 RT_START_TEST(SetPropertyValue_and_GetPropertyValue)
599
600 // In this section, mixed up usage of wxT("propname") and "propname"
601 // in wxPropertyGridInterface functions is intentional.
602 // Purpose is to test wxPGPropArgCls ctors.
603
604 //pg = (wxPropertyGrid*) NULL;
605
606 wxArrayString test_arrstr_1;
607 test_arrstr_1.Add(wxT("Apple"));
608 test_arrstr_1.Add(wxT("Orange"));
609 test_arrstr_1.Add(wxT("Lemon"));
610
611 wxArrayString test_arrstr_2;
612 test_arrstr_2.Add(wxT("Potato"));
613 test_arrstr_2.Add(wxT("Cabbage"));
614 test_arrstr_2.Add(wxT("Cucumber"));
615
616 wxArrayInt test_arrint_1;
617 test_arrint_1.Add(1);
618 test_arrint_1.Add(2);
619 test_arrint_1.Add(3);
620
621 wxArrayInt test_arrint_2;
622 test_arrint_2.Add(0);
623 test_arrint_2.Add(1);
624 test_arrint_2.Add(4);
625
626 #if wxUSE_DATETIME
627 wxDateTime dt1 = wxDateTime::Now();
628 dt1.SetYear(dt1.GetYear()-1);
629
630 wxDateTime dt2 = wxDateTime::Now();
631 dt2.SetYear(dt2.GetYear()-10);
632 #endif
633
634 #define FLAG_TEST_SET1 (wxCAPTION|wxCLOSE_BOX|wxSYSTEM_MENU|wxRESIZE_BORDER)
635 #define FLAG_TEST_SET2 (wxSTAY_ON_TOP|wxCAPTION|wxICONIZE|wxSYSTEM_MENU)
636
637 pgman->SetPropertyValue(wxT("StringProperty"),wxT("Text1"));
638 pgman->SetPropertyValue(wxT("IntProperty"),1024);
639 pgman->SetPropertyValue(wxT("FloatProperty"),1024.0000000001);
640 pgman->SetPropertyValue(wxT("BoolProperty"),FALSE);
641 pgman->SetPropertyValue(wxT("EnumProperty"),120);
642 pgman->SetPropertyValue(wxT("ArrayStringProperty"),test_arrstr_1);
643 wxColour emptyCol;
644 pgman->SetPropertyValue(wxT("ColourProperty"),emptyCol);
645 pgman->SetPropertyValue(wxT("ColourProperty"),(wxObject*)wxBLACK);
646 pgman->SetPropertyValue(wxT("Size"),WXVARIANT(wxSize(150,150)));
647 pgman->SetPropertyValue(wxT("Position"),WXVARIANT(wxPoint(150,150)));
648 pgman->SetPropertyValue(wxT("MultiChoiceProperty"),test_arrint_1);
649 #if wxUSE_DATETIME
650 pgman->SetPropertyValue(wxT("DateProperty"),dt1);
651 #endif
652
653 pgman->SelectPage(2);
654 pg = pgman->GetGrid();
655
656 if ( pg->GetPropertyValueAsString(wxT("StringProperty")) != wxT("Text1") )
657 RT_FAILURE();
658 if ( pg->GetPropertyValueAsInt(wxT("IntProperty")) != 1024 )
659 RT_FAILURE();
660 if ( pg->GetPropertyValueAsDouble(wxT("FloatProperty")) != 1024.0000000001 )
661 RT_FAILURE();
662 if ( pg->GetPropertyValueAsBool(wxT("BoolProperty")) != FALSE )
663 RT_FAILURE();
664 if ( pg->GetPropertyValueAsLong(wxT("EnumProperty")) != 120 )
665 RT_FAILURE();
666 if ( pg->GetPropertyValueAsArrayString(wxT("ArrayStringProperty")) != test_arrstr_1 )
667 RT_FAILURE();
668 wxColour col;
669 col << pgman->GetPropertyValue(wxT("ColourProperty"));
670 if ( col != *wxBLACK )
671 RT_FAILURE();
672 if ( wxSizeRefFromVariant(pg->GetPropertyValue(wxT("Size"))) != wxSize(150,150) )
673 RT_FAILURE();
674 if ( wxPointRefFromVariant(pg->GetPropertyValue(wxT("Position"))) != wxPoint(150,150) )
675 RT_FAILURE();
676 if ( !(pg->GetPropertyValueAsArrayInt(wxT("MultiChoiceProperty")) == test_arrint_1) )
677 RT_FAILURE();
678 #if wxUSE_DATETIME
679 if ( !(pg->GetPropertyValueAsDateTime(wxT("DateProperty")) == dt1) )
680 RT_FAILURE();
681 #endif
682
683 pgman->SetPropertyValue(wxT("IntProperty"),wxLL(10000000000));
684 if ( pg->GetPropertyValueAsLongLong(wxT("IntProperty")) != wxLL(10000000000) )
685 RT_FAILURE();
686
687 pg->SetPropertyValue(wxT("StringProperty"),wxT("Text2"));
688 pg->SetPropertyValue(wxT("IntProperty"),512);
689 pg->SetPropertyValue(wxT("FloatProperty"),512.0);
690 pg->SetPropertyValue(wxT("BoolProperty"),TRUE);
691 pg->SetPropertyValue(wxT("EnumProperty"),80);
692 pg->SetPropertyValue(wxT("ArrayStringProperty"),test_arrstr_2);
693 pg->SetPropertyValue(wxT("ColourProperty"),(wxObject*)wxWHITE);
694 pg->SetPropertyValue(wxT("Size"),WXVARIANT(wxSize(300,300)));
695 pg->SetPropertyValue(wxT("Position"),WXVARIANT(wxPoint(300,300)));
696 pg->SetPropertyValue(wxT("MultiChoiceProperty"),test_arrint_2);
697 #if wxUSE_DATETIME
698 pg->SetPropertyValue(wxT("DateProperty"),dt2);
699 #endif
700
701 //pg = (wxPropertyGrid*) NULL;
702
703 pgman->SelectPage(0);
704
705 if ( pgman->GetPropertyValueAsString(wxT("StringProperty")) != wxT("Text2") )
706 RT_FAILURE();
707 if ( pgman->GetPropertyValueAsInt(wxT("IntProperty")) != 512 )
708 RT_FAILURE();
709 if ( pgman->GetPropertyValueAsDouble(wxT("FloatProperty")) != 512.0 )
710 RT_FAILURE();
711 if ( pgman->GetPropertyValueAsBool(wxT("BoolProperty")) != TRUE )
712 RT_FAILURE();
713 if ( pgman->GetPropertyValueAsLong(wxT("EnumProperty")) != 80 )
714 RT_FAILURE();
715 if ( pgman->GetPropertyValueAsArrayString(wxT("ArrayStringProperty")) != test_arrstr_2 )
716 RT_FAILURE();
717 col << pgman->GetPropertyValue(wxT("ColourProperty"));
718 if ( col != *wxWHITE )
719 RT_FAILURE();
720 if ( wxSizeRefFromVariant(pgman->GetPropertyValue(wxT("Size"))) != wxSize(300,300) )
721 RT_FAILURE();
722 if ( wxPointRefFromVariant(pgman->GetPropertyValue(wxT("Position"))) != wxPoint(300,300) )
723 RT_FAILURE();
724 if ( !(pgman->GetPropertyValueAsArrayInt(wxT("MultiChoiceProperty")) == test_arrint_2) )
725 RT_FAILURE();
726 #if wxUSE_DATETIME
727 if ( !(pgman->GetPropertyValueAsDateTime(wxT("DateProperty")) == dt2) )
728 RT_FAILURE();
729 #endif
730
731 pgman->SetPropertyValue(wxT("IntProperty"),wxLL(-80000000000));
732 if ( pgman->GetPropertyValueAsLongLong(wxT("IntProperty")) != wxLL(-80000000000) )
733 RT_FAILURE();
734
735 //
736 // Flexible wx(U)LongLong << operator safety conformance tests
737 wxPGProperty* prop;
738 wxLongLong ll;
739 wxULongLong ull;
740
741 prop = pgman->GetProperty(wxT("IntProperty"));
742 prop->SetValue(128);
743 ll << prop->GetValue();
744 if ( ll != 128 )
745 RT_FAILURE();
746
747 prop->SetValue(WXVARIANT(wxLL(68719476736)));
748 ll << prop->GetValue();
749 if ( ll.GetValue() != wxLL(68719476736) )
750 RT_FAILURE();
751
752 #if wxUSE_LONGLONG_NATIVE
753 wxLongLong_t ll_t;
754 ll_t << prop->GetValue();
755 if ( ll_t != wxLL(68719476736) )
756 RT_FAILURE();
757 #endif
758
759 prop->SetValue(256);
760 ll << prop->GetValue();
761 if ( ll != 256 )
762 RT_FAILURE();
763
764 prop = pgman->GetProperty(wxT("UIntProperty"));
765 prop->SetValue(128);
766 ull << prop->GetValue();
767 if ( ull != 128 )
768 RT_FAILURE();
769
770 prop->SetValue(WXVARIANT(wxULL(68719476739)));
771 ull << prop->GetValue();
772 if ( ull.GetValue() != wxULL(68719476739) )
773 RT_FAILURE();
774
775 #if wxUSE_LONGLONG_NATIVE
776 wxULongLong_t ull_t;
777 ull_t << prop->GetValue();
778 if ( ull_t != wxLL(68719476739) )
779 RT_FAILURE();
780 #endif
781
782 prop->SetValue(256);
783 ull << prop->GetValue();
784 if ( ull != 256 )
785 RT_FAILURE();
786
787 // Make sure children of composite parent get updated as well
788 // Original string value: "Lamborghini Diablo SV; 5707; [300; 3.9; 8.6] 300000"
789
790 //
791 // This updates children as well
792 wxString nvs = "Lamborghini Diablo XYZ; 5707; [100; 3.9; 8.6] 3000002";
793 pgman->SetPropertyValue("Car", nvs);
794
795 if ( pgman->GetPropertyValueAsString("Car.Model") != "Lamborghini Diablo XYZ" )
796 {
797 wxLogDebug("Did not match: Car.Model=%s", pgman->GetPropertyValueAsString("Car.Model").c_str());
798 RT_FAILURE();
799 }
800
801 if ( pgman->GetPropertyValueAsInt("Car.Speeds.Max. Speed (mph)") != 100 )
802 {
803 wxLogDebug("Did not match: Car.Speeds.Max. Speed (mph)=%s", pgman->GetPropertyValueAsString("Car.Speeds.Max. Speed (mph)").c_str());
804 RT_FAILURE();
805 }
806
807 if ( pgman->GetPropertyValueAsInt("Car.Price ($)") != 3000002 )
808 {
809 wxLogDebug("Did not match: Car.Price ($)=%s", pgman->GetPropertyValueAsString("Car.Price ($)").c_str());
810 RT_FAILURE();
811 }
812 }
813
814 {
815 RT_START_TEST(SetPropertyValueUnspecified)
816
817 // Null variant setter tests
818 pgman->SetPropertyValueUnspecified(wxT("StringProperty"));
819 pgman->SetPropertyValueUnspecified(wxT("IntProperty"));
820 pgman->SetPropertyValueUnspecified(wxT("FloatProperty"));
821 pgman->SetPropertyValueUnspecified(wxT("BoolProperty"));
822 pgman->SetPropertyValueUnspecified(wxT("EnumProperty"));
823 pgman->SetPropertyValueUnspecified(wxT("ArrayStringProperty"));
824 pgman->SetPropertyValueUnspecified(wxT("ColourProperty"));
825 pgman->SetPropertyValueUnspecified(wxT("Size"));
826 pgman->SetPropertyValueUnspecified(wxT("Position"));
827 pgman->SetPropertyValueUnspecified(wxT("MultiChoiceProperty"));
828 #if wxUSE_DATETIME
829 pgman->SetPropertyValueUnspecified(wxT("DateProperty"));
830 #endif
831 }
832
833 {
834 RT_START_TEST(Attributes)
835
836 wxPGProperty* prop = pgman->GetProperty(wxT("StringProperty"));
837 prop->SetAttribute(wxT("Dummy Attribute"), (long)15);
838
839 if ( prop->GetAttribute(wxT("Dummy Attribute")).GetLong() != 15 )
840 RT_FAILURE();
841
842 prop->SetAttribute(wxT("Dummy Attribute"), wxVariant());
843
844 if ( !prop->GetAttribute(wxT("Dummy Attribute")).IsNull() )
845 RT_FAILURE();
846 }
847
848 {
849 wxPropertyGridPage* page1;
850 wxPropertyGridPage* page2;
851 wxPropertyGridPage* page3;
852 wxVariant pg1_values;
853 wxVariant pg2_values;
854 wxVariant pg3_values;
855
856 {
857 RT_START_TEST(GetPropertyValues)
858
859 page1 = pgman->GetPage(0);
860 pg1_values = page1->GetPropertyValues(wxT("Page1"),NULL,wxPG_KEEP_STRUCTURE);
861 page2 = pgman->GetPage(1);
862 pg2_values = page2->GetPropertyValues(wxT("Page2"),NULL,wxPG_KEEP_STRUCTURE);
863 page3 = pgman->GetPage(2);
864 pg3_values = page3->GetPropertyValues(wxT("Page3"),NULL,wxPG_KEEP_STRUCTURE);
865 }
866
867 {
868 RT_START_TEST(SetPropertyValues)
869
870 page1->SetPropertyValues(pg3_values);
871 page2->SetPropertyValues(pg1_values);
872 page3->SetPropertyValues(pg2_values);
873 }
874 }
875
876 if ( !(pgman->GetWindowStyleFlag()&wxPG_HIDE_CATEGORIES) )
877 {
878 RT_START_TEST(Collapse_and_GetFirstCategory_and_GetNextCategory)
879
880 for ( i=0; i<3; i++ )
881 {
882 wxPropertyGridPage* page = pgman->GetPage(i);
883
884 wxPropertyGridIterator it;
885
886 for ( it = page->GetIterator( wxPG_ITERATE_CATEGORIES );
887 !it.AtEnd();
888 it++ )
889 {
890 wxPGProperty* p = *it;
891
892 if ( !page->IsPropertyCategory(p) )
893 RT_FAILURE();
894
895 page->Collapse( p );
896
897 t.Printf(wxT("Collapsing: %s\n"),page->GetPropertyLabel(p).c_str());
898 ed->AppendText(t);
899 }
900 }
901 }
902
903 {
904 RT_START_TEST(Save_And_RestoreEditableState)
905
906 for ( i=0; i<3; i++ )
907 {
908 pgman->SelectPage(i);
909
910 wxString stringState = pgman->SaveEditableState();
911 bool res = pgman->RestoreEditableState(stringState);
912 if ( !res )
913 RT_FAILURE();
914 }
915 }
916
917 //if ( !(pgman->GetWindowStyleFlag()&wxPG_HIDE_CATEGORIES) )
918 {
919 RT_START_TEST(Expand_and_GetFirstCategory_and_GetNextCategory)
920
921 for ( i=0; i<3; i++ )
922 {
923 wxPropertyGridPage* page = pgman->GetPage(i);
924
925 wxPropertyGridIterator it;
926
927 for ( it = page->GetIterator( wxPG_ITERATE_CATEGORIES );
928 !it.AtEnd();
929 it++ )
930 {
931 wxPGProperty* p = *it;
932
933 if ( !page->IsPropertyCategory(p) )
934 RT_FAILURE();
935
936 page->Expand( p );
937
938 t.Printf(wxT("Expand: %s\n"),page->GetPropertyLabel(p).c_str());
939 ed->AppendText(t);
940 }
941 }
942 }
943
944 {
945 RT_START_TEST(Choice_Manipulation)
946
947 wxPGProperty* enumProp = pgman->GetProperty(wxT("EnumProperty"));
948
949 pgman->SelectPage(2);
950 pgman->SelectProperty(enumProp);
951 wxASSERT(pgman->GetGrid()->GetSelection() == enumProp);
952
953 const wxPGChoices& choices = enumProp->GetChoices();
954 int ind = enumProp->InsertChoice(wxT("New Choice"), choices.GetCount()/2);
955 enumProp->DeleteChoice(ind);
956
957 // Recreate the original grid
958 CreateGrid( -1, -1 );
959 pgman = m_pPropGridManager;
960 }
961
962 //if ( !(pgman->GetWindowStyleFlag()&wxPG_HIDE_CATEGORIES) )
963 {
964 RT_START_TEST(RandomCollapse)
965
966 // Select the most error prone page as visible.
967 pgman->SelectPage(1);
968
969 for ( i=0; i<3; i++ )
970 {
971 wxArrayPtrVoid arr;
972
973 wxPropertyGridPage* page = pgman->GetPage(i);
974
975 wxPropertyGridIterator it;
976
977 for ( it = page->GetIterator( wxPG_ITERATE_CATEGORIES );
978 !it.AtEnd();
979 it++ )
980 {
981 arr.Add((void*)*it);
982 }
983
984 if ( arr.GetCount() )
985 {
986 size_t n;
987
988 pgman->Collapse( (wxPGProperty*)arr.Item(0) );
989
990 for ( n=arr.GetCount()-1; n>0; n-- )
991 {
992 pgman->Collapse( (wxPGProperty*)arr.Item(n) );
993 }
994 }
995
996 }
997 }
998
999 {
1000 RT_START_TEST(EnsureVisible)
1001 pgman->EnsureVisible(wxT("Cell Colour"));
1002 }
1003
1004 {
1005 RT_START_TEST(SetPropertyBackgroundColour)
1006 wxCommandEvent evt;
1007 evt.SetInt(1); // IsChecked() will return TRUE.
1008 evt.SetId(ID_COLOURSCHEME4);
1009 OnCatColours(evt);
1010 OnColourScheme(evt);
1011 }
1012
1013 {
1014 RT_START_TEST(ManagerClear)
1015 pgman->Clear();
1016
1017 if ( pgman->GetPageCount() )
1018 RT_FAILURE();
1019
1020 // Recreate the original grid
1021 CreateGrid( -1, -1 );
1022 pgman = m_pPropGridManager;
1023 }
1024
1025 /*
1026 {
1027 // TODO: This test fails.
1028 RT_START_TEST(SetSplitterPosition)
1029
1030 InitPanel();
1031
1032 const int trySplitterPos = 50;
1033
1034 int style = wxPG_AUTO_SORT; // wxPG_SPLITTER_AUTO_CENTER;
1035 pgman = m_pPropGridManager =
1036 new wxPropertyGridManager(m_panel, wxID_ANY,
1037 wxDefaultPosition,
1038 wxDefaultSize,
1039 style );
1040
1041 PopulateGrid();
1042 pgman->SetSplitterPosition(trySplitterPos);
1043
1044 if ( pgman->GetGrid()->GetSplitterPosition() != trySplitterPos )
1045 RT_FAILURE_MSG(wxString::Format(wxT("Splitter position was %i (should have been %i)"),(int)pgman->GetGrid()->GetSplitterPosition(),trySplitterPos).c_str());
1046
1047 m_topSizer->Add( m_pPropGridManager, 1, wxEXPAND );
1048 FinalizePanel();
1049
1050 wxSize sz = GetSize();
1051 wxSize origSz = sz;
1052 sz.x += 5;
1053 sz.y += 5;
1054
1055 if ( pgman->GetGrid()->GetSplitterPosition() != trySplitterPos )
1056 RT_FAILURE_MSG(wxString::Format(wxT("Splitter position was %i (should have been %i)"),(int)pgman->GetGrid()->GetSplitterPosition(),trySplitterPos).c_str());
1057
1058 SetSize(origSz);
1059
1060 // Recreate the original grid
1061 CreateGrid( -1, -1 );
1062 pgman = m_pPropGridManager;
1063 }
1064 */
1065
1066 {
1067 RT_START_TEST(HideProperty)
1068
1069 wxPropertyGridPage* page = pgman->GetPage(0);
1070
1071 srand(0x1234);
1072
1073 wxArrayPGProperty arr1;
1074
1075 arr1 = GetPropertiesInRandomOrder(page);
1076
1077 if ( !_failed_ )
1078 {
1079 for ( i=0; i<arr1.size(); i++ )
1080 {
1081 wxPGProperty* p = arr1[i];
1082 page->HideProperty(p, true);
1083
1084 wxString s = wxString::Format(wxT("HideProperty(%i, %s)"), i, p->GetLabel().c_str());
1085 RT_VALIDATE_VIRTUAL_HEIGHT(page, s)
1086 if ( _failed_ )
1087 break;
1088 }
1089 }
1090
1091 if ( !_failed_ )
1092 {
1093 wxArrayPGProperty arr2 = GetPropertiesInRandomOrder(page);
1094
1095 for ( i=0; i<arr2.size(); i++ )
1096 {
1097 wxPGProperty* p = arr2[i];
1098 page->HideProperty(p, false);
1099
1100 wxString s = wxString::Format(wxT("ShowProperty(%i, %s)"), i, p->GetLabel().c_str());
1101 RT_VALIDATE_VIRTUAL_HEIGHT(page, s)
1102 if ( _failed_ )
1103 break;
1104 }
1105 }
1106
1107 //
1108 // Let's do some more, for better consistency
1109 arr1 = GetPropertiesInRandomOrder(page);
1110
1111 if ( !_failed_ )
1112 {
1113 for ( i=0; i<arr1.size(); i++ )
1114 {
1115 wxPGProperty* p = arr1[i];
1116 page->HideProperty(p, true);
1117
1118 wxString s = wxString::Format(wxT("HideProperty(%i, %s)"), i, p->GetLabel().c_str());
1119 RT_VALIDATE_VIRTUAL_HEIGHT(page, s)
1120 if ( _failed_ )
1121 break;
1122 }
1123 }
1124
1125 if ( !_failed_ )
1126 {
1127 wxArrayPGProperty arr2 = GetPropertiesInRandomOrder(page);
1128
1129 for ( i=0; i<arr2.size(); i++ )
1130 {
1131 wxPGProperty* p = arr2[i];
1132 page->HideProperty(p, false);
1133
1134 wxString s = wxString::Format(wxT("ShowProperty(%i, %s)"), i, p->GetLabel().c_str());
1135 RT_VALIDATE_VIRTUAL_HEIGHT(page, s)
1136 if ( _failed_ )
1137 break;
1138 }
1139 }
1140
1141 //
1142 // Ok, this time only hide half of them
1143 arr1 = GetPropertiesInRandomOrder(page);
1144 arr1.resize(arr1.size()/2);
1145
1146 if ( !_failed_ )
1147 {
1148 for ( i=0; i<arr1.size(); i++ )
1149 {
1150 wxPGProperty* p = arr1[i];
1151 page->HideProperty(p, true);
1152
1153 wxString s = wxString::Format(wxT("HideProperty(%i, %s)"), i, p->GetLabel().c_str());
1154 RT_VALIDATE_VIRTUAL_HEIGHT(page, s)
1155 if ( _failed_ )
1156 break;
1157 }
1158 }
1159
1160 if ( !_failed_ )
1161 {
1162 wxArrayPGProperty arr2 = GetPropertiesInRandomOrder(page);
1163
1164 for ( i=0; i<arr2.size(); i++ )
1165 {
1166 wxPGProperty* p = arr2[i];
1167 page->HideProperty(p, false);
1168
1169 wxString s = wxString::Format(wxT("ShowProperty(%i, %s)"), i, p->GetLabel().c_str());
1170 RT_VALIDATE_VIRTUAL_HEIGHT(page, s)
1171 if ( _failed_ )
1172 break;
1173 }
1174 }
1175
1176 // Recreate the original grid
1177 CreateGrid( -1, -1 );
1178 pgman = m_pPropGridManager;
1179 }
1180
1181 if ( fullTest )
1182 {
1183 RT_START_TEST(MultipleColumns)
1184
1185 // Test with multiple columns
1186 // FIXME: Does not display changes.
1187 for ( i=3; i<12; i+=2 )
1188 {
1189 RT_MSG(wxString::Format(wxT("%i columns"),i));
1190 CreateGrid( -1, -1 );
1191 pgman = m_pPropGridManager;
1192 pgman->SetColumnCount(i);
1193 Refresh();
1194 Update();
1195 wxMilliSleep(500);
1196 }
1197 }
1198
1199 if ( fullTest )
1200 {
1201 RT_START_TEST(WindowStyles)
1202
1203 // Recreate grid with all possible (single) flags
1204 wxASSERT(wxPG_AUTO_SORT == 0x000000010);
1205
1206 for ( i=4; i<16; i++ )
1207 {
1208 int flag = 1<<i;
1209 RT_MSG(wxString::Format(wxT("Style: 0x%X"),flag));
1210 CreateGrid( flag, -1 );
1211 pgman = m_pPropGridManager;
1212 Update();
1213 wxMilliSleep(500);
1214 }
1215
1216 wxASSERT(wxPG_EX_INIT_NOCAT == 0x00001000);
1217
1218 for ( i=12; i<24; i++ )
1219 {
1220 int flag = 1<<i;
1221 RT_MSG(wxString::Format(wxT("ExStyle: 0x%X"),flag));
1222 CreateGrid( -1, flag );
1223 pgman = m_pPropGridManager;
1224 Update();
1225 wxMilliSleep(500);
1226 }
1227
1228 // Recreate the original grid
1229 CreateGrid( -1, -1 );
1230 pgman = m_pPropGridManager;
1231 }
1232
1233 RT_START_TEST(none)
1234
1235 bool retVal;
1236
1237 if ( failures || errorMessages.size() )
1238 {
1239 retVal = false;
1240
1241 wxString s;
1242 #ifdef __WXDEBUG__
1243 if ( failures )
1244 #endif
1245 s = wxString::Format(wxT("%i tests failed!!!"), failures);
1246 #ifdef __WXDEBUG__
1247 else
1248 s = wxString::Format(wxT("All tests were succesfull, but there were %i warnings!"), wxPGGlobalVars->m_warnings);
1249 #endif
1250 RT_MSG(s)
1251 for ( i=0; i<errorMessages.size(); i++ )
1252 RT_MSG(errorMessages[i])
1253 wxMessageBox(s, wxT("Some Tests Failed"));
1254 }
1255 else
1256 {
1257 RT_MSG(wxT("All tests succesfull"))
1258 retVal = true;
1259
1260 if ( !interactive )
1261 dlg->Close();
1262 }
1263
1264 pgman->SelectPage(0);
1265
1266 // Test may screw up the toolbar, so we need to refresh it.
1267 wxToolBar* toolBar = pgman->GetToolBar();
1268 if ( toolBar )
1269 toolBar->Refresh();
1270
1271 return retVal;
1272 }
1273
1274 // -----------------------------------------------------------------------