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