--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: prop.cpp
+// Purpose: Propert sheet classes implementation
+// Author: Julian Smart
+// Modified by:
+// Created: 04/01/98
+// RCS-ID: $Id$
+// Copyright: (c) Julian Smart
+// Licence: wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "prop.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 <ctype.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+
+#if wxUSE_IOSTREAMH
+#if defined(__WXMSW__) && !defined(__GNUWIN32__)
+#include <strstrea.h>
+#else
+#include <strstream.h>
+#endif
+#else
+#include <strstream>
+#endif
+
+#include "wx/window.h"
+#include "wx/utils.h"
+#include "wx/list.h"
+#include "prop.h"
+
+IMPLEMENT_DYNAMIC_CLASS(wxPropertyValue, wxObject)
+
+wxPropertyValue::wxPropertyValue(void)
+{
+ m_type = wxPropertyValueNull;
+ m_next = NULL;
+ m_last = NULL;
+ m_value.first = NULL;
+ m_clientData = NULL;
+ m_modifiedFlag = FALSE;
+}
+
+wxPropertyValue::wxPropertyValue(const wxPropertyValue& copyFrom)
+{
+ m_modifiedFlag = FALSE;
+ Copy((wxPropertyValue& )copyFrom);
+}
+
+wxPropertyValue::wxPropertyValue(const char *val)
+{
+ m_modifiedFlag = FALSE;
+ m_type = wxPropertyValueString;
+
+ m_value.string = copystring(val);
+ m_clientData = NULL;
+ m_next = NULL;
+ m_last = NULL;
+}
+
+wxPropertyValue::wxPropertyValue(const wxString& val)
+{
+ m_modifiedFlag = FALSE;
+ m_type = wxPropertyValueString;
+
+ m_value.string = copystring((const char *)val);
+ m_clientData = NULL;
+ m_next = NULL;
+ m_last = NULL;
+}
+
+wxPropertyValue::wxPropertyValue(long the_integer)
+{
+ m_modifiedFlag = FALSE;
+ m_type = wxPropertyValueInteger;
+ m_value.integer = the_integer;
+ m_clientData = NULL;
+ m_next = NULL;
+}
+
+wxPropertyValue::wxPropertyValue(bool val)
+{
+ m_modifiedFlag = FALSE;
+ m_type = wxPropertyValuebool;
+ m_value.integer = val;
+ m_clientData = NULL;
+ m_next = NULL;
+}
+
+wxPropertyValue::wxPropertyValue(float the_real)
+{
+ m_modifiedFlag = FALSE;
+ m_type = wxPropertyValueReal;
+ m_value.real = the_real;
+ m_clientData = NULL;
+ m_next = NULL;
+}
+
+wxPropertyValue::wxPropertyValue(double the_real)
+{
+ m_modifiedFlag = FALSE;
+ m_type = wxPropertyValueReal;
+ m_value.real = (float)the_real;
+ m_clientData = NULL;
+ m_next = NULL;
+}
+
+// Pointer versions: we have a pointer to the real C++ value.
+wxPropertyValue::wxPropertyValue(char **val)
+{
+ m_modifiedFlag = FALSE;
+ m_type = wxPropertyValueStringPtr;
+
+ m_value.stringPtr = val;
+ m_clientData = NULL;
+ m_next = NULL;
+ m_last = NULL;
+}
+
+wxPropertyValue::wxPropertyValue(long *val)
+{
+ m_modifiedFlag = FALSE;
+ m_type = wxPropertyValueIntegerPtr;
+ m_value.integerPtr = val;
+ m_clientData = NULL;
+ m_next = NULL;
+}
+
+wxPropertyValue::wxPropertyValue(bool *val)
+{
+ m_modifiedFlag = FALSE;
+ m_type = wxPropertyValueboolPtr;
+ m_value.boolPtr = val;
+ m_clientData = NULL;
+ m_next = NULL;
+}
+
+wxPropertyValue::wxPropertyValue(float *val)
+{
+ m_modifiedFlag = FALSE;
+ m_type = wxPropertyValueRealPtr;
+ m_value.realPtr = val;
+ m_clientData = NULL;
+ m_next = NULL;
+}
+
+wxPropertyValue::wxPropertyValue(wxList *the_list)
+{
+ m_modifiedFlag = FALSE;
+ m_type = wxPropertyValueList;
+ m_clientData = NULL;
+ m_last = NULL;
+ m_value.first = NULL;
+
+ wxNode *node = the_list->First();
+ while (node)
+ {
+ wxPropertyValue *expr = (wxPropertyValue *)node->Data();
+ Append(expr);
+ node = node->Next();
+ }
+
+ delete the_list;
+}
+
+wxPropertyValue::wxPropertyValue(wxStringList *the_list)
+{
+ m_modifiedFlag = FALSE;
+ m_type = wxPropertyValueList;
+ m_clientData = NULL;
+ m_last = NULL;
+ m_value.first = NULL;
+
+ wxNode *node = the_list->First();
+ while (node)
+ {
+ char *s = (char *)node->Data();
+ Append(new wxPropertyValue(s));
+ node = node->Next();
+ }
+ delete the_list;
+}
+
+wxPropertyValue::~wxPropertyValue(void)
+{
+ switch (m_type)
+ {
+ case wxPropertyValueInteger:
+ case wxPropertyValuebool:
+ case wxPropertyValueReal:
+ {
+ break;
+ }
+ case wxPropertyValueString:
+ {
+ delete m_value.string;
+ break;
+ }
+ case wxPropertyValueList:
+ {
+ wxPropertyValue *expr = m_value.first;
+ while (expr)
+ {
+ wxPropertyValue *expr1 = expr->m_next;
+
+ delete expr;
+ expr = expr1;
+ }
+ break;
+ }
+ default:
+ case wxPropertyValueNull: break;
+ }
+}
+
+void wxPropertyValue::Append(wxPropertyValue *expr)
+{
+ m_modifiedFlag = TRUE;
+ if (!m_value.first)
+ m_value.first = expr;
+
+ if (m_last)
+ m_last->m_next = expr;
+ m_last = expr;
+}
+
+void wxPropertyValue::Insert(wxPropertyValue *expr)
+{
+ m_modifiedFlag = TRUE;
+ expr->m_next = m_value.first;
+ m_value.first = expr;
+
+ if (!m_last)
+ m_last = expr;
+}
+
+// Delete from list
+void wxPropertyValue::Delete(wxPropertyValue *node)
+{
+ wxPropertyValue *expr = GetFirst();
+
+ wxPropertyValue *previous = NULL;
+ while (expr && (expr != node))
+ {
+ previous = expr;
+ expr = expr->GetNext();
+ }
+
+ if (expr)
+ {
+ if (previous)
+ previous->m_next = expr->m_next;
+
+ // If node was the first in the list,
+ // make the list point to the NEXT one.
+ if (GetFirst() == expr)
+ {
+ m_value.first = expr->m_next;
+ }
+
+ // If node was the last in the list,
+ // make the list 'last' pointer point to the PREVIOUS one.
+ if (GetLast() == expr)
+ {
+ if (previous)
+ m_last = previous;
+ else
+ m_last = NULL;
+ }
+ m_modifiedFlag = TRUE;
+ delete expr;
+ }
+
+}
+
+void wxPropertyValue::ClearList(void)
+{
+ wxPropertyValue *val = GetFirst();
+ if (val)
+ m_modifiedFlag = TRUE;
+
+ while (val)
+ {
+ wxPropertyValue *next = val->GetNext();
+ delete val;
+ val = next;
+ }
+ m_value.first = NULL;
+ m_last = NULL;
+}
+
+wxPropertyValue *wxPropertyValue::NewCopy(void) const
+{
+ switch (m_type)
+ {
+ case wxPropertyValueInteger:
+ return new wxPropertyValue(m_value.integer);
+ case wxPropertyValuebool:
+ return new wxPropertyValue((bool) (m_value.integer != 0));
+ case wxPropertyValueReal:
+ return new wxPropertyValue(m_value.real);
+ case wxPropertyValueString:
+ return new wxPropertyValue(m_value.string);
+ case wxPropertyValueList:
+ {
+ wxPropertyValue *expr = m_value.first;
+ wxPropertyValue *new_list = new wxPropertyValue;
+ new_list->SetType(wxPropertyValueList);
+ while (expr)
+ {
+ wxPropertyValue *expr2 = expr->NewCopy();
+ new_list->Append(expr2);
+ expr = expr->m_next;
+ }
+ return new_list;
+ }
+ case wxPropertyValueIntegerPtr:
+ return new wxPropertyValue(m_value.integerPtr);
+ case wxPropertyValueRealPtr:
+ return new wxPropertyValue(m_value.realPtr);
+ case wxPropertyValueboolPtr:
+ return new wxPropertyValue(m_value.boolPtr);
+ case wxPropertyValueStringPtr:
+ return new wxPropertyValue(m_value.stringPtr);
+
+ case wxPropertyValueNull:
+#ifdef __X__
+ cerr << "Should never get here!\n";
+#endif
+ break;
+ }
+ return NULL;
+}
+
+void wxPropertyValue::Copy(wxPropertyValue& copyFrom)
+{
+ m_type = copyFrom.Type();
+
+ switch (m_type)
+ {
+ case wxPropertyValueInteger:
+ (*this) = copyFrom.IntegerValue();
+ return ;
+
+ case wxPropertyValueReal:
+ (*this) = copyFrom.RealValue();
+ return ;
+
+ case wxPropertyValueString:
+ (*this) = wxString(copyFrom.StringValue());
+ return ;
+
+ case wxPropertyValuebool:
+ (*this) = copyFrom.BoolValue();
+ return ;
+
+ // Pointers
+ case wxPropertyValueboolPtr:
+ (*this) = copyFrom.BoolValuePtr();
+ return ;
+ case wxPropertyValueRealPtr:
+ (*this) = copyFrom.RealValuePtr();
+ return ;
+ case wxPropertyValueIntegerPtr:
+ (*this) = copyFrom.IntegerValuePtr();
+ return ;
+ case wxPropertyValueStringPtr:
+ {
+ char** s = copyFrom.StringValuePtr();
+ (*this) = s;
+ return ;
+ }
+
+ case wxPropertyValueList:
+ {
+ m_value.first = NULL;
+ m_next = NULL;
+ m_last = NULL;
+ wxPropertyValue *expr = copyFrom.m_value.first;
+ while (expr)
+ {
+ wxPropertyValue *expr2 = expr->NewCopy();
+ Append(expr2);
+ expr = expr->m_next;
+ }
+ return;
+ }
+ case wxPropertyValueNull:
+#ifdef __X__
+ cerr << "Should never get here!\n";
+#endif
+ break;
+ }
+}
+
+// Return nth argument of a clause (starting from 1)
+wxPropertyValue *wxPropertyValue::Arg(wxPropertyValueType type, int arg) const
+{
+ wxPropertyValue *expr = m_value.first;
+ for (int i = 1; i < arg; i++)
+ if (expr)
+ expr = expr->m_next;
+
+ if (expr && (expr->m_type == type))
+ return expr;
+ else
+ return NULL;
+}
+
+// Return nth argument of a list expression (starting from zero)
+wxPropertyValue *wxPropertyValue::Nth(int arg) const
+{
+ if (m_type != wxPropertyValueList)
+ return NULL;
+
+ wxPropertyValue *expr = m_value.first;
+ for (int i = 0; i < arg; i++)
+ if (expr)
+ expr = expr->m_next;
+ else return NULL;
+
+ if (expr)
+ return expr;
+ else
+ return NULL;
+}
+
+ // Returns the number of elements in a list expression
+int wxPropertyValue::Number(void) const
+{
+ if (m_type != wxPropertyValueList)
+ return 0;
+
+ int i = 0;
+ wxPropertyValue *expr = m_value.first;
+ while (expr)
+ {
+ expr = expr->m_next;
+ i ++;
+ }
+ return i;
+}
+
+void wxPropertyValue::WritePropertyClause(ostream& stream) // Write this expression as a top-level clause
+{
+ if (m_type != wxPropertyValueList)
+ return;
+
+ wxPropertyValue *node = m_value.first;
+ if (node)
+ {
+ node->WritePropertyType(stream);
+ stream << "(";
+ node = node->m_next;
+ bool first = TRUE;
+ while (node)
+ {
+ if (!first)
+ stream << " ";
+ node->WritePropertyType(stream);
+ node = node->m_next;
+ if (node) stream << ",\n";
+ first = FALSE;
+ }
+ stream << ").\n\n";
+ }
+}
+
+void wxPropertyValue::WritePropertyType(ostream& stream) // Write as any other subexpression
+{
+ switch (m_type)
+ {
+ case wxPropertyValueInteger:
+ {
+ stream << m_value.integer;
+ break;
+ }
+ case wxPropertyValueIntegerPtr:
+ {
+ stream << *m_value.integerPtr;
+ break;
+ }
+ case wxPropertyValuebool:
+ {
+ if (m_value.integer)
+ stream << "True";
+ else
+ stream << "False";
+ break;
+ }
+ case wxPropertyValueboolPtr:
+ {
+ if (*m_value.integerPtr)
+ stream << "True";
+ else
+ stream << "False";
+ break;
+ }
+ case wxPropertyValueReal:
+ {
+ float f = m_value.real;
+ sprintf(wxBuffer, "%.6g", (double)f);
+ stream << wxBuffer;
+ break;
+ }
+ case wxPropertyValueRealPtr:
+ {
+ float f = *m_value.realPtr;
+/* Now the parser can cope with this.
+ // Prevent printing in 'e' notation. Any better way?
+ if (fabs(f) < 0.00001)
+ f = 0.0;
+*/
+ sprintf(wxBuffer, "%.6g", f);
+ stream << wxBuffer;
+ break;
+ }
+ case wxPropertyValueString:
+ {
+// stream << "\"";
+ int i;
+ int len = strlen(m_value.string);
+ for (i = 0; i < len; i++)
+ {
+ char ch = m_value.string[i];
+// if (ch == '"' || ch == '\\')
+// stream << "\\";
+ stream << ch;
+ }
+
+// stream << "\"";
+ break;
+ }
+ case wxPropertyValueStringPtr:
+ {
+ int i;
+ int len = strlen(*(m_value.stringPtr));
+ for (i = 0; i < len; i++)
+ {
+ char ch = *(m_value.stringPtr)[i];
+
+ }
+ break;
+ }
+ case wxPropertyValueList:
+ {
+ if (!m_value.first)
+ stream << "[]";
+ else
+ {
+ wxPropertyValue *expr = m_value.first;
+
+ stream << "[";
+ while (expr)
+ {
+ expr->WritePropertyType(stream);
+ expr = expr->m_next;
+ if (expr) stream << ", ";
+ }
+ stream << "]";
+ }
+ break;
+ }
+ case wxPropertyValueNull: break;
+ }
+}
+
+wxString wxPropertyValue::GetStringRepresentation(void)
+{
+ char buf[500];
+ buf[0] = 0;
+
+ ostrstream str((char *)buf, (int)500, ios::out);
+ WritePropertyType(str);
+ str << '\0';
+ str.flush();
+
+ wxString theString(buf);
+ return theString;
+}
+
+void wxPropertyValue::operator=(const wxPropertyValue& val)
+{
+ m_modifiedFlag = TRUE;
+ Copy((wxPropertyValue&)val);
+}
+
+// void wxPropertyValue::operator=(const char *val)
+void wxPropertyValue::operator=(const wxString& val1)
+{
+ const char *val = (const char *)val1;
+
+ m_modifiedFlag = TRUE;
+ if (m_type == wxPropertyValueNull)
+ m_type = wxPropertyValueString;
+
+ if (m_type == wxPropertyValueString)
+ {
+ if (val)
+ m_value.string = copystring(val);
+ else
+ m_value.string = NULL;
+ }
+ else if (m_type == wxPropertyValueStringPtr)
+ {
+ if (*m_value.stringPtr)
+ delete[] *m_value.stringPtr;
+ if (val)
+ *m_value.stringPtr = copystring(val);
+ else
+ *m_value.stringPtr = NULL;
+ }
+
+ m_clientData = NULL;
+ m_next = NULL;
+ m_last = NULL;
+
+}
+
+void wxPropertyValue::operator=(const long val)
+{
+ m_modifiedFlag = TRUE;
+ if (m_type == wxPropertyValueNull)
+ m_type = wxPropertyValueInteger;
+
+ if (m_type == wxPropertyValueInteger)
+ m_value.integer = val;
+ else if (m_type == wxPropertyValueIntegerPtr)
+ *m_value.integerPtr = val;
+ else if (m_type == wxPropertyValueReal)
+ m_value.real = (float)val;
+ else if (m_type == wxPropertyValueRealPtr)
+ *m_value.realPtr = (float)val;
+
+ m_clientData = NULL;
+ m_next = NULL;
+}
+
+void wxPropertyValue::operator=(const bool val)
+{
+ m_modifiedFlag = TRUE;
+ if (m_type == wxPropertyValueNull)
+ m_type = wxPropertyValuebool;
+
+ if (m_type == wxPropertyValuebool)
+ m_value.integer = (long)val;
+ else if (m_type == wxPropertyValueboolPtr)
+ *m_value.boolPtr = val;
+
+ m_clientData = NULL;
+ m_next = NULL;
+}
+
+void wxPropertyValue::operator=(const float val)
+{
+ m_modifiedFlag = TRUE;
+ if (m_type == wxPropertyValueNull)
+ m_type = wxPropertyValueReal;
+
+ if (m_type == wxPropertyValueInteger)
+ m_value.integer = (long)val;
+ else if (m_type == wxPropertyValueIntegerPtr)
+ *m_value.integerPtr = (long)val;
+ else if (m_type == wxPropertyValueReal)
+ m_value.real = val;
+ else if (m_type == wxPropertyValueRealPtr)
+ *m_value.realPtr = val;
+
+ m_clientData = NULL;
+ m_next = NULL;
+}
+
+void wxPropertyValue::operator=(const char **val)
+{
+ m_modifiedFlag = TRUE;
+ m_type = wxPropertyValueStringPtr;
+
+ if (val)
+ m_value.stringPtr = (char **)val;
+ else
+ m_value.stringPtr = NULL;
+ m_clientData = NULL;
+ m_next = NULL;
+ m_last = NULL;
+
+}
+
+void wxPropertyValue::operator=(const long *val)
+{
+ m_modifiedFlag = TRUE;
+ m_type = wxPropertyValueIntegerPtr;
+ m_value.integerPtr = (long *)val;
+ m_clientData = NULL;
+ m_next = NULL;
+}
+
+void wxPropertyValue::operator=(const bool *val)
+{
+ m_modifiedFlag = TRUE;
+ m_type = wxPropertyValueboolPtr;
+ m_value.boolPtr = (bool *)val;
+ m_clientData = NULL;
+ m_next = NULL;
+}
+
+void wxPropertyValue::operator=(const float *val)
+{
+ m_modifiedFlag = TRUE;
+ m_type = wxPropertyValueRealPtr;
+ m_value.realPtr = (float *)val;
+ m_clientData = NULL;
+ m_next = NULL;
+}
+
+long wxPropertyValue::IntegerValue(void) const
+ {
+ if (m_type == wxPropertyValueInteger)
+ return m_value.integer;
+ else if (m_type == wxPropertyValueReal)
+ return (long)m_value.real;
+ else if (m_type == wxPropertyValueIntegerPtr)
+ return *m_value.integerPtr;
+ else if (m_type == wxPropertyValueRealPtr)
+ return (long)(*m_value.realPtr);
+ else return 0;
+ }
+
+long *wxPropertyValue::IntegerValuePtr(void) const
+{
+ return m_value.integerPtr;
+}
+
+float wxPropertyValue::RealValue(void) const {
+ if (m_type == wxPropertyValueReal)
+ return m_value.real;
+ else if (m_type == wxPropertyValueRealPtr)
+ return *m_value.realPtr;
+ else if (m_type == wxPropertyValueInteger)
+ return (float)m_value.integer;
+ else if (m_type == wxPropertyValueIntegerPtr)
+ return (float)*(m_value.integerPtr);
+ else return 0.0;
+ }
+
+float *wxPropertyValue::RealValuePtr(void) const
+{
+ return m_value.realPtr;
+}
+
+bool wxPropertyValue::BoolValue(void) const {
+ if (m_type == wxPropertyValueReal)
+ return (m_value.real != 0.0);
+ if (m_type == wxPropertyValueRealPtr)
+ return (*(m_value.realPtr) != 0.0);
+ else if (m_type == wxPropertyValueInteger)
+ return (m_value.integer != 0);
+ else if (m_type == wxPropertyValueIntegerPtr)
+ return (*(m_value.integerPtr) != 0);
+ else if (m_type == wxPropertyValuebool)
+ return (m_value.integer != 0);
+ else if (m_type == wxPropertyValueboolPtr)
+ return (*(m_value.boolPtr) != 0);
+ else return FALSE;
+ }
+
+bool *wxPropertyValue::BoolValuePtr(void) const
+{
+ return m_value.boolPtr;
+}
+
+char *wxPropertyValue::StringValue(void) const {
+ if (m_type == wxPropertyValueString)
+ return m_value.string;
+ else if (m_type == wxPropertyValueStringPtr)
+ return *(m_value.stringPtr);
+ else return NULL;
+ }
+
+char **wxPropertyValue::StringValuePtr(void) const
+{
+ return m_value.stringPtr;
+}
+
+/*
+ * A property (name plus value)
+ */
+
+IMPLEMENT_DYNAMIC_CLASS(wxProperty, wxObject)
+
+wxProperty::wxProperty(void)
+{
+ m_propertyRole = (char *)NULL;
+ m_propertyValidator = NULL;
+ m_propertyWindow = NULL;
+ m_enabled = TRUE;
+}
+
+wxProperty::wxProperty(wxProperty& copyFrom)
+{
+ m_value = copyFrom.GetValue();
+ m_name = copyFrom.GetName();
+ m_propertyRole = copyFrom.GetRole();
+ m_propertyValidator = copyFrom.GetValidator();
+ m_enabled = copyFrom.IsEnabled();
+ m_propertyWindow = NULL;
+}
+
+wxProperty::wxProperty(wxString nm, wxString role, wxPropertyValidator *ed):m_name(nm), m_propertyRole(role)
+{
+ m_propertyValidator = ed;
+ m_propertyWindow = NULL;
+ m_enabled = TRUE;
+}
+
+wxProperty::wxProperty(wxString nm, const wxPropertyValue& val, wxString role, wxPropertyValidator *ed):
+ m_name(nm), m_value(val), m_propertyRole(role)
+{
+ m_propertyValidator = ed;
+ m_propertyWindow = NULL;
+ m_enabled = TRUE;
+}
+
+wxProperty::~wxProperty(void)
+{
+ if (m_propertyValidator)
+ delete m_propertyValidator;
+}
+
+wxPropertyValue& wxProperty::GetValue(void) const
+{
+ return (wxPropertyValue&) m_value;
+}
+
+wxPropertyValidator *wxProperty::GetValidator(void) const
+{
+ return m_propertyValidator;
+}
+
+wxString& wxProperty::GetName(void) const
+{
+ return (wxString&) m_name;
+}
+
+wxString& wxProperty::GetRole(void) const
+{
+ return (wxString&) m_propertyRole;
+}
+
+void wxProperty::SetValue(const wxPropertyValue& val)
+{
+ m_value = val;
+}
+
+void wxProperty::SetValidator(wxPropertyValidator *ed)
+{
+ m_propertyValidator = ed;
+}
+
+void wxProperty::SetRole(wxString& role)
+{
+ m_propertyRole = role;
+}
+
+void wxProperty::SetName(wxString& nm)
+{
+ m_name = nm;
+}
+
+void wxProperty::operator=(const wxPropertyValue& val)
+{
+ m_value = val;
+}
+
+/*
+ * Base property view class
+ */
+
+IMPLEMENT_DYNAMIC_CLASS(wxPropertyView, wxEvtHandler)
+
+wxPropertyView::wxPropertyView(long flags)
+{
+ m_buttonFlags = flags;
+ m_propertySheet = NULL;
+ m_currentValidator = NULL;
+ m_currentProperty = NULL;
+}
+
+wxPropertyView::~wxPropertyView(void)
+{
+}
+
+void wxPropertyView::AddRegistry(wxPropertyValidatorRegistry *registry)
+{
+ m_validatorRegistryList.Append(registry);
+}
+
+wxPropertyValidator *wxPropertyView::FindPropertyValidator(wxProperty *property)
+{
+ if (property->GetValidator())
+ return property->GetValidator();
+
+ wxNode *node = m_validatorRegistryList.First();
+ while (node)
+ {
+ wxPropertyValidatorRegistry *registry = (wxPropertyValidatorRegistry *)node->Data();
+ wxPropertyValidator *validator = registry->GetValidator(property->GetRole());
+ if (validator)
+ return validator;
+ node = node->Next();
+ }
+ return NULL;
+/*
+ if (!wxDefaultPropertyValidator)
+ wxDefaultPropertyValidator = new wxPropertyListValidator;
+ return wxDefaultPropertyValidator;
+*/
+}
+
+/*
+ * Property sheet
+ */
+
+IMPLEMENT_DYNAMIC_CLASS(wxPropertySheet, wxObject)
+
+wxPropertySheet::wxPropertySheet(void):m_properties(wxKEY_STRING)
+{
+}
+
+wxPropertySheet::~wxPropertySheet(void)
+{
+ Clear();
+}
+
+bool wxPropertySheet::Save( ostream& WXUNUSED(str) )
+{
+ return FALSE;
+}
+
+bool wxPropertySheet::Load( ostream& WXUNUSED(str) )
+{
+ return FALSE;
+}
+
+void wxPropertySheet::UpdateAllViews( wxPropertyView *WXUNUSED(thisView) )
+{
+}
+
+// Add a property
+void wxPropertySheet::AddProperty(wxProperty *property)
+{
+ m_properties.Append(property->GetName().GetData(), property);
+}
+
+// Get property by name
+wxProperty *wxPropertySheet::GetProperty(wxString name)
+{
+ wxNode *node = m_properties.Find(name.GetData());
+ if (!node)
+ return NULL;
+ else
+ return (wxProperty *)node->Data();
+}
+
+// Clear all properties
+void wxPropertySheet::Clear(void)
+{
+ wxNode *node = m_properties.First();
+ while (node)
+ {
+ wxProperty *prop = (wxProperty *)node->Data();
+ wxNode *next = node->Next();
+ delete prop;
+ delete node;
+ node = next;
+ }
+}
+
+// Sets/clears the modified flag for each property value
+void wxPropertySheet::SetAllModified(bool flag)
+{
+ wxNode *node = m_properties.First();
+ while (node)
+ {
+ wxProperty *prop = (wxProperty *)node->Data();
+ prop->GetValue().SetModified(flag);
+ node = node->Next();
+ }
+}
+
+/*
+ * Property validator registry
+ *
+ */
+
+IMPLEMENT_DYNAMIC_CLASS(wxPropertyValidatorRegistry, wxHashTable)
+
+wxPropertyValidatorRegistry::wxPropertyValidatorRegistry(void):wxHashTable(wxKEY_STRING)
+{
+}
+
+wxPropertyValidatorRegistry::~wxPropertyValidatorRegistry(void)
+{
+ ClearRegistry();
+}
+
+void wxPropertyValidatorRegistry::RegisterValidator(wxString& typeName, wxPropertyValidator *validator)
+{
+ Put(typeName.GetData(), validator);
+}
+
+wxPropertyValidator *wxPropertyValidatorRegistry::GetValidator(wxString& typeName)
+{
+ return (wxPropertyValidator *)Get(typeName.GetData());
+}
+
+void wxPropertyValidatorRegistry::ClearRegistry(void)
+{
+ BeginFind();
+ wxNode *node;
+ while (node = Next())
+ {
+ delete (wxPropertyValidator *)node->Data();
+ }
+}
+
+ /*
+ * Property validator
+ */
+
+
+IMPLEMENT_ABSTRACT_CLASS(wxPropertyValidator, wxEvtHandler)
+
+wxPropertyValidator::wxPropertyValidator(long flags)
+{
+ m_validatorFlags = flags;
+ m_validatorProperty = NULL;
+}
+
+wxPropertyValidator::~wxPropertyValidator(void)
+{}
+
+bool wxPropertyValidator::StringToFloat (char *s, float *number) {
+ double num;
+ bool ok = StringToDouble (s, &num);
+ *number = (float) num;
+ return ok;
+}
+
+bool wxPropertyValidator::StringToDouble (char *s, double *number) {
+ bool ok = TRUE;
+ char *value_ptr;
+ *number = strtod (s, &value_ptr);
+ if (value_ptr) {
+ int len = strlen (value_ptr);
+ for (int i = 0; i < len; i++) {
+ ok = (isspace (value_ptr[i]) != 0);
+ if (!ok) return FALSE;
+ }
+ }
+ return ok;
+}
+
+bool wxPropertyValidator::StringToInt (char *s, int *number) {
+ long num;
+ bool ok = StringToLong (s, &num);
+ *number = (int) num;
+ return ok;
+}
+
+bool wxPropertyValidator::StringToLong (char *s, long *number) {
+ bool ok = TRUE;
+ char *value_ptr;
+ *number = strtol (s, &value_ptr, 10);
+ if (value_ptr) {
+ int len = strlen (value_ptr);
+ for (int i = 0; i < len; i++) {
+ ok = (isspace (value_ptr[i]) != 0);
+ if (!ok) return FALSE;
+ }
+ }
+ return ok;
+}
+
+char *wxPropertyValidator::FloatToString (float number) {
+ static char buf[20];
+ sprintf (buf, "%.6g", number);
+ return buf;
+}
+
+char *wxPropertyValidator::DoubleToString (double number) {
+ static char buf[20];
+ sprintf (buf, "%.6g", number);
+ return buf;
+}
+
+char *wxPropertyValidator::IntToString (int number) {
+ return ::IntToString (number);
+}
+
+char *wxPropertyValidator::LongToString (long number) {
+ return ::LongToString (number);
+ }
+
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: prop.h
+// Purpose: Property sheet classes
+// Author: Julian Smart
+// Modified by:
+// Created: 04/01/98
+// RCS-ID: $Id$
+// Copyright: (c) Julian Smart
+// Licence: wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef _PROP_H_
+#define _PROP_H_
+
+#ifdef __GNUG__
+#pragma interface "prop.h"
+#endif
+
+#include "wx/defs.h"
+#include "wx/string.h"
+#include "wx/hash.h"
+#include "wx/dialog.h"
+#include "wx/frame.h"
+#include "wx/button.h"
+#include "wx/listbox.h"
+#include "wx/textctrl.h"
+#include "wx/gdicmn.h"
+#include "wx/layout.h"
+
+class wxWindow;
+class wxProperty;
+class wxPropertyValue;
+class wxPropertySheet;
+class wxPropertyView;
+class wxPropertyValidator;
+class wxPropertyValidatorRegistry;
+
+#define wxPROPERTY_VERSION 2.0
+
+// A storable sheet of values
+class wxPropertySheet: public wxObject
+{
+ DECLARE_DYNAMIC_CLASS(wxPropertySheet)
+ public:
+ wxPropertySheet(void);
+ ~wxPropertySheet(void);
+
+ // Add a property
+ virtual void AddProperty(wxProperty *property);
+
+ // Get property by name
+ virtual wxProperty *GetProperty(wxString name);
+
+ // Clear all properties
+ virtual void Clear(void);
+
+ virtual bool Save(ostream& str);
+ virtual bool Load(ostream& str);
+
+ virtual void UpdateAllViews(wxPropertyView *thisView = NULL);
+ inline virtual wxList& GetProperties(void) const { return (wxList&) m_properties; }
+
+ // Sets/clears the modified flag for each property value
+ virtual void SetAllModified(bool flag = TRUE);
+
+ protected:
+ wxObject* m_viewedObject;
+ wxList m_properties;
+ wxPropertyView* m_propertyView;
+
+};
+
+
+// Base class for property sheet views. There are currently two directly derived
+// classes: wxPropertyListView, and wxPropertyFormView.
+class wxPropertyView: public wxEvtHandler
+{
+ DECLARE_DYNAMIC_CLASS(wxPropertyView)
+ public:
+ wxPropertyView(long flags = 0);
+ ~wxPropertyView(void);
+
+ // Associates and shows the view
+ virtual void ShowView(wxPropertySheet *WXUNUSED(propertySheet), wxWindow *WXUNUSED(panel)) {}
+
+ // Update this view of the viewed object, called e.g. by
+ // the object itself.
+ virtual bool OnUpdateView(void) {return FALSE;};
+
+ // Override this to do something as soon as the property changed,
+ // if the view and validators support it.
+ virtual void OnPropertyChanged(wxProperty *WXUNUSED(property)) {}
+
+ virtual void AddRegistry(wxPropertyValidatorRegistry *registry);
+ inline virtual wxList& GetRegistryList(void) const
+ { return (wxList&) m_validatorRegistryList; }
+
+ virtual wxPropertyValidator *FindPropertyValidator(wxProperty *property);
+ inline virtual void SetPropertySheet(wxPropertySheet *sheet) { m_propertySheet = sheet; }
+ inline virtual wxPropertySheet *GetPropertySheet(void) const { return m_propertySheet; }
+
+ virtual void OnOk(void) {};
+ virtual void OnCancel(void) {};
+ virtual void OnHelp(void) {};
+
+ inline virtual bool OnClose(void) { return FALSE; }
+ inline long GetFlags(void) { return m_buttonFlags; }
+
+ protected:
+ long m_buttonFlags;
+ wxPropertySheet* m_propertySheet;
+ wxProperty* m_currentProperty;
+ wxList m_validatorRegistryList;
+ wxPropertyValidator* m_currentValidator;
+};
+
+
+class wxPropertyValidator: public wxEvtHandler
+{
+ DECLARE_DYNAMIC_CLASS(wxPropertyValidator)
+ public:
+ wxPropertyValidator(long flags = 0);
+ ~wxPropertyValidator(void);
+
+ inline long GetFlags(void) const { return m_validatorFlags; }
+ inline void SetValidatorProperty(wxProperty *prop) { m_validatorProperty = prop; }
+ inline wxProperty *GetValidatorProperty(void) const { return m_validatorProperty; }
+
+ virtual bool StringToFloat (char *s, float *number);
+ virtual bool StringToDouble (char *s, double *number);
+ virtual bool StringToInt (char *s, int *number);
+ virtual bool StringToLong (char *s, long *number);
+ virtual char *FloatToString (float number);
+ virtual char *DoubleToString (double number);
+ virtual char *IntToString (int number);
+ virtual char *LongToString (long number);
+
+ protected:
+ long m_validatorFlags;
+ wxProperty* m_validatorProperty;
+};
+
+
+// extern wxPropertyValidator *wxDefaultPropertyValidator;
+
+class wxPropertyValidatorRegistry: public wxHashTable
+{
+ DECLARE_DYNAMIC_CLASS(wxPropertyValidatorRegistry)
+ public:
+ wxPropertyValidatorRegistry(void);
+ ~wxPropertyValidatorRegistry(void);
+
+ virtual void RegisterValidator(wxString& roleName, wxPropertyValidator *validator);
+ virtual wxPropertyValidator *GetValidator(wxString& roleName);
+ void ClearRegistry(void);
+};
+
+/*
+ * Property value class
+ */
+
+typedef enum {
+ wxPropertyValueNull,
+ wxPropertyValueInteger,
+ wxPropertyValueReal,
+ wxPropertyValuebool,
+ wxPropertyValueString,
+ wxPropertyValueList,
+ wxPropertyValueIntegerPtr,
+ wxPropertyValueRealPtr,
+ wxPropertyValueboolPtr,
+ wxPropertyValueStringPtr
+} wxPropertyValueType;
+
+class wxPropertyValue: public wxObject
+{
+ DECLARE_DYNAMIC_CLASS(wxPropertyValue)
+
+ wxPropertyValue(void); // Unknown type
+ wxPropertyValue(const wxPropertyValue& copyFrom); // Copy constructor
+ wxPropertyValue(const char *val);
+ wxPropertyValue(const wxString& val);
+ wxPropertyValue(long val);
+ wxPropertyValue(bool val);
+ wxPropertyValue(float val);
+ wxPropertyValue(double the_real);
+ wxPropertyValue(wxList *val);
+ wxPropertyValue(wxStringList *val);
+ // Pointer versions
+ wxPropertyValue(char **val);
+ wxPropertyValue(long *val);
+ wxPropertyValue(bool *val);
+ wxPropertyValue(float *val);
+
+ ~wxPropertyValue(void);
+
+ virtual inline wxPropertyValueType Type(void) const { return m_type; }
+ virtual inline void SetType(wxPropertyValueType typ) { m_type = typ; }
+ virtual long IntegerValue(void) const;
+ virtual float RealValue(void) const;
+ virtual bool BoolValue(void) const;
+ virtual char *StringValue(void) const;
+ virtual long *IntegerValuePtr(void) const;
+ virtual float *RealValuePtr(void) const;
+ virtual bool *BoolValuePtr(void) const;
+ virtual char **StringValuePtr(void) const;
+
+ // Get nth arg of clause (starting from 1)
+ virtual wxPropertyValue *Arg(wxPropertyValueType type, int arg) const;
+
+ // Return nth argument of a list expression (starting from zero)
+ virtual wxPropertyValue *Nth(int arg) const;
+ // Returns the number of elements in a list expression
+ virtual int Number(void) const;
+
+ virtual wxPropertyValue *NewCopy(void) const;
+ virtual void Copy(wxPropertyValue& copyFrom);
+
+ virtual void WritePropertyClause(ostream& stream); // Write this expression as a top-level clause
+ virtual void WritePropertyType(ostream& stream); // Write as any other subexpression
+
+ // Append an expression to a list
+ virtual void Append(wxPropertyValue *expr);
+ // Insert at beginning of list
+ virtual void Insert(wxPropertyValue *expr);
+
+ // Get first expr in list
+ virtual inline wxPropertyValue *GetFirst(void) const
+ { return ((m_type == wxPropertyValueList) ? m_value.first : (wxPropertyValue*)NULL); }
+
+ // Get next expr if this is a node in a list
+ virtual inline wxPropertyValue *GetNext(void) const
+ { return m_next; }
+
+ // Get last expr in list
+ virtual inline wxPropertyValue *GetLast(void) const
+ { return ((m_type == wxPropertyValueList) ? m_last : (wxPropertyValue*)NULL); }
+
+ // Delete this node from the list
+ virtual void Delete(wxPropertyValue *node);
+
+ // Clear list
+ virtual void ClearList(void);
+
+ virtual inline void SetClientData(wxObject *data) { m_clientData = data; }
+ virtual inline wxObject *GetClientData(void) { return m_clientData; }
+
+ virtual wxString GetStringRepresentation(void);
+
+ inline void SetModified(bool flag = TRUE) { m_modifiedFlag = flag; }
+ inline bool GetModified(void) { return m_modifiedFlag; }
+
+ // Operators
+ void operator=(const wxPropertyValue& val);
+// void operator=(const char *val);
+ void operator=(const wxString& val);
+ void operator=(const long val);
+ void operator=(const bool val);
+ void operator=(const float val);
+ void operator=(const char **val);
+ void operator=(const long *val);
+ void operator=(const bool *val);
+ void operator=(const float *val);
+
+ public:
+ wxObject* m_clientData;
+ wxPropertyValueType m_type;
+ bool m_modifiedFlag;
+
+ union {
+ long integer; // Also doubles as bool
+ char *string;
+ float real;
+ long *integerPtr;
+ bool *boolPtr;
+ char **stringPtr;
+ float *realPtr;
+ wxPropertyValue *first; // If is a list expr, points to the first node
+ } m_value;
+
+ wxPropertyValue* m_next; // If this is a node in a list, points to the next node
+ wxPropertyValue* m_last; // If is a list expr, points to the last node
+
+};
+
+/*
+ * Property class: contains a name and a value.
+ */
+
+class wxProperty: public wxObject
+{
+ DECLARE_DYNAMIC_CLASS(wxProperty)
+ protected:
+ bool m_enabled;
+ public:
+ wxPropertyValue m_value;
+ wxString m_name;
+ wxString m_propertyRole;
+ wxPropertyValidator* m_propertyValidator;
+ wxWindow* m_propertyWindow; // Usually a panel item, if anything
+
+ wxProperty(void);
+ wxProperty(wxProperty& copyFrom);
+ wxProperty(wxString name, wxString role, wxPropertyValidator *ed = NULL);
+ wxProperty(wxString name, const wxPropertyValue& val, wxString role, wxPropertyValidator *ed = NULL);
+ ~wxProperty(void);
+
+ virtual wxPropertyValue& GetValue(void) const;
+ virtual wxPropertyValidator *GetValidator(void) const;
+ virtual wxString& GetName(void) const;
+ virtual wxString& GetRole(void) const;
+ virtual void SetValue(const wxPropertyValue& val);
+ virtual void SetValidator(wxPropertyValidator *v);
+ virtual void SetName(wxString& nm);
+ virtual void SetRole(wxString& role);
+ void operator=(const wxPropertyValue& val);
+ virtual inline void SetWindow(wxWindow *win) { m_propertyWindow = win; }
+ virtual inline wxWindow *GetWindow(void) const { return m_propertyWindow; }
+
+ inline void Enable(bool en) { m_enabled = en; }
+ inline bool IsEnabled(void) const { return m_enabled; }
+};
+
+#endif
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: propform.cpp
+// Purpose: Property form classes
+// Author: Julian Smart
+// Modified by:
+// Created: 04/01/98
+// RCS-ID: $Id$
+// Copyright: (c) Julian Smart
+// Licence: wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "propform.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 <ctype.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+
+#if wxUSE_IOSTREAMH
+#if defined(__WXMSW__) && !defined(__GNUWIN32__)
+#include <strstrea.h>
+#else
+#include <strstream.h>
+#endif
+#else
+#include <strstream>
+#endif
+
+#include "wx/window.h"
+#include "wx/utils.h"
+#include "wx/list.h"
+#include "propform.h"
+
+/*
+ * Property view
+ */
+
+IMPLEMENT_DYNAMIC_CLASS(wxPropertyFormView, wxPropertyView)
+
+BEGIN_EVENT_TABLE(wxPropertyFormView, wxPropertyView)
+ EVT_BUTTON(wxID_OK, wxPropertyFormView::OnOk)
+ EVT_BUTTON(wxID_CANCEL, wxPropertyFormView::OnCancel)
+ EVT_BUTTON(wxID_HELP, wxPropertyFormView::OnHelp)
+ EVT_BUTTON(wxID_PROP_REVERT, wxPropertyFormView::OnRevert)
+ EVT_BUTTON(wxID_PROP_UPDATE, wxPropertyFormView::OnUpdate)
+END_EVENT_TABLE()
+
+bool wxPropertyFormView::sm_dialogCancelled = FALSE;
+
+wxPropertyFormView::wxPropertyFormView(wxWindow *propPanel, long flags):wxPropertyView(flags)
+{
+ m_propertyWindow = propPanel;
+ m_managedWindow = NULL;
+
+ m_windowCloseButton = NULL;
+ m_windowCancelButton = NULL;
+ m_windowHelpButton = NULL;
+
+ m_detailedEditing = FALSE;
+}
+
+wxPropertyFormView::~wxPropertyFormView(void)
+{
+}
+
+void wxPropertyFormView::ShowView(wxPropertySheet *ps, wxWindow *panel)
+{
+ m_propertySheet = ps;
+
+ AssociatePanel(panel);
+// CreateControls();
+// UpdatePropertyList();
+}
+
+// Update this view of the viewed object, called e.g. by
+// the object itself.
+bool wxPropertyFormView::OnUpdateView(void)
+{
+ return TRUE;
+}
+
+bool wxPropertyFormView::Check(void)
+{
+ if (!m_propertySheet)
+ return FALSE;
+
+ wxNode *node = m_propertySheet->GetProperties().First();
+ while (node)
+ {
+ wxProperty *prop = (wxProperty *)node->Data();
+ wxPropertyValidator *validator = FindPropertyValidator(prop);
+ if (validator && validator->IsKindOf(CLASSINFO(wxPropertyFormValidator)))
+ {
+ wxPropertyFormValidator *formValidator = (wxPropertyFormValidator *)validator;
+ if (!formValidator->OnCheckValue(prop, this, m_propertyWindow))
+ return FALSE;
+ }
+ node = node->Next();
+ }
+ return TRUE;
+}
+
+bool wxPropertyFormView::TransferToPropertySheet(void)
+{
+ if (!m_propertySheet)
+ return FALSE;
+
+ wxNode *node = m_propertySheet->GetProperties().First();
+ while (node)
+ {
+ wxProperty *prop = (wxProperty *)node->Data();
+ wxPropertyValidator *validator = FindPropertyValidator(prop);
+ if (validator && validator->IsKindOf(CLASSINFO(wxPropertyFormValidator)))
+ {
+ wxPropertyFormValidator *formValidator = (wxPropertyFormValidator *)validator;
+ formValidator->OnRetrieveValue(prop, this, m_propertyWindow);
+ }
+ node = node->Next();
+ }
+ return TRUE;
+}
+
+bool wxPropertyFormView::TransferToDialog(void)
+{
+ if (!m_propertySheet)
+ return FALSE;
+
+ wxNode *node = m_propertySheet->GetProperties().First();
+ while (node)
+ {
+ wxProperty *prop = (wxProperty *)node->Data();
+ wxPropertyValidator *validator = FindPropertyValidator(prop);
+ if (validator && validator->IsKindOf(CLASSINFO(wxPropertyFormValidator)))
+ {
+ wxPropertyFormValidator *formValidator = (wxPropertyFormValidator *)validator;
+ formValidator->OnDisplayValue(prop, this, m_propertyWindow);
+ }
+ node = node->Next();
+ }
+ return TRUE;
+}
+
+bool wxPropertyFormView::AssociateNames(void)
+{
+ if (!m_propertySheet || !m_propertyWindow)
+ return FALSE;
+
+ wxNode *node = m_propertyWindow->GetChildren()->First();
+ while (node)
+ {
+ wxWindow *win = (wxWindow *)node->Data();
+ if (win->GetName() != "")
+ {
+ wxProperty *prop = m_propertySheet->GetProperty(win->GetName());
+ if (prop)
+ prop->SetWindow(win);
+ }
+ node = node->Next();
+ }
+ return TRUE;
+}
+
+
+bool wxPropertyFormView::OnClose(void)
+{
+ delete this;
+ return TRUE;
+}
+
+void wxPropertyFormView::OnOk(wxCommandEvent& WXUNUSED(event))
+{
+ // Retrieve the value if any
+ if (!Check())
+ return;
+
+ sm_dialogCancelled = FALSE;
+
+ m_managedWindow->Close(TRUE);
+}
+
+void wxPropertyFormView::OnCancel(wxCommandEvent& WXUNUSED(event))
+{
+ sm_dialogCancelled = TRUE;
+
+ m_managedWindow->Close(TRUE);
+}
+
+void wxPropertyFormView::OnHelp(wxCommandEvent& WXUNUSED(event))
+{
+}
+
+void wxPropertyFormView::OnUpdate(wxCommandEvent& WXUNUSED(event))
+{
+ TransferToPropertySheet();
+}
+
+void wxPropertyFormView::OnRevert(wxCommandEvent& WXUNUSED(event))
+{
+ TransferToDialog();
+}
+
+void wxPropertyFormView::OnCommand(wxWindow& win, wxCommandEvent& event)
+{
+ if (!m_propertySheet)
+ return;
+
+ if (win.GetName() == "")
+ return;
+
+ if (strcmp(win.GetName(), "ok") == 0)
+ OnOk(event);
+ else if (strcmp(win.GetName(), "cancel") == 0)
+ OnCancel(event);
+ else if (strcmp(win.GetName(), "help") == 0)
+ OnHelp(event);
+ else if (strcmp(win.GetName(), "update") == 0)
+ OnUpdate(event);
+ else if (strcmp(win.GetName(), "revert") == 0)
+ OnRevert(event);
+ else
+ {
+ // Find a validator to route the command to.
+ wxNode *node = m_propertySheet->GetProperties().First();
+ while (node)
+ {
+ wxProperty *prop = (wxProperty *)node->Data();
+ if (prop->GetWindow() && (prop->GetWindow() == &win))
+ {
+ wxPropertyValidator *validator = FindPropertyValidator(prop);
+ if (validator && validator->IsKindOf(CLASSINFO(wxPropertyFormValidator)))
+ {
+ wxPropertyFormValidator *formValidator = (wxPropertyFormValidator *)validator;
+ formValidator->OnCommand(prop, this, m_propertyWindow, event);
+ return;
+ }
+ }
+ node = node->Next();
+ }
+ }
+}
+
+void wxPropertyFormView::OnDoubleClick(wxControl *item)
+{
+ if (!m_propertySheet)
+ return;
+
+ // Find a validator to route the command to.
+ wxNode *node = m_propertySheet->GetProperties().First();
+ while (node)
+ {
+ wxProperty *prop = (wxProperty *)node->Data();
+ if (prop->GetWindow() && ((wxControl *)prop->GetWindow() == item))
+ {
+ wxPropertyValidator *validator = FindPropertyValidator(prop);
+ if (validator && validator->IsKindOf(CLASSINFO(wxPropertyFormValidator)))
+ {
+ wxPropertyFormValidator *formValidator = (wxPropertyFormValidator *)validator;
+ formValidator->OnDoubleClick(prop, this, m_propertyWindow);
+ return;
+ }
+ }
+ node = node->Next();
+ }
+}
+
+/*
+ * Property form dialog box
+ */
+
+IMPLEMENT_CLASS(wxPropertyFormDialog, wxDialog)
+
+wxPropertyFormDialog::wxPropertyFormDialog(wxPropertyFormView *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)
+{
+ m_view = v;
+ m_view->AssociatePanel(this);
+ m_view->SetManagedWindow(this);
+// SetAutoLayout(TRUE);
+}
+
+bool wxPropertyFormDialog::OnClose(void)
+{
+ if (m_view)
+ {
+ m_view->OnClose();
+ m_view = NULL;
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+void wxPropertyFormDialog::OnDefaultAction(wxControl *item)
+{
+ m_view->OnDoubleClick(item);
+}
+
+void wxPropertyFormDialog::OnCommand(wxWindow& win, wxCommandEvent& event)
+{
+ if ( m_view )
+ m_view->OnCommand(win, event);
+}
+
+// Extend event processing to search the view's event table
+bool wxPropertyFormDialog::ProcessEvent(wxEvent& event)
+{
+ if ( !m_view || ! m_view->ProcessEvent(event) )
+ return wxEvtHandler::ProcessEvent(event);
+ else
+ return TRUE;
+}
+
+
+/*
+ * Property form panel
+ */
+
+IMPLEMENT_CLASS(wxPropertyFormPanel, wxPanel)
+
+void wxPropertyFormPanel::OnDefaultAction(wxControl *item)
+{
+ m_view->OnDoubleClick(item);
+}
+
+void wxPropertyFormPanel::OnCommand(wxWindow& win, wxCommandEvent& event)
+{
+ m_view->OnCommand(win, event);
+}
+
+// Extend event processing to search the view's event table
+bool wxPropertyFormPanel::ProcessEvent(wxEvent& event)
+{
+ if ( !m_view || ! m_view->ProcessEvent(event) )
+ return wxEvtHandler::ProcessEvent(event);
+ else
+ return TRUE;
+}
+
+/*
+ * Property frame
+ */
+
+IMPLEMENT_CLASS(wxPropertyFormFrame, wxFrame)
+
+bool wxPropertyFormFrame::OnClose(void)
+{
+ if (m_view)
+ return m_view->OnClose();
+ else
+ return FALSE;
+}
+
+wxPanel *wxPropertyFormFrame::OnCreatePanel(wxFrame *parent, wxPropertyFormView *v)
+{
+ return new wxPropertyFormPanel(v, parent);
+}
+
+bool wxPropertyFormFrame::Initialize(void)
+{
+ m_propertyPanel = OnCreatePanel(this, m_view);
+ if (m_propertyPanel)
+ {
+ m_view->AssociatePanel(m_propertyPanel);
+ m_view->SetManagedWindow(this);
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+ /*
+ * Property form specific validator
+ */
+
+IMPLEMENT_ABSTRACT_CLASS(wxPropertyFormValidator, wxPropertyValidator)
+
+
+/*
+ * Default validators
+ */
+
+IMPLEMENT_DYNAMIC_CLASS(wxRealFormValidator, wxPropertyFormValidator)
+
+///
+/// Real number form validator
+///
+bool wxRealFormValidator::OnCheckValue( wxProperty *property, wxPropertyFormView *WXUNUSED(view),
+ wxWindow *parentWindow)
+{
+ if (m_realMin == 0.0 && m_realMax == 0.0)
+ return TRUE;
+
+ // The item used for viewing the real number: should be a text item.
+ wxWindow *m_propertyWindow = property->GetWindow();
+ if (!m_propertyWindow || !m_propertyWindow->IsKindOf(CLASSINFO(wxTextCtrl)))
+ return FALSE;
+
+ wxString value(((wxTextCtrl *)m_propertyWindow)->GetValue());
+
+ float val = 0.0;
+ if (!StringToFloat(WXSTRINGCAST value, &val))
+ {
+ char buf[200];
+ sprintf(buf, "Value %s is not a valid real number!", (const char *)value);
+ wxMessageBox(buf, "Property value error", wxOK | wxICON_EXCLAMATION, parentWindow);
+ return FALSE;
+ }
+
+ if (val < m_realMin || val > m_realMax)
+ {
+ char buf[200];
+ sprintf(buf, "Value must be a real number between %.2f and %.2f!", m_realMin, m_realMax);
+ wxMessageBox(buf, "Property value error", wxOK | wxICON_EXCLAMATION, parentWindow);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool wxRealFormValidator::OnRetrieveValue(wxProperty *property, wxPropertyFormView *WXUNUSED(view),
+ wxWindow *WXUNUSED(parentWindow) )
+{
+ // The item used for viewing the real number: should be a text item.
+ wxWindow *m_propertyWindow = property->GetWindow();
+ if (!m_propertyWindow || !m_propertyWindow->IsKindOf(CLASSINFO(wxTextCtrl)))
+ return FALSE;
+
+ wxString value(((wxTextCtrl *)m_propertyWindow)->GetValue());
+
+ if (value.Length() == 0)
+ return FALSE;
+
+ float f = (float)atof((const char *)value);
+ property->GetValue() = f;
+ return TRUE;
+}
+
+bool wxRealFormValidator::OnDisplayValue(wxProperty *property, wxPropertyFormView *WXUNUSED(view),
+ wxWindow *WXUNUSED(parentWindow) )
+{
+ // The item used for viewing the real number: should be a text item.
+ wxWindow *m_propertyWindow = property->GetWindow();
+ if (!m_propertyWindow || !m_propertyWindow->IsKindOf(CLASSINFO(wxTextCtrl)))
+ return FALSE;
+
+ wxTextCtrl *textItem = (wxTextCtrl *)m_propertyWindow;
+ textItem->SetValue(FloatToString(property->GetValue().RealValue()));
+ return TRUE;
+}
+
+///
+/// Integer validator
+///
+IMPLEMENT_DYNAMIC_CLASS(wxIntegerFormValidator, wxPropertyFormValidator)
+
+bool wxIntegerFormValidator::OnCheckValue(wxProperty *property, wxPropertyFormView *WXUNUSED(view),
+ wxWindow *parentWindow)
+{
+ if (m_integerMin == 0.0 && m_integerMax == 0.0)
+ return TRUE;
+
+ // The item used for viewing the real number: should be a text item or a slider
+ wxWindow *m_propertyWindow = property->GetWindow();
+ if (!m_propertyWindow)
+ return FALSE;
+
+ long val = 0;
+
+ if (m_propertyWindow->IsKindOf(CLASSINFO(wxTextCtrl)))
+ {
+ wxString value(((wxTextCtrl *)m_propertyWindow)->GetValue());
+
+ if (!StringToLong(WXSTRINGCAST value, &val))
+ {
+ char buf[200];
+ sprintf(buf, "Value %s is not a valid integer!", (const char *)value);
+ wxMessageBox(buf, "Property value error", wxOK | wxICON_EXCLAMATION, parentWindow);
+ return FALSE;
+ }
+ }
+ else if (m_propertyWindow->IsKindOf(CLASSINFO(wxSlider)))
+ {
+ val = (long)((wxSlider *)m_propertyWindow)->GetValue();
+ }
+ else
+ return FALSE;
+
+ if (val < m_integerMin || val > m_integerMax)
+ {
+ char buf[200];
+ sprintf(buf, "Value must be an integer between %ld and %ld!", m_integerMin, m_integerMax);
+ wxMessageBox(buf, "Property value error", wxOK | wxICON_EXCLAMATION, parentWindow);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool wxIntegerFormValidator::OnRetrieveValue(wxProperty *property, wxPropertyFormView *WXUNUSED(view),
+ wxWindow *WXUNUSED(parentWindow))
+{
+ // The item used for viewing the real number: should be a text item or a slider
+ wxWindow *m_propertyWindow = property->GetWindow();
+ if (!m_propertyWindow)
+ return FALSE;
+
+ if (m_propertyWindow->IsKindOf(CLASSINFO(wxTextCtrl)))
+ {
+ wxString value(((wxTextCtrl *)m_propertyWindow)->GetValue());
+
+ if (value.Length() == 0)
+ return FALSE;
+
+ long i = atol((const char *)value);
+ property->GetValue() = i;
+ }
+ else if (m_propertyWindow->IsKindOf(CLASSINFO(wxSlider)))
+ {
+ property->GetValue() = (long)((wxSlider *)m_propertyWindow)->GetValue();
+ }
+ else
+ return FALSE;
+
+ return TRUE;
+}
+
+bool wxIntegerFormValidator::OnDisplayValue( wxProperty *property, wxPropertyFormView *WXUNUSED(view),
+ wxWindow *WXUNUSED(parentWindow))
+{
+ // The item used for viewing the real number: should be a text item or a slider
+ wxWindow *m_propertyWindow = property->GetWindow();
+ if (!m_propertyWindow)
+ return FALSE;
+
+ if (m_propertyWindow->IsKindOf(CLASSINFO(wxTextCtrl)))
+ {
+ wxTextCtrl *textItem = (wxTextCtrl *)m_propertyWindow;
+ textItem->SetValue(LongToString(property->GetValue().IntegerValue()));
+ }
+ else if (m_propertyWindow->IsKindOf(CLASSINFO(wxSlider)))
+ {
+ ((wxSlider *)m_propertyWindow)->SetValue((int)property->GetValue().IntegerValue());
+ }
+ else
+ return FALSE;
+ return TRUE;
+}
+
+///
+/// Boolean validator
+///
+IMPLEMENT_DYNAMIC_CLASS(wxBoolFormValidator, wxPropertyFormValidator)
+
+bool wxBoolFormValidator::OnCheckValue(wxProperty *property, wxPropertyFormView *WXUNUSED(view),
+ wxWindow *WXUNUSED(parentWindow))
+{
+ // The item used for viewing the boolean: should be a checkbox
+ wxWindow *m_propertyWindow = property->GetWindow();
+ if (!m_propertyWindow || !m_propertyWindow->IsKindOf(CLASSINFO(wxCheckBox)))
+ return FALSE;
+
+ return TRUE;
+}
+
+bool wxBoolFormValidator::OnRetrieveValue(wxProperty *property, wxPropertyFormView *WXUNUSED(view),
+ wxWindow *WXUNUSED(parentWindow) )
+{
+ // The item used for viewing the boolean: should be a checkbox.
+ wxWindow *m_propertyWindow = property->GetWindow();
+ if (!m_propertyWindow || !m_propertyWindow->IsKindOf(CLASSINFO(wxCheckBox)))
+ return FALSE;
+
+ wxCheckBox *checkBox = (wxCheckBox *)m_propertyWindow;
+
+ property->GetValue() = (bool)checkBox->GetValue();
+ return TRUE;
+}
+
+bool wxBoolFormValidator::OnDisplayValue(wxProperty *property, wxPropertyFormView *WXUNUSED(view),
+ wxWindow *WXUNUSED(parentWindow))
+{
+ // The item used for viewing the boolean: should be a checkbox.
+ wxWindow *m_propertyWindow = property->GetWindow();
+ if (!m_propertyWindow || !m_propertyWindow->IsKindOf(CLASSINFO(wxCheckBox)))
+ return FALSE;
+
+ wxCheckBox *checkBox = (wxCheckBox *)m_propertyWindow;
+ checkBox->SetValue((bool)property->GetValue().BoolValue());
+ return TRUE;
+}
+
+///
+/// String validator
+///
+IMPLEMENT_DYNAMIC_CLASS(wxStringFormValidator, wxPropertyFormValidator)
+
+wxStringFormValidator::wxStringFormValidator(wxStringList *list, long flags):
+ wxPropertyFormValidator(flags)
+{
+ m_strings = list;
+}
+
+bool wxStringFormValidator::OnCheckValue(wxProperty *property, wxPropertyFormView *WXUNUSED(view),
+ wxWindow *parentWindow )
+{
+ if (!m_strings)
+ return TRUE;
+
+ // The item used for viewing the string: should be a text item, choice item or listbox.
+ wxWindow *m_propertyWindow = property->GetWindow();
+ if (!m_propertyWindow)
+ return FALSE;
+ if (m_propertyWindow->IsKindOf(CLASSINFO(wxTextCtrl)))
+ {
+ wxTextCtrl *text = (wxTextCtrl *)m_propertyWindow;
+ if (!m_strings->Member(text->GetValue()))
+ {
+ wxString s("Value ");
+ s += text->GetValue();
+ s += " is not valid.";
+ wxMessageBox(s, "Property value error", wxOK | wxICON_EXCLAMATION, parentWindow);
+ return FALSE;
+ }
+ }
+ else
+ {
+ // Any other item constrains the string value,
+ // so we don't have to check it.
+ }
+ return TRUE;
+}
+
+bool wxStringFormValidator::OnRetrieveValue(wxProperty *property, wxPropertyFormView *WXUNUSED(view),
+ wxWindow *WXUNUSED(parentWindow) )
+{
+ // The item used for viewing the string: should be a text item, choice item or listbox.
+ wxWindow *m_propertyWindow = property->GetWindow();
+ if (!m_propertyWindow)
+ return FALSE;
+ if (m_propertyWindow->IsKindOf(CLASSINFO(wxTextCtrl)))
+ {
+ wxTextCtrl *text = (wxTextCtrl *)m_propertyWindow;
+ property->GetValue() = text->GetValue();
+ }
+ else if (m_propertyWindow->IsKindOf(CLASSINFO(wxListBox)))
+ {
+ wxListBox *lbox = (wxListBox *)m_propertyWindow;
+ if (lbox->GetSelection() > -1)
+ property->GetValue() = lbox->GetStringSelection();
+ }
+/*
+ else if (m_propertyWindow->IsKindOf(CLASSINFO(wxRadioBox)))
+ {
+ wxRadioBox *rbox = (wxRadioBox *)m_propertyWindow;
+ int n = 0;
+ if ((n = rbox->GetSelection()) > -1)
+ property->GetValue() = rbox->GetString(n);
+ }
+*/
+ else if (m_propertyWindow->IsKindOf(CLASSINFO(wxChoice)))
+ {
+ wxChoice *choice = (wxChoice *)m_propertyWindow;
+ if (choice->GetSelection() > -1)
+ property->GetValue() = choice->GetStringSelection();
+ }
+ else
+ return FALSE;
+ return TRUE;
+}
+
+bool wxStringFormValidator::OnDisplayValue(wxProperty *property, wxPropertyFormView *WXUNUSED(view),
+ wxWindow *WXUNUSED(parentWindow) )
+{
+ // The item used for viewing the string: should be a text item, choice item or listbox.
+ wxWindow *m_propertyWindow = property->GetWindow();
+ if (!m_propertyWindow)
+ return FALSE;
+ if (m_propertyWindow->IsKindOf(CLASSINFO(wxTextCtrl)))
+ {
+ wxTextCtrl *text = (wxTextCtrl *)m_propertyWindow;
+ text->SetValue(property->GetValue().StringValue());
+ }
+ else if (m_propertyWindow->IsKindOf(CLASSINFO(wxListBox)))
+ {
+ wxListBox *lbox = (wxListBox *)m_propertyWindow;
+ if (lbox->Number() == 0 && m_strings)
+ {
+ // Try to initialize the listbox from 'strings'
+ wxNode *node = m_strings->First();
+ while (node)
+ {
+ char *s = (char *)node->Data();
+ lbox->Append(s);
+ node = node->Next();
+ }
+ }
+ lbox->SetStringSelection(property->GetValue().StringValue());
+ }
+/*
+ else if (m_propertyWindow->IsKindOf(CLASSINFO(wxRadioBox)))
+ {
+ wxRadioBox *rbox = (wxRadioBox *)m_propertyWindow;
+ rbox->SetStringSelection(property->GetValue().StringValue());
+ }
+*/
+ else if (m_propertyWindow->IsKindOf(CLASSINFO(wxChoice)))
+ {
+ wxChoice *choice = (wxChoice *)m_propertyWindow;
+#ifndef __XVIEW__
+ if (choice->Number() == 0 && m_strings)
+ {
+ // Try to initialize the choice item from 'strings'
+ // XView doesn't allow this kind of thing.
+ wxNode *node = m_strings->First();
+ while (node)
+ {
+ char *s = (char *)node->Data();
+ choice->Append(s);
+ node = node->Next();
+ }
+ }
+#endif
+ choice->SetStringSelection(property->GetValue().StringValue());
+ }
+ else
+ return FALSE;
+ return TRUE;
+}
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: propform.h
+// Purpose: Property form classes
+// Author: Julian Smart
+// Modified by:
+// Created: 04/01/98
+// RCS-ID: $Id$
+// Copyright: (c) Julian Smart
+// Licence: wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef _PROPFORM_H_
+#define _PROPFORM_H_
+
+#ifdef __GNUG__
+#pragma interface "propform.h"
+#endif
+
+#include "prop.h"
+
+////
+//// Property form classes: for using an existing dialog or panel
+////
+
+#define wxID_PROP_REVERT 3100
+#define wxID_PROP_UPDATE 3101
+
+// Mediates between a physical panel and the property sheet
+class wxPropertyFormView: public wxPropertyView
+{
+ DECLARE_DYNAMIC_CLASS(wxPropertyFormView)
+ public:
+ wxPropertyFormView(wxWindow *propPanel = NULL, long flags = 0);
+ ~wxPropertyFormView(void);
+
+ // Associates and shows the view
+ virtual void ShowView(wxPropertySheet *propertySheet, wxWindow *panel);
+
+ // Update this view of the viewed object, called e.g. by
+ // the object itself.
+ virtual bool OnUpdateView(void);
+
+ // Transfer values from property sheet to dialog
+ virtual bool TransferToDialog(void);
+
+ // Transfer values from dialog to property sheet
+ virtual bool TransferToPropertySheet(void);
+
+ // Check that all the values are valid
+ virtual bool Check(void);
+
+ // Give each property in the sheet a panel item, by matching
+ // the name of the property to the name of the panel item.
+ // The user doesn't always want to call this; sometimes, it
+ // will have been done explicitly (e.g., no matching names).
+ virtual bool AssociateNames(void);
+
+ void OnOk(wxCommandEvent& event);
+ void OnCancel(wxCommandEvent& event);
+ void OnHelp(wxCommandEvent& event);
+ void OnUpdate(wxCommandEvent& event);
+ void OnRevert(wxCommandEvent& event);
+
+ virtual bool OnClose(void);
+ virtual void OnDoubleClick(wxControl *item);
+
+ // TODO: does OnCommand still get called...???
+ virtual void OnCommand(wxWindow& win, wxCommandEvent& event);
+
+ inline virtual void AssociatePanel(wxWindow *win) { m_propertyWindow = win; }
+ inline virtual wxWindow *GetPanel(void) const { return m_propertyWindow; }
+
+ inline virtual void SetManagedWindow(wxWindow *win) { m_managedWindow = win; }
+ inline virtual wxWindow *GetManagedWindow(void) const { return m_managedWindow; }
+
+ inline virtual wxButton *GetWindowCloseButton() const { return m_windowCloseButton; }
+ inline virtual wxButton *GetWindowCancelButton() const { return m_windowCancelButton; }
+ inline virtual wxButton *GetHelpButton() const { return m_windowHelpButton; }
+
+public:
+ static bool sm_dialogCancelled;
+
+ protected:
+ bool m_detailedEditing; // E.g. using listbox for choices
+
+ wxWindow* m_propertyWindow; // Panel that the controls will appear on
+ wxWindow* m_managedWindow; // Frame or dialog
+
+ wxButton* m_windowCloseButton; // Or OK
+ wxButton* m_windowCancelButton;
+ wxButton* m_windowHelpButton;
+
+DECLARE_EVENT_TABLE()
+
+};
+
+/*
+ * The type of validator used for forms (wxForm style but using an existing panel
+ * or dialog box).
+ * Classes derived from this know how to map from whatever widget they
+ * find themselves paired with, to the wxProperty and vice versa.
+ * Should the widget pointer be stored with the validator, or
+ * the wxProperty? If with the property, we don't have to supply
+ * a validator for every property. Otherwise, there ALWAYS needs
+ * to be a validator. On the other hand, not storing a wxWindow pointer
+ * in the wxProperty is more elegant. Perhaps.
+ * I think on balance, should put wxWindow pointer into wxProperty.
+ * After all, wxProperty will often be used to represent the data
+ * assocated with a window. It's that kinda thing.
+ */
+
+class wxPropertyFormValidator: public wxPropertyValidator
+{
+ DECLARE_DYNAMIC_CLASS(wxPropertyFormValidator)
+ protected:
+ public:
+ wxPropertyFormValidator(long flags = 0): wxPropertyValidator(flags) { }
+ ~wxPropertyFormValidator(void) {}
+
+ // Called to check value is OK (e.g. when OK is pressed)
+ // Return FALSE if value didn't check out; signal to restore old value.
+ virtual bool OnCheckValue( wxProperty *WXUNUSED(property), wxPropertyFormView *WXUNUSED(view),
+ wxWindow *WXUNUSED(parentWindow) ) { return TRUE; }
+
+ // Does the transferance from the property editing area to the property itself.
+ // Called by the view, e.g. when closing the window.
+ virtual bool OnRetrieveValue(wxProperty *property, wxPropertyFormView *view, wxWindow *parentWindow) = 0;
+
+ // Called by the view to transfer the property to the window.
+ virtual bool OnDisplayValue(wxProperty *property, wxPropertyFormView *view, wxWindow *parentWindow) = 0;
+
+ virtual void OnDoubleClick( wxProperty *WXUNUSED(property), wxPropertyFormView *WXUNUSED(view),
+ wxWindow *WXUNUSED(parentWindow) ) { }
+ virtual void OnSetFocus( wxProperty *WXUNUSED(property), wxPropertyFormView *WXUNUSED(view),
+ wxWindow *WXUNUSED(parentWindow) ) { }
+ virtual void OnKillFocus( wxProperty *WXUNUSED(property), wxPropertyFormView *WXUNUSED(view),
+ wxWindow *WXUNUSED(parentWindow) ) { }
+ virtual void OnCommand( wxProperty *WXUNUSED(property), wxPropertyFormView *WXUNUSED(view),
+ wxWindow *WXUNUSED(parentWindow), wxCommandEvent& WXUNUSED(event) ) {}
+};
+
+/*
+ * Some default validators
+ */
+
+class wxRealFormValidator: public wxPropertyFormValidator
+{
+ DECLARE_DYNAMIC_CLASS(wxRealFormValidator)
+ public:
+ // 0.0, 0.0 means no range
+ wxRealFormValidator(float min = 0.0, float max = 0.0, long flags = 0):wxPropertyFormValidator(flags)
+ {
+ m_realMin = min; m_realMax = max;
+ }
+ ~wxRealFormValidator(void) {}
+
+ bool OnCheckValue(wxProperty *property, wxPropertyFormView *view, wxWindow *parentWindow);
+ bool OnRetrieveValue(wxProperty *property, wxPropertyFormView *view, wxWindow *parentWindow);
+ // Called by the view to transfer the property to the window.
+ bool OnDisplayValue(wxProperty *property, wxPropertyFormView *view, wxWindow *parentWindow);
+
+ protected:
+ float m_realMin;
+ float m_realMax;
+};
+
+class wxIntegerFormValidator: public wxPropertyFormValidator
+{
+ DECLARE_DYNAMIC_CLASS(wxIntegerFormValidator)
+ public:
+ // 0, 0 means no range
+ wxIntegerFormValidator(long min = 0, long max = 0, long flags = 0):wxPropertyFormValidator(flags)
+ {
+ m_integerMin = min; m_integerMax = max;
+ }
+ ~wxIntegerFormValidator(void) {}
+
+ bool OnCheckValue(wxProperty *property, wxPropertyFormView *view, wxWindow *parentWindow);
+ bool OnRetrieveValue(wxProperty *property, wxPropertyFormView *view, wxWindow *parentWindow);
+ bool OnDisplayValue(wxProperty *property, wxPropertyFormView *view, wxWindow *parentWindow);
+
+ protected:
+ long m_integerMin;
+ long m_integerMax;
+};
+
+class wxBoolFormValidator: public wxPropertyFormValidator
+{
+ DECLARE_DYNAMIC_CLASS(wxBoolFormValidator)
+ protected:
+ public:
+ wxBoolFormValidator(long flags = 0):wxPropertyFormValidator(flags)
+ {
+ }
+ ~wxBoolFormValidator(void) {}
+
+ bool OnCheckValue(wxProperty *property, wxPropertyFormView *view, wxWindow *parentWindow);
+ bool OnRetrieveValue(wxProperty *property, wxPropertyFormView *view, wxWindow *parentWindow);
+ bool OnDisplayValue(wxProperty *property, wxPropertyFormView *view, wxWindow *parentWindow);
+};
+
+class wxStringFormValidator: public wxPropertyFormValidator
+{
+ DECLARE_DYNAMIC_CLASS(wxStringFormValidator)
+ public:
+ wxStringFormValidator(wxStringList *list = NULL, long flags = 0);
+
+ ~wxStringFormValidator(void)
+ {
+ if (m_strings)
+ delete m_strings;
+ }
+
+ bool OnCheckValue(wxProperty *property, wxPropertyFormView *view, wxWindow *parentWindow);
+ bool OnRetrieveValue(wxProperty *property, wxPropertyFormView *view, wxWindow *parentWindow);
+ bool OnDisplayValue(wxProperty *property, wxPropertyFormView *view, wxWindow *parentWindow);
+
+ protected:
+ wxStringList* m_strings;
+};
+
+/*
+ * A default dialog box class to use.
+ */
+
+class wxPropertyFormDialog: public wxDialog
+{
+ DECLARE_CLASS(wxPropertyFormDialog)
+ public:
+ wxPropertyFormDialog(wxPropertyFormView *v, wxWindow *parent, const wxString& title,
+ const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
+ long style = wxDEFAULT_DIALOG_STYLE, const wxString& name = "dialogBox");
+ bool OnClose(void);
+ void OnDefaultAction(wxControl *item);
+ void OnCommand(wxWindow& win, wxCommandEvent& event);
+
+ // Extend event processing to search the view's event table
+ virtual bool ProcessEvent(wxEvent& event);
+
+ private:
+ wxPropertyFormView* m_view;
+};
+
+/*
+ * A default panel class to use.
+ */
+
+class wxPropertyFormPanel: public wxPanel
+{
+ DECLARE_CLASS(wxPropertyFormPanel)
+ public:
+ wxPropertyFormPanel(wxPropertyFormView *v, wxWindow *parent, const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize, long style = 0, const wxString& name = "panel"):
+ wxPanel(parent, -1, pos, size, style, name)
+ {
+ m_view = v;
+ }
+ void OnDefaultAction(wxControl *item);
+ void OnCommand(wxWindow& win, wxCommandEvent& event);
+
+ // Extend event processing to search the view's event table
+ virtual bool ProcessEvent(wxEvent& event);
+
+ private:
+ wxPropertyFormView* m_view;
+};
+
+/*
+ * A default frame class to use.
+ */
+
+class wxPropertyFormFrame: public wxFrame
+{
+ DECLARE_CLASS(wxPropertyFormFrame)
+ public:
+ wxPropertyFormFrame(wxPropertyFormView *v, wxFrame *parent, const wxString& title,
+ const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
+ long style = wxDEFAULT_FRAME, const wxString& name = "frame"):
+ wxFrame(parent, -1, title, pos, size, style, name)
+ {
+ m_view = v;
+ m_propertyPanel = NULL;
+ }
+ bool OnClose(void);
+
+ // Must call this to create panel and associate view
+ virtual bool Initialize(void);
+ virtual wxPanel *OnCreatePanel(wxFrame *parent, wxPropertyFormView *v);
+ inline virtual wxPanel *GetPropertyPanel(void) const { return m_propertyPanel; }
+
+ private:
+ wxPropertyFormView* m_view;
+ wxPanel* m_propertyPanel;
+};
+
+#endif
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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 <ctype.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+
+#if wxUSE_IOSTREAMH
+#if defined(__WXMSW__) && !defined(__GNUWIN32__)
+#include <strstrea.h>
+#else
+#include <strstream.h>
+#endif
+#else
+#include <strstream>
+#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)
+{
+ m_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_LISTBOX(wxID_PROP_VALUE_SELECT, wxPropertyListView::OnValueListSelect)
+END_EVENT_TABLE()
+
+bool wxPropertyListView::sm_dialogCancelled = FALSE;
+wxBitmap *wxPropertyListView::sm_tickBitmap = NULL;
+wxBitmap *wxPropertyListView::sm_crossBitmap = NULL;
+
+wxPropertyListView::wxPropertyListView(wxPanel *propPanel, long flags):wxPropertyView(flags)
+{
+ m_propertyScrollingList = NULL;
+ m_valueList = NULL;
+ m_valueText = NULL;
+ m_editButton = NULL;
+ m_confirmButton = NULL;
+ m_cancelButton = NULL;
+ m_propertyWindow = propPanel;
+ m_managedWindow = NULL;
+
+ m_windowCloseButton = NULL;
+ m_windowCancelButton = NULL;
+ m_windowHelpButton = NULL;
+
+ m_detailedEditing = FALSE;
+}
+
+wxPropertyListView::~wxPropertyListView(void)
+{
+/*
+ if (m_tickBitmap)
+ delete m_tickBitmap;
+ if (m_crossBitmap)
+ delete m_crossBitmap;
+*/
+}
+
+void wxPropertyListView::ShowView(wxPropertySheet *ps, wxPanel *panel)
+{
+ m_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 (!m_propertyScrollingList || !m_propertySheet)
+ return FALSE;
+
+ m_propertyScrollingList->Clear();
+ if (clearEditArea)
+ {
+ m_valueList->Clear();
+ m_valueText->SetValue("");
+ }
+ wxNode *node = m_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));
+
+ m_propertyScrollingList->Append(paddedString.GetData(), (char *)property);
+ node = node->Next();
+ }
+ return TRUE;
+}
+
+bool wxPropertyListView::UpdatePropertyDisplayInList(wxProperty *property)
+{
+ if (!m_propertyScrollingList || !m_propertySheet)
+ return FALSE;
+
+ int currentlySelected = m_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 != m_propertyScrollingList->GetString(sel))
+ m_propertyScrollingList->SetString(sel, paddedString.GetData());
+ }
+//#else
+// UpdatePropertyList(FALSE);
+//#endif
+
+ // TODO: why is this necessary?
+#ifdef __WXMSW__
+ if (currentlySelected > -1)
+ m_propertyScrollingList->SetSelection(currentlySelected);
+#endif
+
+ return TRUE;
+}
+
+// Find the wxListBox index corresponding to this property
+int wxPropertyListView::FindListIndexForProperty(wxProperty *property)
+{
+ int n = m_propertyScrollingList->Number();
+ for (int i = 0; i < n; i++)
+ {
+ if (property == (wxProperty *)m_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 (m_currentProperty)
+ {
+ EndShowingProperty(m_currentProperty);
+ m_currentProperty = NULL;
+ }
+
+ m_valueList->Clear();
+ m_valueText->SetValue("");
+
+ if (property)
+ {
+ m_currentProperty = property;
+ BeginShowingProperty(property);
+ }
+ if (select)
+ {
+ int sel = FindListIndexForProperty(property);
+ if (sel > -1)
+ m_propertyScrollingList->SetSelection(sel);
+ }
+ return TRUE;
+}
+
+// Find appropriate validator and load property into value controls
+bool wxPropertyListView::BeginShowingProperty(wxProperty *property)
+{
+ m_currentValidator = FindPropertyValidator(property);
+ if (!m_currentValidator)
+ return FALSE;
+
+ if (!m_currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator)))
+ return FALSE;
+
+ wxPropertyListValidator *listValidator = (wxPropertyListValidator *)m_currentValidator;
+
+ listValidator->OnPrepareControls(property, this, m_propertyWindow);
+ DisplayProperty(property);
+ return TRUE;
+}
+
+// Find appropriate validator and unload property from value controls
+bool wxPropertyListView::EndShowingProperty(wxProperty *property)
+{
+ if (!m_currentValidator)
+ return FALSE;
+
+ RetrieveProperty(property);
+
+ if (!m_currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator)))
+ return FALSE;
+
+ wxPropertyListValidator *listValidator = (wxPropertyListValidator *)m_currentValidator;
+
+ listValidator->OnClearControls(property, this, m_propertyWindow);
+ if (m_detailedEditing)
+ {
+ listValidator->OnClearDetailControls(property, this, m_propertyWindow);
+ m_detailedEditing = FALSE;
+ }
+ return TRUE;
+}
+
+void wxPropertyListView::BeginDetailedEditing(void)
+{
+ if (!m_currentValidator)
+ return;
+ if (!m_currentProperty)
+ return;
+ if (m_detailedEditing)
+ return;
+ if (!m_currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator)))
+ return;
+ if (!m_currentProperty->IsEnabled())
+ return;
+
+ wxPropertyListValidator *listValidator = (wxPropertyListValidator *)m_currentValidator;
+
+ if (listValidator->OnPrepareDetailControls(m_currentProperty, this, m_propertyWindow))
+ m_detailedEditing = TRUE;
+}
+
+void wxPropertyListView::EndDetailedEditing(void)
+{
+ if (!m_currentValidator)
+ return;
+ if (!m_currentProperty)
+ return;
+
+ RetrieveProperty(m_currentProperty);
+
+ if (!m_currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator)))
+ return;
+
+ wxPropertyListValidator *listValidator = (wxPropertyListValidator *)m_currentValidator;
+
+ if (m_detailedEditing)
+ {
+ listValidator->OnClearDetailControls(m_currentProperty, this, m_propertyWindow);
+ m_detailedEditing = FALSE;
+ }
+}
+
+bool wxPropertyListView::DisplayProperty(wxProperty *property)
+{
+ if (!m_currentValidator)
+ return FALSE;
+
+ if (((m_currentValidator->GetFlags() & wxPROP_ALLOW_TEXT_EDITING) == 0) || !property->IsEnabled())
+ m_valueText->SetEditable(FALSE);
+ else
+ m_valueText->SetEditable(TRUE);
+
+ if (!m_currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator)))
+ return FALSE;
+
+ wxPropertyListValidator *listValidator = (wxPropertyListValidator *)m_currentValidator;
+
+ listValidator->OnDisplayValue(property, this, m_propertyWindow);
+ return TRUE;
+}
+
+bool wxPropertyListView::RetrieveProperty(wxProperty *property)
+{
+ if (!m_currentValidator)
+ return FALSE;
+ if (!property->IsEnabled())
+ return FALSE;
+
+ if (!m_currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator)))
+ return FALSE;
+
+ wxPropertyListValidator *listValidator = (wxPropertyListValidator *)m_currentValidator;
+
+ if (listValidator->OnCheckValue(property, this, m_propertyWindow))
+ {
+ if (listValidator->OnRetrieveValue(property, this, m_propertyWindow))
+ {
+ UpdatePropertyDisplayInList(property);
+ OnPropertyChanged(property);
+ }
+ }
+ else
+ {
+ // Revert to old value
+ listValidator->OnDisplayValue(property, this, m_propertyWindow);
+ }
+ return TRUE;
+}
+
+
+bool wxPropertyListView::EditProperty(wxProperty *WXUNUSED(property))
+{
+ return TRUE;
+}
+
+// Called by the listbox callback
+void wxPropertyListView::OnPropertySelect(wxCommandEvent& WXUNUSED(event))
+{
+ int sel = m_propertyScrollingList->GetSelection();
+ if (sel > -1)
+ {
+ wxProperty *newSel = (wxProperty *)m_propertyScrollingList->wxListBox::GetClientData(sel);
+ if (newSel && newSel != m_currentProperty)
+ {
+ ShowProperty(newSel, FALSE);
+ }
+ }
+}
+
+bool wxPropertyListView::CreateControls(void)
+{
+ wxPanel *panel = (wxPanel *)m_propertyWindow;
+
+ int largeButtonWidth = 60;
+ 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 (m_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);
+
+#ifdef __WXMSW__
+ wxFont *boringFont = wxTheFontList->FindOrCreateFont(guiFont.GetPointSize(), wxMODERN, wxNORMAL, wxNORMAL, FALSE, "Courier New");
+#else
+ wxFont *boringFont = wxTheFontList->FindOrCreateFont(guiFont.GetPointSize(), wxTELETYPE, wxNORMAL, wxNORMAL);
+#endif
+
+ // May need to be changed in future to eliminate clashes with app.
+ panel->SetClientData((char *)this);
+
+ // These buttons are at the bottom of the window, but create them now
+ // so the constraints are evaluated in the correct order
+ if (m_buttonFlags & wxPROP_BUTTON_OK)
+ {
+ m_windowCloseButton = new wxButton(panel, wxID_OK, "OK",
+ wxPoint(-1, -1), wxSize(largeButtonWidth, largeButtonHeight));
+ m_windowCloseButton->SetDefault();
+ m_windowCloseButton->SetFocus();
+ }
+ else if (m_buttonFlags & wxPROP_BUTTON_CLOSE)
+ {
+ m_windowCloseButton = new wxButton(panel, wxID_OK, "Close",
+ wxPoint(-1, -1), wxSize(largeButtonWidth, largeButtonHeight));
+ }
+ if (m_buttonFlags & wxPROP_BUTTON_CANCEL)
+ {
+ m_windowCancelButton = new wxButton(panel, wxID_CANCEL, "Cancel",
+ wxPoint(-1, -1), wxSize(largeButtonWidth, largeButtonHeight));
+ }
+ if (m_buttonFlags & wxPROP_BUTTON_HELP)
+ {
+ m_windowHelpButton = new wxButton(panel, wxID_HELP, "Help",
+ wxPoint(-1, -1), wxSize(largeButtonWidth, largeButtonHeight));
+ }
+
+ if (m_windowCloseButton)
+ {
+ wxLayoutConstraints *c1 = new wxLayoutConstraints;
+
+ c1->left.SameAs (panel, wxLeft, 2);
+ c1->bottom.SameAs (panel, wxBottom, 2);
+ c1->width.AsIs();
+ c1->height.AsIs();
+ m_windowCloseButton->SetConstraints(c1);
+ leftMostWindow = m_windowCloseButton;
+ }
+ if (m_windowCancelButton)
+ {
+ wxLayoutConstraints *c2 = new wxLayoutConstraints;
+
+ c2->right.SameAs (panel, wxRight, 2);
+ c2->bottom.SameAs (panel, wxBottom, 2);
+ c2->width.AsIs();
+ c2->height.AsIs();
+ m_windowCancelButton->SetConstraints(c2);
+ leftMostWindow = m_windowCancelButton;
+ }
+ if (m_windowHelpButton)
+ {
+ wxLayoutConstraints *c2 = new wxLayoutConstraints;
+ if (leftMostWindow == panel)
+ c2->left.SameAs (panel, wxLeft, 2);
+ else
+ c2->left.RightOf (leftMostWindow, 2);
+
+ c2->bottom.SameAs (panel, wxBottom, 2);
+ c2->width.AsIs();
+ c2->height.AsIs();
+ m_windowHelpButton->SetConstraints(c2);
+ leftMostWindow = m_windowHelpButton;
+ }
+
+ if (m_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)
+ {
+ m_confirmButton = new wxBitmapButton(panel, wxID_PROP_CHECK, tickBitmap,
+ wxPoint(-1, -1), wxSize(smallButtonWidth-5, smallButtonHeight-5));
+ m_cancelButton = new wxBitmapButton(panel, wxID_PROP_CROSS, crossBitmap,
+ wxPoint(-1, -1), wxSize(smallButtonWidth-5, smallButtonHeight-5));
+ }
+ else
+*/
+ {
+ m_confirmButton = new wxButton(panel, wxID_PROP_CHECK, ":-)",
+ wxPoint(-1, -1), wxSize(smallButtonWidth, smallButtonHeight));
+ m_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 (m_windowCloseButton, 2);
+ else
+*/
+ c->top.SameAs (panel, wxTop, 2);
+
+ c->width.AsIs();
+ c->height.AsIs();
+
+ m_cancelButton->SetConstraints(c);
+
+ c = new wxLayoutConstraints;
+ c->left.RightOf (m_cancelButton, 2);
+ c->top.SameAs (m_cancelButton, wxTop, 0);
+ c->width.AsIs();
+ c->height.AsIs();
+
+ m_confirmButton->SetConstraints(c);
+
+ m_cancelButton->Enable(FALSE);
+ m_confirmButton->Enable(FALSE);
+ }
+
+ if (m_buttonFlags & wxPROP_PULLDOWN)
+ {
+ m_editButton = new wxButton(panel, wxID_PROP_EDIT, "...",
+ wxPoint(-1, -1), wxSize(smallButtonWidth, smallButtonHeight));
+ m_editButton->Enable(FALSE);
+ wxLayoutConstraints *c = new wxLayoutConstraints;
+
+/*
+ if (m_windowCloseButton)
+ c->top.Below (m_windowCloseButton, 2);
+ else
+*/
+ c->top.SameAs (panel, wxTop, 2);
+
+ c->right.SameAs (panel, wxRight, 2);
+ c->width.AsIs();
+ c->height.AsIs();
+ m_editButton->SetConstraints(c);
+ }
+
+ m_valueText = new wxPropertyTextEdit(this, panel, wxID_PROP_TEXT, "", wxPoint(-1, -1), wxSize(-1, -1), wxPROCESS_ENTER);
+ m_valueText->Enable(FALSE);
+
+ wxLayoutConstraints *c = new wxLayoutConstraints;
+
+ if (m_cancelButton)
+ c->left.RightOf (m_confirmButton, 2);
+ else
+ c->left.SameAs (panel, wxLeft, 2);
+/*
+ if (m_windowCloseButton)
+ c->top.Below (m_windowCloseButton, 2);
+ else
+*/
+ c->top.SameAs (panel, wxTop, 2);
+
+ if (m_editButton)
+ c->right.LeftOf (m_editButton, 2);
+ else
+ c->right.SameAs (panel, wxRight, 2);
+ c->height.AsIs();
+
+ m_valueText->SetConstraints(c);
+
+ m_valueList = new wxListBox(panel, wxID_PROP_VALUE_SELECT, wxPoint(-1, -1), wxSize(-1, 60));
+ m_valueList->Show(FALSE);
+
+ c = new wxLayoutConstraints;
+
+ c->left.SameAs (panel, wxLeft, 2);
+ c->top.Below (m_valueText, 2);
+ c->right.SameAs (panel, wxRight, 2);
+ c->height.Absolute(60);
+
+ m_valueList->SetConstraints(c);
+
+ m_propertyScrollingList = new wxListBox(panel, wxID_PROP_SELECT,
+ wxPoint(-1, -1), wxSize(300, 300));
+ m_propertyScrollingList->SetFont(boringFont);
+
+ c = new wxLayoutConstraints;
+
+ c->left.SameAs (panel, wxLeft, 2);
+
+ if (m_buttonFlags & wxPROP_DYNAMIC_VALUE_FIELD)
+ c->top.Below (m_valueText, 2);
+ else
+ c->top.Below (m_valueList, 2);
+
+ c->right.SameAs (panel, wxRight, 2);
+
+ if (m_windowCloseButton)
+ c->bottom.Above (m_windowCloseButton, -2);
+ else
+ c->bottom.SameAs (panel, wxBottom, 2);
+
+ m_propertyScrollingList->SetConstraints(c);
+
+ // Note: if this is called now, it causes a GPF.
+ // Why?
+// panel->Layout();
+
+ return TRUE;
+}
+
+void wxPropertyListView::ShowTextControl(bool show)
+{
+ if (m_valueText)
+ m_valueText->Show(show);
+}
+
+void wxPropertyListView::ShowListBoxControl(bool show)
+{
+ if (m_valueList)
+ {
+ m_valueList->Show(show);
+ if (m_buttonFlags & wxPROP_DYNAMIC_VALUE_FIELD)
+ {
+ wxLayoutConstraints *constraints = m_propertyScrollingList->GetConstraints();
+ if (constraints)
+ {
+ if (show)
+ {
+ constraints->top.Below(m_valueList, 2);
+ // Maintain back-pointer so when valueList is deleted,
+ // any reference to it from this window is removed.
+ m_valueList->AddConstraintReference(m_propertyScrollingList);
+ }
+ else
+ {
+ constraints->top.Below(m_valueText, 2);
+ m_valueText->AddConstraintReference(m_propertyScrollingList);
+ }
+ m_propertyWindow->Layout();
+ }
+ }
+ }
+}
+
+void wxPropertyListView::EnableCheck(bool show)
+{
+ if (m_confirmButton)
+ m_confirmButton->Enable(show);
+}
+
+void wxPropertyListView::EnableCross(bool show)
+{
+ if (m_cancelButton)
+ m_cancelButton->Enable(show);
+}
+
+bool wxPropertyListView::OnClose(void)
+{
+ // Retrieve the value if any
+ wxCommandEvent event;
+ OnCheck(event);
+
+ delete this;
+ return TRUE;
+}
+
+void wxPropertyListView::OnValueListSelect(wxCommandEvent& WXUNUSED(event))
+{
+ if (m_currentProperty && m_currentValidator)
+ {
+ if (!m_currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator)))
+ return;
+
+ wxPropertyListValidator *listValidator = (wxPropertyListValidator *)m_currentValidator;
+
+ listValidator->OnValueListSelect(m_currentProperty, this, m_propertyWindow);
+ }
+}
+
+void wxPropertyListView::OnOk(wxCommandEvent& event)
+{
+ // Retrieve the value if any
+ OnCheck(event);
+
+ m_managedWindow->Close(TRUE);
+}
+
+void wxPropertyListView::OnCancel(wxCommandEvent& WXUNUSED(event))
+{
+// SetReturnCode(wxID_CANCEL);
+ m_managedWindow->Close(TRUE);
+ sm_dialogCancelled = TRUE;
+}
+
+void wxPropertyListView::OnHelp(wxCommandEvent& WXUNUSED(event))
+{
+}
+
+void wxPropertyListView::OnCheck(wxCommandEvent& WXUNUSED(event))
+{
+ if (m_currentProperty)
+ {
+ RetrieveProperty(m_currentProperty);
+ }
+}
+
+void wxPropertyListView::OnCross(wxCommandEvent& WXUNUSED(event))
+{
+ if (m_currentProperty && m_currentValidator)
+ {
+ if (!m_currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator)))
+ return;
+
+ wxPropertyListValidator *listValidator = (wxPropertyListValidator *)m_currentValidator;
+
+ // Revert to old value
+ listValidator->OnDisplayValue(m_currentProperty, this, m_propertyWindow);
+ }
+}
+
+void wxPropertyListView::OnPropertyDoubleClick(wxCommandEvent& WXUNUSED(event))
+{
+ if (m_currentProperty && m_currentValidator)
+ {
+ if (!m_currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator)))
+ return;
+
+ wxPropertyListValidator *listValidator = (wxPropertyListValidator *)m_currentValidator;
+
+ // Revert to old value
+ listValidator->OnDoubleClick(m_currentProperty, this, m_propertyWindow);
+ }
+}
+
+void wxPropertyListView::OnEdit(wxCommandEvent& WXUNUSED(event))
+{
+ if (m_currentProperty && m_currentValidator)
+ {
+ if (!m_currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator)))
+ return;
+
+ wxPropertyListValidator *listValidator = (wxPropertyListValidator *)m_currentValidator;
+
+ listValidator->OnEdit(m_currentProperty, this, m_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)
+{
+ m_view = v;
+ m_view->AssociatePanel( ((wxPanel*)this) );
+ m_view->SetManagedWindow(this);
+ SetAutoLayout(TRUE);
+}
+
+bool wxPropertyListDialog::OnClose(void)
+{
+ if (m_view)
+ {
+ SetReturnCode(wxID_CANCEL);
+ m_view->OnClose();
+ m_view = NULL;
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+void wxPropertyListDialog::OnCancel(wxCommandEvent& WXUNUSED(event))
+{
+ SetReturnCode(wxID_CANCEL);
+ this->Close();
+}
+
+void wxPropertyListDialog::OnDefaultAction(wxControl *item)
+{
+/*
+ if (item == m_view->GetPropertyScrollingList())
+ view->OnDoubleClick();
+*/
+}
+
+// Extend event processing to search the view's event table
+bool wxPropertyListDialog::ProcessEvent(wxEvent& event)
+{
+ if ( !m_view || ! m_view->ProcessEvent(event) )
+ return wxEvtHandler::ProcessEvent(event);
+ else
+ return TRUE;
+}
+
+/*
+ * Property panel
+ */
+
+IMPLEMENT_CLASS(wxPropertyListPanel, wxPanel)
+
+BEGIN_EVENT_TABLE(wxPropertyListPanel, wxPanel)
+ EVT_SIZE(wxPropertyListPanel::OnSize)
+END_EVENT_TABLE()
+
+wxPropertyListPanel::~wxPropertyListPanel()
+{
+}
+
+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 ( !m_view || ! m_view->ProcessEvent(event) )
+ return wxEvtHandler::ProcessEvent(event);
+ else
+ return TRUE;
+}
+
+void wxPropertyListPanel::OnSize(wxSizeEvent& WXUNUSED(event))
+{
+ Layout();
+}
+
+/*
+ * Property frame
+ */
+
+IMPLEMENT_CLASS(wxPropertyListFrame, wxFrame)
+
+bool wxPropertyListFrame::OnClose(void)
+{
+ if (m_view)
+ {
+ if (m_propertyPanel)
+ m_propertyPanel->SetView(NULL);
+ m_view->OnClose();
+ m_view = NULL;
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+wxPropertyListPanel *wxPropertyListFrame::OnCreatePanel(wxFrame *parent, wxPropertyListView *v)
+{
+ return new wxPropertyListPanel(v, parent);
+}
+
+bool wxPropertyListFrame::Initialize(void)
+{
+ m_propertyPanel = OnCreatePanel(this, m_view);
+ if (m_propertyPanel)
+ {
+ m_view->AssociatePanel(m_propertyPanel);
+ m_view->SetManagedWindow(this);
+ m_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);
+ 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 (m_realMin == 0.0 && m_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 < m_realMin || val > m_realMax)
+ {
+ char buf[200];
+ sprintf(buf, "Value must be a real number between %.2f and %.2f!", m_realMin, m_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 (m_integerMin == 0 && m_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 < m_integerMin || val > m_integerMax)
+ {
+ char buf[200];
+ sprintf(buf, "Value must be an integer between %ld and %ld!", m_integerMin, m_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);
+
+ if (view->GetValueList()->IsShown())
+ {
+ view->GetValueList()->SetStringSelection(str);
+ }
+ 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)
+{
+ m_strings = list;
+ // If no constraint, we just allow the string to be edited.
+ if (!m_strings && ((m_validatorFlags & wxPROP_ALLOW_TEXT_EDITING) == 0))
+ m_validatorFlags |= wxPROP_ALLOW_TEXT_EDITING;
+}
+
+bool wxStringListValidator::OnCheckValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
+{
+ if (!m_strings)
+ return TRUE;
+
+ if (!view->GetValueText())
+ return FALSE;
+ wxString value(view->GetValueText()->GetValue());
+
+ if (!m_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);
+ if (m_strings && view->GetValueList() && view->GetValueList()->IsShown() && view->GetValueList()->Number() > 0)
+ {
+ view->GetValueList()->SetStringSelection(str);
+ }
+ return TRUE;
+}
+
+bool wxStringListValidator::OnPrepareControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
+{
+ // Unconstrained
+ if (!m_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 = m_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 (!m_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 (!m_strings)
+ return FALSE;
+
+ wxNode *node = m_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 *)m_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), m_filenameWildCard(wildcard), m_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(
+ m_filenameMessage.GetData(),
+ wxPathOnly(property->GetValue().StringValue()),
+ wxFileNameFromPath(property->GetValue().StringValue()),
+ NULL,
+ m_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);
+ 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:
+ 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)
+ {
+ m_stringList = NULL;
+ m_stringText = NULL;
+ m_listBox = NULL;
+ sm_dialogCancelled = FALSE;
+ m_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);
+
+public:
+ wxStringList* m_stringList;
+ wxListBox* m_listBox;
+ wxTextCtrl* m_stringText;
+ static bool sm_dialogCancelled;
+ int m_currentSelection;
+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_ENTER(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::sm_dialogCancelled = FALSE;
+
+// Edit the string list.
+bool wxListOfStringsListValidator::EditStringList(wxWindow *parent, wxStringList *stringList, const char *title)
+{
+ int largeButtonWidth = 60;
+ int largeButtonHeight = 25;
+
+ wxBeginBusyCursor();
+ wxPropertyStringListEditorDialog *dialog = new wxPropertyStringListEditorDialog(parent,
+ title, wxPoint(10, 10), wxSize(400, 400), wxDEFAULT_DIALOG_STYLE|wxDIALOG_MODAL);
+
+ dialog->m_stringList = stringList;
+
+ dialog->m_listBox = new wxListBox(dialog, wxID_PROP_SL_STRINGS,
+ wxPoint(-1, -1), wxSize(-1, -1), 0, NULL, wxLB_SINGLE);
+
+ dialog->m_stringText = new wxPropertyStringListEditorText(dialog,
+ wxID_PROP_SL_TEXT, "", wxPoint(5, 240),
+ wxSize(300, -1), wxPROCESS_ENTER);
+ dialog->m_stringText->Enable(FALSE);
+
+ wxButton *addButton = new wxButton(dialog, wxID_PROP_SL_ADD, "Add", wxPoint(-1, -1), wxSize(largeButtonWidth, largeButtonHeight));
+ wxButton *deleteButton = new wxButton(dialog, wxID_PROP_SL_DELETE, "Delete", wxPoint(-1, -1), wxSize(largeButtonWidth, largeButtonHeight));
+ wxButton *cancelButton = new wxButton(dialog, wxID_CANCEL, "Cancel", wxPoint(-1, -1), wxSize(largeButtonWidth, largeButtonHeight));
+ wxButton *okButton = new wxButton(dialog, wxID_OK, "OK", wxPoint(-1, -1), wxSize(largeButtonWidth, largeButtonHeight));
+
+ okButton->SetDefault();
+
+ wxLayoutConstraints *c = new wxLayoutConstraints;
+
+ c->top.SameAs (dialog, wxTop, 2);
+ c->left.SameAs (dialog, wxLeft, 2);
+ c->right.SameAs (dialog, wxRight, 2);
+ c->bottom.SameAs (dialog->m_stringText, wxTop, 2);
+ dialog->m_listBox->SetConstraints(c);
+
+ c = new wxLayoutConstraints;
+ c->left.SameAs (dialog, wxLeft, 2);
+ c->right.SameAs (dialog, wxRight, 2);
+ c->bottom.SameAs (addButton, wxTop, 2);
+ c->height.AsIs();
+ dialog->m_stringText->SetConstraints(c);
+
+ c = new wxLayoutConstraints;
+ c->bottom.SameAs (dialog, wxBottom, 2);
+ c->left.SameAs (dialog, wxLeft, 2);
+ c->width.AsIs();
+ c->height.AsIs();
+ addButton->SetConstraints(c);
+
+ c = new wxLayoutConstraints;
+ c->bottom.SameAs (dialog, wxBottom, 2);
+ c->left.SameAs (addButton, wxRight, 2);
+ c->width.AsIs();
+ c->height.AsIs();
+ deleteButton->SetConstraints(c);
+
+ c = new wxLayoutConstraints;
+ c->bottom.SameAs (dialog, wxBottom, 2);
+ c->right.SameAs (dialog, wxRight, 2);
+ c->width.AsIs();
+ c->height.AsIs();
+ cancelButton->SetConstraints(c);
+
+ c = new wxLayoutConstraints;
+ c->bottom.SameAs (dialog, wxBottom, 2);
+ c->right.SameAs (cancelButton, wxLeft, 2);
+ c->width.AsIs();
+ c->height.AsIs();
+ okButton->SetConstraints(c);
+
+ wxNode *node = stringList->First();
+ while (node)
+ {
+ char *str = (char *)node->Data();
+ // Save node as client data for each listbox item
+ dialog->m_listBox->Append(str, (char *)node);
+ node = node->Next();
+ }
+
+ dialog->SetClientSize(310, 305);
+ dialog->Layout();
+
+ dialog->Centre(wxBOTH);
+ wxEndBusyCursor();
+ if (dialog->ShowModal() == wxID_CANCEL)
+ return FALSE;
+ else
+ return TRUE;
+}
+
+/*
+ * String list editor callbacks
+ *
+ */
+
+void wxPropertyStringListEditorDialog::OnStrings(wxCommandEvent& WXUNUSED(event))
+{
+ int sel = m_listBox->GetSelection();
+ if (sel > -1)
+ {
+ m_currentSelection = sel;
+
+ ShowCurrentSelection();
+ }
+}
+
+void wxPropertyStringListEditorDialog::OnDelete(wxCommandEvent& WXUNUSED(event))
+{
+ int sel = m_listBox->GetSelection();
+ if (sel == -1)
+ return;
+
+ wxNode *node = (wxNode *)m_listBox->wxListBox::GetClientData(sel);
+ if (!node)
+ return;
+
+ m_listBox->Delete(sel);
+ delete[] (char *)node->Data();
+ delete node;
+ m_currentSelection = -1;
+ m_stringText->SetValue("");
+}
+
+void wxPropertyStringListEditorDialog::OnAdd(wxCommandEvent& WXUNUSED(event))
+{
+ SaveCurrentSelection();
+
+ char *initialText = "";
+ wxNode *node = m_stringList->Add(initialText);
+ m_listBox->Append(initialText, (char *)node);
+ m_currentSelection = m_stringList->Number() - 1;
+ m_listBox->SetSelection(m_currentSelection);
+ ShowCurrentSelection();
+ m_stringText->SetFocus();
+}
+
+void wxPropertyStringListEditorDialog::OnOK(wxCommandEvent& WXUNUSED(event))
+{
+ SaveCurrentSelection();
+ EndModal(wxID_OK);
+ Close(TRUE);
+}
+
+void wxPropertyStringListEditorDialog::OnCancel(wxCommandEvent& WXUNUSED(event))
+{
+ sm_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 (m_currentSelection == -1)
+ return;
+
+ wxNode *node = (wxNode *)m_listBox->wxListBox::GetClientData(m_currentSelection);
+ if (!node)
+ return;
+
+ wxString txt(m_stringText->GetValue());
+ if (node->Data())
+ delete[] (char *)node->Data();
+ node->SetData((wxObject *)copystring(txt));
+
+ m_listBox->SetString(m_currentSelection, (char *)node->Data());
+}
+
+void wxPropertyStringListEditorDialog::ShowCurrentSelection(void)
+{
+ if (m_currentSelection == -1)
+ {
+ m_stringText->SetValue("");
+ return;
+ }
+ wxNode *node = (wxNode *)m_listBox->wxListBox::GetClientData(m_currentSelection);
+ char *txt = (char *)node->Data();
+ m_stringText->SetValue(txt);
+ m_stringText->Enable(TRUE);
+}
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: proplist.h
+// Purpose: Property list classes
+// Author: Julian Smart
+// Modified by:
+// Created: 04/01/98
+// RCS-ID: $Id$
+// Copyright: (c) Julian Smart
+// Licence: wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+ /*
+
+ TO DO:
+
+ (1) Optional popup-help for each item, and an optional Help button
+ for dialog.
+
+ (2) Align Ok, Cancel, Help buttons properly.
+
+ (3) Consider retrieving the rectangle on the panel that can be
+ drawn into (where the value listbox is) and giving an example
+ of editing graphically. May be too fancy.
+
+ (4) Deriveable types for wxPropertyValue => may need to reorganise
+ wxPropertyValue to use inheritance rather than present all-types-in-one
+ scheme.
+
+ (5) Optional popup panel for value list, perhaps.
+
+ (6) Floating point checking routine still crashes with Floating
+ point error for zany input.
+
+ (7) Property sheet with choice (or listbox) to select alternative
+ sheets... multiple views per panel, only one active. For this
+ we really need a wxChoice that can be dynamically set: XView
+ may be a problem; Motif?
+
+ (8) More example validators, e.g. colour selector.
+ */
+
+#ifndef _PROPLIST_H_
+#define _PROPLIST_H_
+
+#ifdef __GNUG__
+#pragma interface "proplist.h"
+#endif
+
+#include "prop.h"
+
+#define wxPROP_BUTTON_CLOSE 1
+#define wxPROP_BUTTON_OK 2
+#define wxPROP_BUTTON_CANCEL 4
+#define wxPROP_BUTTON_CHECK_CROSS 8
+#define wxPROP_BUTTON_HELP 16
+#define wxPROP_DYNAMIC_VALUE_FIELD 32
+#define wxPROP_PULLDOWN 64
+#define wxPROP_SHOWVALUES 128
+
+#ifdef __XVIEW__
+#define wxPROP_BUTTON_DEFAULT wxPROP_BUTTON_OK | wxPROP_BUTTON_CANCEL | wxPROP_BUTTON_CHECK_CROSS | wxPROP_PULLDOWN
+#else
+#define wxPROP_BUTTON_DEFAULT wxPROP_BUTTON_CHECK_CROSS | wxPROP_PULLDOWN | wxPROP_SHOWVALUES
+#endif
+
+#define wxID_PROP_CROSS 3000
+#define wxID_PROP_CHECK 3001
+#define wxID_PROP_EDIT 3002
+#define wxID_PROP_TEXT 3003
+#define wxID_PROP_SELECT 3004
+#define wxID_PROP_VALUE_SELECT 3005
+
+// Mediates between a physical panel and the property sheet
+class wxPropertyListView: public wxPropertyView
+{
+ DECLARE_DYNAMIC_CLASS(wxPropertyListView)
+ public:
+ wxPropertyListView(wxPanel *propPanel = NULL, long flags = wxPROP_BUTTON_DEFAULT);
+ ~wxPropertyListView(void);
+
+ // Associates and shows the view
+ virtual void ShowView(wxPropertySheet *propertySheet, wxPanel *panel);
+
+ // Update this view of the viewed object, called e.g. by
+ // the object itself.
+ virtual bool OnUpdateView(void);
+
+ wxString MakeNameValueString(wxString name, wxString value);
+
+ // Update a single line in the list of properties
+ virtual bool UpdatePropertyDisplayInList(wxProperty *property);
+
+ // Update the whole list
+ virtual bool UpdatePropertyList(bool clearEditArea = TRUE);
+
+ // Find the wxListBox index corresponding to this property
+ virtual int FindListIndexForProperty(wxProperty *property);
+
+ // Select and show string representation in editor the given
+ // property. NULL resets to show no property.
+ virtual bool ShowProperty(wxProperty *property, bool select = TRUE);
+ virtual bool EditProperty(wxProperty *property);
+
+ // Update the display from the property
+ virtual bool DisplayProperty(wxProperty *property);
+ // Update the property from the display
+ virtual bool RetrieveProperty(wxProperty *property);
+
+ // Find appropriate validator and load property into value controls
+ virtual bool BeginShowingProperty(wxProperty *property);
+ // Find appropriate validator and unload property from value controls
+ virtual bool EndShowingProperty(wxProperty *property);
+
+ // Begin detailed editing (e.g. using value listbox)
+ virtual void BeginDetailedEditing(void);
+
+ // End detailed editing (e.g. using value listbox)
+ virtual void EndDetailedEditing(void);
+
+ // Called by the property listbox
+ void OnPropertySelect(wxCommandEvent& event);
+
+ // Called by the value listbox
+ void OnValueListSelect(wxCommandEvent& event);
+
+ virtual bool CreateControls(void);
+ virtual void ShowTextControl(bool show);
+ virtual void ShowListBoxControl(bool show);
+ virtual void EnableCheck(bool show);
+ virtual void EnableCross(bool show);
+
+ void OnOk(wxCommandEvent& event);
+ void OnCancel(wxCommandEvent& event);
+ void OnHelp(wxCommandEvent& event);
+ void OnPropertyDoubleClick(wxCommandEvent& event);
+// virtual void OnDoubleClick(void);
+
+ void OnCheck(wxCommandEvent& event);
+ void OnCross(wxCommandEvent& event);
+ void OnEdit(wxCommandEvent& event);
+ void OnText(wxCommandEvent& event);
+
+ inline virtual wxListBox *GetPropertyScrollingList() const { return m_propertyScrollingList; }
+ inline virtual wxListBox *GetValueList() const { return m_valueList; }
+ inline virtual wxTextCtrl *GetValueText() const { return m_valueText; }
+ inline virtual wxButton *GetConfirmButton() const { return m_confirmButton; }
+ inline virtual wxButton *GetCancelButton() const { return m_cancelButton; }
+ inline virtual wxButton *GetEditButton() const { return m_editButton; }
+ inline virtual bool GetDetailedEditing(void) const { return m_detailedEditing; }
+
+ inline virtual void AssociatePanel(wxPanel *win) { m_propertyWindow = win; }
+ inline virtual wxPanel *GetPanel(void) const { return m_propertyWindow; }
+
+ inline virtual void SetManagedWindow(wxWindow *win) { m_managedWindow = win; }
+ inline virtual wxWindow *GetManagedWindow(void) const { return m_managedWindow; }
+
+ inline virtual wxButton *GetWindowCloseButton() const { return m_windowCloseButton; }
+ inline virtual wxButton *GetWindowCancelButton() const { return m_windowCancelButton; }
+ inline virtual wxButton *GetHelpButton() const { return m_windowHelpButton; }
+
+ bool OnClose(void);
+
+public:
+ static bool sm_dialogCancelled;
+
+ protected:
+ wxListBox* m_propertyScrollingList;
+ wxListBox* m_valueList; // Should really be a combobox, but we don't have one.
+ wxTextCtrl* m_valueText;
+ wxButton* m_confirmButton; // A tick, as in VB
+ wxButton* m_cancelButton; // A cross, as in VB
+ wxButton* m_editButton; // Invokes the custom validator, if any
+
+ bool m_detailedEditing; // E.g. using listbox for choices
+
+ static wxBitmap* sm_tickBitmap;
+ static wxBitmap* sm_crossBitmap;
+
+ wxPanel* m_propertyWindow; // Panel that the controls will appear on
+ wxWindow* m_managedWindow; // Frame or dialog
+
+ wxButton* m_windowCloseButton; // Or OK
+ wxButton* m_windowCancelButton;
+ wxButton* m_windowHelpButton;
+
+DECLARE_EVENT_TABLE()
+};
+
+class wxPropertyTextEdit: public wxTextCtrl
+{
+ DECLARE_CLASS(wxPropertyTextEdit)
+ public:
+ wxPropertyTextEdit(wxPropertyListView *v, wxWindow *parent, const wxWindowID id,
+ const wxString& value, const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize, long style = 0, const wxString& name = "text");
+ void OnSetFocus(void);
+ void OnKillFocus(void);
+
+ wxPropertyListView* m_view;
+};
+
+#define wxPROP_ALLOW_TEXT_EDITING 1
+
+/*
+ * The type of validator used for property lists (Visual Basic style)
+ */
+
+class wxPropertyListValidator: public wxPropertyValidator
+{
+ DECLARE_DYNAMIC_CLASS(wxPropertyListValidator)
+ protected:
+ public:
+ wxPropertyListValidator(long flags = wxPROP_ALLOW_TEXT_EDITING): wxPropertyValidator(flags) { }
+ ~wxPropertyListValidator(void) {}
+
+ // Called when the property is selected or deselected: typically displays the value
+ // in the edit control (having chosen a suitable control to display: (non)editable text or listbox)
+ virtual bool OnSelect(bool select, wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+
+ // Called when the property is double clicked. Extra functionality can be provided, such as
+ // cycling through possible values.
+ inline virtual bool OnDoubleClick(
+ wxProperty *WXUNUSED(property), wxPropertyListView *WXUNUSED(view), wxWindow *WXUNUSED(parentWindow) )
+ { return TRUE; }
+
+ // Called when the value listbox is selected. Default behaviour is to copy
+ // string to text control, and retrieve the value into the property.
+ virtual bool OnValueListSelect(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+
+ // Called when the property value is edited using standard text control
+ inline virtual bool OnPrepareControls(
+ wxProperty *WXUNUSED(property), wxPropertyListView *WXUNUSED(view), wxWindow *WXUNUSED(parentWindow) )
+ { return TRUE; }
+
+ virtual bool OnClearControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+
+ // Called when the property is edited in detail
+ inline virtual bool OnPrepareDetailControls(
+ wxProperty *WXUNUSED(property), wxPropertyListView *WXUNUSED(view), wxWindow *WXUNUSED(parentWindow) )
+ { return TRUE; }
+
+ // Called if focus lost, IF we're in a modeless property editing situation.
+ inline virtual bool OnClearDetailControls(
+ wxProperty *WXUNUSED(property), wxPropertyListView *WXUNUSED(view), wxWindow *WXUNUSED(parentWindow) )
+ { return TRUE; }
+
+ // Called when the edit (...) button is pressed. The default implementation
+ // calls view->BeginDetailedEditing; the filename validator (for example) overrides
+ // this function to show the file selector.
+ virtual void OnEdit(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+
+ // Called when TICK is pressed or focus is lost.
+ // Return FALSE if value didn't check out; signal to restore old value.
+ inline virtual bool OnCheckValue(
+ wxProperty *WXUNUSED(property), wxPropertyListView *WXUNUSED(view), wxWindow *WXUNUSED(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
+ virtual bool OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+
+ virtual bool OnDisplayValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+};
+
+/*
+ * A default dialog box class to use.
+ */
+
+class wxPropertyListDialog: public wxDialog
+{
+ DECLARE_CLASS(wxPropertyListDialog)
+ public:
+ wxPropertyListDialog(wxPropertyListView *v, wxWindow *parent, const wxString& title,
+ const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
+ long style = wxDEFAULT_DIALOG_STYLE, const wxString& name = "dialogBox");
+ bool OnClose(void);
+ void OnDefaultAction(wxControl *item);
+ void OnCancel(wxCommandEvent& event);
+
+ // Extend event processing to search the view's event table
+ virtual bool ProcessEvent(wxEvent& event);
+
+ private:
+ wxPropertyListView* m_view;
+
+DECLARE_EVENT_TABLE()
+};
+
+/*
+ * A default panel class to use.
+ */
+
+class wxPropertyListPanel: public wxPanel
+{
+ DECLARE_CLASS(wxPropertyListPanel)
+ public:
+ wxPropertyListPanel(wxPropertyListView *v, wxWindow *parent, const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize,
+ long style = 0, const wxString& name = "panel"):
+ wxPanel(parent, -1, pos, size, style, name)
+ {
+ m_view = v;
+ }
+ ~wxPropertyListPanel();
+ void OnDefaultAction(wxControl *item);
+
+ inline void SetView(wxPropertyListView* v) { m_view = v; }
+ inline wxPropertyListView* GetView() const { return m_view; }
+
+ // Extend event processing to search the view's event table
+ virtual bool ProcessEvent(wxEvent& event);
+
+ // Call Layout()
+ void OnSize(wxSizeEvent& event);
+
+ private:
+ wxPropertyListView* m_view;
+
+DECLARE_EVENT_TABLE()
+};
+
+/*
+ * A default frame class to use.
+ */
+
+class wxPropertyListFrame: public wxFrame
+{
+ DECLARE_CLASS(wxPropertyListFrame)
+ public:
+ wxPropertyListFrame(wxPropertyListView *v, wxFrame *parent, const wxString& title,
+ const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
+ long style = wxDEFAULT_FRAME, const wxString& name = "frame"):
+ wxFrame(parent, -1, title, pos, size, style, name)
+ {
+ m_view = v;
+ m_propertyPanel = NULL;
+ }
+ bool OnClose(void);
+
+ // Must call this to create panel and associate view
+ virtual bool Initialize(void);
+ virtual wxPropertyListPanel *OnCreatePanel(wxFrame *parent, wxPropertyListView *v);
+ inline virtual wxPropertyListPanel *GetPropertyPanel(void) const { return m_propertyPanel; }
+
+ private:
+ wxPropertyListView* m_view;
+ wxPropertyListPanel* m_propertyPanel;
+};
+
+/*
+ * Some default validators
+ */
+
+class wxRealListValidator: public wxPropertyListValidator
+{
+ DECLARE_DYNAMIC_CLASS(wxRealListValidator)
+ public:
+ // 0.0, 0.0 means no range
+ wxRealListValidator(float min = 0.0, float max = 0.0, long flags = wxPROP_ALLOW_TEXT_EDITING):wxPropertyListValidator(flags)
+ {
+ m_realMin = min; m_realMax = max;
+ }
+ ~wxRealListValidator(void) {}
+
+ bool OnPrepareControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+
+ // Called when TICK is pressed or focus is lost.
+ // Return FALSE if value didn't check out; signal to restore old value.
+ bool OnCheckValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+
+ // Called when TICK is pressed or focus is lost or view wants to update
+ // the property list.
+ // Does the transfer from the property editing area to the property itself
+ bool OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+
+ protected:
+ float m_realMin;
+ float m_realMax;
+};
+
+class wxIntegerListValidator: public wxPropertyListValidator
+{
+ DECLARE_DYNAMIC_CLASS(wxIntegerListValidator)
+ public:
+ // 0, 0 means no range
+ wxIntegerListValidator(long min = 0, long max = 0, long flags = wxPROP_ALLOW_TEXT_EDITING):wxPropertyListValidator(flags)
+ {
+ m_integerMin = min; m_integerMax = max;
+ }
+ ~wxIntegerListValidator(void) {}
+
+ bool OnPrepareControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+
+ // Called when TICK is pressed or focus is lost.
+ // Return FALSE if value didn't check out; signal to restore old value.
+ bool OnCheckValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+
+ // Called when TICK is pressed or focus is lost or view wants to update
+ // the property list.
+ // Does the transfer from the property editing area to the property itself
+ bool OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+
+ protected:
+ long m_integerMin;
+ long m_integerMax;
+};
+
+class wxBoolListValidator: public wxPropertyListValidator
+{
+ DECLARE_DYNAMIC_CLASS(wxBoolListValidator)
+ protected:
+ public:
+ wxBoolListValidator(long flags = 0):wxPropertyListValidator(flags)
+ {
+ }
+ ~wxBoolListValidator(void) {}
+
+ bool OnPrepareControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+ bool OnPrepareDetailControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+ bool OnClearDetailControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+
+ // Called when TICK is pressed or focus is lost.
+ // Return FALSE if value didn't check out; signal to restore old value.
+ bool OnCheckValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+
+ // Called when TICK is pressed or focus is lost or view wants to update
+ // the property list.
+ // Does the transfer from the property editing area to the property itself
+ bool OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+ bool OnDisplayValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+
+ // Called when the property is double clicked. Extra functionality can be provided,
+ // cycling through possible values.
+ virtual bool OnDoubleClick(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+};
+
+class wxStringListValidator: public wxPropertyListValidator
+{
+ DECLARE_DYNAMIC_CLASS(wxStringListValidator)
+ public:
+ wxStringListValidator(wxStringList *list = NULL, long flags = 0);
+
+ ~wxStringListValidator(void)
+ {
+ if (m_strings)
+ delete m_strings;
+ }
+
+ bool OnPrepareControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+ bool OnPrepareDetailControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+ bool OnClearDetailControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+
+ // Called when TICK is pressed or focus is lost.
+ // Return FALSE if value didn't check out; signal to restore old value.
+ bool OnCheckValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+
+ // Called when TICK is pressed or focus is lost or view wants to update
+ // the property list.
+ // Does the transfer from the property editing area to the property itself
+ bool OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+ bool OnDisplayValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+
+ // Called when the property is double clicked. Extra functionality can be provided,
+ // cycling through possible values.
+ bool OnDoubleClick(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+
+ protected:
+ wxStringList* m_strings;
+};
+
+class wxFilenameListValidator: public wxPropertyListValidator
+{
+ DECLARE_DYNAMIC_CLASS(wxFilenameListValidator)
+ public:
+ wxFilenameListValidator(wxString message = "Select a file", wxString wildcard = "*.*", long flags = 0);
+
+ ~wxFilenameListValidator(void);
+
+ // Called when TICK is pressed or focus is lost.
+ // Return FALSE if value didn't check out; signal to restore old value.
+ bool OnCheckValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+
+ // 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 OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+ bool OnDisplayValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+
+ bool OnDoubleClick(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+
+ bool OnPrepareControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+
+ // Called when the edit (...) button is pressed.
+ void OnEdit(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+
+ protected:
+ wxString m_filenameWildCard;
+ wxString m_filenameMessage;
+
+};
+
+class wxColourListValidator: public wxPropertyListValidator
+{
+ DECLARE_DYNAMIC_CLASS(wxColourListValidator)
+ protected:
+ public:
+ wxColourListValidator(long flags = 0);
+
+ ~wxColourListValidator(void);
+
+ bool OnCheckValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+ bool OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+ bool OnDisplayValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+
+ bool OnDoubleClick(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+
+ bool OnPrepareControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+
+ // Called when the edit (...) button is pressed.
+ void OnEdit(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+};
+
+class wxListOfStringsListValidator: public wxPropertyListValidator
+{
+ DECLARE_DYNAMIC_CLASS(wxListOfStringsListValidator)
+ protected:
+ public:
+ wxListOfStringsListValidator(long flags = 0);
+
+ ~wxListOfStringsListValidator(void)
+ {
+ }
+
+ bool OnPrepareControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+
+ // Called when TICK is pressed or focus is lost.
+ // Return FALSE if value didn't check out; signal to restore old value.
+ bool OnCheckValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+
+ // Called when TICK is pressed or focus is lost or view wants to update
+ // the property list.
+ // Does the transfer from the property editing area to the property itself
+ bool OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+ bool OnDisplayValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+
+ // Called when the property is double clicked.
+ bool OnDoubleClick(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+
+ bool EditStringList(wxWindow *parent, wxStringList *stringList, const char *title = "String List Editor");
+
+ // Called when the edit (...) button is pressed.
+ void OnEdit(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow);
+};
+
+#endif
+