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