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