// Author: Jaakko Salli
// Modified by:
// Created: 2008-08-24
-// RCS-ID: $Id:
+// RCS-ID: $Id$
// Copyright: (c) Jaakko Salli
-// Licence: wxWindows license
+// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx/wx.h".
#pragma hdrstop
#endif
+#if wxUSE_PROPGRID
+
#ifndef WX_PRECOMP
#include "wx/defs.h"
#include "wx/object.h"
#include "wx/button.h"
#include "wx/pen.h"
#include "wx/brush.h"
- #include "wx/cursor.h"
- #include "wx/dialog.h"
#include "wx/settings.h"
- #include "wx/msgdlg.h"
- #include "wx/choice.h"
- #include "wx/stattext.h"
- #include "wx/scrolwin.h"
- #include "wx/dirdlg.h"
- #include "wx/layout.h"
#include "wx/sizer.h"
- #include "wx/textdlg.h"
- #include "wx/filedlg.h"
- #include "wx/statusbr.h"
#include "wx/intl.h"
- #include "wx/frame.h"
#endif
-#include <wx/propgrid/property.h>
-#include <wx/propgrid/propgrid.h>
-
-#include <typeinfo>
+#include "wx/propgrid/property.h"
+#include "wx/propgrid/propgrid.h"
const wxChar *wxPGTypeName_long = wxT("long");
// VariantDatas
// ----------------------------------------------------------------------------
-WX_PG_IMPLEMENT_VARIANT_DATA(wxPGVariantDataPoint, wxPoint)
-WX_PG_IMPLEMENT_VARIANT_DATA(wxPGVariantDataSize, wxSize)
-WX_PG_IMPLEMENT_VARIANT_DATA(wxPGVariantDataArrayInt, wxArrayInt)
-WX_PG_IMPLEMENT_VARIANT_DATA(wxPGVariantDataLongLong, wxLongLong)
-WX_PG_IMPLEMENT_VARIANT_DATA(wxPGVariantDataULongLong, wxULongLong)
-
-WX_PG_IMPLEMENT_WXOBJECT_VARIANT_DATA(wxPGVariantDataFont, wxFont)
-
-wxObject* wxPG_VariantToWxObject( const wxVariant& variant, wxClassInfo* classInfo )
-{
- if ( !variant.IsValueKindOf(classInfo) )
- return (wxObject*) NULL;
-
- wxVariantData* vdata = variant.GetData();
-
- wxPGVariantData* pgvdata = wxDynamicCastVariantData(vdata, wxPGVariantData);
- if ( pgvdata )
- return (wxObject*) pgvdata->GetValuePtr();
-
- if ( wxPGIsVariantClassInfo(wxPGVariantDataGetClassInfo(vdata), wxobject) )
- return variant.GetWxObjectPtr();
-
- return (wxObject*) NULL;
-}
+WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED(wxPoint, WXDLLIMPEXP_PROPGRID)
+WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED(wxSize, WXDLLIMPEXP_PROPGRID)
+WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED_DUMMY_EQ(wxArrayInt, WXDLLIMPEXP_PROPGRID)
+IMPLEMENT_VARIANT_OBJECT_EXPORTED(wxFont, WXDLLIMPEXP_PROPGRID)
// -----------------------------------------------------------------------
-// wxVariant helpers
+// wxPGPropArgCls
// -----------------------------------------------------------------------
-long wxPGVariantToInt( const wxVariant& variant, long defVal )
+wxPGProperty* wxPGPropArgCls::GetPtr( wxPropertyGridInterface* iface ) const
{
- if ( variant.IsNull() )
- return defVal;
-
- if ( wxPGIsVariantType(variant, long) )
- return variant.GetLong();
-
- if ( wxPGIsVariantType(variant, bool) )
- return variant.GetBool() ? 1 : 0;
-
- if ( typeid(*variant.GetData()) == typeid(wxPGVariantDataLongLong) )
+ if ( m_flags == IsProperty )
{
- wxLongLong ll = ((const wxPGVariantDataLongLong&)variant).GetValue();
- if ( ll >= LONG_MAX )
- return LONG_MAX;
- else if ( ll <= LONG_MIN )
- return LONG_MIN;
- return ll.ToLong();
+ wxASSERT_MSG( m_ptr.property, wxT("invalid property ptr") );
+ return m_ptr.property;
}
-
- long l = defVal;
-
- if ( wxPGIsVariantType(variant, string) )
- variant.GetString().ToLong(&l, 0);
-
- return l;
+ else if ( m_flags & IsWxString )
+ return iface->GetPropertyByNameA(*m_ptr.stringName);
+ else if ( m_flags & IsCharPtr )
+ return iface->GetPropertyByNameA(m_ptr.charName);
+ else if ( m_flags & IsWCharPtr )
+ return iface->GetPropertyByNameA(m_ptr.wcharName);
+
+ return NULL;
}
// -----------------------------------------------------------------------
-
-bool wxPGVariantToLongLong( const wxVariant& variant, wxLongLong_t* pResult )
-{
- if ( variant.IsNull() )
- return false;
-
- if ( wxPGIsVariantType(variant, long) )
- {
- *pResult = variant.GetLong();
- return true;
- }
-
- if ( typeid(*variant.GetData()) == typeid(wxPGVariantDataLongLong) )
- {
- *pResult = ((const wxPGVariantDataLongLong&)variant).GetValue().GetValue();
- return true;
- }
-
- return false;
-}
-
-// -----------------------------------------------------------------------
-
-bool wxPGVariantToULongLong( const wxVariant& variant, wxULongLong_t* pResult )
-{
- if ( variant.IsNull() )
- return false;
-
- if ( wxPGIsVariantType(variant, long) )
- {
- *pResult = (unsigned long)variant.GetLong();
- return true;
- }
-
- if ( typeid(*variant.GetData()) == typeid(wxPGVariantDataULongLong) )
- {
- *pResult = ((const wxPGVariantDataULongLong&)variant).GetValue().GetValue();
- return true;
- }
-
- return false;
-}
-
-// -----------------------------------------------------------------------
-
-bool wxPGVariantToDouble( const wxVariant& variant, double* pResult )
-{
- if ( variant.IsNull() )
- return false;
-
- if ( wxPGIsVariantType(variant, double) )
- {
- *pResult = variant.GetDouble();
- return true;
- }
-
- if ( wxPGIsVariantType(variant, long) )
- {
- *pResult = (double)variant.GetLong();
- return true;
- }
-
- if ( typeid(*variant.GetData()) == typeid(wxPGVariantDataLongLong) )
- {
- wxLongLong ll = ((const wxPGVariantDataLongLong&)variant).GetValue();
- *pResult = ll.ToDouble();
- return true;
- }
-
- if ( wxPGIsVariantType(variant, string) )
- if ( variant.GetString().ToDouble(pResult) )
- return true;
-
- return false;
-}
-
-// -----------------------------------------------------------------------
-// Choice related methods
-// -----------------------------------------------------------------------
-
-void wxPropertyGridInterface::AddPropertyChoice( wxPGPropArg id,
- const wxString& label,
- int value )
-{
- wxPG_PROP_ARG_CALL_PROLOG()
-
- p->InsertChoice(label,-1,value);
-}
-
-
-void wxPropertyGridInterface::InsertPropertyChoice( wxPGPropArg id,
- const wxString& label,
- int index,
- int value )
-{
- wxPG_PROP_ARG_CALL_PROLOG()
-
- p->InsertChoice(label,index,value);
-}
-
-
-void wxPropertyGridInterface::DeletePropertyChoice( wxPGPropArg id,
- int index )
-{
- wxPG_PROP_ARG_CALL_PROLOG()
-
- p->DeleteChoice(index);
-}
-
+// wxPropertyGridInterface
// -----------------------------------------------------------------------
void wxPropertyGridInterface::RefreshGrid( wxPropertyGridPageState* state )
wxPGProperty* wxPropertyGridInterface::Append( wxPGProperty* property )
{
wxPGProperty* retp = m_pState->DoAppend(property);
-
+
wxPropertyGrid* grid = m_pState->GetGrid();
if ( grid )
grid->RefreshGrid();
wxPGProperty* wxPropertyGridInterface::Insert( wxPGPropArg id, wxPGProperty* property )
{
wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty)
- wxPGProperty* retp = m_pState->DoInsert(p->GetParent(), p->GetArrIndex(), property);
+ wxPGProperty* retp = m_pState->DoInsert(p->GetParent(), p->GetIndexInParent(), property);
RefreshGrid();
return retp;
}
wxPG_PROP_ARG_CALL_PROLOG()
wxPropertyGridPageState* state = p->GetParentState();
- wxPropertyGrid* grid = state->GetGrid();
- if ( grid->GetState() == state )
- {
- bool selRes = grid->DoSelectProperty(NULL, wxPG_SEL_DELETING);
- wxPG_CHECK_RET_DBG( selRes,
- wxT("failed to deselect a property (editor probably had invalid value)") );
- }
+ state->DoDelete( p, true );
+
+ RefreshGrid(state);
+}
+
+// -----------------------------------------------------------------------
- state->DoDelete( p );
+wxPGProperty* wxPropertyGridInterface::RemoveProperty( wxPGPropArg id )
+{
+ wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty)
+
+ wxCHECK( !p->GetChildCount() || p->HasFlag(wxPG_PROP_AGGREGATE),
+ wxNullProperty);
+
+ wxPropertyGridPageState* state = p->GetParentState();
+
+ state->DoDelete( p, false );
RefreshGrid(state);
+
+ return p;
}
// -----------------------------------------------------------------------
// wxPropertyGridInterface property operations
// -----------------------------------------------------------------------
-bool wxPropertyGridInterface::ClearSelection()
+wxPGProperty* wxPropertyGridInterface::GetSelection() const
{
+ return m_pState->GetSelection();
+}
+
+// -----------------------------------------------------------------------
+
+bool wxPropertyGridInterface::ClearSelection( bool validation )
+{
+ bool res = DoClearSelection(validation, wxPG_SEL_DONT_SEND_EVENT);
+ wxPropertyGrid* pg = GetPropertyGrid();
+ if ( pg )
+ pg->Refresh();
+ return res;
+}
+
+// -----------------------------------------------------------------------
+
+bool wxPropertyGridInterface::DoClearSelection( bool validation,
+ int selFlags )
+{
+ if ( !validation )
+ selFlags |= wxPG_SEL_NOVALIDATE;
+
wxPropertyGridPageState* state = m_pState;
- wxPropertyGrid* pg = state->GetGrid();
- if ( pg->GetState() == state )
- return pg->DoClearSelection();
- else
- state->SetSelection(NULL);
+
+ if ( state )
+ {
+ wxPropertyGrid* pg = state->GetGrid();
+ if ( pg->GetState() == state )
+ return pg->DoSelectProperty(NULL, selFlags);
+ else
+ state->DoSetSelection(NULL);
+ }
+
return true;
}
return false;
// If active, Set active Editor.
- if ( grid->GetState() == state && p == grid->GetSelection() )
+ if ( grid && grid->GetState() == state && p == grid->GetSelection() )
grid->DoSelectProperty( p, wxPG_SEL_FORCE );
}
else
return false;
// If active, Disable as active Editor.
- if ( grid->GetState() == state && p == grid->GetSelection() )
+ if ( grid && grid->GetState() == state && p == grid->GetSelection() )
grid->DoSelectProperty( p, wxPG_SEL_FORCE );
}
- state->DoEnableProperty(p, enable);
+ p->DoEnable(enable);
RefreshProperty( p );
if ( GetSelection() && GetSelection() != state->DoGetRoot() &&
!doExpand )
{
- if ( !pg->ClearSelection() )
- return false;
+ pg->DoClearSelection();
}
wxPGVIterator it;
// -----------------------------------------------------------------------
-void wxPropertyGridInterface::SetPropertyValueUnspecified( wxPGPropArg id )
+void wxPropertyGridInterface::ClearModifiedStatus()
{
- wxPG_PROP_ARG_CALL_PROLOG()
- wxPropertyGrid* propGrid = p->GetGridIfDisplayed();
- if ( propGrid )
- propGrid->DoSetPropertyValueUnspecified(p);
- else
- p->GetParentState()->DoSetPropertyValueUnspecified(p);
+ unsigned int pageIndex = 0;
+
+ for (;;)
+ {
+ wxPropertyGridPageState* page = GetPageState(pageIndex);
+ if ( !page ) break;
+
+ page->DoGetRoot()->SetFlagRecursively(wxPG_PROP_MODIFIED, false);
+ page->m_anyModified = false;
+
+ pageIndex++;
+ }
+
+ // Update active editor control, if any
+ GetPropertyGrid()->RefreshEditor();
+}
+
+bool wxPropertyGridInterface::SetColumnProportion( unsigned int column,
+ int proportion )
+{
+ wxCHECK(m_pState, false);
+ wxPropertyGrid* pg = m_pState->GetGrid();
+ wxCHECK(pg, false);
+ wxCHECK(pg->HasFlag(wxPG_SPLITTER_AUTO_CENTER), false);
+ m_pState->DoSetColumnProportion(column, proportion);
+ return true;
}
// -----------------------------------------------------------------------
// wxPropertyGridInterface property value setting and getting
// -----------------------------------------------------------------------
-void wxPGGetFailed( const wxPGProperty* p, const wxChar* typestr )
+void wxPGGetFailed( const wxPGProperty* p, const wxString& typestr )
{
- wxPGTypeOperationFailed(p,typestr,wxT("Get"));
+ wxPGTypeOperationFailed(p, typestr, wxS("Get"));
}
// -----------------------------------------------------------------------
-void wxPGTypeOperationFailed( const wxPGProperty* p, const wxChar* typestr,
- const wxChar* op )
+void wxPGTypeOperationFailed( const wxPGProperty* p,
+ const wxString& typestr,
+ const wxString& op )
{
wxASSERT( p != NULL );
wxLogError( _("Type operation \"%s\" failed: Property labeled \"%s\" is of type \"%s\", NOT \"%s\"."),
- op,p->GetLabel().c_str(),p->GetValue().GetType().c_str(),typestr );
+ op.c_str(), p->GetLabel().c_str(), p->GetValue().GetType().c_str(), typestr.c_str() );
}
// -----------------------------------------------------------------------
wxPG_PROP_ARG_CALL_PROLOG()
if ( p )
- {
p->SetValue(value);
- wxPropertyGrid* propGrid = p->GetGridIfDisplayed();
- if ( propGrid )
- propGrid->DrawItemAndValueRelated( p );
-
- }
}
// -----------------------------------------------------------------------
{
wxPG_PROP_ARG_CALL_PROLOG()
- if ( m_pState->DoSetPropertyValueString(p,value) )
- {
- wxPropertyGrid* propGrid = p->GetGridIfDisplayed();
- if ( propGrid )
- propGrid->DrawItemAndValueRelated( p );
- }
+ if ( p )
+ m_pState->DoSetPropertyValueString(p, value);
}
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
+void wxPropertyGridInterface::SetPropertyAttributeAll( const wxString& attrName,
+ wxVariant value )
+{
+ unsigned int pageIndex = 0;
+
+ for (;;)
+ {
+ wxPropertyGridPageState* page = GetPageState(pageIndex);
+ if ( !page ) break;
+
+ DoSetPropertyAttribute(page->DoGetRoot(), attrName, value, wxPG_RECURSE);
+
+ pageIndex++;
+ }
+}
+
+// -----------------------------------------------------------------------
+
void wxPropertyGridInterface::GetPropertiesWithFlag( wxArrayPGProperty* targetArr,
wxPGProperty::FlagType flags,
bool inverse,
// -----------------------------------------------------------------------
-void wxPropertyGridInterface::SetPropertiesFlag( const wxArrayPGProperty& srcArr,
- wxPGProperty::FlagType flags,
- bool inverse )
-{
- unsigned int i;
-
- for ( i=0; i<srcArr.size(); i++ )
- {
- wxPGProperty* property = srcArr[i];
-
- if ( !inverse )
- property->SetFlag(flags);
- else
- property->ClearFlag(flags);
- }
-
- // If collapsed flag or hidden was manipulated, we need to update virtual
- // size.
- wxPropertyGrid* pg = GetPropertyGrid();
- if ( flags & (wxPG_PROP_COLLAPSED|wxPG_PROP_HIDDEN) )
- {
- GetState()->VirtualHeightChanged();
- pg->RecalculateVirtualSize();
- }
-}
-
-// -----------------------------------------------------------------------
-
void wxPropertyGridInterface::SetBoolChoices( const wxString& trueChoice,
const wxString& falseChoice )
{
// -----------------------------------------------------------------------
-wxPGChoices gs_emptyChoices;
-
-wxPGChoices& wxPropertyGridInterface::GetPropertyChoices( wxPGPropArg id )
-{
- wxPG_PROP_ARG_CALL_PROLOG_RETVAL(gs_emptyChoices)
-
- wxPGChoiceInfo ci;
- ci.m_choices = (wxPGChoices*) NULL;
-
- p->GetChoiceInfo(&ci);
-
- if ( !ci.m_choices )
- return gs_emptyChoices;
-
- return *ci.m_choices;
-}
-
-// -----------------------------------------------------------------------
-
wxPGProperty* wxPropertyGridInterface::DoGetPropertyByName( const wxString& name ) const
{
return m_pState->BaseGetPropertyByName(name);
// -----------------------------------------------------------------------
+void wxPropertyGridInterface::Sort( int flags )
+{
+ wxPropertyGrid* pg = GetPropertyGrid();
+
+ unsigned int pageIndex = 0;
+
+ for (;;)
+ {
+ wxPropertyGridPageState* page = GetPageState(pageIndex);
+ if ( !page ) break;
+ page->DoSort(flags);
+ pageIndex++;
+ }
+
+ // Fix positions of any open editor controls
+ if ( pg )
+ pg->CorrectEditorWidgetPosY();
+}
+
+// -----------------------------------------------------------------------
+
void wxPropertyGridInterface::SetPropertyLabel( wxPGPropArg id, const wxString& newproplabel )
{
wxPG_PROP_ARG_CALL_PROLOG()
return true;
}
+// -----------------------------------------------------------------------
+
+void
+wxPropertyGridInterface::SetPropertyBackgroundColour( wxPGPropArg id,
+ const wxColour& colour,
+ int flags )
+{
+ wxPG_PROP_ARG_CALL_PROLOG()
+ p->SetBackgroundColour(colour, flags);
+ RefreshProperty(p);
+}
+
+// -----------------------------------------------------------------------
+
+void wxPropertyGridInterface::SetPropertyTextColour( wxPGPropArg id,
+ const wxColour& colour,
+ int flags )
+{
+ wxPG_PROP_ARG_CALL_PROLOG()
+ p->SetTextColour(colour, flags);
+ RefreshProperty(p);
+}
+
+// -----------------------------------------------------------------------
+
+void wxPropertyGridInterface::SetPropertyColoursToDefault( wxPGPropArg id )
+{
+ wxPG_PROP_ARG_CALL_PROLOG()
+
+ p->m_cells.clear();
+}
+
+// -----------------------------------------------------------------------
+
+void wxPropertyGridInterface::SetPropertyCell( wxPGPropArg id,
+ int column,
+ const wxString& text,
+ const wxBitmap& bitmap,
+ const wxColour& fgCol,
+ const wxColour& bgCol )
+{
+ wxPG_PROP_ARG_CALL_PROLOG()
+
+ wxPGCell& cell = p->GetCell(column);
+ if ( !text.empty() && text != wxPG_LABEL )
+ cell.SetText(text);
+ if ( bitmap.IsOk() )
+ cell.SetBitmap(bitmap);
+ if ( fgCol != wxNullColour )
+ cell.SetFgCol(fgCol);
+ if ( bgCol != wxNullColour )
+ cell.SetBgCol(bgCol);
+}
+
// -----------------------------------------------------------------------
// GetPropertyValueAsXXX methods
IMPLEMENT_GET_VALUE(long,long,Long,0)
IMPLEMENT_GET_VALUE(double,double,Double,0.0)
-IMPLEMENT_GET_VALUE(void,void*,VoidPtr,NULL)
-
-// wxObject is different than others.
-wxObject* wxPropertyGridInterface::GetPropertyValueAsWxObjectPtr( wxPGPropArg id ) const
-{
- wxPG_PROP_ARG_CALL_PROLOG_RETVAL((wxObject*)NULL)
-
- wxVariant value = p->GetValue();
- wxVariantData* vdata = value.GetData();
-
- if ( !vdata->GetValueClassInfo() )
- return (wxObject*) NULL;
-
- wxPGVariantData* pgvdata = wxDynamicCastVariantData(vdata, wxPGVariantData);
- if ( pgvdata )
- return (wxObject*) pgvdata->GetValuePtr();
-
- if ( wxPGIsVariantClassInfo(wxPGVariantDataGetClassInfo(vdata), wxobject) )
- return (wxObject*) value.GetWxObjectPtr();
-
- return (wxObject*) NULL;
-}
-
-// -----------------------------------------------------------------------
bool wxPropertyGridInterface::IsPropertyExpanded( wxPGPropArg id ) const
{
//
// Save state on page basis
- size_t pageIndex = 0;
- wxPropertyGridPageState* pageState = GetPageState(pageIndex);
+ unsigned int pageIndex = 0;
wxArrayPtrVoid pageStates;
- while ( pageState )
+
+ for (;;)
{
- pageStates.Add(pageState);
- pageIndex += 1;
- pageState = GetPageState(pageIndex);
+ wxPropertyGridPageState* page = GetPageState(pageIndex);
+ if ( !page ) break;
+
+ pageStates.Add(page);
+
+ pageIndex++;
}
for ( pageIndex=0; pageIndex < pageStates.size(); pageIndex++ )
if ( includedStates & ExpandedState )
{
wxArrayPGProperty ptrs;
- wxPropertyGridConstIterator it =
+ wxPropertyGridConstIterator it =
wxPropertyGridConstIterator( pageState,
wxPG_ITERATE_ALL_PARENTS_RECURSIVELY|wxPG_ITERATE_HIDDEN,
wxNullProperty );
if ( !p->HasFlag(wxPG_PROP_COLLAPSED) )
result += EscapeDelimiters(p->GetName());
- result += wxS(",");
+ result += wxS(",");
}
else
result += wxS("0;");
}
+ if ( includedStates & DescBoxState )
+ {
+ wxVariant v = GetEditableStateItem(wxS("descboxheight"));
+ if ( !v.IsNull() )
+ result += wxString::Format(wxS("descboxheight=%i;"), (int)v.GetLong());
+ }
result.RemoveLast(); // Remove last semicolon
result += wxS("|");
}
// Remove last '|'
- if ( result.length() )
+ if ( !result.empty() )
result.RemoveLast();
return result;
{
if ( restoreStates & ExpandedState )
{
- wxPropertyGridIterator it =
+ wxPropertyGridIterator it =
wxPropertyGridIterator( pageState,
wxPG_ITERATE_ALL,
wxNullProperty );
{
if ( pageState->IsDisplayed() )
{
- if ( values[0].length() )
+ if ( !values[0].empty() )
newSelection = GetPropertyByName(value);
pgSelectionSet = true;
}
else
{
- if ( values[0].length() )
- pageState->SetSelection(GetPropertyByName(value));
+ if ( !values[0].empty() )
+ pageState->DoSetSelection(GetPropertyByName(value));
else
pageState->DoClearSelection();
}
}
}
}
+ else if ( key == wxS("descboxheight") )
+ {
+ if ( restoreStates & DescBoxState )
+ {
+ long descBoxHeight;
+ if ( values.size() == 1 && values[0].ToLong(&descBoxHeight) )
+ {
+ SetEditableStateItem(wxS("descboxheight"), descBoxHeight);
+ }
+ else
+ {
+ res = false;
+ }
+ }
+ }
else
{
res = false;
if ( pgSelectionSet )
{
if ( newSelection )
- pg->SelectProperty(newSelection);
+ pg->DoSelectProperty(newSelection);
else
- pg->ClearSelection();
+ pg->DoClearSelection();
}
if ( selectedPage != -1 )
return res;
}
+#endif // wxUSE_PROPGRID
+