///////////////////////////////////////////////////////////////////////////// // Name: proplist.cpp // Purpose: Property list classes // Author: Julian Smart // Modified by: // Created: 04/01/98 // RCS-ID: $Id$ // Copyright: (c) Julian Smart // Licence: wxWindows license ///////////////////////////////////////////////////////////////////////////// #ifdef __GNUG__ #pragma implementation "proplist.h" #endif // For compilers that support precompilation, includes "wx/wx.h". #include "wx/wxprec.h" #ifdef __BORLANDC__ #pragma hdrstop #endif #ifndef WX_PRECOMP #include "wx/wx.h" #endif #include #include #include #include #if defined(__WXMSW__) && !defined(__GNUWIN32__) #include #else #include #endif #include "wx/window.h" #include "wx/utils.h" #include "wx/list.h" #include "wx/colordlg.h" #include "proplist.h" /* * Property text edit control */ IMPLEMENT_CLASS(wxPropertyTextEdit, wxTextCtrl) wxPropertyTextEdit::wxPropertyTextEdit(wxPropertyListView *v, wxWindow *parent, const wxWindowID id, const wxString& value, const wxPoint& pos, const wxSize& size, long style, const wxString& name): wxTextCtrl(parent, id, value, pos, size, style, wxDefaultValidator, name) { view = v; } void wxPropertyTextEdit::OnSetFocus(void) { } void wxPropertyTextEdit::OnKillFocus(void) { } /* * Property list view */ IMPLEMENT_DYNAMIC_CLASS(wxPropertyListView, wxPropertyView) BEGIN_EVENT_TABLE(wxPropertyListView, wxPropertyView) EVT_BUTTON(wxID_OK, wxPropertyListView::OnOk) EVT_BUTTON(wxID_CANCEL, wxPropertyListView::OnCancel) EVT_BUTTON(wxID_HELP, wxPropertyListView::OnHelp) EVT_BUTTON(wxID_PROP_CROSS, wxPropertyListView::OnCross) EVT_BUTTON(wxID_PROP_CHECK, wxPropertyListView::OnCheck) EVT_BUTTON(wxID_PROP_EDIT, wxPropertyListView::OnEdit) EVT_TEXT_ENTER(wxID_PROP_TEXT, wxPropertyListView::OnText) EVT_LISTBOX(wxID_PROP_SELECT, wxPropertyListView::OnPropertySelect) EVT_COMMAND(wxID_PROP_SELECT, wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, wxPropertyListView::OnPropertyDoubleClick) EVT_TEXT(wxID_PROP_VALUE_SELECT, wxPropertyListView::OnValueListSelect) END_EVENT_TABLE() bool wxPropertyListView::dialogCancelled = FALSE; wxBitmap *wxPropertyListView::tickBitmap = NULL; wxBitmap *wxPropertyListView::crossBitmap = NULL; wxPropertyListView::wxPropertyListView(wxPanel *propPanel, long flags):wxPropertyView(flags) { propertyScrollingList = NULL; valueList = NULL; valueText = NULL; editButton = NULL; confirmButton = NULL; cancelButton = NULL; propertyWindow = propPanel; managedWindow = NULL; windowCloseButton = NULL; windowCancelButton = NULL; windowHelpButton = NULL; detailedEditing = FALSE; } wxPropertyListView::~wxPropertyListView(void) { /* if (tickBitmap) delete tickBitmap; if (crossBitmap) delete crossBitmap; */ } void wxPropertyListView::ShowView(wxPropertySheet *ps, wxPanel *panel) { propertySheet = ps; AssociatePanel(panel); CreateControls(); UpdatePropertyList(); panel->Layout(); } // Update this view of the viewed object, called e.g. by // the object itself. bool wxPropertyListView::OnUpdateView(void) { return TRUE; } bool wxPropertyListView::UpdatePropertyList(bool clearEditArea) { if (!propertyScrollingList || !propertySheet) return FALSE; propertyScrollingList->Clear(); if (clearEditArea) { valueList->Clear(); valueText->SetValue(""); } wxNode *node = propertySheet->GetProperties().First(); // Should sort them... later... while (node) { wxProperty *property = (wxProperty *)node->Data(); wxString stringValueRepr(property->GetValue().GetStringRepresentation()); wxString paddedString(MakeNameValueString(property->GetName(), stringValueRepr)); propertyScrollingList->Append(paddedString.GetData(), (char *)property); node = node->Next(); } return TRUE; } bool wxPropertyListView::UpdatePropertyDisplayInList(wxProperty *property) { if (!propertyScrollingList || !propertySheet) return FALSE; int currentlySelected = propertyScrollingList->GetSelection(); // #ifdef __WXMSW__ wxString stringValueRepr(property->GetValue().GetStringRepresentation()); wxString paddedString(MakeNameValueString(property->GetName(), stringValueRepr)); int sel = FindListIndexForProperty(property); if (sel > -1) { // Don't update the listbox unnecessarily because it can cause // ugly flashing. if (paddedString != propertyScrollingList->GetString(sel)) propertyScrollingList->SetString(sel, paddedString.GetData()); } //#else // UpdatePropertyList(FALSE); //#endif if (currentlySelected > -1) propertyScrollingList->SetSelection(currentlySelected); return TRUE; } // Find the wxListBox index corresponding to this property int wxPropertyListView::FindListIndexForProperty(wxProperty *property) { int n = propertyScrollingList->Number(); for (int i = 0; i < n; i++) { if (property == (wxProperty *)propertyScrollingList->wxListBox::GetClientData(i)) return i; } return -1; } wxString wxPropertyListView::MakeNameValueString(wxString name, wxString value) { wxString theString(name); int nameWidth = 25; int padWith = nameWidth - theString.Length(); if (padWith < 0) padWith = 0; if (GetFlags() & wxPROP_SHOWVALUES) { // Want to pad with spaces theString.Append(' ', padWith); theString += value; } return theString; } // Select and show string representation in validator the given // property. NULL resets to show no property. bool wxPropertyListView::ShowProperty(wxProperty *property, bool select) { if (currentProperty) { EndShowingProperty(currentProperty); currentProperty = NULL; } valueList->Clear(); valueText->SetValue(""); if (property) { currentProperty = property; BeginShowingProperty(property); } if (select) { int sel = FindListIndexForProperty(property); if (sel > -1) propertyScrollingList->SetSelection(sel); } return TRUE; } // Find appropriate validator and load property into value controls bool wxPropertyListView::BeginShowingProperty(wxProperty *property) { currentValidator = FindPropertyValidator(property); if (!currentValidator) return FALSE; if (!currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator))) return FALSE; wxPropertyListValidator *listValidator = (wxPropertyListValidator *)currentValidator; listValidator->OnPrepareControls(property, this, propertyWindow); DisplayProperty(property); return TRUE; } // Find appropriate validator and unload property from value controls bool wxPropertyListView::EndShowingProperty(wxProperty *property) { if (!currentValidator) return FALSE; RetrieveProperty(property); if (!currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator))) return FALSE; wxPropertyListValidator *listValidator = (wxPropertyListValidator *)currentValidator; listValidator->OnClearControls(property, this, propertyWindow); if (detailedEditing) { listValidator->OnClearDetailControls(property, this, propertyWindow); detailedEditing = FALSE; } return TRUE; } void wxPropertyListView::BeginDetailedEditing(void) { if (!currentValidator) return; if (!currentProperty) return; if (detailedEditing) return; if (!currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator))) return; if (!currentProperty->IsEnabled()) return; wxPropertyListValidator *listValidator = (wxPropertyListValidator *)currentValidator; if (listValidator->OnPrepareDetailControls(currentProperty, this, propertyWindow)) detailedEditing = TRUE; } void wxPropertyListView::EndDetailedEditing(void) { if (!currentValidator) return; if (!currentProperty) return; RetrieveProperty(currentProperty); if (!currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator))) return; wxPropertyListValidator *listValidator = (wxPropertyListValidator *)currentValidator; if (detailedEditing) { listValidator->OnClearDetailControls(currentProperty, this, propertyWindow); detailedEditing = FALSE; } } bool wxPropertyListView::DisplayProperty(wxProperty *property) { if (!currentValidator) return FALSE; if (((currentValidator->GetFlags() & wxPROP_ALLOW_TEXT_EDITING) == 0) || !property->IsEnabled()) valueText->SetEditable(FALSE); else valueText->SetEditable(TRUE); if (!currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator))) return FALSE; wxPropertyListValidator *listValidator = (wxPropertyListValidator *)currentValidator; listValidator->OnDisplayValue(property, this, propertyWindow); return TRUE; } bool wxPropertyListView::RetrieveProperty(wxProperty *property) { if (!currentValidator) return FALSE; if (!property->IsEnabled()) return FALSE; if (!currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator))) return FALSE; wxPropertyListValidator *listValidator = (wxPropertyListValidator *)currentValidator; if (listValidator->OnCheckValue(property, this, propertyWindow)) { if (listValidator->OnRetrieveValue(property, this, propertyWindow)) { UpdatePropertyDisplayInList(property); OnPropertyChanged(property); } } else { // Revert to old value listValidator->OnDisplayValue(property, this, propertyWindow); } return TRUE; } bool wxPropertyListView::EditProperty(wxProperty *property) { return TRUE; } // Called by the listbox callback void wxPropertyListView::OnPropertySelect(wxCommandEvent& event) { int sel = propertyScrollingList->GetSelection(); if (sel > -1) { wxProperty *newSel = (wxProperty *)propertyScrollingList->wxListBox::GetClientData(sel); if (newSel && newSel != currentProperty) { ShowProperty(newSel, FALSE); } } } bool wxPropertyListView::CreateControls(void) { wxPanel *panel = (wxPanel *)propertyWindow; int largeButtonWidth = 50; int largeButtonHeight = 25; int smallButtonWidth = 25; int smallButtonHeight = 20; // XView must be allowed to choose its own sized buttons #ifdef __XVIEW__ largeButtonWidth = -1; largeButtonHeight = -1; smallButtonWidth = -1; smallButtonHeight = -1; #endif if (valueText) return TRUE; if (!panel) return FALSE; wxWindow *leftMostWindow = panel; wxWindow *topMostWindow = panel; wxWindow *rightMostWindow = panel; wxSystemSettings settings; wxFont guiFont = settings.GetSystemFont(wxSYS_DEFAULT_GUI_FONT); wxFont *boringFont = wxTheFontList->FindOrCreateFont(guiFont.GetPointSize(), wxMODERN, wxNORMAL, wxNORMAL); // May need to be changed in future to eliminate clashes with app. panel->SetClientData((char *)this); if (buttonFlags & wxPROP_BUTTON_OK) { windowCloseButton = new wxButton(panel, wxID_OK, "OK", wxPoint(-1, -1), wxSize(largeButtonWidth, largeButtonHeight)); windowCloseButton->SetDefault(); windowCloseButton->SetFocus(); } if (buttonFlags & wxPROP_BUTTON_CLOSE) { windowCloseButton = new wxButton(panel, wxID_OK, "Close", wxPoint(-1, -1), wxSize(largeButtonWidth, largeButtonHeight)); } if (buttonFlags & wxPROP_BUTTON_CANCEL) { windowCancelButton = new wxButton(panel, wxID_CANCEL, "Cancel", wxPoint(-1, -1), wxSize(largeButtonWidth, largeButtonHeight)); } if (buttonFlags & wxPROP_BUTTON_HELP) { windowHelpButton = new wxButton(panel, wxID_HELP, "Help", wxPoint(-1, -1), wxSize(largeButtonWidth, largeButtonHeight)); } if (windowCloseButton) { wxLayoutConstraints *c1 = new wxLayoutConstraints; c1->left.SameAs (panel, wxLeft, 2); c1->top.SameAs (panel, wxTop, 2); c1->width.AsIs(); c1->height.AsIs(); windowCloseButton->SetConstraints(c1); leftMostWindow = windowCloseButton; } if (windowCancelButton) { wxLayoutConstraints *c2 = new wxLayoutConstraints; if (leftMostWindow == panel) c2->left.SameAs (panel, wxLeft, 2); else c2->left.RightOf (leftMostWindow, 2); c2->top.SameAs (panel, wxTop, 2); c2->width.AsIs(); c2->height.AsIs(); windowCancelButton->SetConstraints(c2); leftMostWindow = windowCancelButton; } if (windowHelpButton) { wxLayoutConstraints *c2 = new wxLayoutConstraints; if (leftMostWindow == panel) c2->left.SameAs (panel, wxLeft, 2); else c2->left.RightOf (leftMostWindow, 2); c2->top.SameAs (panel, wxTop, 2); c2->width.AsIs(); c2->height.AsIs(); windowHelpButton->SetConstraints(c2); leftMostWindow = windowHelpButton; } if (buttonFlags & wxPROP_BUTTON_CHECK_CROSS) { /* if (!tickBitmap) { #ifdef __WXMSW__ tickBitmap = new wxBitmap("tick_bmp", wxBITMAP_TYPE_RESOURCE); crossBitmap = new wxBitmap("cross_bmp", wxBITMAP_TYPE_RESOURCE); if (!tickBitmap || !crossBitmap || !tickBitmap->Ok() || !crossBitmap->Ok()) { if (tickBitmap) delete tickBitmap; if (crossBitmap) delete crossBitmap; tickBitmap = NULL; crossBitmap = NULL; } #endif } */ /* if (tickBitmap && crossBitmap) { confirmButton = new wxBitmapButton(panel, wxID_PROP_CHECK, tickBitmap, wxPoint(-1, -1), wxSize(smallButtonWidth-5, smallButtonHeight-5)); cancelButton = new wxBitmapButton(panel, wxID_PROP_CROSS, crossBitmap, wxPoint(-1, -1), wxSize(smallButtonWidth-5, smallButtonHeight-5)); } else */ { confirmButton = new wxButton(panel, wxID_PROP_CHECK, ":-)", wxPoint(-1, -1), wxSize(smallButtonWidth, smallButtonHeight)); cancelButton = new wxButton(panel, wxID_PROP_CROSS, "X", wxPoint(-1, -1), wxSize(smallButtonWidth, smallButtonHeight)); } wxLayoutConstraints *c = new wxLayoutConstraints; c->left.SameAs (panel, wxLeft, 2); if (windowCloseButton) c->top.Below (windowCloseButton, 2); else c->top.SameAs (panel, wxTop, 2); c->width.AsIs(); c->height.AsIs(); cancelButton->SetConstraints(c); c = new wxLayoutConstraints; c->left.RightOf (cancelButton, 2); c->top.SameAs (cancelButton, wxTop, 0); c->width.AsIs(); c->height.AsIs(); confirmButton->SetConstraints(c); cancelButton->Enable(FALSE); confirmButton->Enable(FALSE); } if (buttonFlags & wxPROP_PULLDOWN) { editButton = new wxButton(panel, wxID_PROP_EDIT, "...", wxPoint(-1, -1), wxSize(smallButtonWidth, smallButtonHeight)); editButton->Enable(FALSE); wxLayoutConstraints *c = new wxLayoutConstraints; if (windowCloseButton) c->top.Below (windowCloseButton, 2); else c->top.SameAs (panel, wxTop, 2); c->right.SameAs (panel, wxRight, 2); c->width.AsIs(); c->height.AsIs(); editButton->SetConstraints(c); } valueText = new wxPropertyTextEdit(this, panel, wxID_PROP_TEXT, "", wxPoint(-1, -1), wxSize(-1, -1), wxPROCESS_ENTER); valueText->Enable(FALSE); wxLayoutConstraints *c = new wxLayoutConstraints; if (cancelButton) c->left.RightOf (confirmButton, 2); else c->left.SameAs (panel, wxLeft, 2); if (windowCloseButton) c->top.Below (windowCloseButton, 2); else c->top.SameAs (panel, wxTop, 2); if (editButton) c->right.LeftOf (editButton, 2); else c->right.SameAs (panel, wxRight, 2); c->height.AsIs(); valueText->SetConstraints(c); valueList = new wxListBox(panel, wxID_PROP_VALUE_SELECT, wxPoint(-1, -1), wxSize(-1, 60)); valueList->Show(FALSE); c = new wxLayoutConstraints; c->left.SameAs (panel, wxLeft, 2); c->top.Below (valueText, 2); c->right.SameAs (panel, wxRight, 2); c->height.Absolute(60); valueList->SetConstraints(c); propertyScrollingList = new wxListBox(panel, wxID_PROP_SELECT, wxPoint(-1, -1), wxSize(300, 300)); propertyScrollingList->SetFont(boringFont); c = new wxLayoutConstraints; c->left.SameAs (panel, wxLeft, 2); if (buttonFlags & wxPROP_DYNAMIC_VALUE_FIELD) c->top.Below (valueText, 2); else c->top.Below (valueList, 2); c->right.SameAs (panel, wxRight, 2); c->bottom.SameAs (panel, wxBottom, 2); propertyScrollingList->SetConstraints(c); // Note: if this is called now, it causes a GPF. // Why? // panel->Layout(); return TRUE; } void wxPropertyListView::ShowTextControl(bool show) { if (valueText) valueText->Show(show); } void wxPropertyListView::ShowListBoxControl(bool show) { if (valueList) { valueList->Show(show); if (buttonFlags & wxPROP_DYNAMIC_VALUE_FIELD) { wxLayoutConstraints *constraints = propertyScrollingList->GetConstraints(); if (constraints) { if (show) constraints->top.Below(valueList, 2); else constraints->top.Below(valueText, 2); propertyWindow->Layout(); } } } } void wxPropertyListView::EnableCheck(bool show) { if (confirmButton) confirmButton->Enable(show); } void wxPropertyListView::EnableCross(bool show) { if (cancelButton) cancelButton->Enable(show); } bool wxPropertyListView::OnClose(void) { // Retrieve the value if any wxCommandEvent event; OnCheck(event); delete this; return TRUE; } void wxPropertyListView::OnValueListSelect(wxCommandEvent& event) { if (currentProperty && currentValidator) { if (!currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator))) return; wxPropertyListValidator *listValidator = (wxPropertyListValidator *)currentValidator; listValidator->OnValueListSelect(currentProperty, this, propertyWindow); } } void wxPropertyListView::OnOk(wxCommandEvent& event) { // Retrieve the value if any OnCheck(event); managedWindow->Close(TRUE); } void wxPropertyListView::OnCancel(wxCommandEvent& event) { // SetReturnCode(wxID_CANCEL); managedWindow->Close(TRUE); dialogCancelled = TRUE; } void wxPropertyListView::OnHelp(wxCommandEvent& event) { } void wxPropertyListView::OnCheck(wxCommandEvent& event) { if (currentProperty) { RetrieveProperty(currentProperty); } } void wxPropertyListView::OnCross(wxCommandEvent& event) { if (currentProperty && currentValidator) { if (!currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator))) return; wxPropertyListValidator *listValidator = (wxPropertyListValidator *)currentValidator; // Revert to old value listValidator->OnDisplayValue(currentProperty, this, propertyWindow); } } void wxPropertyListView::OnPropertyDoubleClick(wxCommandEvent& event) { if (currentProperty && currentValidator) { if (!currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator))) return; wxPropertyListValidator *listValidator = (wxPropertyListValidator *)currentValidator; // Revert to old value listValidator->OnDoubleClick(currentProperty, this, propertyWindow); } } void wxPropertyListView::OnEdit(wxCommandEvent& event) { if (currentProperty && currentValidator) { if (!currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator))) return; wxPropertyListValidator *listValidator = (wxPropertyListValidator *)currentValidator; listValidator->OnEdit(currentProperty, this, propertyWindow); } } void wxPropertyListView::OnText(wxCommandEvent& event) { if (event.GetEventType() == wxEVT_COMMAND_TEXT_ENTER) { OnCheck(event); } } /* * Property dialog box */ IMPLEMENT_CLASS(wxPropertyListDialog, wxDialog) BEGIN_EVENT_TABLE(wxPropertyListDialog, wxDialog) EVT_BUTTON(wxID_CANCEL, wxPropertyListDialog::OnCancel) END_EVENT_TABLE() wxPropertyListDialog::wxPropertyListDialog(wxPropertyListView *v, wxWindow *parent, const wxString& title, const wxPoint& pos, const wxSize& size, long style, const wxString& name): wxDialog(parent, -1, title, pos, size, style, name) { view = v; view->AssociatePanel(this); view->SetManagedWindow(this); SetAutoLayout(TRUE); } bool wxPropertyListDialog::OnClose(void) { if (view) { SetReturnCode(wxID_CANCEL); view->OnClose(); view = NULL; return TRUE; } else return FALSE; } void wxPropertyListDialog::OnCancel(wxCommandEvent& event) { SetReturnCode(wxID_CANCEL); this->Close(); } void wxPropertyListDialog::OnDefaultAction(wxControl *item) { /* if (item == view->GetPropertyScrollingList()) view->OnDoubleClick(); */ } // Extend event processing to search the view's event table bool wxPropertyListDialog::ProcessEvent(wxEvent& event) { if ( !view || ! view->ProcessEvent(event) ) return wxEvtHandler::ProcessEvent(event); else return TRUE; } /* * Property panel */ IMPLEMENT_CLASS(wxPropertyListPanel, wxPanel) void wxPropertyListPanel::OnDefaultAction(wxControl *item) { /* if (item == view->GetPropertyScrollingList()) view->OnDoubleClick(); */ } // Extend event processing to search the view's event table bool wxPropertyListPanel::ProcessEvent(wxEvent& event) { if ( !view || ! view->ProcessEvent(event) ) return wxEvtHandler::ProcessEvent(event); else return TRUE; } /* * Property frame */ IMPLEMENT_CLASS(wxPropertyListFrame, wxFrame) bool wxPropertyListFrame::OnClose(void) { if (view) return view->OnClose(); else return FALSE; } wxPanel *wxPropertyListFrame::OnCreatePanel(wxFrame *parent, wxPropertyListView *v) { return new wxPropertyListPanel(v, parent); } bool wxPropertyListFrame::Initialize(void) { propertyPanel = OnCreatePanel(this, view); if (propertyPanel) { view->AssociatePanel(propertyPanel); view->SetManagedWindow(this); propertyPanel->SetAutoLayout(TRUE); return TRUE; } else return FALSE; } /* * Property list specific validator */ IMPLEMENT_ABSTRACT_CLASS(wxPropertyListValidator, wxPropertyValidator) bool wxPropertyListValidator::OnSelect(bool select, wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { // view->GetValueText()->Show(TRUE); if (select) OnDisplayValue(property, view, parentWindow); return TRUE; } bool wxPropertyListValidator::OnValueListSelect(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { wxString s(view->GetValueList()->GetStringSelection()); if (s != "") { view->GetValueText()->SetValue(s); view->RetrieveProperty(property); } return TRUE; } bool wxPropertyListValidator::OnDisplayValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { // view->GetValueText()->Show(TRUE); wxString str(property->GetValue().GetStringRepresentation()); view->GetValueText()->SetValue(str.GetData()); return TRUE; } // Called when TICK is pressed or focus is lost or view wants to update // the property list. // Does the transferance from the property editing area to the property itself bool wxPropertyListValidator::OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { if (!view->GetValueText()) return FALSE; return FALSE; } void wxPropertyListValidator::OnEdit(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { if (view->GetDetailedEditing()) view->EndDetailedEditing(); else view->BeginDetailedEditing(); } bool wxPropertyListValidator::OnClearControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { if (view->GetConfirmButton()) view->GetConfirmButton()->Enable(FALSE); if (view->GetCancelButton()) view->GetCancelButton()->Enable(FALSE); if (view->GetEditButton()) view->GetEditButton()->Enable(FALSE); return TRUE; } /* * Default validators */ IMPLEMENT_DYNAMIC_CLASS(wxRealListValidator, wxPropertyListValidator) /// /// Real number validator /// bool wxRealListValidator::OnCheckValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { if (realMin == 0.0 && realMax == 0.0) return TRUE; if (!view->GetValueText()) return FALSE; wxString value(view->GetValueText()->GetValue()); float val = 0.0; if (!StringToFloat(WXSTRINGCAST value, &val)) { char buf[200]; sprintf(buf, "Value %s is not a valid real number!", value.GetData()); wxMessageBox(buf, "Property value error", wxOK | wxICON_EXCLAMATION, parentWindow); return FALSE; } if (val < realMin || val > realMax) { char buf[200]; sprintf(buf, "Value must be a real number between %.2f and %.2f!", realMin, realMax); wxMessageBox(buf, "Property value error", wxOK | wxICON_EXCLAMATION, parentWindow); return FALSE; } return TRUE; } // Called when TICK is pressed or focus is lost or view wants to update // the property list. // Does the transferance from the property editing area to the property itself bool wxRealListValidator::OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { if (!view->GetValueText()) return FALSE; if (strlen(view->GetValueText()->GetValue()) == 0) return FALSE; wxString value(view->GetValueText()->GetValue()); float f = (float)atof(value.GetData()); property->GetValue() = f; return TRUE; } bool wxRealListValidator::OnPrepareControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { if (view->GetConfirmButton()) view->GetConfirmButton()->Enable(TRUE); if (view->GetCancelButton()) view->GetCancelButton()->Enable(TRUE); if (view->GetEditButton()) view->GetEditButton()->Enable(FALSE); if (view->GetValueText()) view->GetValueText()->Enable(TRUE); return TRUE; } /// /// Integer validator /// IMPLEMENT_DYNAMIC_CLASS(wxIntegerListValidator, wxPropertyListValidator) bool wxIntegerListValidator::OnCheckValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { if (integerMin == 0 && integerMax == 0) return TRUE; if (!view->GetValueText()) return FALSE; wxString value(view->GetValueText()->GetValue()); long val = 0; if (!StringToLong(WXSTRINGCAST value, &val)) { char buf[200]; sprintf(buf, "Value %s is not a valid integer!", value.GetData()); wxMessageBox(buf, "Property value error", wxOK | wxICON_EXCLAMATION, parentWindow); return FALSE; } if (val < integerMin || val > integerMax) { char buf[200]; sprintf(buf, "Value must be an integer between %ld and %ld!", integerMin, integerMax); wxMessageBox(buf, "Property value error", wxOK | wxICON_EXCLAMATION, parentWindow); return FALSE; } return TRUE; } // Called when TICK is pressed or focus is lost or view wants to update // the property list. // Does the transferance from the property editing area to the property itself bool wxIntegerListValidator::OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { if (!view->GetValueText()) return FALSE; if (strlen(view->GetValueText()->GetValue()) == 0) return FALSE; wxString value(view->GetValueText()->GetValue()); long val = (long)atoi(value.GetData()); property->GetValue() = (long)val; return TRUE; } bool wxIntegerListValidator::OnPrepareControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { if (view->GetConfirmButton()) view->GetConfirmButton()->Enable(TRUE); if (view->GetCancelButton()) view->GetCancelButton()->Enable(TRUE); if (view->GetEditButton()) view->GetEditButton()->Enable(FALSE); if (view->GetValueText()) view->GetValueText()->Enable(TRUE); return TRUE; } /// /// boolean validator /// IMPLEMENT_DYNAMIC_CLASS(wxBoolListValidator, wxPropertyListValidator) bool wxBoolListValidator::OnCheckValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { if (!view->GetValueText()) return FALSE; wxString value(view->GetValueText()->GetValue()); if (value != "True" && value != "False") { wxMessageBox("Value must be True or False!", "Property value error", wxOK | wxICON_EXCLAMATION, parentWindow); return FALSE; } return TRUE; } // Called when TICK is pressed or focus is lost or view wants to update // the property list. // Does the transferance from the property editing area to the property itself bool wxBoolListValidator::OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { if (!view->GetValueText()) return FALSE; if (strlen(view->GetValueText()->GetValue()) == 0) return FALSE; wxString value(view->GetValueText()->GetValue()); bool boolValue = FALSE; if (value == "True") boolValue = TRUE; else boolValue = FALSE; property->GetValue() = (bool)boolValue; return TRUE; } bool wxBoolListValidator::OnDisplayValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { if (!view->GetValueText()) return FALSE; wxString str(property->GetValue().GetStringRepresentation()); view->GetValueText()->SetValue(str.GetData()); view->GetValueList()->SetStringSelection(str.GetData()); return TRUE; } bool wxBoolListValidator::OnPrepareControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { if (view->GetConfirmButton()) view->GetConfirmButton()->Enable(FALSE); if (view->GetCancelButton()) view->GetCancelButton()->Enable(FALSE); if (view->GetEditButton()) view->GetEditButton()->Enable(TRUE); if (view->GetValueText()) view->GetValueText()->Enable(FALSE); return TRUE; } bool wxBoolListValidator::OnPrepareDetailControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { if (view->GetValueList()) { view->ShowListBoxControl(TRUE); view->GetValueList()->Enable(TRUE); view->GetValueList()->Append("True"); view->GetValueList()->Append("False"); char *currentString = copystring(view->GetValueText()->GetValue()); view->GetValueList()->SetStringSelection(currentString); delete[] currentString; } return TRUE; } bool wxBoolListValidator::OnClearDetailControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { if (view->GetValueList()) { view->GetValueList()->Clear(); view->ShowListBoxControl(FALSE); view->GetValueList()->Enable(FALSE); } return TRUE; } // Called when the property is double clicked. Extra functionality can be provided, // cycling through possible values. bool wxBoolListValidator::OnDoubleClick(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { if (!view->GetValueText()) return FALSE; if (property->GetValue().BoolValue()) property->GetValue() = (bool)FALSE; else property->GetValue() = (bool)TRUE; view->DisplayProperty(property); view->UpdatePropertyDisplayInList(property); view->OnPropertyChanged(property); return TRUE; } /// /// String validator /// IMPLEMENT_DYNAMIC_CLASS(wxStringListValidator, wxPropertyListValidator) wxStringListValidator::wxStringListValidator(wxStringList *list, long flags): wxPropertyListValidator(flags) { strings = list; // If no constraint, we just allow the string to be edited. if (!strings && ((validatorFlags & wxPROP_ALLOW_TEXT_EDITING) == 0)) validatorFlags |= wxPROP_ALLOW_TEXT_EDITING; } bool wxStringListValidator::OnCheckValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { if (!strings) return TRUE; if (!view->GetValueText()) return FALSE; wxString value(view->GetValueText()->GetValue()); if (!strings->Member(value.GetData())) { wxString s("Value "); s += value.GetData(); s += " is not valid."; wxMessageBox(s.GetData(), "Property value error", wxOK | wxICON_EXCLAMATION, parentWindow); return FALSE; } return TRUE; } // Called when TICK is pressed or focus is lost or view wants to update // the property list. // Does the transferance from the property editing area to the property itself bool wxStringListValidator::OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { if (!view->GetValueText()) return FALSE; wxString value(view->GetValueText()->GetValue()); property->GetValue() = value ; return TRUE; } // Called when TICK is pressed or focus is lost or view wants to update // the property list. // Does the transferance from the property editing area to the property itself bool wxStringListValidator::OnDisplayValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { if (!view->GetValueText()) return FALSE; wxString str(property->GetValue().GetStringRepresentation()); view->GetValueText()->SetValue(str.GetData()); if (strings) { view->GetValueList()->SetStringSelection(str.GetData()); } return TRUE; } bool wxStringListValidator::OnPrepareControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { // Unconstrained if (!strings) { if (view->GetEditButton()) view->GetEditButton()->Enable(FALSE); if (view->GetConfirmButton()) view->GetConfirmButton()->Enable(TRUE); if (view->GetCancelButton()) view->GetCancelButton()->Enable(TRUE); if (view->GetValueText()) view->GetValueText()->Enable(TRUE); return TRUE; } // Constrained if (view->GetValueText()) view->GetValueText()->Enable(FALSE); if (view->GetEditButton()) view->GetEditButton()->Enable(TRUE); if (view->GetConfirmButton()) view->GetConfirmButton()->Enable(FALSE); if (view->GetCancelButton()) view->GetCancelButton()->Enable(FALSE); return TRUE; } bool wxStringListValidator::OnPrepareDetailControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { if (view->GetValueList()) { view->ShowListBoxControl(TRUE); view->GetValueList()->Enable(TRUE); wxNode *node = strings->First(); while (node) { char *s = (char *)node->Data(); view->GetValueList()->Append(s); node = node->Next(); } char *currentString = property->GetValue().StringValue(); view->GetValueList()->SetStringSelection(currentString); } return TRUE; } bool wxStringListValidator::OnClearDetailControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { if (!strings) { return TRUE; } if (view->GetValueList()) { view->GetValueList()->Clear(); view->ShowListBoxControl(FALSE); view->GetValueList()->Enable(FALSE); } return TRUE; } // Called when the property is double clicked. Extra functionality can be provided, // cycling through possible values. bool wxStringListValidator::OnDoubleClick(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { if (!view->GetValueText()) return FALSE; if (!strings) return FALSE; wxNode *node = strings->First(); char *currentString = property->GetValue().StringValue(); while (node) { char *s = (char *)node->Data(); if (strcmp(s, currentString) == 0) { char *nextString = NULL; if (node->Next()) nextString = (char *)node->Next()->Data(); else nextString = (char *)strings->First()->Data(); property->GetValue() = wxString(nextString); view->DisplayProperty(property); view->UpdatePropertyDisplayInList(property); view->OnPropertyChanged(property); return TRUE; } else node = node->Next(); } return TRUE; } /// /// Filename validator /// IMPLEMENT_DYNAMIC_CLASS(wxFilenameListValidator, wxPropertyListValidator) wxFilenameListValidator::wxFilenameListValidator(wxString message , wxString wildcard, long flags): wxPropertyListValidator(flags), filenameWildCard(wildcard), filenameMessage(message) { } wxFilenameListValidator::~wxFilenameListValidator(void) { } bool wxFilenameListValidator::OnCheckValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { return TRUE; } // Called when TICK is pressed or focus is lost or view wants to update // the property list. // Does the transferance from the property editing area to the property itself bool wxFilenameListValidator::OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { if (!view->GetValueText()) return FALSE; wxString value(view->GetValueText()->GetValue()); property->GetValue() = value ; return TRUE; } // Called when TICK is pressed or focus is lost or view wants to update // the property list. // Does the transferance from the property editing area to the property itself bool wxFilenameListValidator::OnDisplayValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { if (!view->GetValueText()) return FALSE; wxString str(property->GetValue().GetStringRepresentation()); view->GetValueText()->SetValue(str); return TRUE; } // Called when the property is double clicked. Extra functionality can be provided, // cycling through possible values. bool wxFilenameListValidator::OnDoubleClick(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { if (!view->GetValueText()) return FALSE; OnEdit(property, view, parentWindow); return TRUE; } bool wxFilenameListValidator::OnPrepareControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { if (view->GetConfirmButton()) view->GetConfirmButton()->Enable(TRUE); if (view->GetCancelButton()) view->GetCancelButton()->Enable(TRUE); if (view->GetEditButton()) view->GetEditButton()->Enable(TRUE); if (view->GetValueText()) view->GetValueText()->Enable((GetFlags() & wxPROP_ALLOW_TEXT_EDITING) == wxPROP_ALLOW_TEXT_EDITING); return TRUE; } void wxFilenameListValidator::OnEdit(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { if (!view->GetValueText()) return; char *s = wxFileSelector( filenameMessage.GetData(), wxPathOnly(property->GetValue().StringValue()), wxFileNameFromPath(property->GetValue().StringValue()), NULL, filenameWildCard.GetData(), 0, parentWindow); if (s) { property->GetValue() = wxString(s); view->DisplayProperty(property); view->UpdatePropertyDisplayInList(property); view->OnPropertyChanged(property); } } /// /// Colour validator /// IMPLEMENT_DYNAMIC_CLASS(wxColourListValidator, wxPropertyListValidator) wxColourListValidator::wxColourListValidator(long flags): wxPropertyListValidator(flags) { } wxColourListValidator::~wxColourListValidator(void) { } bool wxColourListValidator::OnCheckValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { return TRUE; } // Called when TICK is pressed or focus is lost or view wants to update // the property list. // Does the transferance from the property editing area to the property itself bool wxColourListValidator::OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { if (!view->GetValueText()) return FALSE; wxString value(view->GetValueText()->GetValue()); property->GetValue() = value ; return TRUE; } // Called when TICK is pressed or focus is lost or view wants to update // the property list. // Does the transferance from the property editing area to the property itself bool wxColourListValidator::OnDisplayValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { if (!view->GetValueText()) return FALSE; wxString str(property->GetValue().GetStringRepresentation()); view->GetValueText()->SetValue(str); return TRUE; } // Called when the property is double clicked. Extra functionality can be provided, // cycling through possible values. bool wxColourListValidator::OnDoubleClick(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { if (!view->GetValueText()) return FALSE; OnEdit(property, view, parentWindow); return TRUE; } bool wxColourListValidator::OnPrepareControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { if (view->GetConfirmButton()) view->GetConfirmButton()->Enable(TRUE); if (view->GetCancelButton()) view->GetCancelButton()->Enable(TRUE); if (view->GetEditButton()) view->GetEditButton()->Enable(TRUE); if (view->GetValueText()) view->GetValueText()->Enable((GetFlags() & wxPROP_ALLOW_TEXT_EDITING) == wxPROP_ALLOW_TEXT_EDITING); return TRUE; } void wxColourListValidator::OnEdit(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { if (!view->GetValueText()) return; char *s = property->GetValue().StringValue(); int r = 0; int g = 0; int b = 0; if (s) { r = wxHexToDec(s); g = wxHexToDec(s+2); b = wxHexToDec(s+4); } wxColour col(r,g,b); wxColourData data; data.SetChooseFull(TRUE); data.SetColour(col); for (int i = 0; i < 16; i++) { wxColour colour(i*16, i*16, i*16); data.SetCustomColour(i, colour); } wxColourDialog dialog(parentWindow, &data); if (dialog.ShowModal() != wxID_CANCEL) { wxColourData retData = dialog.GetColourData(); col = retData.GetColour(); char buf[7]; wxDecToHex(col.Red(), buf); wxDecToHex(col.Green(), buf+2); wxDecToHex(col.Blue(), buf+4); property->GetValue() = wxString(buf); view->DisplayProperty(property); view->UpdatePropertyDisplayInList(property); view->OnPropertyChanged(property); } } /// /// List of strings validator. For this we need more user interface than /// we get with a property list; so create a new dialog for editing the list. /// IMPLEMENT_DYNAMIC_CLASS(wxListOfStringsListValidator, wxPropertyListValidator) wxListOfStringsListValidator::wxListOfStringsListValidator(long flags): wxPropertyListValidator(flags) { } bool wxListOfStringsListValidator::OnCheckValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { // No constraints for an arbitrary, user-editable list of strings. return TRUE; } // Called when TICK is pressed or focus is lost or view wants to update // the property list. // Does the transferance from the property editing area to the property itself. // In this case, the user cannot directly edit the string list. bool wxListOfStringsListValidator::OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { return TRUE; } bool wxListOfStringsListValidator::OnDisplayValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { if (!view->GetValueText()) return FALSE; wxString str(property->GetValue().GetStringRepresentation()); view->GetValueText()->SetValue(str.GetData()); return TRUE; } bool wxListOfStringsListValidator::OnPrepareControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { if (view->GetEditButton()) view->GetEditButton()->Enable(TRUE); if (view->GetValueText()) view->GetValueText()->Enable(FALSE); if (view->GetConfirmButton()) view->GetConfirmButton()->Enable(FALSE); if (view->GetCancelButton()) view->GetCancelButton()->Enable(FALSE); return TRUE; } // Called when the property is double clicked. Extra functionality can be provided, // cycling through possible values. bool wxListOfStringsListValidator::OnDoubleClick(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { OnEdit(property, view, parentWindow); return TRUE; } void wxListOfStringsListValidator::OnEdit(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow) { // Convert property value to a list of strings for editing wxStringList *stringList = new wxStringList; wxPropertyValue *expr = property->GetValue().GetFirst(); while (expr) { char *s = expr->StringValue(); if (s) stringList->Add(s); expr = expr->GetNext(); } wxString title("Editing "); title += property->GetName(); if (EditStringList(parentWindow, stringList, title.GetData())) { wxPropertyValue& oldValue = property->GetValue(); oldValue.ClearList(); wxNode *node = stringList->First(); while (node) { char *s = (char *)node->Data(); oldValue.Append(new wxPropertyValue(s)); node = node->Next(); } view->DisplayProperty(property); view->UpdatePropertyDisplayInList(property); view->OnPropertyChanged(property); } delete stringList; } class wxPropertyStringListEditorDialog: public wxDialog { public: wxStringList *stringList; wxListBox *listBox; wxTextCtrl *stringText; static bool dialogCancelled; int currentSelection; wxPropertyStringListEditorDialog(wxWindow *parent, const wxString& title, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long windowStyle = wxDEFAULT_DIALOG_STYLE, const wxString& name = "stringEditorDialogBox"): wxDialog(parent, -1, title, pos, size, windowStyle, name) { stringList = NULL; stringText = NULL; listBox = NULL; dialogCancelled = FALSE; currentSelection = -1; } ~wxPropertyStringListEditorDialog(void) {} bool OnClose(void); void SaveCurrentSelection(void); void ShowCurrentSelection(void); void OnOK(wxCommandEvent& event); void OnCancel(wxCommandEvent& event); void OnAdd(wxCommandEvent& event); void OnDelete(wxCommandEvent& event); void OnStrings(wxCommandEvent& event); void OnText(wxCommandEvent& event); DECLARE_EVENT_TABLE() }; #define wxID_PROP_SL_ADD 3000 #define wxID_PROP_SL_DELETE 3001 #define wxID_PROP_SL_STRINGS 3002 #define wxID_PROP_SL_TEXT 3003 BEGIN_EVENT_TABLE(wxPropertyStringListEditorDialog, wxDialog) EVT_BUTTON(wxID_OK, wxPropertyStringListEditorDialog::OnOK) EVT_BUTTON(wxID_CANCEL, wxPropertyStringListEditorDialog::OnCancel) EVT_BUTTON(wxID_PROP_SL_ADD, wxPropertyStringListEditorDialog::OnAdd) EVT_BUTTON(wxID_PROP_SL_DELETE, wxPropertyStringListEditorDialog::OnDelete) EVT_LISTBOX(wxID_PROP_SL_STRINGS, wxPropertyStringListEditorDialog::OnStrings) EVT_TEXT(wxID_PROP_SL_TEXT, wxPropertyStringListEditorDialog::OnText) END_EVENT_TABLE() class wxPropertyStringListEditorText: public wxTextCtrl { public: wxPropertyStringListEditorText(wxWindow *parent, wxWindowID id, const wxString& val, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long windowStyle = 0, const wxString& name = "text"): wxTextCtrl(parent, id, val, pos, size, windowStyle, wxDefaultValidator, name) { } void OnKillFocus(void) { wxPropertyStringListEditorDialog *dialog = (wxPropertyStringListEditorDialog *)GetParent(); dialog->SaveCurrentSelection(); } }; bool wxPropertyStringListEditorDialog::dialogCancelled = FALSE; // Edit the string list. bool wxListOfStringsListValidator::EditStringList(wxWindow *parent, wxStringList *stringList, const char *title) { wxBeginBusyCursor(); wxPropertyStringListEditorDialog *dialog = new wxPropertyStringListEditorDialog(parent, title, wxPoint(10, 10), wxSize(400, 400), wxDEFAULT_DIALOG_STYLE|wxDIALOG_MODAL); dialog->stringList = stringList; wxButton *okButton = new wxButton(dialog, wxID_OK, "OK", wxPoint(5, 5)); wxButton *cancelButton = new wxButton(dialog, wxID_CANCEL, "Cancel", wxPoint(40, 5)); // wxButton *helpButton = new wxButton(dialog, (wxFunction)StringListEditorHelpProc, "Help"); // helpButton->SetClientData((char *)this); dialog->listBox = new wxListBox(dialog, wxID_PROP_SL_STRINGS, wxPoint(5, 30), wxSize(300, 200), 0, NULL, wxLB_SINGLE); dialog->stringText = new wxPropertyStringListEditorText(dialog, wxID_PROP_SL_TEXT, "", wxPoint(5, 240), wxSize(300, -1), wxPROCESS_ENTER); dialog->stringText->Enable(FALSE); wxButton *addButton = new wxButton(dialog, wxID_PROP_SL_ADD, "Add", wxPoint(5, 280)); wxButton *deleteButton = new wxButton(dialog, wxID_PROP_SL_DELETE, "Delete", wxPoint(40, 280)); wxNode *node = stringList->First(); while (node) { char *str = (char *)node->Data(); // Save node as client data for each listbox item dialog->listBox->Append(str, (char *)node); node = node->Next(); } dialog->SetClientSize(310, 305); dialog->Centre(wxBOTH); wxEndBusyCursor(); if (dialog->ShowModal() == wxID_CANCEL) return FALSE; else return TRUE; } /* * String list editor callbacks * */ void wxPropertyStringListEditorDialog::OnStrings(wxCommandEvent& event) { int sel = listBox->GetSelection(); if (sel > -1) { currentSelection = sel; ShowCurrentSelection(); } } void wxPropertyStringListEditorDialog::OnDelete(wxCommandEvent& event) { int sel = listBox->GetSelection(); if (sel == -1) return; wxNode *node = (wxNode *)listBox->wxListBox::GetClientData(sel); if (!node) return; listBox->Delete(sel); delete[] (char *)node->Data(); delete node; currentSelection = -1; stringText->SetValue(""); } void wxPropertyStringListEditorDialog::OnAdd(wxCommandEvent& event) { SaveCurrentSelection(); char *initialText = ""; wxNode *node = stringList->Add(initialText); listBox->Append(initialText, (char *)node); currentSelection = stringList->Number() - 1; listBox->SetSelection(currentSelection); ShowCurrentSelection(); stringText->SetFocus(); } void wxPropertyStringListEditorDialog::OnOK(wxCommandEvent& event) { SaveCurrentSelection(); EndModal(wxID_OK); Close(TRUE); } void wxPropertyStringListEditorDialog::OnCancel(wxCommandEvent& event) { dialogCancelled = TRUE; EndModal(wxID_CANCEL); Close(TRUE); } void wxPropertyStringListEditorDialog::OnText(wxCommandEvent& event) { if (event.GetEventType() == wxEVENT_TYPE_TEXT_ENTER_COMMAND) { SaveCurrentSelection(); } } bool wxPropertyStringListEditorDialog::OnClose(void) { SaveCurrentSelection(); return TRUE; } void wxPropertyStringListEditorDialog::SaveCurrentSelection(void) { if (currentSelection == -1) return; wxNode *node = (wxNode *)listBox->wxListBox::GetClientData(currentSelection); if (!node) return; wxString txt(stringText->GetValue()); if (node->Data()) delete[] (char *)node->Data(); node->SetData((wxObject *)copystring(txt)); listBox->SetString(currentSelection, (char *)node->Data()); } void wxPropertyStringListEditorDialog::ShowCurrentSelection(void) { if (currentSelection == -1) { stringText->SetValue(""); return; } wxNode *node = (wxNode *)listBox->wxListBox::GetClientData(currentSelection); char *txt = (char *)node->Data(); stringText->SetValue(txt); stringText->Enable(TRUE); }