]> git.saurik.com Git - wxWidgets.git/blob - utils/wxprop/src/proplist.cpp
*** empty log message ***
[wxWidgets.git] / utils / wxprop / src / proplist.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: proplist.cpp
3 // Purpose: Property list classes
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "proplist.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx/wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #ifndef WX_PRECOMP
24 #include "wx/wx.h"
25 #endif
26
27 #include <ctype.h>
28 #include <stdlib.h>
29 #include <math.h>
30 #include <string.h>
31
32 #if defined(__WINDOWS__) && !defined(__GNUWIN32__)
33 #include <strstrea.h>
34 #else
35 #include <strstream.h>
36 #endif
37
38 #include "wx/window.h"
39 #include "wx/utils.h"
40 #include "wx/list.h"
41 #include "wx/colordlg.h"
42 #include "proplist.h"
43
44 /*
45 * Property text edit control
46 */
47
48 IMPLEMENT_CLASS(wxPropertyTextEdit, wxTextCtrl)
49
50 wxPropertyTextEdit::wxPropertyTextEdit(wxPropertyListView *v, wxWindow *parent,
51 const wxWindowID id, const wxString& value,
52 const wxPoint& pos, const wxSize& size,
53 long style, const wxString& name):
54 wxTextCtrl(parent, id, value, pos, size, style, wxDefaultValidator, name)
55 {
56 view = v;
57 }
58
59 void wxPropertyTextEdit::OnSetFocus(void)
60 {
61 }
62
63 void wxPropertyTextEdit::OnKillFocus(void)
64 {
65 }
66
67 /*
68 * Property list view
69 */
70
71 IMPLEMENT_DYNAMIC_CLASS(wxPropertyListView, wxPropertyView)
72
73 BEGIN_EVENT_TABLE(wxPropertyListView, wxPropertyView)
74 EVT_BUTTON(wxID_OK, wxPropertyListView::OnOk)
75 EVT_BUTTON(wxID_CANCEL, wxPropertyListView::OnCancel)
76 EVT_BUTTON(wxID_HELP, wxPropertyListView::OnHelp)
77 EVT_BUTTON(wxID_PROP_CROSS, wxPropertyListView::OnCross)
78 EVT_BUTTON(wxID_PROP_CHECK, wxPropertyListView::OnCheck)
79 EVT_BUTTON(wxID_PROP_EDIT, wxPropertyListView::OnEdit)
80 EVT_TEXT_ENTER(wxID_PROP_TEXT, wxPropertyListView::OnText)
81 EVT_LISTBOX(wxID_PROP_SELECT, wxPropertyListView::OnPropertySelect)
82 EVT_COMMAND(wxID_PROP_SELECT, wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, wxPropertyListView::OnPropertyDoubleClick)
83 EVT_TEXT(wxID_PROP_VALUE_SELECT, wxPropertyListView::OnValueListSelect)
84 END_EVENT_TABLE()
85
86 bool wxPropertyListView::dialogCancelled = FALSE;
87 wxBitmap *wxPropertyListView::tickBitmap = NULL;
88 wxBitmap *wxPropertyListView::crossBitmap = NULL;
89
90 wxPropertyListView::wxPropertyListView(wxPanel *propPanel, long flags):wxPropertyView(flags)
91 {
92 propertyScrollingList = NULL;
93 valueList = NULL;
94 valueText = NULL;
95 editButton = NULL;
96 confirmButton = NULL;
97 cancelButton = NULL;
98 propertyWindow = propPanel;
99 managedWindow = NULL;
100
101 windowCloseButton = NULL;
102 windowCancelButton = NULL;
103 windowHelpButton = NULL;
104
105 detailedEditing = FALSE;
106 }
107
108 wxPropertyListView::~wxPropertyListView(void)
109 {
110 /*
111 if (tickBitmap)
112 delete tickBitmap;
113 if (crossBitmap)
114 delete crossBitmap;
115 */
116 }
117
118 void wxPropertyListView::ShowView(wxPropertySheet *ps, wxPanel *panel)
119 {
120 propertySheet = ps;
121
122 AssociatePanel(panel);
123 CreateControls();
124
125 UpdatePropertyList();
126 panel->Layout();
127 }
128
129 // Update this view of the viewed object, called e.g. by
130 // the object itself.
131 bool wxPropertyListView::OnUpdateView(void)
132 {
133 return TRUE;
134 }
135
136 bool wxPropertyListView::UpdatePropertyList(bool clearEditArea)
137 {
138 if (!propertyScrollingList || !propertySheet)
139 return FALSE;
140
141 propertyScrollingList->Clear();
142 if (clearEditArea)
143 {
144 valueList->Clear();
145 valueText->SetValue("");
146 }
147 wxNode *node = propertySheet->GetProperties().First();
148
149 // Should sort them... later...
150 while (node)
151 {
152 wxProperty *property = (wxProperty *)node->Data();
153 wxString stringValueRepr(property->GetValue().GetStringRepresentation());
154 wxString paddedString(MakeNameValueString(property->GetName(), stringValueRepr));
155
156 propertyScrollingList->Append(paddedString.GetData(), (char *)property);
157 node = node->Next();
158 }
159 return TRUE;
160 }
161
162 bool wxPropertyListView::UpdatePropertyDisplayInList(wxProperty *property)
163 {
164 if (!propertyScrollingList || !propertySheet)
165 return FALSE;
166
167 int currentlySelected = propertyScrollingList->GetSelection();
168 // #ifdef __WINDOWS__
169 wxString stringValueRepr(property->GetValue().GetStringRepresentation());
170 wxString paddedString(MakeNameValueString(property->GetName(), stringValueRepr));
171 int sel = FindListIndexForProperty(property);
172
173 if (sel > -1)
174 {
175 // Don't update the listbox unnecessarily because it can cause
176 // ugly flashing.
177
178 if (paddedString != propertyScrollingList->GetString(sel))
179 propertyScrollingList->SetString(sel, paddedString.GetData());
180 }
181 //#else
182 // UpdatePropertyList(FALSE);
183 //#endif
184
185 if (currentlySelected > -1)
186 propertyScrollingList->SetSelection(currentlySelected);
187
188 return TRUE;
189 }
190
191 // Find the wxListBox index corresponding to this property
192 int wxPropertyListView::FindListIndexForProperty(wxProperty *property)
193 {
194 int n = propertyScrollingList->Number();
195 for (int i = 0; i < n; i++)
196 {
197 if (property == (wxProperty *)propertyScrollingList->wxListBox::GetClientData(i))
198 return i;
199 }
200 return -1;
201 }
202
203 wxString wxPropertyListView::MakeNameValueString(wxString name, wxString value)
204 {
205 wxString theString(name);
206
207 int nameWidth = 25;
208 int padWith = nameWidth - theString.Length();
209 if (padWith < 0)
210 padWith = 0;
211
212 if (GetFlags() & wxPROP_SHOWVALUES)
213 {
214 // Want to pad with spaces
215 theString.Append(' ', padWith);
216 theString += value;
217 }
218
219 return theString;
220 }
221
222 // Select and show string representation in validator the given
223 // property. NULL resets to show no property.
224 bool wxPropertyListView::ShowProperty(wxProperty *property, bool select)
225 {
226 if (currentProperty)
227 {
228 EndShowingProperty(currentProperty);
229 currentProperty = NULL;
230 }
231
232 valueList->Clear();
233 valueText->SetValue("");
234
235 if (property)
236 {
237 currentProperty = property;
238 BeginShowingProperty(property);
239 }
240 if (select)
241 {
242 int sel = FindListIndexForProperty(property);
243 if (sel > -1)
244 propertyScrollingList->SetSelection(sel);
245 }
246 return TRUE;
247 }
248
249 // Find appropriate validator and load property into value controls
250 bool wxPropertyListView::BeginShowingProperty(wxProperty *property)
251 {
252 currentValidator = FindPropertyValidator(property);
253 if (!currentValidator)
254 return FALSE;
255
256 if (!currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator)))
257 return FALSE;
258
259 wxPropertyListValidator *listValidator = (wxPropertyListValidator *)currentValidator;
260
261 listValidator->OnPrepareControls(property, this, propertyWindow);
262 DisplayProperty(property);
263 return TRUE;
264 }
265
266 // Find appropriate validator and unload property from value controls
267 bool wxPropertyListView::EndShowingProperty(wxProperty *property)
268 {
269 if (!currentValidator)
270 return FALSE;
271
272 RetrieveProperty(property);
273
274 if (!currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator)))
275 return FALSE;
276
277 wxPropertyListValidator *listValidator = (wxPropertyListValidator *)currentValidator;
278
279 listValidator->OnClearControls(property, this, propertyWindow);
280 if (detailedEditing)
281 {
282 listValidator->OnClearDetailControls(property, this, propertyWindow);
283 detailedEditing = FALSE;
284 }
285 return TRUE;
286 }
287
288 void wxPropertyListView::BeginDetailedEditing(void)
289 {
290 if (!currentValidator)
291 return;
292 if (!currentProperty)
293 return;
294 if (detailedEditing)
295 return;
296 if (!currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator)))
297 return;
298 if (!currentProperty->IsEnabled())
299 return;
300
301 wxPropertyListValidator *listValidator = (wxPropertyListValidator *)currentValidator;
302
303 if (listValidator->OnPrepareDetailControls(currentProperty, this, propertyWindow))
304 detailedEditing = TRUE;
305 }
306
307 void wxPropertyListView::EndDetailedEditing(void)
308 {
309 if (!currentValidator)
310 return;
311 if (!currentProperty)
312 return;
313
314 RetrieveProperty(currentProperty);
315
316 if (!currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator)))
317 return;
318
319 wxPropertyListValidator *listValidator = (wxPropertyListValidator *)currentValidator;
320
321 if (detailedEditing)
322 {
323 listValidator->OnClearDetailControls(currentProperty, this, propertyWindow);
324 detailedEditing = FALSE;
325 }
326 }
327
328 bool wxPropertyListView::DisplayProperty(wxProperty *property)
329 {
330 if (!currentValidator)
331 return FALSE;
332
333 if (((currentValidator->GetFlags() & wxPROP_ALLOW_TEXT_EDITING) == 0) || !property->IsEnabled())
334 valueText->SetEditable(FALSE);
335 else
336 valueText->SetEditable(TRUE);
337
338 if (!currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator)))
339 return FALSE;
340
341 wxPropertyListValidator *listValidator = (wxPropertyListValidator *)currentValidator;
342
343 listValidator->OnDisplayValue(property, this, propertyWindow);
344 return TRUE;
345 }
346
347 bool wxPropertyListView::RetrieveProperty(wxProperty *property)
348 {
349 if (!currentValidator)
350 return FALSE;
351 if (!property->IsEnabled())
352 return FALSE;
353
354 if (!currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator)))
355 return FALSE;
356
357 wxPropertyListValidator *listValidator = (wxPropertyListValidator *)currentValidator;
358
359 if (listValidator->OnCheckValue(property, this, propertyWindow))
360 {
361 if (listValidator->OnRetrieveValue(property, this, propertyWindow))
362 {
363 UpdatePropertyDisplayInList(property);
364 OnPropertyChanged(property);
365 }
366 }
367 else
368 {
369 // Revert to old value
370 listValidator->OnDisplayValue(property, this, propertyWindow);
371 }
372 return TRUE;
373 }
374
375
376 bool wxPropertyListView::EditProperty(wxProperty *property)
377 {
378 return TRUE;
379 }
380
381 // Called by the listbox callback
382 void wxPropertyListView::OnPropertySelect(wxCommandEvent& event)
383 {
384 int sel = propertyScrollingList->GetSelection();
385 if (sel > -1)
386 {
387 wxProperty *newSel = (wxProperty *)propertyScrollingList->wxListBox::GetClientData(sel);
388 if (newSel && newSel != currentProperty)
389 {
390 ShowProperty(newSel, FALSE);
391 }
392 }
393 }
394
395 bool wxPropertyListView::CreateControls(void)
396 {
397 wxPanel *panel = (wxPanel *)propertyWindow;
398
399 int largeButtonWidth = 50;
400 int largeButtonHeight = 25;
401
402 int smallButtonWidth = 25;
403 int smallButtonHeight = 20;
404
405 // XView must be allowed to choose its own sized buttons
406 #ifdef __XVIEW__
407 largeButtonWidth = -1;
408 largeButtonHeight = -1;
409
410 smallButtonWidth = -1;
411 smallButtonHeight = -1;
412 #endif
413
414 if (valueText)
415 return TRUE;
416
417 if (!panel)
418 return FALSE;
419
420 wxWindow *leftMostWindow = panel;
421 wxWindow *topMostWindow = panel;
422 wxWindow *rightMostWindow = panel;
423
424 wxSystemSettings settings;
425 wxFont guiFont = settings.GetSystemFont(wxSYS_DEFAULT_GUI_FONT);
426
427 wxFont *boringFont = wxTheFontList->FindOrCreateFont(guiFont.GetPointSize(), wxMODERN, wxNORMAL, wxNORMAL);
428
429 // May need to be changed in future to eliminate clashes with app.
430 panel->SetClientData((char *)this);
431
432 if (buttonFlags & wxPROP_BUTTON_OK)
433 {
434 windowCloseButton = new wxButton(panel, wxID_OK, "OK",
435 wxPoint(-1, -1), wxSize(largeButtonWidth, largeButtonHeight));
436 windowCloseButton->SetDefault();
437 windowCloseButton->SetFocus();
438 }
439 if (buttonFlags & wxPROP_BUTTON_CLOSE)
440 {
441 windowCloseButton = new wxButton(panel, wxID_OK, "Close",
442 wxPoint(-1, -1), wxSize(largeButtonWidth, largeButtonHeight));
443 }
444 if (buttonFlags & wxPROP_BUTTON_CANCEL)
445 {
446 windowCancelButton = new wxButton(panel, wxID_CANCEL, "Cancel",
447 wxPoint(-1, -1), wxSize(largeButtonWidth, largeButtonHeight));
448 }
449 if (buttonFlags & wxPROP_BUTTON_HELP)
450 {
451 windowHelpButton = new wxButton(panel, wxID_HELP, "Help",
452 wxPoint(-1, -1), wxSize(largeButtonWidth, largeButtonHeight));
453 }
454
455 if (windowCloseButton)
456 {
457 wxLayoutConstraints *c1 = new wxLayoutConstraints;
458 c1->left.SameAs (panel, wxLeft, 2);
459 c1->top.SameAs (panel, wxTop, 2);
460 c1->width.AsIs();
461 c1->height.AsIs();
462 windowCloseButton->SetConstraints(c1);
463 leftMostWindow = windowCloseButton;
464 }
465 if (windowCancelButton)
466 {
467 wxLayoutConstraints *c2 = new wxLayoutConstraints;
468 if (leftMostWindow == panel)
469 c2->left.SameAs (panel, wxLeft, 2);
470 else
471 c2->left.RightOf (leftMostWindow, 2);
472
473 c2->top.SameAs (panel, wxTop, 2);
474 c2->width.AsIs();
475 c2->height.AsIs();
476 windowCancelButton->SetConstraints(c2);
477 leftMostWindow = windowCancelButton;
478 }
479 if (windowHelpButton)
480 {
481 wxLayoutConstraints *c2 = new wxLayoutConstraints;
482 if (leftMostWindow == panel)
483 c2->left.SameAs (panel, wxLeft, 2);
484 else
485 c2->left.RightOf (leftMostWindow, 2);
486
487 c2->top.SameAs (panel, wxTop, 2);
488 c2->width.AsIs();
489 c2->height.AsIs();
490 windowHelpButton->SetConstraints(c2);
491 leftMostWindow = windowHelpButton;
492 }
493
494 if (buttonFlags & wxPROP_BUTTON_CHECK_CROSS)
495 {
496 /*
497 if (!tickBitmap)
498 {
499 #ifdef __WINDOWS__
500 tickBitmap = new wxBitmap("tick_bmp", wxBITMAP_TYPE_RESOURCE);
501 crossBitmap = new wxBitmap("cross_bmp", wxBITMAP_TYPE_RESOURCE);
502 if (!tickBitmap || !crossBitmap || !tickBitmap->Ok() || !crossBitmap->Ok())
503 {
504 if (tickBitmap)
505 delete tickBitmap;
506 if (crossBitmap)
507 delete crossBitmap;
508 tickBitmap = NULL;
509 crossBitmap = NULL;
510 }
511 #endif
512 }
513 */
514 /*
515 if (tickBitmap && crossBitmap)
516 {
517 confirmButton = new wxBitmapButton(panel, wxID_PROP_CHECK, tickBitmap,
518 wxPoint(-1, -1), wxSize(smallButtonWidth-5, smallButtonHeight-5));
519 cancelButton = new wxBitmapButton(panel, wxID_PROP_CROSS, crossBitmap,
520 wxPoint(-1, -1), wxSize(smallButtonWidth-5, smallButtonHeight-5));
521 }
522 else
523 */
524 {
525 confirmButton = new wxButton(panel, wxID_PROP_CHECK, ":-)",
526 wxPoint(-1, -1), wxSize(smallButtonWidth, smallButtonHeight));
527 cancelButton = new wxButton(panel, wxID_PROP_CROSS, "X",
528 wxPoint(-1, -1), wxSize(smallButtonWidth, smallButtonHeight));
529 }
530
531 wxLayoutConstraints *c = new wxLayoutConstraints;
532 c->left.SameAs (panel, wxLeft, 2);
533 if (windowCloseButton)
534 c->top.Below (windowCloseButton, 2);
535 else
536 c->top.SameAs (panel, wxTop, 2);
537
538 c->width.AsIs();
539 c->height.AsIs();
540
541 cancelButton->SetConstraints(c);
542
543 c = new wxLayoutConstraints;
544 c->left.RightOf (cancelButton, 2);
545 c->top.SameAs (cancelButton, wxTop, 0);
546 c->width.AsIs();
547 c->height.AsIs();
548
549 confirmButton->SetConstraints(c);
550
551 cancelButton->Enable(FALSE);
552 confirmButton->Enable(FALSE);
553 }
554
555 if (buttonFlags & wxPROP_PULLDOWN)
556 {
557 editButton = new wxButton(panel, wxID_PROP_EDIT, "...",
558 wxPoint(-1, -1), wxSize(smallButtonWidth, smallButtonHeight));
559 editButton->Enable(FALSE);
560 wxLayoutConstraints *c = new wxLayoutConstraints;
561
562 if (windowCloseButton)
563 c->top.Below (windowCloseButton, 2);
564 else
565 c->top.SameAs (panel, wxTop, 2);
566
567 c->right.SameAs (panel, wxRight, 2);
568 c->width.AsIs();
569 c->height.AsIs();
570 editButton->SetConstraints(c);
571 }
572
573 valueText = new wxPropertyTextEdit(this, panel, wxID_PROP_TEXT, "", wxPoint(-1, -1), wxSize(-1, -1), wxPROCESS_ENTER);
574 valueText->Enable(FALSE);
575
576 wxLayoutConstraints *c = new wxLayoutConstraints;
577
578 if (cancelButton)
579 c->left.RightOf (confirmButton, 2);
580 else
581 c->left.SameAs (panel, wxLeft, 2);
582
583 if (windowCloseButton)
584 c->top.Below (windowCloseButton, 2);
585 else
586 c->top.SameAs (panel, wxTop, 2);
587
588 if (editButton)
589 c->right.LeftOf (editButton, 2);
590 else
591 c->right.SameAs (panel, wxRight, 2);
592 c->height.AsIs();
593
594 valueText->SetConstraints(c);
595
596 valueList = new wxListBox(panel, wxID_PROP_VALUE_SELECT, wxPoint(-1, -1), wxSize(-1, 60));
597 valueList->Show(FALSE);
598
599 c = new wxLayoutConstraints;
600
601 c->left.SameAs (panel, wxLeft, 2);
602 c->top.Below (valueText, 2);
603 c->right.SameAs (panel, wxRight, 2);
604 c->height.Absolute(60);
605
606 valueList->SetConstraints(c);
607
608 propertyScrollingList = new wxListBox(panel, wxID_PROP_SELECT,
609 wxPoint(-1, -1), wxSize(300, 300));
610 propertyScrollingList->SetFont(boringFont);
611
612 c = new wxLayoutConstraints;
613
614 c->left.SameAs (panel, wxLeft, 2);
615
616 if (buttonFlags & wxPROP_DYNAMIC_VALUE_FIELD)
617 c->top.Below (valueText, 2);
618 else
619 c->top.Below (valueList, 2);
620
621 c->right.SameAs (panel, wxRight, 2);
622 c->bottom.SameAs (panel, wxBottom, 2);
623
624 propertyScrollingList->SetConstraints(c);
625
626 // Note: if this is called now, it causes a GPF.
627 // Why?
628 // panel->Layout();
629
630 return TRUE;
631 }
632
633 void wxPropertyListView::ShowTextControl(bool show)
634 {
635 if (valueText)
636 valueText->Show(show);
637 }
638
639 void wxPropertyListView::ShowListBoxControl(bool show)
640 {
641 if (valueList)
642 {
643 valueList->Show(show);
644 if (buttonFlags & wxPROP_DYNAMIC_VALUE_FIELD)
645 {
646 wxLayoutConstraints *constraints = propertyScrollingList->GetConstraints();
647 if (constraints)
648 {
649 if (show)
650 constraints->top.Below(valueList, 2);
651 else
652 constraints->top.Below(valueText, 2);
653 propertyWindow->Layout();
654 }
655 }
656 }
657 }
658
659 void wxPropertyListView::EnableCheck(bool show)
660 {
661 if (confirmButton)
662 confirmButton->Enable(show);
663 }
664
665 void wxPropertyListView::EnableCross(bool show)
666 {
667 if (cancelButton)
668 cancelButton->Enable(show);
669 }
670
671 bool wxPropertyListView::OnClose(void)
672 {
673 // Retrieve the value if any
674 wxCommandEvent event;
675 OnCheck(event);
676
677 delete this;
678 return TRUE;
679 }
680
681 void wxPropertyListView::OnValueListSelect(wxCommandEvent& event)
682 {
683 if (currentProperty && currentValidator)
684 {
685 if (!currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator)))
686 return;
687
688 wxPropertyListValidator *listValidator = (wxPropertyListValidator *)currentValidator;
689
690 listValidator->OnValueListSelect(currentProperty, this, propertyWindow);
691 }
692 }
693
694 void wxPropertyListView::OnOk(wxCommandEvent& event)
695 {
696 // Retrieve the value if any
697 OnCheck(event);
698
699 managedWindow->Close(TRUE);
700 }
701
702 void wxPropertyListView::OnCancel(wxCommandEvent& event)
703 {
704 // SetReturnCode(wxID_CANCEL);
705 managedWindow->Close(TRUE);
706 dialogCancelled = TRUE;
707 }
708
709 void wxPropertyListView::OnHelp(wxCommandEvent& event)
710 {
711 }
712
713 void wxPropertyListView::OnCheck(wxCommandEvent& event)
714 {
715 if (currentProperty)
716 {
717 RetrieveProperty(currentProperty);
718 }
719 }
720
721 void wxPropertyListView::OnCross(wxCommandEvent& event)
722 {
723 if (currentProperty && currentValidator)
724 {
725 if (!currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator)))
726 return;
727
728 wxPropertyListValidator *listValidator = (wxPropertyListValidator *)currentValidator;
729
730 // Revert to old value
731 listValidator->OnDisplayValue(currentProperty, this, propertyWindow);
732 }
733 }
734
735 void wxPropertyListView::OnPropertyDoubleClick(wxCommandEvent& event)
736 {
737 if (currentProperty && currentValidator)
738 {
739 if (!currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator)))
740 return;
741
742 wxPropertyListValidator *listValidator = (wxPropertyListValidator *)currentValidator;
743
744 // Revert to old value
745 listValidator->OnDoubleClick(currentProperty, this, propertyWindow);
746 }
747 }
748
749 void wxPropertyListView::OnEdit(wxCommandEvent& event)
750 {
751 if (currentProperty && currentValidator)
752 {
753 if (!currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator)))
754 return;
755
756 wxPropertyListValidator *listValidator = (wxPropertyListValidator *)currentValidator;
757
758 listValidator->OnEdit(currentProperty, this, propertyWindow);
759 }
760 }
761
762 void wxPropertyListView::OnText(wxCommandEvent& event)
763 {
764 if (event.GetEventType() == wxEVT_COMMAND_TEXT_ENTER)
765 {
766 OnCheck(event);
767 }
768 }
769
770 /*
771 * Property dialog box
772 */
773
774 IMPLEMENT_CLASS(wxPropertyListDialog, wxDialog)
775
776 BEGIN_EVENT_TABLE(wxPropertyListDialog, wxDialog)
777 EVT_BUTTON(wxID_CANCEL, wxPropertyListDialog::OnCancel)
778 END_EVENT_TABLE()
779
780 wxPropertyListDialog::wxPropertyListDialog(wxPropertyListView *v, wxWindow *parent,
781 const wxString& title, const wxPoint& pos,
782 const wxSize& size, long style, const wxString& name):
783 wxDialog(parent, -1, title, pos, size, style, name)
784 {
785 view = v;
786 view->AssociatePanel(this);
787 view->SetManagedWindow(this);
788 SetAutoLayout(TRUE);
789 }
790
791 bool wxPropertyListDialog::OnClose(void)
792 {
793 if (view)
794 {
795 SetReturnCode(wxID_CANCEL);
796 view->OnClose();
797 view = NULL;
798 return TRUE;
799 }
800 else
801 return FALSE;
802 }
803
804 void wxPropertyListDialog::OnCancel(wxCommandEvent& event)
805 {
806 SetReturnCode(wxID_CANCEL);
807 this->Close();
808 }
809
810 void wxPropertyListDialog::OnDefaultAction(wxControl *item)
811 {
812 /*
813 if (item == view->GetPropertyScrollingList())
814 view->OnDoubleClick();
815 */
816 }
817
818 // Extend event processing to search the view's event table
819 bool wxPropertyListDialog::ProcessEvent(wxEvent& event)
820 {
821 if ( !view || ! view->ProcessEvent(event) )
822 return wxEvtHandler::ProcessEvent(event);
823 else
824 return TRUE;
825 }
826
827 /*
828 * Property panel
829 */
830
831 IMPLEMENT_CLASS(wxPropertyListPanel, wxPanel)
832
833 void wxPropertyListPanel::OnDefaultAction(wxControl *item)
834 {
835 /*
836 if (item == view->GetPropertyScrollingList())
837 view->OnDoubleClick();
838 */
839 }
840
841 // Extend event processing to search the view's event table
842 bool wxPropertyListPanel::ProcessEvent(wxEvent& event)
843 {
844 if ( !view || ! view->ProcessEvent(event) )
845 return wxEvtHandler::ProcessEvent(event);
846 else
847 return TRUE;
848 }
849
850 /*
851 * Property frame
852 */
853
854 IMPLEMENT_CLASS(wxPropertyListFrame, wxFrame)
855
856 bool wxPropertyListFrame::OnClose(void)
857 {
858 if (view)
859 return view->OnClose();
860 else
861 return FALSE;
862 }
863
864 wxPanel *wxPropertyListFrame::OnCreatePanel(wxFrame *parent, wxPropertyListView *v)
865 {
866 return new wxPropertyListPanel(v, parent);
867 }
868
869 bool wxPropertyListFrame::Initialize(void)
870 {
871 propertyPanel = OnCreatePanel(this, view);
872 if (propertyPanel)
873 {
874 view->AssociatePanel(propertyPanel);
875 view->SetManagedWindow(this);
876 propertyPanel->SetAutoLayout(TRUE);
877 return TRUE;
878 }
879 else
880 return FALSE;
881 }
882
883 /*
884 * Property list specific validator
885 */
886
887 IMPLEMENT_ABSTRACT_CLASS(wxPropertyListValidator, wxPropertyValidator)
888
889 bool wxPropertyListValidator::OnSelect(bool select, wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
890 {
891 // view->GetValueText()->Show(TRUE);
892 if (select)
893 OnDisplayValue(property, view, parentWindow);
894
895 return TRUE;
896 }
897
898 bool wxPropertyListValidator::OnValueListSelect(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
899 {
900 wxString s(view->GetValueList()->GetStringSelection());
901 if (s != "")
902 {
903 view->GetValueText()->SetValue(s);
904 view->RetrieveProperty(property);
905 }
906 return TRUE;
907 }
908
909 bool wxPropertyListValidator::OnDisplayValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
910 {
911 // view->GetValueText()->Show(TRUE);
912 wxString str(property->GetValue().GetStringRepresentation());
913
914 view->GetValueText()->SetValue(str.GetData());
915 return TRUE;
916 }
917
918 // Called when TICK is pressed or focus is lost or view wants to update
919 // the property list.
920 // Does the transferance from the property editing area to the property itself
921 bool wxPropertyListValidator::OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
922 {
923 if (!view->GetValueText())
924 return FALSE;
925 return FALSE;
926 }
927
928 void wxPropertyListValidator::OnEdit(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
929 {
930 if (view->GetDetailedEditing())
931 view->EndDetailedEditing();
932 else
933 view->BeginDetailedEditing();
934 }
935
936 bool wxPropertyListValidator::OnClearControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
937 {
938 if (view->GetConfirmButton())
939 view->GetConfirmButton()->Enable(FALSE);
940 if (view->GetCancelButton())
941 view->GetCancelButton()->Enable(FALSE);
942 if (view->GetEditButton())
943 view->GetEditButton()->Enable(FALSE);
944 return TRUE;
945 }
946
947 /*
948 * Default validators
949 */
950
951 IMPLEMENT_DYNAMIC_CLASS(wxRealListValidator, wxPropertyListValidator)
952
953 ///
954 /// Real number validator
955 ///
956 bool wxRealListValidator::OnCheckValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
957 {
958 if (realMin == 0.0 && realMax == 0.0)
959 return TRUE;
960
961 if (!view->GetValueText())
962 return FALSE;
963 wxString value(view->GetValueText()->GetValue());
964
965 float val = 0.0;
966 if (!StringToFloat(WXSTRINGCAST value, &val))
967 {
968 char buf[200];
969 sprintf(buf, "Value %s is not a valid real number!", value.GetData());
970 wxMessageBox(buf, "Property value error", wxOK | wxICON_EXCLAMATION, parentWindow);
971 return FALSE;
972 }
973
974 if (val < realMin || val > realMax)
975 {
976 char buf[200];
977 sprintf(buf, "Value must be a real number between %.2f and %.2f!", realMin, realMax);
978 wxMessageBox(buf, "Property value error", wxOK | wxICON_EXCLAMATION, parentWindow);
979 return FALSE;
980 }
981 return TRUE;
982 }
983
984 // Called when TICK is pressed or focus is lost or view wants to update
985 // the property list.
986 // Does the transferance from the property editing area to the property itself
987 bool wxRealListValidator::OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
988 {
989 if (!view->GetValueText())
990 return FALSE;
991
992 if (strlen(view->GetValueText()->GetValue()) == 0)
993 return FALSE;
994
995 wxString value(view->GetValueText()->GetValue());
996 float f = (float)atof(value.GetData());
997 property->GetValue() = f;
998 return TRUE;
999 }
1000
1001 bool wxRealListValidator::OnPrepareControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1002 {
1003 if (view->GetConfirmButton())
1004 view->GetConfirmButton()->Enable(TRUE);
1005 if (view->GetCancelButton())
1006 view->GetCancelButton()->Enable(TRUE);
1007 if (view->GetEditButton())
1008 view->GetEditButton()->Enable(FALSE);
1009 if (view->GetValueText())
1010 view->GetValueText()->Enable(TRUE);
1011 return TRUE;
1012 }
1013
1014 ///
1015 /// Integer validator
1016 ///
1017 IMPLEMENT_DYNAMIC_CLASS(wxIntegerListValidator, wxPropertyListValidator)
1018
1019 bool wxIntegerListValidator::OnCheckValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1020 {
1021 if (integerMin == 0 && integerMax == 0)
1022 return TRUE;
1023
1024 if (!view->GetValueText())
1025 return FALSE;
1026 wxString value(view->GetValueText()->GetValue());
1027
1028 long val = 0;
1029 if (!StringToLong(WXSTRINGCAST value, &val))
1030 {
1031 char buf[200];
1032 sprintf(buf, "Value %s is not a valid integer!", value.GetData());
1033 wxMessageBox(buf, "Property value error", wxOK | wxICON_EXCLAMATION, parentWindow);
1034 return FALSE;
1035 }
1036 if (val < integerMin || val > integerMax)
1037 {
1038 char buf[200];
1039 sprintf(buf, "Value must be an integer between %ld and %ld!", integerMin, integerMax);
1040 wxMessageBox(buf, "Property value error", wxOK | wxICON_EXCLAMATION, parentWindow);
1041 return FALSE;
1042 }
1043 return TRUE;
1044 }
1045
1046 // Called when TICK is pressed or focus is lost or view wants to update
1047 // the property list.
1048 // Does the transferance from the property editing area to the property itself
1049 bool wxIntegerListValidator::OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1050 {
1051 if (!view->GetValueText())
1052 return FALSE;
1053
1054 if (strlen(view->GetValueText()->GetValue()) == 0)
1055 return FALSE;
1056
1057 wxString value(view->GetValueText()->GetValue());
1058 long val = (long)atoi(value.GetData());
1059 property->GetValue() = (long)val;
1060 return TRUE;
1061 }
1062
1063 bool wxIntegerListValidator::OnPrepareControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1064 {
1065 if (view->GetConfirmButton())
1066 view->GetConfirmButton()->Enable(TRUE);
1067 if (view->GetCancelButton())
1068 view->GetCancelButton()->Enable(TRUE);
1069 if (view->GetEditButton())
1070 view->GetEditButton()->Enable(FALSE);
1071 if (view->GetValueText())
1072 view->GetValueText()->Enable(TRUE);
1073 return TRUE;
1074 }
1075
1076 ///
1077 /// boolean validator
1078 ///
1079 IMPLEMENT_DYNAMIC_CLASS(wxBoolListValidator, wxPropertyListValidator)
1080
1081 bool wxBoolListValidator::OnCheckValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1082 {
1083 if (!view->GetValueText())
1084 return FALSE;
1085 wxString value(view->GetValueText()->GetValue());
1086 if (value != "True" && value != "False")
1087 {
1088 wxMessageBox("Value must be True or False!", "Property value error", wxOK | wxICON_EXCLAMATION, parentWindow);
1089 return FALSE;
1090 }
1091 return TRUE;
1092 }
1093
1094 // Called when TICK is pressed or focus is lost or view wants to update
1095 // the property list.
1096 // Does the transferance from the property editing area to the property itself
1097 bool wxBoolListValidator::OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1098 {
1099 if (!view->GetValueText())
1100 return FALSE;
1101
1102 if (strlen(view->GetValueText()->GetValue()) == 0)
1103 return FALSE;
1104
1105 wxString value(view->GetValueText()->GetValue());
1106 bool boolValue = FALSE;
1107 if (value == "True")
1108 boolValue = TRUE;
1109 else
1110 boolValue = FALSE;
1111 property->GetValue() = (bool)boolValue;
1112 return TRUE;
1113 }
1114
1115 bool wxBoolListValidator::OnDisplayValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1116 {
1117 if (!view->GetValueText())
1118 return FALSE;
1119 wxString str(property->GetValue().GetStringRepresentation());
1120
1121 view->GetValueText()->SetValue(str.GetData());
1122 view->GetValueList()->SetStringSelection(str.GetData());
1123 return TRUE;
1124 }
1125
1126 bool wxBoolListValidator::OnPrepareControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1127 {
1128 if (view->GetConfirmButton())
1129 view->GetConfirmButton()->Enable(FALSE);
1130 if (view->GetCancelButton())
1131 view->GetCancelButton()->Enable(FALSE);
1132 if (view->GetEditButton())
1133 view->GetEditButton()->Enable(TRUE);
1134 if (view->GetValueText())
1135 view->GetValueText()->Enable(FALSE);
1136 return TRUE;
1137 }
1138
1139 bool wxBoolListValidator::OnPrepareDetailControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1140 {
1141 if (view->GetValueList())
1142 {
1143 view->ShowListBoxControl(TRUE);
1144 view->GetValueList()->Enable(TRUE);
1145
1146 view->GetValueList()->Append("True");
1147 view->GetValueList()->Append("False");
1148 char *currentString = copystring(view->GetValueText()->GetValue());
1149 view->GetValueList()->SetStringSelection(currentString);
1150 delete[] currentString;
1151 }
1152 return TRUE;
1153 }
1154
1155 bool wxBoolListValidator::OnClearDetailControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1156 {
1157 if (view->GetValueList())
1158 {
1159 view->GetValueList()->Clear();
1160 view->ShowListBoxControl(FALSE);
1161 view->GetValueList()->Enable(FALSE);
1162 }
1163 return TRUE;
1164 }
1165
1166 // Called when the property is double clicked. Extra functionality can be provided,
1167 // cycling through possible values.
1168 bool wxBoolListValidator::OnDoubleClick(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1169 {
1170 if (!view->GetValueText())
1171 return FALSE;
1172 if (property->GetValue().BoolValue())
1173 property->GetValue() = (bool)FALSE;
1174 else
1175 property->GetValue() = (bool)TRUE;
1176 view->DisplayProperty(property);
1177 view->UpdatePropertyDisplayInList(property);
1178 view->OnPropertyChanged(property);
1179 return TRUE;
1180 }
1181
1182 ///
1183 /// String validator
1184 ///
1185 IMPLEMENT_DYNAMIC_CLASS(wxStringListValidator, wxPropertyListValidator)
1186
1187 wxStringListValidator::wxStringListValidator(wxStringList *list, long flags):
1188 wxPropertyListValidator(flags)
1189 {
1190 strings = list;
1191 // If no constraint, we just allow the string to be edited.
1192 if (!strings && ((validatorFlags & wxPROP_ALLOW_TEXT_EDITING) == 0))
1193 validatorFlags |= wxPROP_ALLOW_TEXT_EDITING;
1194 }
1195
1196 bool wxStringListValidator::OnCheckValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1197 {
1198 if (!strings)
1199 return TRUE;
1200
1201 if (!view->GetValueText())
1202 return FALSE;
1203 wxString value(view->GetValueText()->GetValue());
1204
1205 if (!strings->Member(value.GetData()))
1206 {
1207 wxString s("Value ");
1208 s += value.GetData();
1209 s += " is not valid.";
1210 wxMessageBox(s.GetData(), "Property value error", wxOK | wxICON_EXCLAMATION, parentWindow);
1211 return FALSE;
1212 }
1213 return TRUE;
1214 }
1215
1216 // Called when TICK is pressed or focus is lost or view wants to update
1217 // the property list.
1218 // Does the transferance from the property editing area to the property itself
1219 bool wxStringListValidator::OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1220 {
1221 if (!view->GetValueText())
1222 return FALSE;
1223 wxString value(view->GetValueText()->GetValue());
1224 property->GetValue() = value ;
1225 return TRUE;
1226 }
1227
1228 // Called when TICK is pressed or focus is lost or view wants to update
1229 // the property list.
1230 // Does the transferance from the property editing area to the property itself
1231 bool wxStringListValidator::OnDisplayValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1232 {
1233 if (!view->GetValueText())
1234 return FALSE;
1235 wxString str(property->GetValue().GetStringRepresentation());
1236 view->GetValueText()->SetValue(str.GetData());
1237 if (strings)
1238 {
1239 view->GetValueList()->SetStringSelection(str.GetData());
1240 }
1241 return TRUE;
1242 }
1243
1244 bool wxStringListValidator::OnPrepareControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1245 {
1246 // Unconstrained
1247 if (!strings)
1248 {
1249 if (view->GetEditButton())
1250 view->GetEditButton()->Enable(FALSE);
1251 if (view->GetConfirmButton())
1252 view->GetConfirmButton()->Enable(TRUE);
1253 if (view->GetCancelButton())
1254 view->GetCancelButton()->Enable(TRUE);
1255 if (view->GetValueText())
1256 view->GetValueText()->Enable(TRUE);
1257 return TRUE;
1258 }
1259
1260 // Constrained
1261 if (view->GetValueText())
1262 view->GetValueText()->Enable(FALSE);
1263
1264 if (view->GetEditButton())
1265 view->GetEditButton()->Enable(TRUE);
1266
1267 if (view->GetConfirmButton())
1268 view->GetConfirmButton()->Enable(FALSE);
1269 if (view->GetCancelButton())
1270 view->GetCancelButton()->Enable(FALSE);
1271 return TRUE;
1272 }
1273
1274 bool wxStringListValidator::OnPrepareDetailControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1275 {
1276 if (view->GetValueList())
1277 {
1278 view->ShowListBoxControl(TRUE);
1279 view->GetValueList()->Enable(TRUE);
1280 wxNode *node = strings->First();
1281 while (node)
1282 {
1283 char *s = (char *)node->Data();
1284 view->GetValueList()->Append(s);
1285 node = node->Next();
1286 }
1287 char *currentString = property->GetValue().StringValue();
1288 view->GetValueList()->SetStringSelection(currentString);
1289 }
1290 return TRUE;
1291 }
1292
1293 bool wxStringListValidator::OnClearDetailControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1294 {
1295 if (!strings)
1296 {
1297 return TRUE;
1298 }
1299
1300 if (view->GetValueList())
1301 {
1302 view->GetValueList()->Clear();
1303 view->ShowListBoxControl(FALSE);
1304 view->GetValueList()->Enable(FALSE);
1305 }
1306 return TRUE;
1307 }
1308
1309 // Called when the property is double clicked. Extra functionality can be provided,
1310 // cycling through possible values.
1311 bool wxStringListValidator::OnDoubleClick(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1312 {
1313 if (!view->GetValueText())
1314 return FALSE;
1315 if (!strings)
1316 return FALSE;
1317
1318 wxNode *node = strings->First();
1319 char *currentString = property->GetValue().StringValue();
1320 while (node)
1321 {
1322 char *s = (char *)node->Data();
1323 if (strcmp(s, currentString) == 0)
1324 {
1325 char *nextString = NULL;
1326 if (node->Next())
1327 nextString = (char *)node->Next()->Data();
1328 else
1329 nextString = (char *)strings->First()->Data();
1330 property->GetValue() = wxString(nextString);
1331 view->DisplayProperty(property);
1332 view->UpdatePropertyDisplayInList(property);
1333 view->OnPropertyChanged(property);
1334 return TRUE;
1335 }
1336 else node = node->Next();
1337 }
1338 return TRUE;
1339 }
1340
1341 ///
1342 /// Filename validator
1343 ///
1344 IMPLEMENT_DYNAMIC_CLASS(wxFilenameListValidator, wxPropertyListValidator)
1345
1346 wxFilenameListValidator::wxFilenameListValidator(wxString message , wxString wildcard, long flags):
1347 wxPropertyListValidator(flags), filenameWildCard(wildcard), filenameMessage(message)
1348 {
1349 }
1350
1351 wxFilenameListValidator::~wxFilenameListValidator(void)
1352 {
1353 }
1354
1355 bool wxFilenameListValidator::OnCheckValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1356 {
1357 return TRUE;
1358 }
1359
1360 // Called when TICK is pressed or focus is lost or view wants to update
1361 // the property list.
1362 // Does the transferance from the property editing area to the property itself
1363 bool wxFilenameListValidator::OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1364 {
1365 if (!view->GetValueText())
1366 return FALSE;
1367 wxString value(view->GetValueText()->GetValue());
1368 property->GetValue() = value ;
1369 return TRUE;
1370 }
1371
1372 // Called when TICK is pressed or focus is lost or view wants to update
1373 // the property list.
1374 // Does the transferance from the property editing area to the property itself
1375 bool wxFilenameListValidator::OnDisplayValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1376 {
1377 if (!view->GetValueText())
1378 return FALSE;
1379 wxString str(property->GetValue().GetStringRepresentation());
1380 view->GetValueText()->SetValue(str);
1381 return TRUE;
1382 }
1383
1384 // Called when the property is double clicked. Extra functionality can be provided,
1385 // cycling through possible values.
1386 bool wxFilenameListValidator::OnDoubleClick(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1387 {
1388 if (!view->GetValueText())
1389 return FALSE;
1390 OnEdit(property, view, parentWindow);
1391 return TRUE;
1392 }
1393
1394 bool wxFilenameListValidator::OnPrepareControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1395 {
1396 if (view->GetConfirmButton())
1397 view->GetConfirmButton()->Enable(TRUE);
1398 if (view->GetCancelButton())
1399 view->GetCancelButton()->Enable(TRUE);
1400 if (view->GetEditButton())
1401 view->GetEditButton()->Enable(TRUE);
1402 if (view->GetValueText())
1403 view->GetValueText()->Enable((GetFlags() & wxPROP_ALLOW_TEXT_EDITING) == wxPROP_ALLOW_TEXT_EDITING);
1404 return TRUE;
1405 }
1406
1407 void wxFilenameListValidator::OnEdit(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1408 {
1409 if (!view->GetValueText())
1410 return;
1411
1412 char *s = wxFileSelector(
1413 filenameMessage.GetData(),
1414 wxPathOnly(property->GetValue().StringValue()),
1415 wxFileNameFromPath(property->GetValue().StringValue()),
1416 NULL,
1417 filenameWildCard.GetData(),
1418 0,
1419 parentWindow);
1420 if (s)
1421 {
1422 property->GetValue() = wxString(s);
1423 view->DisplayProperty(property);
1424 view->UpdatePropertyDisplayInList(property);
1425 view->OnPropertyChanged(property);
1426 }
1427 }
1428
1429 ///
1430 /// Colour validator
1431 ///
1432 IMPLEMENT_DYNAMIC_CLASS(wxColourListValidator, wxPropertyListValidator)
1433
1434 wxColourListValidator::wxColourListValidator(long flags):
1435 wxPropertyListValidator(flags)
1436 {
1437 }
1438
1439 wxColourListValidator::~wxColourListValidator(void)
1440 {
1441 }
1442
1443 bool wxColourListValidator::OnCheckValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1444 {
1445 return TRUE;
1446 }
1447
1448 // Called when TICK is pressed or focus is lost or view wants to update
1449 // the property list.
1450 // Does the transferance from the property editing area to the property itself
1451 bool wxColourListValidator::OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1452 {
1453 if (!view->GetValueText())
1454 return FALSE;
1455 wxString value(view->GetValueText()->GetValue());
1456
1457 property->GetValue() = value ;
1458 return TRUE;
1459 }
1460
1461 // Called when TICK is pressed or focus is lost or view wants to update
1462 // the property list.
1463 // Does the transferance from the property editing area to the property itself
1464 bool wxColourListValidator::OnDisplayValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1465 {
1466 if (!view->GetValueText())
1467 return FALSE;
1468 wxString str(property->GetValue().GetStringRepresentation());
1469 view->GetValueText()->SetValue(str);
1470 return TRUE;
1471 }
1472
1473 // Called when the property is double clicked. Extra functionality can be provided,
1474 // cycling through possible values.
1475 bool wxColourListValidator::OnDoubleClick(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1476 {
1477 if (!view->GetValueText())
1478 return FALSE;
1479 OnEdit(property, view, parentWindow);
1480 return TRUE;
1481 }
1482
1483 bool wxColourListValidator::OnPrepareControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1484 {
1485 if (view->GetConfirmButton())
1486 view->GetConfirmButton()->Enable(TRUE);
1487 if (view->GetCancelButton())
1488 view->GetCancelButton()->Enable(TRUE);
1489 if (view->GetEditButton())
1490 view->GetEditButton()->Enable(TRUE);
1491 if (view->GetValueText())
1492 view->GetValueText()->Enable((GetFlags() & wxPROP_ALLOW_TEXT_EDITING) == wxPROP_ALLOW_TEXT_EDITING);
1493 return TRUE;
1494 }
1495
1496 void wxColourListValidator::OnEdit(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1497 {
1498 if (!view->GetValueText())
1499 return;
1500
1501 char *s = property->GetValue().StringValue();
1502 int r = 0;
1503 int g = 0;
1504 int b = 0;
1505 if (s)
1506 {
1507 r = wxHexToDec(s);
1508 g = wxHexToDec(s+2);
1509 b = wxHexToDec(s+4);
1510 }
1511
1512 wxColour col(r,g,b);
1513
1514 wxColourData data;
1515 data.SetChooseFull(TRUE);
1516 data.SetColour(col);
1517
1518 for (int i = 0; i < 16; i++)
1519 {
1520 wxColour colour(i*16, i*16, i*16);
1521 data.SetCustomColour(i, colour);
1522 }
1523
1524 wxColourDialog dialog(parentWindow, &data);
1525 if (dialog.ShowModal() != wxID_CANCEL)
1526 {
1527 wxColourData retData = dialog.GetColourData();
1528 col = retData.GetColour();
1529
1530 char buf[7];
1531 wxDecToHex(col.Red(), buf);
1532 wxDecToHex(col.Green(), buf+2);
1533 wxDecToHex(col.Blue(), buf+4);
1534
1535 property->GetValue() = wxString(buf);
1536 view->DisplayProperty(property);
1537 view->UpdatePropertyDisplayInList(property);
1538 view->OnPropertyChanged(property);
1539 }
1540 }
1541
1542 ///
1543 /// List of strings validator. For this we need more user interface than
1544 /// we get with a property list; so create a new dialog for editing the list.
1545 ///
1546 IMPLEMENT_DYNAMIC_CLASS(wxListOfStringsListValidator, wxPropertyListValidator)
1547
1548 wxListOfStringsListValidator::wxListOfStringsListValidator(long flags):
1549 wxPropertyListValidator(flags)
1550 {
1551 }
1552
1553 bool wxListOfStringsListValidator::OnCheckValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1554 {
1555 // No constraints for an arbitrary, user-editable list of strings.
1556 return TRUE;
1557 }
1558
1559 // Called when TICK is pressed or focus is lost or view wants to update
1560 // the property list.
1561 // Does the transferance from the property editing area to the property itself.
1562 // In this case, the user cannot directly edit the string list.
1563 bool wxListOfStringsListValidator::OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1564 {
1565 return TRUE;
1566 }
1567
1568 bool wxListOfStringsListValidator::OnDisplayValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1569 {
1570 if (!view->GetValueText())
1571 return FALSE;
1572 wxString str(property->GetValue().GetStringRepresentation());
1573 view->GetValueText()->SetValue(str.GetData());
1574 return TRUE;
1575 }
1576
1577 bool wxListOfStringsListValidator::OnPrepareControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1578 {
1579 if (view->GetEditButton())
1580 view->GetEditButton()->Enable(TRUE);
1581 if (view->GetValueText())
1582 view->GetValueText()->Enable(FALSE);
1583
1584 if (view->GetConfirmButton())
1585 view->GetConfirmButton()->Enable(FALSE);
1586 if (view->GetCancelButton())
1587 view->GetCancelButton()->Enable(FALSE);
1588 return TRUE;
1589 }
1590
1591 // Called when the property is double clicked. Extra functionality can be provided,
1592 // cycling through possible values.
1593 bool wxListOfStringsListValidator::OnDoubleClick(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1594 {
1595 OnEdit(property, view, parentWindow);
1596 return TRUE;
1597 }
1598
1599 void wxListOfStringsListValidator::OnEdit(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1600 {
1601 // Convert property value to a list of strings for editing
1602 wxStringList *stringList = new wxStringList;
1603
1604 wxPropertyValue *expr = property->GetValue().GetFirst();
1605 while (expr)
1606 {
1607 char *s = expr->StringValue();
1608 if (s)
1609 stringList->Add(s);
1610 expr = expr->GetNext();
1611 }
1612
1613 wxString title("Editing ");
1614 title += property->GetName();
1615
1616 if (EditStringList(parentWindow, stringList, title.GetData()))
1617 {
1618 wxPropertyValue& oldValue = property->GetValue();
1619 oldValue.ClearList();
1620 wxNode *node = stringList->First();
1621 while (node)
1622 {
1623 char *s = (char *)node->Data();
1624 oldValue.Append(new wxPropertyValue(s));
1625
1626 node = node->Next();
1627 }
1628
1629 view->DisplayProperty(property);
1630 view->UpdatePropertyDisplayInList(property);
1631 view->OnPropertyChanged(property);
1632 }
1633 delete stringList;
1634 }
1635
1636 class wxPropertyStringListEditorDialog: public wxDialog
1637 {
1638 public:
1639 wxStringList *stringList;
1640 wxListBox *listBox;
1641 wxTextCtrl *stringText;
1642 static bool dialogCancelled;
1643 int currentSelection;
1644 wxPropertyStringListEditorDialog(wxWindow *parent, const wxString& title,
1645 const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
1646 long windowStyle = wxDEFAULT_DIALOG_STYLE, const wxString& name = "stringEditorDialogBox"):
1647 wxDialog(parent, -1, title, pos, size, windowStyle, name)
1648 {
1649 stringList = NULL;
1650 stringText = NULL;
1651 listBox = NULL;
1652 dialogCancelled = FALSE;
1653 currentSelection = -1;
1654 }
1655 ~wxPropertyStringListEditorDialog(void) {}
1656 bool OnClose(void);
1657 void SaveCurrentSelection(void);
1658 void ShowCurrentSelection(void);
1659
1660 void OnOK(wxCommandEvent& event);
1661 void OnCancel(wxCommandEvent& event);
1662 void OnAdd(wxCommandEvent& event);
1663 void OnDelete(wxCommandEvent& event);
1664 void OnStrings(wxCommandEvent& event);
1665 void OnText(wxCommandEvent& event);
1666
1667 DECLARE_EVENT_TABLE()
1668 };
1669
1670 #define wxID_PROP_SL_ADD 3000
1671 #define wxID_PROP_SL_DELETE 3001
1672 #define wxID_PROP_SL_STRINGS 3002
1673 #define wxID_PROP_SL_TEXT 3003
1674
1675 BEGIN_EVENT_TABLE(wxPropertyStringListEditorDialog, wxDialog)
1676 EVT_BUTTON(wxID_OK, wxPropertyStringListEditorDialog::OnOK)
1677 EVT_BUTTON(wxID_CANCEL, wxPropertyStringListEditorDialog::OnCancel)
1678 EVT_BUTTON(wxID_PROP_SL_ADD, wxPropertyStringListEditorDialog::OnAdd)
1679 EVT_BUTTON(wxID_PROP_SL_DELETE, wxPropertyStringListEditorDialog::OnDelete)
1680 EVT_LISTBOX(wxID_PROP_SL_STRINGS, wxPropertyStringListEditorDialog::OnStrings)
1681 EVT_TEXT(wxID_PROP_SL_TEXT, wxPropertyStringListEditorDialog::OnText)
1682 END_EVENT_TABLE()
1683
1684 class wxPropertyStringListEditorText: public wxTextCtrl
1685 {
1686 public:
1687 wxPropertyStringListEditorText(wxWindow *parent, wxWindowID id, const wxString& val,
1688 const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
1689 long windowStyle = 0, const wxString& name = "text"):
1690 wxTextCtrl(parent, id, val, pos, size, windowStyle, wxDefaultValidator, name)
1691 {
1692 }
1693 void OnKillFocus(void)
1694 {
1695 wxPropertyStringListEditorDialog *dialog = (wxPropertyStringListEditorDialog *)GetParent();
1696 dialog->SaveCurrentSelection();
1697 }
1698 };
1699
1700 bool wxPropertyStringListEditorDialog::dialogCancelled = FALSE;
1701
1702 // Edit the string list.
1703 bool wxListOfStringsListValidator::EditStringList(wxWindow *parent, wxStringList *stringList, const char *title)
1704 {
1705 wxBeginBusyCursor();
1706 wxPropertyStringListEditorDialog *dialog = new wxPropertyStringListEditorDialog(parent,
1707 title, wxPoint(10, 10), wxSize(400, 400), wxDEFAULT_DIALOG_STYLE|wxDIALOG_MODAL);
1708
1709 dialog->stringList = stringList;
1710
1711 wxButton *okButton = new wxButton(dialog, wxID_OK, "OK", wxPoint(5, 5));
1712 wxButton *cancelButton = new wxButton(dialog, wxID_CANCEL, "Cancel", wxPoint(40, 5));
1713
1714 // wxButton *helpButton = new wxButton(dialog, (wxFunction)StringListEditorHelpProc, "Help");
1715 // helpButton->SetClientData((char *)this);
1716
1717 dialog->listBox = new wxListBox(dialog, wxID_PROP_SL_STRINGS,
1718 wxPoint(5, 30), wxSize(300, 200), 0, NULL, wxLB_SINGLE);
1719
1720 dialog->stringText = new wxPropertyStringListEditorText(dialog,
1721 wxID_PROP_SL_TEXT, "", wxPoint(5, 240),
1722 wxSize(300, -1), wxPROCESS_ENTER);
1723 dialog->stringText->Enable(FALSE);
1724
1725 wxButton *addButton = new wxButton(dialog, wxID_PROP_SL_ADD, "Add", wxPoint(5, 280));
1726 wxButton *deleteButton = new wxButton(dialog, wxID_PROP_SL_DELETE, "Delete", wxPoint(40, 280));
1727
1728 wxNode *node = stringList->First();
1729 while (node)
1730 {
1731 char *str = (char *)node->Data();
1732 // Save node as client data for each listbox item
1733 dialog->listBox->Append(str, (char *)node);
1734 node = node->Next();
1735 }
1736
1737 dialog->SetClientSize(310, 305);
1738
1739 dialog->Centre(wxBOTH);
1740 wxEndBusyCursor();
1741 if (dialog->ShowModal() == wxID_CANCEL)
1742 return FALSE;
1743 else
1744 return TRUE;
1745 }
1746
1747 /*
1748 * String list editor callbacks
1749 *
1750 */
1751
1752 void wxPropertyStringListEditorDialog::OnStrings(wxCommandEvent& event)
1753 {
1754 int sel = listBox->GetSelection();
1755 if (sel > -1)
1756 {
1757 currentSelection = sel;
1758
1759 ShowCurrentSelection();
1760 }
1761 }
1762
1763 void wxPropertyStringListEditorDialog::OnDelete(wxCommandEvent& event)
1764 {
1765 int sel = listBox->GetSelection();
1766 if (sel == -1)
1767 return;
1768
1769 wxNode *node = (wxNode *)listBox->wxListBox::GetClientData(sel);
1770 if (!node)
1771 return;
1772
1773 listBox->Delete(sel);
1774 delete[] (char *)node->Data();
1775 delete node;
1776 currentSelection = -1;
1777 stringText->SetValue("");
1778 }
1779
1780 void wxPropertyStringListEditorDialog::OnAdd(wxCommandEvent& event)
1781 {
1782 SaveCurrentSelection();
1783
1784 char *initialText = "";
1785 wxNode *node = stringList->Add(initialText);
1786 listBox->Append(initialText, (char *)node);
1787 currentSelection = stringList->Number() - 1;
1788 listBox->SetSelection(currentSelection);
1789 ShowCurrentSelection();
1790 stringText->SetFocus();
1791 }
1792
1793 void wxPropertyStringListEditorDialog::OnOK(wxCommandEvent& event)
1794 {
1795 SaveCurrentSelection();
1796 EndModal(wxID_OK);
1797 Close(TRUE);
1798 }
1799
1800 void wxPropertyStringListEditorDialog::OnCancel(wxCommandEvent& event)
1801 {
1802 dialogCancelled = TRUE;
1803 EndModal(wxID_CANCEL);
1804 Close(TRUE);
1805 }
1806
1807 void wxPropertyStringListEditorDialog::OnText(wxCommandEvent& event)
1808 {
1809 if (event.GetEventType() == wxEVENT_TYPE_TEXT_ENTER_COMMAND)
1810 {
1811 SaveCurrentSelection();
1812 }
1813 }
1814
1815 bool wxPropertyStringListEditorDialog::OnClose(void)
1816 {
1817 SaveCurrentSelection();
1818 return TRUE;
1819 }
1820
1821 void wxPropertyStringListEditorDialog::SaveCurrentSelection(void)
1822 {
1823 if (currentSelection == -1)
1824 return;
1825
1826 wxNode *node = (wxNode *)listBox->wxListBox::GetClientData(currentSelection);
1827 if (!node)
1828 return;
1829
1830 wxString txt(stringText->GetValue());
1831 if (node->Data())
1832 delete[] (char *)node->Data();
1833 node->SetData((wxObject *)copystring(txt));
1834
1835 listBox->SetString(currentSelection, (char *)node->Data());
1836 }
1837
1838 void wxPropertyStringListEditorDialog::ShowCurrentSelection(void)
1839 {
1840 if (currentSelection == -1)
1841 {
1842 stringText->SetValue("");
1843 return;
1844 }
1845 wxNode *node = (wxNode *)listBox->wxListBox::GetClientData(currentSelection);
1846 char *txt = (char *)node->Data();
1847 stringText->SetValue(txt);
1848 stringText->Enable(TRUE);
1849 }