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