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