1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     Property list classes 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  13 #pragma implementation "proplist.h" 
  16 // For compilers that support precompilation, includes "wx/wx.h". 
  17 #include "wx/wxprec.h" 
  33 #if defined(__WXMSW__) && !defined(__GNUWIN32__) && !defined(__WXWINE__) 
  36 #include <strstream.h> 
  42 #include "wx/window.h" 
  45 #include "wx/colordlg.h" 
  46 #include "wx/proplist.h" 
  49  * Property text edit control 
  52 IMPLEMENT_CLASS(wxPropertyTextEdit
, wxTextCtrl
) 
  54 wxPropertyTextEdit::wxPropertyTextEdit(wxPropertyListView 
*v
, wxWindow 
*parent
, 
  55     const wxWindowID id
, const wxString
& value
, 
  56     const wxPoint
& pos
, const wxSize
& size
, 
  57     long style
, const wxString
& name
): 
  58  wxTextCtrl(parent
, id
, value
, pos
, size
, style
, wxDefaultValidator
, name
) 
  63 void wxPropertyTextEdit::OnSetFocus(void) 
  67 void wxPropertyTextEdit::OnKillFocus(void) 
  75 IMPLEMENT_DYNAMIC_CLASS(wxPropertyListView
, wxPropertyView
) 
  77 BEGIN_EVENT_TABLE(wxPropertyListView
, wxPropertyView
) 
  78     EVT_BUTTON(wxID_OK
,                 wxPropertyListView::OnOk
) 
  79     EVT_BUTTON(wxID_CANCEL
,             wxPropertyListView::OnCancel
) 
  80     EVT_BUTTON(wxID_HELP
,               wxPropertyListView::OnHelp
) 
  81     EVT_BUTTON(wxID_PROP_CROSS
,         wxPropertyListView::OnCross
) 
  82     EVT_BUTTON(wxID_PROP_CHECK
,         wxPropertyListView::OnCheck
) 
  83     EVT_BUTTON(wxID_PROP_EDIT
,          wxPropertyListView::OnEdit
) 
  84     EVT_TEXT_ENTER(wxID_PROP_TEXT
,      wxPropertyListView::OnText
) 
  85     EVT_LISTBOX(wxID_PROP_SELECT
,       wxPropertyListView::OnPropertySelect
) 
  86     EVT_COMMAND(wxID_PROP_SELECT
, wxEVT_COMMAND_LISTBOX_DOUBLECLICKED
, 
  87                                         wxPropertyListView::OnPropertyDoubleClick
) 
  88     EVT_LISTBOX(wxID_PROP_VALUE_SELECT
, wxPropertyListView::OnValueListSelect
) 
  91 bool wxPropertyListView::sm_dialogCancelled 
= FALSE
; 
  92 wxBitmap 
*wxPropertyListView::sm_tickBitmap 
= NULL
; 
  93 wxBitmap 
*wxPropertyListView::sm_crossBitmap 
= NULL
; 
  95 wxPropertyListView::wxPropertyListView(wxPanel 
*propPanel
, long flags
):wxPropertyView(flags
) 
  97   m_propertyScrollingList 
= NULL
; 
 101   m_confirmButton 
= NULL
; 
 102   m_cancelButton 
= NULL
; 
 103   m_propertyWindow 
= propPanel
; 
 104   m_managedWindow 
= NULL
; 
 106   m_windowCloseButton 
= NULL
; 
 107   m_windowCancelButton 
= NULL
; 
 108   m_windowHelpButton 
= NULL
; 
 110   m_detailedEditing 
= FALSE
; 
 113 wxPropertyListView::~wxPropertyListView(void) 
 119     delete m_crossBitmap; 
 123 void wxPropertyListView::ShowView(wxPropertySheet 
*ps
, wxPanel 
*panel
) 
 125   m_propertySheet 
= ps
; 
 127   AssociatePanel(panel
); 
 130   UpdatePropertyList(); 
 134 // Update this view of the viewed object, called e.g. by 
 135 // the object itself. 
 136 bool wxPropertyListView::OnUpdateView(void) 
 141 bool wxPropertyListView::UpdatePropertyList(bool clearEditArea
) 
 143   if (!m_propertyScrollingList 
|| !m_propertySheet
) 
 146   m_propertyScrollingList
->Clear(); 
 149     m_valueList
->Clear(); 
 150     m_valueText
->SetValue(""); 
 152   wxNode 
*node 
= m_propertySheet
->GetProperties().First(); 
 154   // Should sort them... later... 
 157     wxProperty 
*property 
= (wxProperty 
*)node
->Data(); 
 158     wxString 
stringValueRepr(property
->GetValue().GetStringRepresentation()); 
 159     wxString 
paddedString(MakeNameValueString(property
->GetName(), stringValueRepr
)); 
 161     m_propertyScrollingList
->Append(paddedString
.GetData(), (void *)property
); 
 167 bool wxPropertyListView::UpdatePropertyDisplayInList(wxProperty 
*property
) 
 169   if (!m_propertyScrollingList 
|| !m_propertySheet
) 
 173   int currentlySelected 
= m_propertyScrollingList
->GetSelection(); 
 176   wxString 
stringValueRepr(property
->GetValue().GetStringRepresentation()); 
 177   wxString 
paddedString(MakeNameValueString(property
->GetName(), stringValueRepr
)); 
 178   int sel 
= FindListIndexForProperty(property
); 
 182     // Don't update the listbox unnecessarily because it can cause 
 185     if (paddedString 
!= m_propertyScrollingList
->GetString(sel
)) 
 186       m_propertyScrollingList
->SetString(sel
, paddedString
.GetData()); 
 189 //  UpdatePropertyList(FALSE); 
 192   // TODO: why is this necessary? 
 194   if (currentlySelected 
> -1) 
 195     m_propertyScrollingList
->SetSelection(currentlySelected
); 
 201 // Find the wxListBox index corresponding to this property 
 202 int wxPropertyListView::FindListIndexForProperty(wxProperty 
*property
) 
 204   int n 
= m_propertyScrollingList
->Number(); 
 205   for (int i 
= 0; i 
< n
; i
++) 
 207     if (property 
== (wxProperty 
*)m_propertyScrollingList
->wxListBox::GetClientData(i
)) 
 213 wxString 
wxPropertyListView::MakeNameValueString(wxString name
, wxString value
) 
 215   wxString 
theString(name
); 
 218   int padWith 
= nameWidth 
- theString
.Length(); 
 222   if (GetFlags() & wxPROP_SHOWVALUES
) 
 224     // Want to pad with spaces 
 225     theString
.Append(' ', padWith
); 
 232 // Select and show string representation in validator the given 
 233 // property. NULL resets to show no property. 
 234 bool wxPropertyListView::ShowProperty(wxProperty 
*property
, bool select
) 
 236   if (m_currentProperty
) 
 238     EndShowingProperty(m_currentProperty
); 
 239     m_currentProperty 
= NULL
; 
 242   m_valueList
->Clear(); 
 243   m_valueText
->SetValue(""); 
 247     m_currentProperty 
= property
; 
 248     BeginShowingProperty(property
); 
 252     int sel 
= FindListIndexForProperty(property
); 
 254       m_propertyScrollingList
->SetSelection(sel
); 
 259 // Find appropriate validator and load property into value controls 
 260 bool wxPropertyListView::BeginShowingProperty(wxProperty 
*property
) 
 262   m_currentValidator 
= FindPropertyValidator(property
); 
 263   if (!m_currentValidator
) 
 266   if (!m_currentValidator
->IsKindOf(CLASSINFO(wxPropertyListValidator
))) 
 269   wxPropertyListValidator 
*listValidator 
= (wxPropertyListValidator 
*)m_currentValidator
; 
 271   listValidator
->OnPrepareControls(property
, this, m_propertyWindow
); 
 272   DisplayProperty(property
); 
 276 // Find appropriate validator and unload property from value controls 
 277 bool wxPropertyListView::EndShowingProperty(wxProperty 
*property
) 
 279   if (!m_currentValidator
) 
 282   RetrieveProperty(property
); 
 284   if (!m_currentValidator
->IsKindOf(CLASSINFO(wxPropertyListValidator
))) 
 287   wxPropertyListValidator 
*listValidator 
= (wxPropertyListValidator 
*)m_currentValidator
; 
 289   listValidator
->OnClearControls(property
, this, m_propertyWindow
); 
 290   if (m_detailedEditing
) 
 292     listValidator
->OnClearDetailControls(property
, this, m_propertyWindow
); 
 293     m_detailedEditing 
= FALSE
; 
 298 void wxPropertyListView::BeginDetailedEditing(void) 
 300   if (!m_currentValidator
) 
 302   if (!m_currentProperty
) 
 304   if (m_detailedEditing
) 
 306   if (!m_currentValidator
->IsKindOf(CLASSINFO(wxPropertyListValidator
))) 
 308   if (!m_currentProperty
->IsEnabled()) 
 311   wxPropertyListValidator 
