]> git.saurik.com Git - wxWidgets.git/blame - utils/wxprop/src/proplist.cpp
defs.h corrected (syntax error in wxDELETEA). More unnecessary files removed.
[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)
83 EVT_TEXT(wxID_PROP_VALUE_SELECT, wxPropertyListView::OnValueListSelect)
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
JS
427#ifdef __WXMSW__
428 wxFont *boringFont = wxTheFontList->FindOrCreateFont(guiFont.GetPointSize(), wxDEFAULT, wxNORMAL, wxNORMAL, FALSE, "Courier New");
429#else
457814b5 430 wxFont *boringFont = wxTheFontList->FindOrCreateFont(guiFont.GetPointSize(), wxMODERN, 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)
664 constraints->top.Below(valueList, 2);
665 else
666 constraints->top.Below(valueText, 2);
667 propertyWindow->Layout();
668 }
669 }
670 }
671}
672
673void wxPropertyListView::EnableCheck(bool show)
674{
675 if (confirmButton)
676 confirmButton->Enable(show);
677}
678
679void wxPropertyListView::EnableCross(bool show)
680{
681 if (cancelButton)
682 cancelButton->Enable(show);
683}
684
685bool wxPropertyListView::OnClose(void)
686{
687 // Retrieve the value if any
688 wxCommandEvent event;
689 OnCheck(event);
690
691 delete this;
692 return TRUE;
693}
694
8656024d 695void wxPropertyListView::OnValueListSelect(wxCommandEvent& WXUNUSED(event))
457814b5
JS
696{
697 if (currentProperty && currentValidator)
698 {
699 if (!currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator)))
700 return;
701
702 wxPropertyListValidator *listValidator = (wxPropertyListValidator *)currentValidator;
703
704 listValidator->OnValueListSelect(currentProperty, this, propertyWindow);
705 }
706}
707
708void wxPropertyListView::OnOk(wxCommandEvent& event)
709{
710 // Retrieve the value if any
711 OnCheck(event);
712
713 managedWindow->Close(TRUE);
714}
715
8656024d 716void wxPropertyListView::OnCancel(wxCommandEvent& WXUNUSED(event))
457814b5
JS
717{
718// SetReturnCode(wxID_CANCEL);
719 managedWindow->Close(TRUE);
720 dialogCancelled = TRUE;
721}
722
8656024d 723void wxPropertyListView::OnHelp(wxCommandEvent& WXUNUSED(event))
457814b5
JS
724{
725}
726
8656024d 727void wxPropertyListView::OnCheck(wxCommandEvent& WXUNUSED(event))
457814b5
JS
728{
729 if (currentProperty)
730 {
731 RetrieveProperty(currentProperty);
732 }
733}
734
8656024d 735void wxPropertyListView::OnCross(wxCommandEvent& WXUNUSED(event))
457814b5
JS
736{
737 if (currentProperty && currentValidator)
738 {
739 if (!currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator)))
740 return;
741
742 wxPropertyListValidator *listValidator = (wxPropertyListValidator *)currentValidator;
743
744 // Revert to old value
745 listValidator->OnDisplayValue(currentProperty, this, propertyWindow);
746 }
747}
748
8656024d 749void wxPropertyListView::OnPropertyDoubleClick(wxCommandEvent& WXUNUSED(event))
457814b5
JS
750{
751 if (currentProperty && currentValidator)
752 {
753 if (!currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator)))
754 return;
755
756 wxPropertyListValidator *listValidator = (wxPropertyListValidator *)currentValidator;
757
758 // Revert to old value
759 listValidator->OnDoubleClick(currentProperty, this, propertyWindow);
760 }
761}
762
8656024d 763void wxPropertyListView::OnEdit(wxCommandEvent& WXUNUSED(event))
457814b5
JS
764{
765 if (currentProperty && currentValidator)
766 {
767 if (!currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator)))
768 return;
769
770 wxPropertyListValidator *listValidator = (wxPropertyListValidator *)currentValidator;
771
772 listValidator->OnEdit(currentProperty, this, propertyWindow);
773 }
774}
775
776void wxPropertyListView::OnText(wxCommandEvent& event)
777{
778 if (event.GetEventType() == wxEVT_COMMAND_TEXT_ENTER)
779 {
780 OnCheck(event);
781 }
782}
783
784/*
785 * Property dialog box
786 */
787
788IMPLEMENT_CLASS(wxPropertyListDialog, wxDialog)
789
790BEGIN_EVENT_TABLE(wxPropertyListDialog, wxDialog)
791 EVT_BUTTON(wxID_CANCEL, wxPropertyListDialog::OnCancel)
792END_EVENT_TABLE()
793
794wxPropertyListDialog::wxPropertyListDialog(wxPropertyListView *v, wxWindow *parent,
795 const wxString& title, const wxPoint& pos,
796 const wxSize& size, long style, const wxString& name):
797 wxDialog(parent, -1, title, pos, size, style, name)
798{
799 view = v;
8656024d 800 view->AssociatePanel( ((wxPanel*)this) );
457814b5
JS
801 view->SetManagedWindow(this);
802 SetAutoLayout(TRUE);
803}
804
805bool wxPropertyListDialog::OnClose(void)
806{
807 if (view)
808 {
809 SetReturnCode(wxID_CANCEL);
810 view->OnClose();
811 view = NULL;
812 return TRUE;
813 }
814 else
815 return FALSE;
816}
817
8656024d 818void wxPropertyListDialog::OnCancel(wxCommandEvent& WXUNUSED(event))
457814b5
JS
819{
820 SetReturnCode(wxID_CANCEL);
821 this->Close();
822}
823
824void wxPropertyListDialog::OnDefaultAction(wxControl *item)
825{
826/*
827 if (item == view->GetPropertyScrollingList())
828 view->OnDoubleClick();
829*/
830}
831
832// Extend event processing to search the view's event table
833bool wxPropertyListDialog::ProcessEvent(wxEvent& event)
834{
835 if ( !view || ! view->ProcessEvent(event) )
836 return wxEvtHandler::ProcessEvent(event);
837 else
838 return TRUE;
839}
840
841/*
842 * Property panel
843 */
844
845IMPLEMENT_CLASS(wxPropertyListPanel, wxPanel)
846
bbcdf8bc
JS
847BEGIN_EVENT_TABLE(wxPropertyListPanel, wxPanel)
848 EVT_SIZE(wxPropertyListPanel::OnSize)
849END_EVENT_TABLE()
850
457814b5
JS
851void wxPropertyListPanel::OnDefaultAction(wxControl *item)
852{
853/*
854 if (item == view->GetPropertyScrollingList())
855 view->OnDoubleClick();
856*/
857}
858
859// Extend event processing to search the view's event table
860bool wxPropertyListPanel::ProcessEvent(wxEvent& event)
861{
862 if ( !view || ! view->ProcessEvent(event) )
863 return wxEvtHandler::ProcessEvent(event);
864 else
865 return TRUE;
866}
867
8656024d 868void wxPropertyListPanel::OnSize(wxSizeEvent& WXUNUSED(event))
bbcdf8bc
JS
869{
870 Layout();
871}
872
457814b5
JS
873/*
874 * Property frame
875 */
876
877IMPLEMENT_CLASS(wxPropertyListFrame, wxFrame)
878
879bool wxPropertyListFrame::OnClose(void)
880{
881 if (view)
bbcdf8bc
JS
882 {
883 if (propertyPanel)
884 propertyPanel->SetView(NULL);
885 view->OnClose();
886 view = NULL;
887 return TRUE;
888 }
457814b5
JS
889 else
890 return FALSE;
891}
892
bbcdf8bc 893wxPropertyListPanel *wxPropertyListFrame::OnCreatePanel(wxFrame *parent, wxPropertyListView *v)
457814b5
JS
894{
895 return new wxPropertyListPanel(v, parent);
896}
897
898bool wxPropertyListFrame::Initialize(void)
899{
900 propertyPanel = OnCreatePanel(this, view);
901 if (propertyPanel)
902 {
903 view->AssociatePanel(propertyPanel);
904 view->SetManagedWindow(this);
905 propertyPanel->SetAutoLayout(TRUE);
906 return TRUE;
907 }
908 else
909 return FALSE;
910}
911
912 /*
913 * Property list specific validator
914 */
915
916IMPLEMENT_ABSTRACT_CLASS(wxPropertyListValidator, wxPropertyValidator)
917
918bool wxPropertyListValidator::OnSelect(bool select, wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
919{
920// view->GetValueText()->Show(TRUE);
921 if (select)
922 OnDisplayValue(property, view, parentWindow);
923
924 return TRUE;
925}
926
927bool wxPropertyListValidator::OnValueListSelect(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
928{
929 wxString s(view->GetValueList()->GetStringSelection());
930 if (s != "")
931 {
932 view->GetValueText()->SetValue(s);
933 view->RetrieveProperty(property);
934 }
935 return TRUE;
936}
937
938bool wxPropertyListValidator::OnDisplayValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
939{
940// view->GetValueText()->Show(TRUE);
941 wxString str(property->GetValue().GetStringRepresentation());
942
943 view->GetValueText()->SetValue(str.GetData());
944 return TRUE;
945}
946
947// Called when TICK is pressed or focus is lost or view wants to update
948// the property list.
949// Does the transferance from the property editing area to the property itself
950bool wxPropertyListValidator::OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
951{
952 if (!view->GetValueText())
953 return FALSE;
954 return FALSE;
955}
956
957void wxPropertyListValidator::OnEdit(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
958{
959 if (view->GetDetailedEditing())
960 view->EndDetailedEditing();
961 else
962 view->BeginDetailedEditing();
963}
964
965bool wxPropertyListValidator::OnClearControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
966{
967 if (view->GetConfirmButton())
968 view->GetConfirmButton()->Enable(FALSE);
969 if (view->GetCancelButton())
970 view->GetCancelButton()->Enable(FALSE);
971 if (view->GetEditButton())
972 view->GetEditButton()->Enable(FALSE);
973 return TRUE;
974}
975
976/*
977 * Default validators
978 */
979
980IMPLEMENT_DYNAMIC_CLASS(wxRealListValidator, wxPropertyListValidator)
981
982///
983/// Real number validator
984///
985bool wxRealListValidator::OnCheckValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
986{
987 if (realMin == 0.0 && realMax == 0.0)
988 return TRUE;
989
990 if (!view->GetValueText())
991 return FALSE;
992 wxString value(view->GetValueText()->GetValue());
993
994 float val = 0.0;
995 if (!StringToFloat(WXSTRINGCAST value, &val))
996 {
997 char buf[200];
998 sprintf(buf, "Value %s is not a valid real number!", value.GetData());
999 wxMessageBox(buf, "Property value error", wxOK | wxICON_EXCLAMATION, parentWindow);
1000 return FALSE;
1001 }
1002
1003 if (val < realMin || val > realMax)
1004 {
1005 char buf[200];
1006 sprintf(buf, "Value must be a real number between %.2f and %.2f!", realMin, realMax);
1007 wxMessageBox(buf, "Property value error", wxOK | wxICON_EXCLAMATION, parentWindow);
1008 return FALSE;
1009 }
1010 return TRUE;
1011}
1012
1013// Called when TICK is pressed or focus is lost or view wants to update
1014// the property list.
1015// Does the transferance from the property editing area to the property itself
1016bool wxRealListValidator::OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1017{
1018 if (!view->GetValueText())
1019 return FALSE;
1020
1021 if (strlen(view->GetValueText()->GetValue()) == 0)
1022 return FALSE;
1023
1024 wxString value(view->GetValueText()->GetValue());
1025 float f = (float)atof(value.GetData());
1026 property->GetValue() = f;
1027 return TRUE;
1028}
1029
1030bool wxRealListValidator::OnPrepareControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1031{
1032 if (view->GetConfirmButton())
1033 view->GetConfirmButton()->Enable(TRUE);
1034 if (view->GetCancelButton())
1035 view->GetCancelButton()->Enable(TRUE);
1036 if (view->GetEditButton())
1037 view->GetEditButton()->Enable(FALSE);
1038 if (view->GetValueText())
1039 view->GetValueText()->Enable(TRUE);
1040 return TRUE;
1041}
1042
1043///
1044/// Integer validator
1045///
1046IMPLEMENT_DYNAMIC_CLASS(wxIntegerListValidator, wxPropertyListValidator)
1047
1048bool wxIntegerListValidator::OnCheckValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1049{
1050 if (integerMin == 0 && integerMax == 0)
1051 return TRUE;
1052
1053 if (!view->GetValueText())
1054 return FALSE;
1055 wxString value(view->GetValueText()->GetValue());
1056
1057 long val = 0;
1058 if (!StringToLong(WXSTRINGCAST value, &val))
1059 {
1060 char buf[200];
1061 sprintf(buf, "Value %s is not a valid integer!", value.GetData());
1062 wxMessageBox(buf, "Property value error", wxOK | wxICON_EXCLAMATION, parentWindow);
1063 return FALSE;
1064 }
1065 if (val < integerMin || val > integerMax)
1066 {
1067 char buf[200];
1068 sprintf(buf, "Value must be an integer between %ld and %ld!", integerMin, integerMax);
1069 wxMessageBox(buf, "Property value error", wxOK | wxICON_EXCLAMATION, parentWindow);
1070 return FALSE;
1071 }
1072 return TRUE;
1073}
1074
1075// Called when TICK is pressed or focus is lost or view wants to update
1076// the property list.
1077// Does the transferance from the property editing area to the property itself
1078bool wxIntegerListValidator::OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1079{
1080 if (!view->GetValueText())
1081 return FALSE;
1082
1083 if (strlen(view->GetValueText()->GetValue()) == 0)
1084 return FALSE;
1085
1086 wxString value(view->GetValueText()->GetValue());
1087 long val = (long)atoi(value.GetData());
1088 property->GetValue() = (long)val;
1089 return TRUE;
1090}
1091
1092bool wxIntegerListValidator::OnPrepareControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1093{
1094 if (view->GetConfirmButton())
1095 view->GetConfirmButton()->Enable(TRUE);
1096 if (view->GetCancelButton())
1097 view->GetCancelButton()->Enable(TRUE);
1098 if (view->GetEditButton())
1099 view->GetEditButton()->Enable(FALSE);
1100 if (view->GetValueText())
1101 view->GetValueText()->Enable(TRUE);
1102 return TRUE;
1103}
1104
1105///
1106/// boolean validator
1107///
1108IMPLEMENT_DYNAMIC_CLASS(wxBoolListValidator, wxPropertyListValidator)
1109
1110bool wxBoolListValidator::OnCheckValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1111{
1112 if (!view->GetValueText())
1113 return FALSE;
1114 wxString value(view->GetValueText()->GetValue());
1115 if (value != "True" && value != "False")
1116 {
1117 wxMessageBox("Value must be True or False!", "Property value error", wxOK | wxICON_EXCLAMATION, parentWindow);
1118 return FALSE;
1119 }
1120 return TRUE;
1121}
1122
1123// Called when TICK is pressed or focus is lost or view wants to update
1124// the property list.
1125// Does the transferance from the property editing area to the property itself
1126bool wxBoolListValidator::OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1127{
1128 if (!view->GetValueText())
1129 return FALSE;
1130
1131 if (strlen(view->GetValueText()->GetValue()) == 0)
1132 return FALSE;
1133
1134 wxString value(view->GetValueText()->GetValue());
1135 bool boolValue = FALSE;
1136 if (value == "True")
1137 boolValue = TRUE;
1138 else
1139 boolValue = FALSE;
1140 property->GetValue() = (bool)boolValue;
1141 return TRUE;
1142}
1143
1144bool wxBoolListValidator::OnDisplayValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1145{
1146 if (!view->GetValueText())
1147 return FALSE;
1148 wxString str(property->GetValue().GetStringRepresentation());
1149
1150 view->GetValueText()->SetValue(str.GetData());
1151 view->GetValueList()->SetStringSelection(str.GetData());
1152 return TRUE;
1153}
1154
1155bool wxBoolListValidator::OnPrepareControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1156{
1157 if (view->GetConfirmButton())
1158 view->GetConfirmButton()->Enable(FALSE);
1159 if (view->GetCancelButton())
1160 view->GetCancelButton()->Enable(FALSE);
1161 if (view->GetEditButton())
1162 view->GetEditButton()->Enable(TRUE);
1163 if (view->GetValueText())
1164 view->GetValueText()->Enable(FALSE);
1165 return TRUE;
1166}
1167
1168bool wxBoolListValidator::OnPrepareDetailControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1169{
1170 if (view->GetValueList())
1171 {
1172 view->ShowListBoxControl(TRUE);
1173 view->GetValueList()->Enable(TRUE);
1174
1175 view->GetValueList()->Append("True");
1176 view->GetValueList()->Append("False");
1177 char *currentString = copystring(view->GetValueText()->GetValue());
1178 view->GetValueList()->SetStringSelection(currentString);
1179 delete[] currentString;
1180 }
1181 return TRUE;
1182}
1183
1184bool wxBoolListValidator::OnClearDetailControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1185{
1186 if (view->GetValueList())
1187 {
1188 view->GetValueList()->Clear();
1189 view->ShowListBoxControl(FALSE);
1190 view->GetValueList()->Enable(FALSE);
1191 }
1192 return TRUE;
1193}
1194
1195// Called when the property is double clicked. Extra functionality can be provided,
1196// cycling through possible values.
1197bool wxBoolListValidator::OnDoubleClick(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1198{
1199 if (!view->GetValueText())
1200 return FALSE;
1201 if (property->GetValue().BoolValue())
1202 property->GetValue() = (bool)FALSE;
1203 else
1204 property->GetValue() = (bool)TRUE;
1205 view->DisplayProperty(property);
1206 view->UpdatePropertyDisplayInList(property);
1207 view->OnPropertyChanged(property);
1208 return TRUE;
1209}
1210
1211///
1212/// String validator
1213///
1214IMPLEMENT_DYNAMIC_CLASS(wxStringListValidator, wxPropertyListValidator)
1215
1216wxStringListValidator::wxStringListValidator(wxStringList *list, long flags):
1217 wxPropertyListValidator(flags)
1218{
1219 strings = list;
1220 // If no constraint, we just allow the string to be edited.
1221 if (!strings && ((validatorFlags & wxPROP_ALLOW_TEXT_EDITING) == 0))
1222 validatorFlags |= wxPROP_ALLOW_TEXT_EDITING;
1223}
1224
1225bool wxStringListValidator::OnCheckValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1226{
1227 if (!strings)
1228 return TRUE;
1229
1230 if (!view->GetValueText())
1231 return FALSE;
1232 wxString value(view->GetValueText()->GetValue());
1233
1234 if (!strings->Member(value.GetData()))
1235 {
1236 wxString s("Value ");
1237 s += value.GetData();
1238 s += " is not valid.";
1239 wxMessageBox(s.GetData(), "Property value error", wxOK | wxICON_EXCLAMATION, parentWindow);
1240 return FALSE;
1241 }
1242 return TRUE;
1243}
1244
1245// Called when TICK is pressed or focus is lost or view wants to update
1246// the property list.
1247// Does the transferance from the property editing area to the property itself
1248bool wxStringListValidator::OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1249{
1250 if (!view->GetValueText())
1251 return FALSE;
1252 wxString value(view->GetValueText()->GetValue());
1253 property->GetValue() = value ;
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::OnDisplayValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1261{
1262 if (!view->GetValueText())
1263 return FALSE;
1264 wxString str(property->GetValue().GetStringRepresentation());
1265 view->GetValueText()->SetValue(str.GetData());
1266 if (strings)
1267 {
1268 view->GetValueList()->SetStringSelection(str.GetData());
1269 }
1270 return TRUE;
1271}
1272
1273bool wxStringListValidator::OnPrepareControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1274{
1275 // Unconstrained
1276 if (!strings)
1277 {
1278 if (view->GetEditButton())
1279 view->GetEditButton()->Enable(FALSE);
1280 if (view->GetConfirmButton())
1281 view->GetConfirmButton()->Enable(TRUE);
1282 if (view->GetCancelButton())
1283 view->GetCancelButton()->Enable(TRUE);
1284 if (view->GetValueText())
1285 view->GetValueText()->Enable(TRUE);
1286 return TRUE;
1287 }
1288
1289 // Constrained
1290 if (view->GetValueText())
1291 view->GetValueText()->Enable(FALSE);
1292
1293 if (view->GetEditButton())
1294 view->GetEditButton()->Enable(TRUE);
1295
1296 if (view->GetConfirmButton())
1297 view->GetConfirmButton()->Enable(FALSE);
1298 if (view->GetCancelButton())
1299 view->GetCancelButton()->Enable(FALSE);
1300 return TRUE;
1301}
1302
1303bool wxStringListValidator::OnPrepareDetailControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1304{
1305 if (view->GetValueList())
1306 {
1307 view->ShowListBoxControl(TRUE);
1308 view->GetValueList()->Enable(TRUE);
1309 wxNode *node = strings->First();
1310 while (node)
1311 {
1312 char *s = (char *)node->Data();
1313 view->GetValueList()->Append(s);
1314 node = node->Next();
1315 }
1316 char *currentString = property->GetValue().StringValue();
1317 view->GetValueList()->SetStringSelection(currentString);
1318 }
1319 return TRUE;
1320}
1321
1322bool wxStringListValidator::OnClearDetailControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1323{
1324 if (!strings)
1325 {
1326 return TRUE;
1327 }
1328
1329 if (view->GetValueList())
1330 {
1331 view->GetValueList()->Clear();
1332 view->ShowListBoxControl(FALSE);
1333 view->GetValueList()->Enable(FALSE);
1334 }
1335 return TRUE;
1336}
1337
1338// Called when the property is double clicked. Extra functionality can be provided,
1339// cycling through possible values.
1340bool wxStringListValidator::OnDoubleClick(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1341{
1342 if (!view->GetValueText())
1343 return FALSE;
1344 if (!strings)
1345 return FALSE;
1346
1347 wxNode *node = strings->First();
1348 char *currentString = property->GetValue().StringValue();
1349 while (node)
1350 {
1351 char *s = (char *)node->Data();
1352 if (strcmp(s, currentString) == 0)
1353 {
1354 char *nextString = NULL;
1355 if (node->Next())
1356 nextString = (char *)node->Next()->Data();
1357 else
1358 nextString = (char *)strings->First()->Data();
1359 property->GetValue() = wxString(nextString);
1360 view->DisplayProperty(property);
1361 view->UpdatePropertyDisplayInList(property);
1362 view->OnPropertyChanged(property);
1363 return TRUE;
1364 }
1365 else node = node->Next();
1366 }
1367 return TRUE;
1368}
1369
1370///
1371/// Filename validator
1372///
1373IMPLEMENT_DYNAMIC_CLASS(wxFilenameListValidator, wxPropertyListValidator)
1374
1375wxFilenameListValidator::wxFilenameListValidator(wxString message , wxString wildcard, long flags):
1376 wxPropertyListValidator(flags), filenameWildCard(wildcard), filenameMessage(message)
1377{
1378}
1379
1380wxFilenameListValidator::~wxFilenameListValidator(void)
1381{
1382}
1383
1384bool wxFilenameListValidator::OnCheckValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1385{
1386 return TRUE;
1387}
1388
1389// Called when TICK is pressed or focus is lost or view wants to update
1390// the property list.
1391// Does the transferance from the property editing area to the property itself
1392bool wxFilenameListValidator::OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1393{
1394 if (!view->GetValueText())
1395 return FALSE;
1396 wxString value(view->GetValueText()->GetValue());
1397 property->GetValue() = value ;
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::OnDisplayValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1405{
1406 if (!view->GetValueText())
1407 return FALSE;
1408 wxString str(property->GetValue().GetStringRepresentation());
1409 view->GetValueText()->SetValue(str);
1410 return TRUE;
1411}
1412
1413// Called when the property is double clicked. Extra functionality can be provided,
1414// cycling through possible values.
1415bool wxFilenameListValidator::OnDoubleClick(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1416{
1417 if (!view->GetValueText())
1418 return FALSE;
1419 OnEdit(property, view, parentWindow);
1420 return TRUE;
1421}
1422
1423bool wxFilenameListValidator::OnPrepareControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1424{
1425 if (view->GetConfirmButton())
1426 view->GetConfirmButton()->Enable(TRUE);
1427 if (view->GetCancelButton())
1428 view->GetCancelButton()->Enable(TRUE);
1429 if (view->GetEditButton())
1430 view->GetEditButton()->Enable(TRUE);
1431 if (view->GetValueText())
1432 view->GetValueText()->Enable((GetFlags() & wxPROP_ALLOW_TEXT_EDITING) == wxPROP_ALLOW_TEXT_EDITING);
1433 return TRUE;
1434}
1435
1436void wxFilenameListValidator::OnEdit(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1437{
1438 if (!view->GetValueText())
1439 return;
1440
1441 char *s = wxFileSelector(
1442 filenameMessage.GetData(),
1443 wxPathOnly(property->GetValue().StringValue()),
1444 wxFileNameFromPath(property->GetValue().StringValue()),
1445 NULL,
1446 filenameWildCard.GetData(),
1447 0,
1448 parentWindow);
1449 if (s)
1450 {
1451 property->GetValue() = wxString(s);
1452 view->DisplayProperty(property);
1453 view->UpdatePropertyDisplayInList(property);
1454 view->OnPropertyChanged(property);
1455 }
1456}
1457
1458///
1459/// Colour validator
1460///
1461IMPLEMENT_DYNAMIC_CLASS(wxColourListValidator, wxPropertyListValidator)
1462
1463wxColourListValidator::wxColourListValidator(long flags):
1464 wxPropertyListValidator(flags)
1465{
1466}
1467
1468wxColourListValidator::~wxColourListValidator(void)
1469{
1470}
1471
1472bool wxColourListValidator::OnCheckValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1473{
1474 return TRUE;
1475}
1476
1477// Called when TICK is pressed or focus is lost or view wants to update
1478// the property list.
1479// Does the transferance from the property editing area to the property itself
1480bool wxColourListValidator::OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1481{
1482 if (!view->GetValueText())
1483 return FALSE;
1484 wxString value(view->GetValueText()->GetValue());
1485
1486 property->GetValue() = value ;
1487 return TRUE;
1488}
1489
1490// Called when TICK is pressed or focus is lost or view wants to update
1491// the property list.
1492// Does the transferance from the property editing area to the property itself
1493bool wxColourListValidator::OnDisplayValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1494{
1495 if (!view->GetValueText())
1496 return FALSE;
1497 wxString str(property->GetValue().GetStringRepresentation());
1498 view->GetValueText()->SetValue(str);
1499 return TRUE;
1500}
1501
1502// Called when the property is double clicked. Extra functionality can be provided,
1503// cycling through possible values.
1504bool wxColourListValidator::OnDoubleClick(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1505{
1506 if (!view->GetValueText())
1507 return FALSE;
1508 OnEdit(property, view, parentWindow);
1509 return TRUE;
1510}
1511
1512bool wxColourListValidator::OnPrepareControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1513{
1514 if (view->GetConfirmButton())
1515 view->GetConfirmButton()->Enable(TRUE);
1516 if (view->GetCancelButton())
1517 view->GetCancelButton()->Enable(TRUE);
1518 if (view->GetEditButton())
1519 view->GetEditButton()->Enable(TRUE);
1520 if (view->GetValueText())
1521 view->GetValueText()->Enable((GetFlags() & wxPROP_ALLOW_TEXT_EDITING) == wxPROP_ALLOW_TEXT_EDITING);
1522 return TRUE;
1523}
1524
1525void wxColourListValidator::OnEdit(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1526{
1527 if (!view->GetValueText())
1528 return;
1529
1530 char *s = property->GetValue().StringValue();
1531 int r = 0;
1532 int g = 0;
1533 int b = 0;
1534 if (s)
1535 {
1536 r = wxHexToDec(s);
1537 g = wxHexToDec(s+2);
1538 b = wxHexToDec(s+4);
1539 }
1540
1541 wxColour col(r,g,b);
1542
1543 wxColourData data;
1544 data.SetChooseFull(TRUE);
1545 data.SetColour(col);
1546
1547 for (int i = 0; i < 16; i++)
1548 {
1549 wxColour colour(i*16, i*16, i*16);
1550 data.SetCustomColour(i, colour);
1551 }
1552
1553 wxColourDialog dialog(parentWindow, &data);
1554 if (dialog.ShowModal() != wxID_CANCEL)
1555 {
1556 wxColourData retData = dialog.GetColourData();
1557 col = retData.GetColour();
1558
1559 char buf[7];
1560 wxDecToHex(col.Red(), buf);
1561 wxDecToHex(col.Green(), buf+2);
1562 wxDecToHex(col.Blue(), buf+4);
1563
1564 property->GetValue() = wxString(buf);
1565 view->DisplayProperty(property);
1566 view->UpdatePropertyDisplayInList(property);
1567 view->OnPropertyChanged(property);
1568 }
1569}
1570
1571///
1572/// List of strings validator. For this we need more user interface than
1573/// we get with a property list; so create a new dialog for editing the list.
1574///
1575IMPLEMENT_DYNAMIC_CLASS(wxListOfStringsListValidator, wxPropertyListValidator)
1576
1577wxListOfStringsListValidator::wxListOfStringsListValidator(long flags):
1578 wxPropertyListValidator(flags)
1579{
1580}
1581
1582bool wxListOfStringsListValidator::OnCheckValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1583{
1584 // No constraints for an arbitrary, user-editable list of strings.
1585 return TRUE;
1586}
1587
1588// Called when TICK is pressed or focus is lost or view wants to update
1589// the property list.
1590// Does the transferance from the property editing area to the property itself.
1591// In this case, the user cannot directly edit the string list.
1592bool wxListOfStringsListValidator::OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1593{
1594 return TRUE;
1595}
1596
1597bool wxListOfStringsListValidator::OnDisplayValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1598{
1599 if (!view->GetValueText())
1600 return FALSE;
1601 wxString str(property->GetValue().GetStringRepresentation());
1602 view->GetValueText()->SetValue(str.GetData());
1603 return TRUE;
1604}
1605
1606bool wxListOfStringsListValidator::OnPrepareControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1607{
1608 if (view->GetEditButton())
1609 view->GetEditButton()->Enable(TRUE);
1610 if (view->GetValueText())
1611 view->GetValueText()->Enable(FALSE);
1612
1613 if (view->GetConfirmButton())
1614 view->GetConfirmButton()->Enable(FALSE);
1615 if (view->GetCancelButton())
1616 view->GetCancelButton()->Enable(FALSE);
1617 return TRUE;
1618}
1619
1620// Called when the property is double clicked. Extra functionality can be provided,
1621// cycling through possible values.
1622bool wxListOfStringsListValidator::OnDoubleClick(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1623{
1624 OnEdit(property, view, parentWindow);
1625 return TRUE;
1626}
1627
1628void wxListOfStringsListValidator::OnEdit(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1629{
1630 // Convert property value to a list of strings for editing
1631 wxStringList *stringList = new wxStringList;
1632
1633 wxPropertyValue *expr = property->GetValue().GetFirst();
1634 while (expr)
1635 {
1636 char *s = expr->StringValue();
1637 if (s)
1638 stringList->Add(s);
1639 expr = expr->GetNext();
1640 }
1641
1642 wxString title("Editing ");
1643 title += property->GetName();
1644
1645 if (EditStringList(parentWindow, stringList, title.GetData()))
1646 {
1647 wxPropertyValue& oldValue = property->GetValue();
1648 oldValue.ClearList();
1649 wxNode *node = stringList->First();
1650 while (node)
1651 {
1652 char *s = (char *)node->Data();
1653 oldValue.Append(new wxPropertyValue(s));
1654
1655 node = node->Next();
1656 }
1657
1658 view->DisplayProperty(property);
1659 view->UpdatePropertyDisplayInList(property);
1660 view->OnPropertyChanged(property);
1661 }
1662 delete stringList;
1663}
1664
1665class wxPropertyStringListEditorDialog: public wxDialog
1666{
1667 public:
1668 wxStringList *stringList;
1669 wxListBox *listBox;
1670 wxTextCtrl *stringText;
1671 static bool dialogCancelled;
1672 int currentSelection;
1673 wxPropertyStringListEditorDialog(wxWindow *parent, const wxString& title,
1674 const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
1675 long windowStyle = wxDEFAULT_DIALOG_STYLE, const wxString& name = "stringEditorDialogBox"):
1676 wxDialog(parent, -1, title, pos, size, windowStyle, name)
1677 {
1678 stringList = NULL;
1679 stringText = NULL;
1680 listBox = NULL;
1681 dialogCancelled = FALSE;
1682 currentSelection = -1;
1683 }
1684 ~wxPropertyStringListEditorDialog(void) {}
1685 bool OnClose(void);
1686 void SaveCurrentSelection(void);
1687 void ShowCurrentSelection(void);
1688
1689 void OnOK(wxCommandEvent& event);
1690 void OnCancel(wxCommandEvent& event);
1691 void OnAdd(wxCommandEvent& event);
1692 void OnDelete(wxCommandEvent& event);
1693 void OnStrings(wxCommandEvent& event);
1694 void OnText(wxCommandEvent& event);
1695
1696DECLARE_EVENT_TABLE()
1697};
1698
1699#define wxID_PROP_SL_ADD 3000
1700#define wxID_PROP_SL_DELETE 3001
1701#define wxID_PROP_SL_STRINGS 3002
1702#define wxID_PROP_SL_TEXT 3003
1703
1704BEGIN_EVENT_TABLE(wxPropertyStringListEditorDialog, wxDialog)
1705 EVT_BUTTON(wxID_OK, wxPropertyStringListEditorDialog::OnOK)
1706 EVT_BUTTON(wxID_CANCEL, wxPropertyStringListEditorDialog::OnCancel)
1707 EVT_BUTTON(wxID_PROP_SL_ADD, wxPropertyStringListEditorDialog::OnAdd)
1708 EVT_BUTTON(wxID_PROP_SL_DELETE, wxPropertyStringListEditorDialog::OnDelete)
1709 EVT_LISTBOX(wxID_PROP_SL_STRINGS, wxPropertyStringListEditorDialog::OnStrings)
1710 EVT_TEXT(wxID_PROP_SL_TEXT, wxPropertyStringListEditorDialog::OnText)
1711END_EVENT_TABLE()
1712
1713class wxPropertyStringListEditorText: public wxTextCtrl
1714{
1715 public:
1716 wxPropertyStringListEditorText(wxWindow *parent, wxWindowID id, const wxString& val,
1717 const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
1718 long windowStyle = 0, const wxString& name = "text"):
1719 wxTextCtrl(parent, id, val, pos, size, windowStyle, wxDefaultValidator, name)
1720 {
1721 }
1722 void OnKillFocus(void)
1723 {
1724 wxPropertyStringListEditorDialog *dialog = (wxPropertyStringListEditorDialog *)GetParent();
1725 dialog->SaveCurrentSelection();
1726 }
1727};
1728
1729bool wxPropertyStringListEditorDialog::dialogCancelled = FALSE;
1730
1731// Edit the string list.
1732bool wxListOfStringsListValidator::EditStringList(wxWindow *parent, wxStringList *stringList, const char *title)
1733{
1734 wxBeginBusyCursor();
1735 wxPropertyStringListEditorDialog *dialog = new wxPropertyStringListEditorDialog(parent,
1736 title, wxPoint(10, 10), wxSize(400, 400), wxDEFAULT_DIALOG_STYLE|wxDIALOG_MODAL);
1737
1738 dialog->stringList = stringList;
1739
1740 wxButton *okButton = new wxButton(dialog, wxID_OK, "OK", wxPoint(5, 5));
1741 wxButton *cancelButton = new wxButton(dialog, wxID_CANCEL, "Cancel", wxPoint(40, 5));
1742
1743// wxButton *helpButton = new wxButton(dialog, (wxFunction)StringListEditorHelpProc, "Help");
1744// helpButton->SetClientData((char *)this);
1745
1746 dialog->listBox = new wxListBox(dialog, wxID_PROP_SL_STRINGS,
1747 wxPoint(5, 30), wxSize(300, 200), 0, NULL, wxLB_SINGLE);
1748
1749 dialog->stringText = new wxPropertyStringListEditorText(dialog,
1750 wxID_PROP_SL_TEXT, "", wxPoint(5, 240),
1751 wxSize(300, -1), wxPROCESS_ENTER);
1752 dialog->stringText->Enable(FALSE);
1753
1754 wxButton *addButton = new wxButton(dialog, wxID_PROP_SL_ADD, "Add", wxPoint(5, 280));
1755 wxButton *deleteButton = new wxButton(dialog, wxID_PROP_SL_DELETE, "Delete", wxPoint(40, 280));
1756
1757 wxNode *node = stringList->First();
1758 while (node)
1759 {
1760 char *str = (char *)node->Data();
1761 // Save node as client data for each listbox item
1762 dialog->listBox->Append(str, (char *)node);
1763 node = node->Next();
1764 }
1765
1766 dialog->SetClientSize(310, 305);
1767
1768 dialog->Centre(wxBOTH);
1769 wxEndBusyCursor();
1770 if (dialog->ShowModal() == wxID_CANCEL)
1771 return FALSE;
1772 else
1773 return TRUE;
1774}
1775
1776/*
1777 * String list editor callbacks
1778 *
1779 */
1780
8656024d 1781void wxPropertyStringListEditorDialog::OnStrings(wxCommandEvent& WXUNUSED(event))
457814b5
JS
1782{
1783 int sel = listBox->GetSelection();
1784 if (sel > -1)
1785 {
1786 currentSelection = sel;
1787
1788 ShowCurrentSelection();
1789 }
1790}
1791
8656024d 1792void wxPropertyStringListEditorDialog::OnDelete(wxCommandEvent& WXUNUSED(event))
457814b5
JS
1793{
1794 int sel = listBox->GetSelection();
1795 if (sel == -1)
1796 return;
1797
1798 wxNode *node = (wxNode *)listBox->wxListBox::GetClientData(sel);
1799 if (!node)
1800 return;
1801
1802 listBox->Delete(sel);
1803 delete[] (char *)node->Data();
1804 delete node;
1805 currentSelection = -1;
1806 stringText->SetValue("");
1807}
1808
8656024d 1809void wxPropertyStringListEditorDialog::OnAdd(wxCommandEvent& WXUNUSED(event))
457814b5
JS
1810{
1811 SaveCurrentSelection();
1812
1813 char *initialText = "";
1814 wxNode *node = stringList->Add(initialText);
1815 listBox->Append(initialText, (char *)node);
1816 currentSelection = stringList->Number() - 1;
1817 listBox->SetSelection(currentSelection);
1818 ShowCurrentSelection();
1819 stringText->SetFocus();
1820}
1821
8656024d 1822void wxPropertyStringListEditorDialog::OnOK(wxCommandEvent& WXUNUSED(event))
457814b5
JS
1823{
1824 SaveCurrentSelection();
1825 EndModal(wxID_OK);
1826 Close(TRUE);
1827}
1828
8656024d 1829void wxPropertyStringListEditorDialog::OnCancel(wxCommandEvent& WXUNUSED(event))
457814b5
JS
1830{
1831 dialogCancelled = TRUE;
1832 EndModal(wxID_CANCEL);
1833 Close(TRUE);
1834}
1835
1836void wxPropertyStringListEditorDialog::OnText(wxCommandEvent& event)
1837{
1838 if (event.GetEventType() == wxEVENT_TYPE_TEXT_ENTER_COMMAND)
1839 {
1840 SaveCurrentSelection();
1841 }
1842}
1843
1844bool wxPropertyStringListEditorDialog::OnClose(void)
1845{
1846 SaveCurrentSelection();
1847 return TRUE;
1848}
1849
1850void wxPropertyStringListEditorDialog::SaveCurrentSelection(void)
1851{
1852 if (currentSelection == -1)
1853 return;
1854
1855 wxNode *node = (wxNode *)listBox->wxListBox::GetClientData(currentSelection);
1856 if (!node)
1857 return;
1858
1859 wxString txt(stringText->GetValue());
1860 if (node->Data())
1861 delete[] (char *)node->Data();
1862 node->SetData((wxObject *)copystring(txt));
1863
1864 listBox->SetString(currentSelection, (char *)node->Data());
1865}
1866
1867void wxPropertyStringListEditorDialog::ShowCurrentSelection(void)
1868{
1869 if (currentSelection == -1)
1870 {
1871 stringText->SetValue("");
1872 return;
1873 }
1874 wxNode *node = (wxNode *)listBox->wxListBox::GetClientData(currentSelection);
1875 char *txt = (char *)node->Data();
1876 stringText->SetValue(txt);
1877 stringText->Enable(TRUE);
1878}