home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / src / generic / proplist.cpp < prev    next >
C/C++ Source or Header  |  2002-11-04  |  56KB  |  1,831 lines

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