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