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