*listValidator 
= (wxPropertyListValidator 
*)m_currentValidator
; 
 313   if (listValidator
->OnPrepareDetailControls(m_currentProperty
, this, m_propertyWindow
)) 
 314     m_detailedEditing 
= TRUE
; 
 317 void wxPropertyListView::EndDetailedEditing(void) 
 319   if (!m_currentValidator
) 
 321   if (!m_currentProperty
) 
 324   RetrieveProperty(m_currentProperty
); 
 326   if (!m_currentValidator
->IsKindOf(CLASSINFO(wxPropertyListValidator
))) 
 329   wxPropertyListValidator 
*listValidator 
= (wxPropertyListValidator 
*)m_currentValidator
; 
 331   if (m_detailedEditing
) 
 333     listValidator
->OnClearDetailControls(m_currentProperty
, this, m_propertyWindow
); 
 334     m_detailedEditing 
= FALSE
; 
 338 bool wxPropertyListView::DisplayProperty(wxProperty 
*property
) 
 340   if (!m_currentValidator
) 
 343   if (((m_currentValidator
->GetFlags() & wxPROP_ALLOW_TEXT_EDITING
) == 0) || !property
->IsEnabled()) 
 344     m_valueText
->SetEditable(FALSE
); 
 346     m_valueText
->SetEditable(TRUE
); 
 348   if (!m_currentValidator
->IsKindOf(CLASSINFO(wxPropertyListValidator
))) 
 351   wxPropertyListValidator 
*listValidator 
= (wxPropertyListValidator 
*)m_currentValidator
; 
 353   listValidator
->OnDisplayValue(property
, this, m_propertyWindow
); 
 357 bool wxPropertyListView::RetrieveProperty(wxProperty 
*property
) 
 359   if (!m_currentValidator
) 
 361   if (!property
->IsEnabled()) 
 364   if (!m_currentValidator
->IsKindOf(CLASSINFO(wxPropertyListValidator
))) 
 367   wxPropertyListValidator 
*listValidator 
= (wxPropertyListValidator 
*)m_currentValidator
; 
 369   if (listValidator
->OnCheckValue(property
, this, m_propertyWindow
)) 
 371     if (listValidator
->OnRetrieveValue(property
, this, m_propertyWindow
)) 
 373       UpdatePropertyDisplayInList(property
); 
 374       OnPropertyChanged(property
); 
 379     // Revert to old value 
 380     listValidator
->OnDisplayValue(property
, this, m_propertyWindow
); 
 386 bool wxPropertyListView::EditProperty(wxProperty 
*WXUNUSED(property
)) 
 391 // Called by the listbox callback 
 392 void wxPropertyListView::OnPropertySelect(wxCommandEvent
& WXUNUSED(event
)) 
 394   int sel 
= m_propertyScrollingList
->GetSelection(); 
 397     wxProperty 
*newSel 
= (wxProperty 
*)m_propertyScrollingList
->wxListBox::GetClientData(sel
); 
 398     if (newSel 
&& newSel 
!= m_currentProperty
) 
 400       ShowProperty(newSel
, FALSE
); 
 405 bool wxPropertyListView::CreateControls(void) 
 407   wxPanel 
*panel 
= (wxPanel 
*)m_propertyWindow
; 
 409   int largeButtonWidth 
= 60; 
 410   int largeButtonHeight 
= 25; 
 412   int smallButtonWidth 
= 25; 
 413   int smallButtonHeight 
= 20; 
 415   // XView must be allowed to choose its own sized buttons 
 417   largeButtonWidth 
= -1; 
 418   largeButtonHeight 
= -1; 
 420   smallButtonWidth 
= -1; 
 421   smallButtonHeight 
= -1; 
 430   wxWindow 
*leftMostWindow 
= panel
; 
 432   wxWindow *topMostWindow = panel; 
 433   wxWindow *rightMostWindow = panel; 
 436   wxSystemSettings settings
; 
 437   wxFont guiFont 
= settings
.GetSystemFont(wxSYS_DEFAULT_GUI_FONT
); 
 440   wxFont 
*boringFont 
= wxTheFontList
->FindOrCreateFont(guiFont
.GetPointSize(), wxMODERN
, wxNORMAL
, wxNORMAL
, FALSE
, "Courier New"); 
 442   wxFont 
*boringFont 
= wxTheFontList
->FindOrCreateFont(guiFont
.GetPointSize(), wxTELETYPE
, wxNORMAL
, wxNORMAL
); 
 445   // May need to be changed in future to eliminate clashes with app. 
 446   // WHAT WAS THIS FOR? 
 447 //  panel->SetClientData((char *)this); 
 449   // These buttons are at the bottom of the window, but create them now 
 450   // so the constraints are evaluated in the correct order 
 451   if (m_buttonFlags 
& wxPROP_BUTTON_OK
) 
 453     m_windowCloseButton 
= new wxButton(panel
, wxID_OK
, "OK", 
 454      wxPoint(-1, -1), wxSize(largeButtonWidth
, largeButtonHeight
)); 
 455     m_windowCloseButton
->SetDefault(); 
 456     m_windowCloseButton
->SetFocus(); 
 458   else if (m_buttonFlags 
& wxPROP_BUTTON_CLOSE
) 
 460     m_windowCloseButton 
= new wxButton(panel
, wxID_OK
, "Close", 
 461      wxPoint(-1, -1), wxSize(largeButtonWidth
, largeButtonHeight
)); 
 463   if (m_buttonFlags 
& wxPROP_BUTTON_CANCEL
) 
 465     m_windowCancelButton 
= new wxButton(panel
, wxID_CANCEL
, "Cancel", 
 466      wxPoint(-1, -1), wxSize(largeButtonWidth
, largeButtonHeight
)); 
 468   if (m_buttonFlags 
& wxPROP_BUTTON_HELP
) 
 470     m_windowHelpButton 
= new wxButton(panel
, wxID_HELP
, "Help", 
 471      wxPoint(-1, -1), wxSize(largeButtonWidth
, largeButtonHeight
)); 
 474   if (m_windowCloseButton
) 
 476     wxLayoutConstraints 
*c1 
= new wxLayoutConstraints
; 
 478     c1
->left
.SameAs       (panel
, wxLeft
, 2); 
 479     c1
->bottom
.SameAs        (panel
, wxBottom
, 2); 
 482     m_windowCloseButton
->SetConstraints(c1
); 
 483     leftMostWindow 
= m_windowCloseButton
; 
 485   if (m_windowCancelButton
) 
 487     wxLayoutConstraints 
*c2 
= new wxLayoutConstraints
; 
 489     c2
->right
.SameAs       (panel
, wxRight
, 2); 
 490     c2
->bottom
.SameAs          (panel
, wxBottom
, 2); 
 493     m_windowCancelButton
->SetConstraints(c2
); 
 494     leftMostWindow 
= m_windowCancelButton
; 
 496   if (m_windowHelpButton
) 
 498     wxLayoutConstraints 
*c2 
= new wxLayoutConstraints
; 
 499     if (leftMostWindow 
== panel
) 
 500       c2
->left
.SameAs       (panel
, wxLeft
, 2); 
 502       c2
->left
.RightOf      (leftMostWindow
, 2); 
 504     c2
->bottom
.SameAs          (panel
, wxBottom
, 2); 
 507     m_windowHelpButton
->SetConstraints(c2
); 
 508     leftMostWindow 
= m_windowHelpButton
; 
 511   if (m_buttonFlags 
& wxPROP_BUTTON_CHECK_CROSS
) 
 517       tickBitmap = new wxBitmap("tick_bmp", wxBITMAP_TYPE_RESOURCE); 
 518       crossBitmap =  new wxBitmap("cross_bmp", wxBITMAP_TYPE_RESOURCE); 
 519       if (!tickBitmap || !crossBitmap || !tickBitmap->Ok() || !crossBitmap->Ok()) 
 532     if (tickBitmap && crossBitmap) 
 534       m_confirmButton = new wxBitmapButton(panel, wxID_PROP_CHECK, tickBitmap, 
 535        wxPoint(-1, -1), wxSize(smallButtonWidth-5, smallButtonHeight-5)); 
 536       m_cancelButton = new wxBitmapButton(panel, wxID_PROP_CROSS, crossBitmap, 
 537        wxPoint(-1, -1), wxSize(smallButtonWidth-5, smallButtonHeight-5)); 
 542       m_confirmButton 
= new wxButton(panel
, wxID_PROP_CHECK
, ":-)", 
 543        wxPoint(-1, -1), wxSize(smallButtonWidth
, smallButtonHeight
)); 
 544       m_cancelButton 
