///////////////////////////////////////////////////////////////////////////// // Name: xh_propgrid.cpp // Purpose: XRC resource for wxPropertyGrid // Author: Jaakko Salli // Modified by: // Created: May-16-2007 // RCS-ID: $Id: // Copyright: (c) Jaakko Salli // Licence: wxWindows license ///////////////////////////////////////////////////////////////////////////// // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" #ifdef __BORLANDC__ #pragma hdrstop #endif #ifndef WX_PRECOMP #include "wx/wx.h" #endif /* NOTE: This source file is *not* included in the wxPropertyGrid library (to prevent xrc-lib dependency). To use this code, you will need to separately add src/xh_propgrid.cpp to your application. */ #if wxUSE_XRC && wxCHECK_VERSION(2,8,0) #include #include #ifndef WX_PRECOMP #include "wx/intl.h" #endif #if wxCHECK_VERSION(2,9,0) #define wxXML_GetAttribute(A,B,C) (A->GetAttribute(B,C)) #else #define wxXML_GetAttribute(A,B,C) (A->GetPropVal(B,C)) #endif IMPLEMENT_DYNAMIC_CLASS(wxPropertyGridXmlHandler, wxXmlResourceHandler) wxPropertyGridXmlHandler::wxPropertyGridXmlHandler() :wxXmlResourceHandler(), m_manager(NULL), m_populator(NULL) { XRC_ADD_STYLE(wxTAB_TRAVERSAL); XRC_ADD_STYLE(wxPG_AUTO_SORT); XRC_ADD_STYLE(wxPG_HIDE_CATEGORIES); XRC_ADD_STYLE(wxPG_BOLD_MODIFIED); XRC_ADD_STYLE(wxPG_SPLITTER_AUTO_CENTER); XRC_ADD_STYLE(wxPG_TOOLTIPS); XRC_ADD_STYLE(wxPG_HIDE_MARGIN); XRC_ADD_STYLE(wxPG_STATIC_SPLITTER); XRC_ADD_STYLE(wxPG_LIMITED_EDITING); XRC_ADD_STYLE(wxPG_TOOLBAR); XRC_ADD_STYLE(wxPG_DESCRIPTION); XRC_ADD_STYLE(wxPG_EX_INIT_NOCAT); XRC_ADD_STYLE(wxPG_EX_HELP_AS_TOOLTIPS); XRC_ADD_STYLE(wxPG_EX_AUTO_UNSPECIFIED_VALUES); XRC_ADD_STYLE(wxPG_EX_WRITEONLY_BUILTIN_ATTRIBUTES); XRC_ADD_STYLE(wxPG_EX_NO_FLAT_TOOLBAR); XRC_ADD_STYLE(wxPG_EX_MODE_BUTTONS); #if wxPG_COMPATIBILITY_1_2_0 XRC_ADD_STYLE(wxPG_EX_TRADITIONAL_VALIDATORS); #endif AddWindowStyles(); } class wxPropertyGridXrcPopulator : public wxPropertyGridPopulator { public: wxPropertyGridXrcPopulator( wxPropertyGridXmlHandler* handler ) : wxPropertyGridPopulator() { m_xrcHandler = handler; m_prevPopulator = m_xrcHandler->m_populator; } virtual ~wxPropertyGridXrcPopulator() { m_xrcHandler->m_populator = m_prevPopulator; } virtual void DoScanForChildren() { m_xrcHandler->CreateChildrenPrivately(m_pg, NULL); } protected: wxPropertyGridXmlHandler* m_xrcHandler; wxPropertyGridPopulator* m_prevPopulator; }; void wxPropertyGridXmlHandler::InitPopulator() { wxPropertyGridXrcPopulator* populator = new wxPropertyGridXrcPopulator(this); m_populator = populator; } void wxPropertyGridXmlHandler::PopulatePage( wxPropertyGridState* state ) { wxString sColumns(wxT("columns")); if ( HasParam(sColumns) ) state->SetColumnCount( GetLong(sColumns) ); m_populator->SetState( state ); m_populator->AddChildren( state->DoGetRoot() ); } void wxPropertyGridXmlHandler::DonePopulator() { delete m_populator; } void wxPropertyGridXmlHandler::HandlePropertyGridParams() { wxString sVW(wxT("virtualwidth")); if ( HasParam(sVW) ) { int vw = GetLong(sVW); m_pg->SetVirtualWidth(vw); } } wxObject *wxPropertyGridXmlHandler::DoCreateResource() { const wxXmlNode* node = m_node; wxString nodeName = node->GetName(); wxString emptyString; if ( nodeName == wxT("property") ) { // property wxString clas = wxXML_GetAttribute(node, wxT("class"), emptyString); wxString label; wxString sLabel(wxT("label")); if ( HasParam(sLabel) ) label = GetText(sLabel); wxString name; wxString sName(wxT("name")); if ( HasParam(sName) ) name = GetText(sName); else name = label; wxString sValue(wxT("value")); wxString value; wxString* pValue = NULL; if ( HasParam(sValue) ) { value = GetText(sValue); pValue = &value; } wxXmlNode* choicesNode = GetParamNode(wxT("choices")); wxPGChoices choices; if ( choicesNode ) { choices = m_populator->ParseChoices( choicesNode->GetNodeContent(), wxXML_GetAttribute(choicesNode, wxT("id"), emptyString)); } wxPGProperty* property = m_populator->Add( clas, label, name, pValue, &choices ); if ( !property ) return NULL; wxString sFlags(wxT("flags")); wxString flags; if ( HasParam(sFlags) ) property->SetFlagsFromString( GetText(sFlags) ); wxString sTip(wxT("tip")); if ( HasParam(sTip) ) property->SetHelpString(GetText(sTip)); if ( property->GetChildCount() ) { wxPGProperty* pwc = property; // FIXME wxString sExpanded(wxT("expanded")); if ( HasParam(sExpanded) ) pwc->SetExpanded(GetBool(sExpanded)); } // Need to call AddChildren even for non-parent properties for attributes and such m_populator->AddChildren(property); } else if ( nodeName == wxT("attribute") ) { // attribute wxString s1 = wxXML_GetAttribute(node, wxT("name"), emptyString); if ( s1.length() ) { m_populator->AddAttribute( s1, wxXML_GetAttribute(node, wxT("type"), emptyString), node->GetNodeContent() ); } } else if( m_class == wxT("wxPropertyGrid")) { XRC_MAKE_INSTANCE(control, wxPropertyGrid) control->Create(m_parentAsWindow, GetID(), GetPosition(), GetSize(), GetStyle(), GetName()); m_pg = control; HandlePropertyGridParams(); InitPopulator(); PopulatePage(control->GetState()); DonePopulator(); SetupWindow(control); return control; } else if ( nodeName == wxT("choices") ) { // choices // // Add choices list outside of a property m_populator->ParseChoices( node->GetNodeContent(), wxXML_GetAttribute(node, wxT("id"), emptyString)); } else if ( nodeName == wxT("splitterpos") ) { // splitterpos wxASSERT(m_populator); wxString sIndex = wxXML_GetAttribute(node, wxT("index"), emptyString); long index; if ( !sIndex.ToLong(&index, 10) ) index = 0; wxString s = node->GetNodeContent(); long pos; if ( wxPropertyGridPopulator::ToLongPCT(s, &pos, m_pg->GetClientSize().x) ) m_populator->GetState()->DoSetSplitterPosition( pos, index, false ); } #if wxPG_INCLUDE_MANAGER else if ( nodeName == wxT("page") ) { // page wxASSERT(m_manager); wxString label; wxString sLabel(wxT("label")); if ( HasParam(sLabel) ) label = GetText(sLabel); else label = wxString::Format(_("Page %i"),(int)(m_manager->GetPageCount()+1)); m_manager->AddPage(label); wxPropertyGridState* state = m_manager->GetPage(m_manager->GetPageCount()-1); PopulatePage(state); } else if( m_class == wxT("wxPropertyGridManager")) { XRC_MAKE_INSTANCE(control, wxPropertyGridManager) control->Create(m_parentAsWindow, GetID(), GetPosition(), GetSize(), GetStyle(), GetName()); wxPropertyGridManager* oldManager = m_manager; m_manager = control; m_pg = control->GetGrid(); HandlePropertyGridParams(); InitPopulator(); CreateChildrenPrivately(control, NULL); DonePopulator(); m_manager = oldManager; SetupWindow(control); return control; } #endif else { wxASSERT( false ); } return NULL; } bool wxPropertyGridXmlHandler::CanHandle(wxXmlNode *node) { #if wxCHECK_VERSION(2,7,0) #define fOurClass(A) IsOfClass(node, A) #else #define fOurClass(A) (wxXML_GetAttribute(node, wxT("class"), wxEmptyString) == A) #endif wxString name = node->GetName(); return ( ( m_populator && ( name == wxT("property") || name == wxT("attribute") || name == wxT("choices") || name == wxT("splitterpos") ) ) || (m_manager && name == wxT("page")) || (!m_populator && fOurClass(wxT("wxPropertyGrid"))) #if wxPG_INCLUDE_MANAGER || (!m_populator && fOurClass(wxT("wxPropertyGridManager"))) #endif ); } #endif // wxUSE_XRC && wxCHECK_VERSION(2,8,0)