= new wxButton(panel
, wxID_PROP_CROSS
, "X", 
 545        wxPoint(-1, -1), wxSize(smallButtonWidth
, smallButtonHeight
)); 
 548     wxLayoutConstraints 
*c 
= new wxLayoutConstraints
; 
 549     c
->left
.SameAs         (panel
, wxLeft
, 2); 
 551     if (windowCloseButton) 
 552       c->top.Below         (m_windowCloseButton, 2); 
 555       c
->top
.SameAs        (panel
, wxTop
, 2); 
 560     m_cancelButton
->SetConstraints(c
); 
 562     c 
= new wxLayoutConstraints
; 
 563     c
->left
.RightOf        (m_cancelButton
, 2); 
 564     c
->top
.SameAs          (m_cancelButton
, wxTop
, 0); 
 568     m_confirmButton
->SetConstraints(c
); 
 570     m_cancelButton
->Enable(FALSE
); 
 571     m_confirmButton
->Enable(FALSE
); 
 574   if (m_buttonFlags 
& wxPROP_PULLDOWN
) 
 576     m_editButton 
= new wxButton(panel
, wxID_PROP_EDIT
, "...", 
 577      wxPoint(-1, -1), wxSize(smallButtonWidth
, smallButtonHeight
)); 
 578     m_editButton
->Enable(FALSE
); 
 579     wxLayoutConstraints 
*c 
= new wxLayoutConstraints
; 
 582     if (m_windowCloseButton) 
 583       c->top.Below           (m_windowCloseButton, 2); 
 586       c
->top
.SameAs          (panel
, wxTop
, 2); 
 588     c
->right
.SameAs          (panel
, wxRight
, 2); 
 591     m_editButton
->SetConstraints(c
); 
 594   m_valueText 
= new wxPropertyTextEdit(this, panel
, wxID_PROP_TEXT
, "", wxPoint(-1, -1), wxSize(-1, -1), wxPROCESS_ENTER
); 
 595   m_valueText
->Enable(FALSE
); 
 597   wxLayoutConstraints 
*c 
= new wxLayoutConstraints
; 
 600     c
->left
.RightOf        (m_confirmButton
, 2); 
 602     c
->left
.SameAs         (panel
, wxLeft
, 2); 
 604   if (m_windowCloseButton) 
 605     c->top.Below           (m_windowCloseButton, 2); 
 608     c
->top
.SameAs          (panel
, wxTop
, 2); 
 611     c
->right
.LeftOf        (m_editButton
, 2); 
 613     c
->right
.SameAs        (panel
, wxRight
, 2); 
 616   m_valueText
->SetConstraints(c
); 
 618   m_valueList 
= new wxListBox(panel
, wxID_PROP_VALUE_SELECT
, wxPoint(-1, -1), wxSize(-1, 60)); 
 619   m_valueList
->Show(FALSE
); 
 621   c 
= new wxLayoutConstraints
; 
 623   c
->left
.SameAs         (panel
, wxLeft
, 2); 
 624   c
->top
.Below           (m_valueText
, 2); 
 625   c
->right
.SameAs        (panel
, wxRight
, 2); 
 626   c
->height
.Absolute(60); 
 628   m_valueList
->SetConstraints(c
); 
 630   m_propertyScrollingList 
= new wxListBox(panel
, wxID_PROP_SELECT
, 
 631     wxPoint(-1, -1), wxSize(300, 300)); 
 632   m_propertyScrollingList
->SetFont(* boringFont
); 
 634   c 
= new wxLayoutConstraints
; 
 636   c
->left
.SameAs         (panel
, wxLeft
, 2); 
 638   if (m_buttonFlags 
& wxPROP_DYNAMIC_VALUE_FIELD
) 
 639     c
->top
.Below         (m_valueText
, 2); 
 641     c
->top
.Below         (m_valueList
, 2); 
 643   c
->right
.SameAs        (panel
, wxRight
, 2); 
 645   if (m_windowCloseButton
) 
 646     c
->bottom
.Above       (m_windowCloseButton
, -2); 
 648     c
->bottom
.SameAs       (panel
, wxBottom
, 2); 
 650   m_propertyScrollingList
->SetConstraints(c
); 
 652   // Note: if this is called now, it causes a GPF. 
 659 void wxPropertyListView::ShowTextControl(bool show
) 
 662     m_valueText
->Show(show
); 
 665 void wxPropertyListView::ShowListBoxControl(bool show
) 
 669     m_valueList
->Show(show
); 
 670     if (m_buttonFlags 
& wxPROP_DYNAMIC_VALUE_FIELD
) 
 672       wxLayoutConstraints 
*constraints 
= m_propertyScrollingList
->GetConstraints(); 
 677           constraints
->top
.Below(m_valueList
, 2); 
 678           // Maintain back-pointer so when valueList is deleted, 
 679           // any reference to it from this window is removed. 
 680           m_valueList
->AddConstraintReference(m_propertyScrollingList
); 
 684           constraints
->top
.Below(m_valueText
, 2); 
 685           m_valueText
->AddConstraintReference(m_propertyScrollingList
); 
 687         m_propertyWindow
->Layout(); 
 693 void wxPropertyListView::EnableCheck(bool show
) 
 696     m_confirmButton
->Enable(show
); 
 699 void wxPropertyListView::EnableCross(bool show
) 
 702     m_cancelButton
->Enable(show
); 
 705 bool wxPropertyListView::OnClose(void) 
 707   // Retrieve the value if any 
 708   wxCommandEvent event
; 
 715 void wxPropertyListView::OnValueListSelect(wxCommandEvent
& WXUNUSED(event
)) 
 717   if (m_currentProperty 
&& m_currentValidator
) 
 719     if (!m_currentValidator
->IsKindOf(CLASSINFO(wxPropertyListValidator
))) 
 722     wxPropertyListValidator 
*listValidator 
= (wxPropertyListValidator 
*)m_currentValidator
; 
 724     listValidator
->OnValueListSelect(m_currentProperty
, this, m_propertyWindow
); 
 728 void wxPropertyListView::OnOk(wxCommandEvent
& event
) 
 730   // Retrieve the value if any 
 733   m_managedWindow
->Close(TRUE
); 
 736 void wxPropertyListView::OnCancel(wxCommandEvent
& WXUNUSED(event
)) 
 738 //  SetReturnCode(wxID_CANCEL); 
 739   m_managedWindow
->Close(TRUE
); 
 740   sm_dialogCancelled 
= TRUE
; 
 743 void wxPropertyListView::OnHelp(wxCommandEvent
& WXUNUSED(event
)) 
 747 void wxPropertyListView::OnCheck(wxCommandEvent
& WXUNUSED(event
)) 
 749   if (m_currentProperty
) 
 751     RetrieveProperty(m_currentProperty
); 
 755 void wxPropertyListView::OnCross(wxCommandEvent
& WXUNUSED(event
)) 
 757   if (m_currentProperty 
&& m_currentValidator
) 
 759     if (!m_currentValidator
->IsKindOf(CLASSINFO(wxPropertyListValidator
))) 
 762     wxPropertyListValidator 
*listValidator 
= (wxPropertyListValidator 
*)m_currentValidator
; 
 764     // Revert to old value 
 765     listValidator
->OnDisplayValue(m_currentProperty
, this, m_propertyWindow
); 
 769 void wxPropertyListView::OnPropertyDoubleClick(wxCommandEvent
& WXUNUSED(event
)) 
 771   if (m_currentProperty 
&& m_currentValidator
) 
 773     if (!m_currentValidator
->IsKindOf(CLASSINFO(wxPropertyListValidator
))) 
 776     wxPropertyListValidator 
*listValidator 
= (wxPropertyListValidator 
*)m_currentValidator
; 
 778     // Revert to old value 
 779     listValidator
->OnDoubleClick(m_currentProperty
, this, m_propertyWindow
); 
 783 void wxPropertyListView::OnEdit(wxCommandEvent
& WXUNUSED(event
)) 
 785   if (m_currentProperty 
&& m_currentValidator
) 
 787     if (!m_currentValidator
->IsKindOf(CLASSINFO(wxPropertyListValidator
))) 
 790     wxPropertyListValidator 
*listValidator 
= (wxPropertyListValidator 
*)m_currentValidator
; 
 792     listValidator
->OnEdit(m_currentProperty
, this, m_propertyWindow
); 
 796 void wxPropertyListView::OnText(wxCommandEvent
& event
) 
 798   if (event
.GetEventType() == wxEVT_COMMAND_TEXT_ENTER
) 
 805  * Property dialog box 
 808 IMPLEMENT_CLASS(wxPropertyListDialog
, wxDialog
) 
 810 BEGIN_EVENT_TABLE(wxPropertyListDialog
, wxDialog
) 
 811     EVT_BUTTON(wxID_CANCEL
,                wxPropertyListDialog::OnCancel
) 
 812     EVT_CLOSE(wxPropertyListDialog::OnCloseWindow
) 
 815 wxPropertyListDialog::wxPropertyListDialog(wxPropertyListView 
*v
, wxWindow 
*parent
, 
 816     const wxString
& title
, const wxPoint
& pos
, 
 817     const wxSize
& size
, long style
, const wxString
& name
): 
 818      wxDialog(parent
, -1, title
, pos
, size
, style
, name
) 
 821   m_view
->AssociatePanel( ((wxPanel
*)this) ); 
 822   m_view
->SetManagedWindow(this); 
 826 void wxPropertyListDialog::OnCloseWindow(wxCloseEvent
& event
) 
 830     SetReturnCode(wxID_CANCEL
); 
 841 void wxPropertyListDialog::OnCancel(wxCommandEvent
& WXUNUSED(event
)) 
 843     SetReturnCode(wxID_CANCEL
); 
 847 void wxPropertyListDialog::OnDefaultAction(wxControl 
*WXUNUSED(item
)) 
 850   if (item == m_view->GetPropertyScrollingList()) 
 851     view->OnDoubleClick(); 
 855 // Extend event processing to search the view's event table 
 856 bool wxPropertyListDialog::ProcessEvent(wxEvent
& event
) 
 858     if ( !m_view 
|| ! m_view
->ProcessEvent(event
) ) 
 859         return wxEvtHandler::ProcessEvent(event
); 
 868 IMPLEMENT_CLASS(wxPropertyListPanel
, wxPanel
) 
 870 BEGIN_EVENT_TABLE(wxPropertyListPanel
, wxPanel
) 
 871     EVT_SIZE(wxPropertyListPanel::OnSize
) 
 874 wxPropertyListPanel::~wxPropertyListPanel() 
 878 void wxPropertyListPanel::OnDefaultAction(wxControl 
*WXUNUSED(item
)) 
 881   if (item == view->GetPropertyScrollingList()) 
 882     view->OnDoubleClick(); 
 886 // Extend event processing to search the view's event table 
 887 bool wxPropertyListPanel::ProcessEvent(wxEvent
& event
) 
 889     if ( !m_view 
|| ! m_view
->ProcessEvent(event
) ) 
 890         return wxEvtHandler::ProcessEvent(event
); 
 895 void wxPropertyListPanel::OnSize(wxSizeEvent
& WXUNUSED(event
)) 
 904 IMPLEMENT_CLASS(wxPropertyListFrame
, wxFrame
) 
 906 BEGIN_EVENT_TABLE(wxPropertyListFrame
, wxFrame
) 
 907     EVT_CLOSE(wxPropertyListFrame::OnCloseWindow
) 
 910 void wxPropertyListFrame::OnCloseWindow(wxCloseEvent
& event
) 
 915         m_propertyPanel
->SetView(NULL
); 
 926 wxPropertyListPanel 
*wxPropertyListFrame::OnCreatePanel(wxFrame 
*parent
, wxPropertyListView 
*v
) 
 928   return new wxPropertyListPanel(v
, parent
); 
 931 bool wxPropertyListFrame::Initialize(void) 
 933   m_propertyPanel 
= OnCreatePanel(this, m_view
); 
 936     m_view
->AssociatePanel(m_propertyPanel
); 
 937     m_view
->SetManagedWindow(this); 
 938     m_propertyPanel
->SetAutoLayout(TRUE
); 
 946   * Property list specific validator 
 949 IMPLEMENT_ABSTRACT_CLASS(wxPropertyListValidator
, wxPropertyValidator
) 
 951 bool wxPropertyListValidator::OnSelect(bool select
, wxProperty 
*property
, wxPropertyListView 
*view
, wxWindow 
*parentWindow
) 
 953 //  view->GetValueText()->Show(TRUE); 
 955     OnDisplayValue(property
, view
, parentWindow
); 
 960 bool wxPropertyListValidator::OnValueListSelect(wxProperty 
*property
, wxPropertyListView 
*view
, wxWindow 
*WXUNUSED(parentWindow
)) 
 962   wxString 
s(view
->GetValueList()->GetStringSelection()); 
 965     view
->GetValueText()->SetValue(s
); 
 966     view
->RetrieveProperty(property
); 
 971 bool wxPropertyListValidator::OnDisplayValue(wxProperty 
*property
, wxPropertyListView 
*view
, wxWindow 
*WXUNUSED(parentWindow
)) 
 973 //  view->GetValueText()->Show(TRUE); 
 974   wxString 
str(property
->GetValue().GetStringRepresentation()); 
 976   view
->GetValueText()->SetValue(str
); 
 980 // Called when TICK is pressed or focus is lost or view wants to update 
 981 // the property list. 
 982 // Does the transferance from the property editing area to the property itself 
 983 bool wxPropertyListValidator::OnRetrieveValue(wxProperty 
*WXUNUSED(property
), wxPropertyListView 
*view
, wxWindow 
*WXUNUSED(parentWindow
)) 
 985   if (!view
->GetValueText()) 
 990 void wxPropertyListValidator::OnEdit(wxProperty 
*WXUNUSED(property
), wxPropertyListView 
*view
, wxWindow 
*WXUNUSED(parentWindow
)) 
 992   if (view
->GetDetailedEditing()) 
 993     view
->EndDetailedEditing(); 
 995     view
->BeginDetailedEditing(); 
 998 bool wxPropertyListValidator::OnClearControls(wxProperty 
*WXUNUSED(property
), wxPropertyListView 
*view
, wxWindow 
*WXUNUSED(parentWindow
)) 
1000   if (view
->GetConfirmButton()) 
1001     view
->GetConfirmButton()->Enable(FALSE
); 
1002   if (view
->GetCancelButton()) 
1003     view
->GetCancelButton()->Enable(FALSE
); 
1004   if (view
->GetEditButton()) 
1005     view
->GetEditButton()->Enable(FALSE
); 
1010  * Default validators 
1013 IMPLEMENT_DYNAMIC_CLASS(wxRealListValidator
, wxPropertyListValidator
) 
1016 /// Real number validator 
1018 bool wxRealListValidator::OnCheckValue(wxProperty 
*WXUNUSED(property
), wxPropertyListView 
*view
, wxWindow 
*parentWindow
) 
1020   if (m_realMin 
== 0.0 && m_realMax 
== 0.0) 
1023   if (!view
->GetValueText()) 
1025   wxString 
value(view
->GetValueText()->GetValue()); 
1028   if (!StringToFloat(WXSTRINGCAST value
, &val
)) 
1031     wxSprintf(buf
, _T("Value %s is not a valid real number!"), value
.GetData()); 
1032     wxMessageBox(buf
, _T("Property value error"), wxOK 
| wxICON_EXCLAMATION
, parentWindow
); 
1036   if (val 
< m_realMin 
|| val 
> m_realMax
) 
1039     sprintf(buf
, "Value must be a real number between %.2f and %.2f!", m_realMin
, m_realMax
); 
1040     wxMessageBox(buf
, "Property value error", wxOK 
| wxICON_EXCLAMATION
, parentWindow
); 
1046 // Called when TICK is pressed or focus is lost or view wants to update 
1047 // the property list. 
1048 // Does the transferance from the property editing area to the property itself 
1049 bool wxRealListValidator::OnRetrieveValue(wxProperty 
*property
, wxPropertyListView 
*view
, wxWindow 
*WXUNUSED(parentWindow
)) 
1051   if (!view
->GetValueText()) 
1054   if (wxStrlen(view
->GetValueText()->GetValue()) == 0) 
1057   wxString 
value(view
->GetValueText()->GetValue()); 
1058   float f 
= (float)wxAtof(value
.GetData()); 
1059   property
->GetValue() = f
; 
1063 bool wxRealListValidator::OnPrepareControls(wxProperty 
*WXUNUSED(property
), wxPropertyListView 
*view
, wxWindow 
*WXUNUSED(parentWindow
)) 
1065   if (view
->GetConfirmButton()) 
1066     view
->GetConfirmButton()->Enable(TRUE
); 
1067   if (view
->GetCancelButton()) 
1068     view
->GetCancelButton()->Enable(TRUE
); 
1069   if (view
->GetEditButton()) 
1070     view
->GetEditButton()->Enable(FALSE
); 
1071   if (view
->GetValueText()) 
1072     view
->GetValueText()->Enable(TRUE
); 
1077 /// Integer validator 
1079 IMPLEMENT_DYNAMIC_CLASS(wxIntegerListValidator
, wxPropertyListValidator
) 
1081 bool wxIntegerListValidator::OnCheckValue(wxProperty 
*WXUNUSED(property
), wxPropertyListView 
*view
, wxWindow 
*parentWindow
) 
1083   if (m_integerMin 
== 0 && m_integerMax 
== 0) 
1086   if (!view
->GetValueText()) 
1088   wxString 
value(view
->GetValueText()->GetValue()); 
1091   if (!StringToLong(WXSTRINGCAST value
, &val
)) 
1094     wxSprintf(buf
, _T("Value %s is not a valid integer!"), value
.GetData()); 
1095     wxMessageBox(buf
, _T("Property value error"), wxOK 
| wxICON_EXCLAMATION
, parentWindow
); 
1098   if (val 
< m_integerMin 
|| val 
> m_integerMax
) 
1101     wxSprintf(buf
, _T("Value must be an integer between %ld and %ld!"), m_integerMin
, m_integerMax
); 
1102     wxMessageBox(buf
, _T("Property value error"), wxOK 
| wxICON_EXCLAMATION
, parentWindow
); 
1108 // Called when TICK is pressed or focus is lost or view wants to update 
1109 // the property list. 
1110 // Does the transferance from the property editing area to the property itself 
1111 bool wxIntegerListValidator::OnRetrieveValue(wxProperty 
*property
, wxPropertyListView 
*view
, wxWindow 
*WXUNUSED(parentWindow
)) 
1113   if (!view
->GetValueText()) 
1116   if (wxStrlen(view
->GetValueText()->GetValue()) == 0) 
1119   wxString 
value(view
->GetValueText()->GetValue()); 
1120   long val 
= (long)wxAtoi(value
.GetData()); 
1121   property
->GetValue() = (long)val
; 
1125 bool wxIntegerListValidator::OnPrepareControls(wxProperty 
*WXUNUSED(property
), wxPropertyListView 
*view
, wxWindow 
*WXUNUSED(parentWindow
)) 
1127   if (view
->GetConfirmButton()) 
1128     view
->GetConfirmButton()->Enable(TRUE
); 
1129   if (view
->GetCancelButton()) 
1130     view
->GetCancelButton()->Enable(TRUE
); 
1131   if (view
->GetEditButton()) 
1132     view
->GetEditButton()->Enable(FALSE
); 
1133   if (view
->GetValueText()) 
1134     view
->GetValueText()->Enable(TRUE
); 
1139 /// boolean validator 
1141 IMPLEMENT_DYNAMIC_CLASS(wxBoolListValidator
, wxPropertyListValidator
) 
1143 bool wxBoolListValidator::OnCheckValue(wxProperty 
*WXUNUSED(property
), wxPropertyListView 
*view
, wxWindow 
*parentWindow
) 
1145   if (!view
->GetValueText()) 
1147   wxString 
value(view
->GetValueText()->GetValue()); 
1148   if (value 
!= _T("True") && value 
!= _T("False")) 
1150     wxMessageBox(_T("Value must be True or False!"), _T("Property value error"), wxOK 
| wxICON_EXCLAMATION
, parentWindow
); 
1156 // Called when TICK is pressed or focus is lost or view wants to update 
1157 // the property list. 
1158 // Does the transferance from the property editing area to the property itself 
1159 bool wxBoolListValidator::OnRetrieveValue(wxProperty 
*property
, wxPropertyListView 
*view
, wxWindow 
*WXUNUSED(parentWindow
)) 
1161   if (!view
->GetValueText()) 
1164   if (wxStrlen(view
->GetValueText()->GetValue()) == 0) 
1167   wxString 
value(view
->GetValueText()->GetValue()); 
1168   bool boolValue 
= FALSE
; 
1169   if (value 
== _T("True")) 
1173   property
->GetValue() = (bool)boolValue
; 
1177 bool wxBoolListValidator::OnDisplayValue(wxProperty 
*property
, wxPropertyListView 
*view
, wxWindow 
*WXUNUSED(parentWindow
)) 
1179   if (!view
->GetValueText()) 
1181   wxString 
str(property
->GetValue().GetStringRepresentation()); 
1183   view
->GetValueText()->SetValue(str
); 
1185   if (view
->GetValueList()->IsShown()) 
1187     view
->GetValueList()->SetStringSelection(str
); 
1192 bool wxBoolListValidator::OnPrepareControls(wxProperty 
*WXUNUSED(property
), wxPropertyListView 
*view
, wxWindow 
*WXUNUSED(parentWindow
)) 
1194   if (view
->GetConfirmButton()) 
1195     view
->GetConfirmButton()->Enable(FALSE
); 
1196   if (view
->GetCancelButton()) 
1197     view
->GetCancelButton()->Enable(FALSE
); 
1198   if (view
->GetEditButton()) 
1199     view
->GetEditButton()->Enable(TRUE
); 
1200   if (view
->GetValueText()) 
1201     view
->GetValueText()->Enable(FALSE
); 
1205 bool wxBoolListValidator::OnPrepareDetailControls(wxProperty 
*WXUNUSED(property
), wxPropertyListView 
*view
, wxWindow 
*WXUNUSED(parentWindow
)) 
1207   if (view
->GetValueList()) 
1209     view
->ShowListBoxControl(TRUE
); 
1210     view
->GetValueList()->Enable(TRUE
); 
1212     view
->GetValueList()->Append(_T("True")); 
1213     view
->GetValueList()->Append(_T("False")); 
1214     wxChar 
*currentString 
= copystring(view
->GetValueText()->GetValue()); 
1215     view
->GetValueList()->SetStringSelection(currentString
); 
1216     delete[] currentString
; 
1221 bool wxBoolListValidator::OnClearDetailControls(wxProperty 
*WXUNUSED(property
), wxPropertyListView 
*view
, wxWindow 
*WXUNUSED(parentWindow
)) 
1223   if (view
->GetValueList()) 
1225     view
->GetValueList()->Clear(); 
1226     view
->ShowListBoxControl(FALSE
); 
1227     view
->GetValueList()->Enable(FALSE
); 
1232 // Called when the property is double clicked. Extra functionality can be provided, 
1233 // cycling through possible values. 
1234 bool wxBoolListValidator::OnDoubleClick(wxProperty 
*property
, wxPropertyListView 
*view
, wxWindow 
*WXUNUSED(parentWindow
)) 
1236   if (!view
->GetValueText()) 
1238   if (property
->GetValue().BoolValue()) 
1239     property
->GetValue() = (bool)FALSE
; 
1241     property
->GetValue() = (bool)TRUE
; 
1242   view
->DisplayProperty(property
); 
1243   view
->UpdatePropertyDisplayInList(property
); 
1244   view
->OnPropertyChanged(property
); 
1249 /// String validator 
1251 IMPLEMENT_DYNAMIC_CLASS(wxStringListValidator
, wxPropertyListValidator
) 
1253 wxStringListValidator::wxStringListValidator(wxStringList 
*list
, long flags
): 
1254   wxPropertyListValidator(flags
) 
1257   // If no constraint, we just allow the string to be edited. 
1258   if (!m_strings 
&& ((m_validatorFlags 
& wxPROP_ALLOW_TEXT_EDITING
) == 0)) 
1259     m_validatorFlags 
|= wxPROP_ALLOW_TEXT_EDITING
; 
1262 bool wxStringListValidator::OnCheckValue(wxProperty 
*WXUNUSED(property
), wxPropertyListView 
*view
, wxWindow 
*parentWindow
) 
1267   if (!view
->GetValueText()) 
1269   wxString 
value(view
->GetValueText()->GetValue()); 
1271   if (!m_strings
->Member(value
.GetData())) 
1273     wxString 
s("Value "); 
1274     s 
+= value
.GetData(); 
1275     s 
+= " is not valid."; 
1276     wxMessageBox(s
.GetData(), "Property value error", wxOK 
| wxICON_EXCLAMATION
, parentWindow
); 
1282 // Called when TICK is pressed or focus is lost or view wants to update 
1283 // the property list. 
1284 // Does the transferance from the property editing area to the property itself 
1285 bool wxStringListValidator::OnRetrieveValue(wxProperty 
*property
, wxPropertyListView 
*view
, wxWindow 
*WXUNUSED(parentWindow
)) 
1287   if (!view
->GetValueText()) 
1289   wxString 
value(view
->GetValueText()->GetValue()); 
1290   property
->GetValue() = value 
; 
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 
1297 bool wxStringListValidator::OnDisplayValue(wxProperty 
*property
, wxPropertyListView 
*view
, wxWindow 
*WXUNUSED(parentWindow
)) 
1299   if (!view
->GetValueText()) 
1301   wxString 
str(property
->GetValue().GetStringRepresentation()); 
1302   view
->GetValueText()->SetValue(str
); 
1303   if (m_strings 
&& view
->GetValueList() && view
->GetValueList()->IsShown() && view
->GetValueList()->Number() > 0) 
1305     view
->GetValueList()->SetStringSelection(str
); 
1310 bool wxStringListValidator::OnPrepareControls(wxProperty 
*WXUNUSED(property
), wxPropertyListView 
*view
, wxWindow 
*WXUNUSED(parentWindow
)) 
1315     if (view
->GetEditButton()) 
1316       view
->GetEditButton()->Enable(FALSE
); 
1317     if (view
->GetConfirmButton()) 
1318       view
->GetConfirmButton()->Enable(TRUE
); 
1319     if (view
->GetCancelButton()) 
1320       view
->GetCancelButton()->Enable(TRUE
); 
1321     if (view
->GetValueText()) 
1322       view
->GetValueText()->Enable(TRUE
); 
1327   if (view
->GetValueText()) 
1328     view
->GetValueText()->Enable(FALSE
); 
1330   if (view
->GetEditButton()) 
1331     view
->GetEditButton()->Enable(TRUE
); 
1333   if (view
->GetConfirmButton()) 
1334     view
->GetConfirmButton()->Enable(FALSE
); 
1335   if (view
->GetCancelButton()) 
1336     view
->GetCancelButton()->Enable(FALSE
); 
1340 bool wxStringListValidator::OnPrepareDetailControls(wxProperty 
*property
, wxPropertyListView 
*view
, wxWindow 
*WXUNUSED(parentWindow
)) 
1342   if (view
->GetValueList()) 
1344     view
->ShowListBoxControl(TRUE
); 
1345     view
->GetValueList()->Enable(TRUE
); 
1346     wxNode 
*node 
= m_strings
->First(); 
1349       wxChar 
*s 
= (wxChar 
*)node
->Data(); 
1350       view
->GetValueList()->Append(s
); 
1351       node 
= node
->Next(); 
1353     wxChar 
*currentString 
= property
->GetValue().StringValue(); 
1354     view
->GetValueList()->SetStringSelection(currentString
); 
1359 bool wxStringListValidator::OnClearDetailControls(wxProperty 
*WXUNUSED(property
), wxPropertyListView 
*view
, wxWindow 
*WXUNUSED(parentWindow
)) 
1366   if (view
->GetValueList()) 
1368     view
->GetValueList()->Clear(); 
1369     view
->ShowListBoxControl(FALSE
); 
1370     view
->GetValueList()->Enable(FALSE
); 
1375 // Called when the property is double clicked. Extra functionality can be provided, 
1376 // cycling through possible values. 
1377 bool wxStringListValidator::OnDoubleClick(wxProperty 
*property
, wxPropertyListView 
*view
, wxWindow 
*WXUNUSED(parentWindow
)) 
1379   if (!view
->GetValueText()) 
1384   wxNode 
*node 
= m_strings
->First(); 
1385   wxChar 
*currentString 
= property
->GetValue().StringValue(); 
1388     wxChar 
*s 
= (wxChar 
*)node
->Data(); 
1389     if (wxStrcmp(s
, currentString
) == 0) 
1391       wxChar 
*nextString 
= NULL
; 
1393         nextString 
= (wxChar 
*)node
->Next()->Data(); 
1395         nextString 
= (wxChar 
*)m_strings
->First()->Data(); 
1396       property
->GetValue() = wxString(nextString
); 
1397       view
->DisplayProperty(property
); 
1398       view
->UpdatePropertyDisplayInList(property
); 
1399       view
->OnPropertyChanged(property
); 
1402     else node 
= node
->Next(); 
1408 /// Filename validator 
1410 IMPLEMENT_DYNAMIC_CLASS(wxFilenameListValidator
, wxPropertyListValidator
) 
1412 wxFilenameListValidator::wxFilenameListValidator(wxString message 
, wxString wildcard
, long flags
): 
1413   wxPropertyListValidator(flags
), m_filenameWildCard(wildcard
), m_filenameMessage(message
) 
1417 wxFilenameListValidator::~wxFilenameListValidator(void) 
1421 bool wxFilenameListValidator::OnCheckValue(wxProperty 
*WXUNUSED(property
), wxPropertyListView 
*WXUNUSED(view
), wxWindow 
*WXUNUSED(parentWindow
)) 
1426 // Called when TICK is pressed or focus is lost or view wants to update 
1427 // the property list. 
1428 // Does the transferance from the property editing area to the property itself 
1429 bool wxFilenameListValidator::OnRetrieveValue(wxProperty 
*property
, wxPropertyListView 
*view
, wxWindow 
*WXUNUSED(parentWindow
)) 
1431   if (!view
->GetValueText()) 
1433   wxString 
value(view
->GetValueText()->GetValue()); 
1434   property
->GetValue() = value 
; 
1438 // Called when TICK is pressed or focus is lost or view wants to update 
1439 // the property list. 
1440 // Does the transferance from the property editing area to the property itself 
1441 bool wxFilenameListValidator::OnDisplayValue(wxProperty 
*property
, wxPropertyListView 
*view
, wxWindow 
*WXUNUSED(parentWindow
)) 
1443   if (!view
->GetValueText()) 
1445   wxString 
str(property
->GetValue().GetStringRepresentation()); 
1446   view
->GetValueText()->SetValue(str
); 
1450 // Called when the property is double clicked. Extra functionality can be provided, 
1451 // cycling through possible values. 
1452 bool wxFilenameListValidator::OnDoubleClick(wxProperty 
*property
, wxPropertyListView 
*view
, wxWindow 
*parentWindow
) 
1454   if (!view
->GetValueText()) 
1456   OnEdit(property
, view
, parentWindow
); 
1460 bool wxFilenameListValidator::OnPrepareControls(wxProperty 
*WXUNUSED(property
), wxPropertyListView 
*view
, wxWindow 
*WXUNUSED(parentWindow
)) 
1462   if (view
->GetConfirmButton()) 
1463     view
->GetConfirmButton()->Enable(TRUE
); 
1464   if (view
->GetCancelButton()) 
1465     view
->GetCancelButton()->Enable(TRUE
); 
1466   if (view
->GetEditButton()) 
1467     view
->GetEditButton()->Enable(TRUE
); 
1468   if (view
->GetValueText()) 
1469     view
->GetValueText()->Enable((GetFlags() & wxPROP_ALLOW_TEXT_EDITING
) == wxPROP_ALLOW_TEXT_EDITING
); 
1473 void wxFilenameListValidator::OnEdit(wxProperty 
*property
, wxPropertyListView 
*view
, wxWindow 
*parentWindow
) 
1475   if (!view
->GetValueText()) 
1478   wxString s 
= wxFileSelector( 
1479      m_filenameMessage
.GetData(), 
1480      wxPathOnly(property
->GetValue().StringValue()), 
1481      wxFileNameFromPath(property
->GetValue().StringValue()), 
1483      m_filenameWildCard
.GetData(), 
1488     property
->GetValue() = s
; 
1489     view
->DisplayProperty(property
); 
1490     view
->UpdatePropertyDisplayInList(property
); 
1491     view
->OnPropertyChanged(property
); 
1496 /// Colour validator 
1498 IMPLEMENT_DYNAMIC_CLASS(wxColourListValidator
, wxPropertyListValidator
) 
1500 wxColourListValidator::wxColourListValidator(long flags
): 
1501   wxPropertyListValidator(flags
) 
1505 wxColourListValidator::~wxColourListValidator(void) 
1509 bool wxColourListValidator::OnCheckValue(wxProperty 
*WXUNUSED(property
), wxPropertyListView 
*WXUNUSED(view
), wxWindow 
*WXUNUSED(parentWindow
)) 
1514 // Called when TICK is pressed or focus is lost or view wants to update 
1515 // the property list. 
1516 // Does the transferance from the property editing area to the property itself 
1517 bool wxColourListValidator::OnRetrieveValue(wxProperty 
*property
, wxPropertyListView 
*view
, wxWindow 
*WXUNUSED(parentWindow
)) 
1519   if (!view
->GetValueText()) 
1521   wxString 
value(view
->GetValueText()->GetValue()); 
1523   property
->GetValue() = value 
; 
1527 // Called when TICK is pressed or focus is lost or view wants to update 
1528 // the property list. 
1529 // Does the transferance from the property editing area to the property itself 
1530 bool wxColourListValidator::OnDisplayValue(wxProperty 
*property
, wxPropertyListView 
*view
, wxWindow 
*WXUNUSED(parentWindow
)) 
1532   if (!view
->GetValueText()) 
1534   wxString 
str(property
->GetValue().GetStringRepresentation()); 
1535   view
->GetValueText()->SetValue(str
); 
1539 // Called when the property is double clicked. Extra functionality can be provided, 
1540 // cycling through possible values. 
1541 bool wxColourListValidator::OnDoubleClick(wxProperty 
*property
, wxPropertyListView 
*view
, wxWindow 
*parentWindow
) 
1543   if (!view
->GetValueText()) 
1545   OnEdit(property
, view
, parentWindow
); 
1549 bool wxColourListValidator::OnPrepareControls(wxProperty 
*WXUNUSED(property
), wxPropertyListView 
*view
, wxWindow 
*WXUNUSED(parentWindow
)) 
1551   if (view
->GetConfirmButton()) 
1552     view
->GetConfirmButton()->Enable(TRUE
); 
1553   if (view
->GetCancelButton()) 
1554     view
->GetCancelButton()->Enable(TRUE
); 
1555   if (view
->GetEditButton()) 
1556     view
->GetEditButton()->Enable(TRUE
); 
1557   if (view
->GetValueText()) 
1558     view
->GetValueText()->Enable((GetFlags() & wxPROP_ALLOW_TEXT_EDITING
) == wxPROP_ALLOW_TEXT_EDITING
); 
1562 void wxColourListValidator::OnEdit(wxProperty 
*property
, wxPropertyListView 
*view
, wxWindow 
*parentWindow
) 
1564   if (!view
->GetValueText()) 
1567   wxChar 
*s 
= property
->GetValue().StringValue(); 
1574     g 
= wxHexToDec(s
+2); 
1575     b 
= wxHexToDec(s
+4); 
1578   wxColour 
col(r
,g
,b
); 
1581   data
.SetChooseFull(TRUE
); 
1582   data
.SetColour(col
); 
1584   for (int i 
= 0; i 
< 16; i
++) 
1586     wxColour 
colour(i
*16, i
*16, i
*16); 
1587     data
.SetCustomColour(i
, colour
); 
1590   wxColourDialog 
dialog(parentWindow
, &data
); 
1591   if (dialog
.ShowModal() != wxID_CANCEL
) 
1593     wxColourData retData 
= dialog
.GetColourData(); 
1594     col 
= retData
.GetColour(); 
1597     wxDecToHex(col
.Red(), buf
); 
1598     wxDecToHex(col
.Green(), buf
+2); 
1599     wxDecToHex(col
.Blue(), buf
+4); 
1601     property
->GetValue() = wxString(buf
); 
1602     view
->DisplayProperty(property
); 
1603     view
->UpdatePropertyDisplayInList(property
); 
1604     view
->OnPropertyChanged(property
); 
1609 /// List of strings validator. For this we need more user interface than 
1610 /// we get with a property list; so create a new dialog for editing the list. 
1612 IMPLEMENT_DYNAMIC_CLASS(wxListOfStringsListValidator
, wxPropertyListValidator
) 
1614 wxListOfStringsListValidator::wxListOfStringsListValidator(long flags
): 
1615   wxPropertyListValidator(flags
) 
1619 bool wxListOfStringsListValidator::OnCheckValue(wxProperty 
*WXUNUSED(property
), wxPropertyListView 
*WXUNUSED(view
), wxWindow 
*WXUNUSED(parentWindow
)) 
1621   // No constraints for an arbitrary, user-editable list of strings. 
1625 // Called when TICK is pressed or focus is lost or view wants to update 
1626 // the property list. 
1627 // Does the transferance from the property editing area to the property itself. 
1628 // In this case, the user cannot directly edit the string list. 
1629 bool wxListOfStringsListValidator::OnRetrieveValue(wxProperty 
*WXUNUSED(property
), wxPropertyListView 
*WXUNUSED(view
), wxWindow 
*WXUNUSED(parentWindow
)) 
1634 bool wxListOfStringsListValidator::OnDisplayValue(wxProperty 
*property
, wxPropertyListView 
*view
, wxWindow 
*WXUNUSED(parentWindow
)) 
1636   if (!view
->GetValueText()) 
1638   wxString 
str(property
->GetValue().GetStringRepresentation()); 
1639   view
->GetValueText()->SetValue(str
); 
1643 bool wxListOfStringsListValidator::OnPrepareControls(wxProperty 
*WXUNUSED(property
), wxPropertyListView 
*view
, wxWindow 
*WXUNUSED(parentWindow
)) 
1645   if (view
->GetEditButton()) 
1646     view
->GetEditButton()->Enable(TRUE
); 
1647   if (view
->GetValueText()) 
1648     view
->GetValueText()->Enable(FALSE
); 
1650   if (view
->GetConfirmButton()) 
1651     view
->GetConfirmButton()->Enable(FALSE
); 
1652   if (view
->GetCancelButton()) 
1653     view
->GetCancelButton()->Enable(FALSE
); 
1657 // Called when the property is double clicked. Extra functionality can be provided, 
1658 // cycling through possible values. 
1659 bool wxListOfStringsListValidator::OnDoubleClick(wxProperty 
*property
, wxPropertyListView 
*view
, wxWindow 
*parentWindow
) 
1661   OnEdit(property
, view
, parentWindow
); 
1665 void wxListOfStringsListValidator::OnEdit(wxProperty 
*property
, wxPropertyListView 
*view
, wxWindow 
*parentWindow
) 
1667   // Convert property value to a list of strings for editing 
1668   wxStringList 
*stringList 
= new wxStringList
; 
1670   wxPropertyValue 
*expr 
= property
->GetValue().GetFirst(); 
1673     wxChar 
*s 
= expr
->StringValue(); 
1676     expr 
= expr
->GetNext(); 
1679   wxString 
title(_T("Editing ")); 
1680   title 
+= property
->GetName(); 
1682   if (EditStringList(parentWindow
, stringList
, title
.GetData())) 
1684     wxPropertyValue
& oldValue 
= property
->GetValue(); 
1685     oldValue
.ClearList(); 
1686     wxNode 
*node 
= stringList
->First(); 
1689       wxChar 
*s 
= (wxChar 
*)node
->Data(); 
1690       oldValue
.Append(new wxPropertyValue(s
)); 
1692       node 
= node
->Next(); 
1695     view
->DisplayProperty(property
); 
1696     view
->UpdatePropertyDisplayInList(property
); 
1697     view
->OnPropertyChanged(property
); 
1702 class wxPropertyStringListEditorDialog
: public wxDialog
 
1705     wxPropertyStringListEditorDialog(wxWindow 
*parent
, const wxString
& title
, 
1706         const wxPoint
& pos 
= wxDefaultPosition
, const wxSize
& size 
= wxDefaultSize
, 
1707           long windowStyle 
= wxDEFAULT_DIALOG_STYLE
, const wxString
& name 
= "stringEditorDialogBox"): 
1708                wxDialog(parent
, -1, title
, pos
, size
, windowStyle
, name
) 
1710       m_stringList 
= NULL
; 
1711       m_stringText 
= NULL
; 
1713       sm_dialogCancelled 
= FALSE
; 
1714       m_currentSelection 
= -1; 
1716     ~wxPropertyStringListEditorDialog(void) {} 
1717     void OnCloseWindow(wxCloseEvent
& event
); 
1718     void SaveCurrentSelection(void); 
1719     void ShowCurrentSelection(void); 
1721     void OnOK(wxCommandEvent
& event
); 
1722     void OnCancel(wxCommandEvent
& event
); 
1723     void OnAdd(wxCommandEvent
& event
); 
1724     void OnDelete(wxCommandEvent
& event
); 
1725     void OnStrings(wxCommandEvent
& event
); 
1726     void OnText(wxCommandEvent
& event
); 
1729     wxStringList
*       m_stringList
; 
1730     wxListBox
*          m_listBox
; 
1731     wxTextCtrl
*         m_stringText
; 
1732     static bool         sm_dialogCancelled
; 
1733     int                 m_currentSelection
; 
1734 DECLARE_EVENT_TABLE() 
1737 #define    wxID_PROP_SL_ADD            3000 
1738 #define    wxID_PROP_SL_DELETE            3001 
1739 #define    wxID_PROP_SL_STRINGS        3002 
1740 #define    wxID_PROP_SL_TEXT            3003 
1742 BEGIN_EVENT_TABLE(wxPropertyStringListEditorDialog
, wxDialog
) 
1743     EVT_BUTTON(wxID_OK
,                 wxPropertyStringListEditorDialog::OnOK
) 
1744     EVT_BUTTON(wxID_CANCEL
,                wxPropertyStringListEditorDialog::OnCancel
) 
1745     EVT_BUTTON(wxID_PROP_SL_ADD
,        wxPropertyStringListEditorDialog::OnAdd
) 
1746     EVT_BUTTON(wxID_PROP_SL_DELETE
,        wxPropertyStringListEditorDialog::OnDelete
) 
1747     EVT_LISTBOX(wxID_PROP_SL_STRINGS
,    wxPropertyStringListEditorDialog::OnStrings
) 
1748     EVT_TEXT_ENTER(wxID_PROP_SL_TEXT
,            wxPropertyStringListEditorDialog::OnText
) 
1749     EVT_CLOSE(wxPropertyStringListEditorDialog::OnCloseWindow
) 
1752 class wxPropertyStringListEditorText
: public wxTextCtrl
 
1755   wxPropertyStringListEditorText(wxWindow 
*parent
, wxWindowID id
, const wxString
& val
, 
1756       const wxPoint
& pos 
= wxDefaultPosition
, const wxSize
& size 
= wxDefaultSize
, 
1757     long windowStyle 
= 0, const wxString
& name 
= "text"): 
1758      wxTextCtrl(parent
, id
, val
, pos
, size
, windowStyle
, wxDefaultValidator
, name
) 
1761   void OnKillFocus(void) 
1763     wxPropertyStringListEditorDialog 
*dialog 
= (wxPropertyStringListEditorDialog 
*)GetParent(); 
1764     dialog
->SaveCurrentSelection(); 
1768 bool wxPropertyStringListEditorDialog::sm_dialogCancelled 
= FALSE
; 
1770 // Edit the string list. 
1771 bool wxListOfStringsListValidator::EditStringList(wxWindow 
*parent
, wxStringList 
*stringList
, const wxChar 
*title
) 
1773   int largeButtonWidth 
= 60; 
1774   int largeButtonHeight 
= 25; 
1776   wxBeginBusyCursor(); 
1777   wxPropertyStringListEditorDialog 
*dialog 
= new wxPropertyStringListEditorDialog(parent
, 
1778       title
, wxPoint(10, 10), wxSize(400, 400), wxDEFAULT_DIALOG_STYLE
|wxDIALOG_MODAL
); 
1780   dialog
->m_stringList 
= stringList
; 
1782   dialog
->m_listBox 
= new wxListBox(dialog
, wxID_PROP_SL_STRINGS
, 
1783     wxPoint(-1, -1), wxSize(-1, -1), 0, NULL
, wxLB_SINGLE
); 
1785   dialog
->m_stringText 
= new wxPropertyStringListEditorText(dialog
, 
1786   wxID_PROP_SL_TEXT
, "", wxPoint(5, 240), 
1787        wxSize(300, -1), wxPROCESS_ENTER
); 
1788   dialog
->m_stringText
->Enable(FALSE
); 
1790   wxButton 
*addButton 
= new wxButton(dialog
, wxID_PROP_SL_ADD
, "Add", wxPoint(-1, -1), wxSize(largeButtonWidth
, largeButtonHeight
)); 
1791   wxButton 
*deleteButton 
= new wxButton(dialog
, wxID_PROP_SL_DELETE
, "Delete", wxPoint(-1, -1), wxSize(largeButtonWidth
, largeButtonHeight
)); 
1792   wxButton 
*cancelButton 
= new wxButton(dialog
, wxID_CANCEL
, "Cancel", wxPoint(-1, -1), wxSize(largeButtonWidth
, largeButtonHeight
)); 
1793   wxButton 
*okButton 
= new wxButton(dialog
, wxID_OK
, "OK", wxPoint(-1, -1), wxSize(largeButtonWidth
, largeButtonHeight
)); 
1795   okButton
->SetDefault(); 
1797   wxLayoutConstraints 
*c 
= new wxLayoutConstraints
; 
1799   c
->top
.SameAs     (dialog
, wxTop
, 2); 
1800   c
->left
.SameAs    (dialog
, wxLeft
, 2); 
1801   c
->right
.SameAs   (dialog
, wxRight
, 2); 
1802   c
->bottom
.SameAs  (dialog
->m_stringText
, wxTop
, 2); 
1803   dialog
->m_listBox
->SetConstraints(c
); 
1805   c 
= new wxLayoutConstraints
; 
1806   c
->left
.SameAs    (dialog
, wxLeft
, 2); 
1807   c
->right
.SameAs   (dialog
, wxRight
, 2); 
1808   c
->bottom
.SameAs  (addButton
, wxTop
, 2); 
1810   dialog
->m_stringText
->SetConstraints(c
); 
1812   c 
= new wxLayoutConstraints
; 
1813   c
->bottom
.SameAs  (dialog
, wxBottom
, 2); 
1814   c
->left
.SameAs    (dialog
, wxLeft
, 2); 
1817   addButton
->SetConstraints(c
); 
1819   c 
= new wxLayoutConstraints
; 
1820   c
->bottom
.SameAs  (dialog
, wxBottom
, 2); 
1821   c
->left
.SameAs    (addButton
, wxRight
, 2); 
1824   deleteButton
->SetConstraints(c
); 
1826   c 
= new wxLayoutConstraints
; 
1827   c
->bottom
.SameAs  (dialog
, wxBottom
, 2); 
1828   c
->right
.SameAs   (dialog
, wxRight
, 2); 
1831   cancelButton
->SetConstraints(c
); 
1833   c 
= new wxLayoutConstraints
; 
1834   c
->bottom
.SameAs  (dialog
, wxBottom
, 2); 
1835   c
->right
.SameAs   (cancelButton
, wxLeft
, 2); 
1838   okButton
->SetConstraints(c
); 
1840   wxNode 
*node 
= stringList
->First(); 
1843     char *str 
= (char *)node
->Data(); 
1844     // Save node as client data for each listbox item 
1845     dialog
->m_listBox
->Append(str
, (char *)node
); 
1846     node 
= node
->Next(); 
1849   dialog
->SetClientSize(310, 305); 
1852   dialog
->Centre(wxBOTH
); 
1854   if (dialog
->ShowModal() == wxID_CANCEL
) 
1861  * String list editor callbacks 
1865 void wxPropertyStringListEditorDialog::OnStrings(wxCommandEvent
& WXUNUSED(event
)) 
1867   int sel 
= m_listBox
->GetSelection(); 
1870     m_currentSelection 
= sel
; 
1872     ShowCurrentSelection(); 
1876 void wxPropertyStringListEditorDialog::OnDelete(wxCommandEvent
& WXUNUSED(event
)) 
1878   int sel 
= m_listBox
->GetSelection(); 
1882   wxNode 
*node 
= (wxNode 
*)m_listBox
->wxListBox::GetClientData(sel
); 
1886   m_listBox
->Delete(sel
); 
1887   delete[] (wxChar 
*)node
->Data(); 
1889   m_currentSelection 
= -1; 
1890   m_stringText
->SetValue(""); 
1893 void wxPropertyStringListEditorDialog::OnAdd(wxCommandEvent
& WXUNUSED(event
)) 
1895   SaveCurrentSelection(); 
1897   wxChar 
*initialText 
= _T(""); 
1898   wxNode 
*node 
= m_stringList
->Add(initialText
); 
1899   m_listBox
->Append(initialText
, (void *)node
); 
1900   m_currentSelection 
= m_stringList
->Number() - 1; 
1901   m_listBox
->SetSelection(m_currentSelection
); 
1902   ShowCurrentSelection(); 
1903   m_stringText
->SetFocus(); 
1906 void wxPropertyStringListEditorDialog::OnOK(wxCommandEvent
& WXUNUSED(event
)) 
1908   SaveCurrentSelection(); 
1914 void wxPropertyStringListEditorDialog::OnCancel(wxCommandEvent
& WXUNUSED(event
)) 
1916   sm_dialogCancelled 
= TRUE
; 
1917   EndModal(wxID_CANCEL
); 
1922 void wxPropertyStringListEditorDialog::OnText(wxCommandEvent
& event
) 
1924   if (event
.GetEventType() == wxEVT_COMMAND_TEXT_ENTER
) 
1926     SaveCurrentSelection(); 
1930 void wxPropertyStringListEditorDialog::OnCloseWindow(wxCloseEvent
& event
) 
1932   SaveCurrentSelection(); 
1936 void wxPropertyStringListEditorDialog::SaveCurrentSelection(void) 
1938   if (m_currentSelection 
== -1) 
1941   wxNode 
*node 
= (wxNode 
*)m_listBox
->wxListBox::GetClientData(m_currentSelection
); 
1945   wxString 
txt(m_stringText
->GetValue()); 
1947     delete[] (char *)node
->Data(); 
1948   node
->SetData((wxObject 
*)copystring(txt
)); 
1950   m_listBox
->SetString(m_currentSelection
, (char *)node
->Data()); 
1953 void wxPropertyStringListEditorDialog::ShowCurrentSelection(void) 
1955   if (m_currentSelection 
== -1) 
1957     m_stringText
->SetValue(""); 
1960   wxNode 
*node 
= (wxNode 
*)m_listBox
->wxListBox::GetClientData(m_currentSelection
); 
1961   char *txt 
= (char *)node
->Data(); 
1962   m_stringText
->SetValue(txt
); 
1963   m_stringText
->Enable(TRUE
);