wxWidgets/contrib/utils/wxrcedit/nodehnd.cpp

325 lines
7.6 KiB
C++

/////////////////////////////////////////////////////////////////////////////
// Author: Vaclav Slavik
// Created: 2000/05/05
// RCS-ID: $Id$
// Copyright: (c) 2000 Vaclav Slavik
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "nodehnd.h"
#endif
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#include "nodehnd.h"
#include "wx/xml/xml.h"
#include "wx/filefn.h"
#include "wx/wx.h"
#include "wx/arrimpl.cpp"
#include "wx/textfile.h"
#include "wx/tokenzr.h"
#include "wx/listctrl.h"
#include "editor.h"
#include "treedt.h"
#include "xmlhelpr.h"
#include "nodesdb.h"
wxList NodeHandler::ms_Handlers;
bool NodeHandler::ms_HandlersLoaded = false;
NodeHandler *NodeHandler::Find(wxXmlNode *node)
{
if (!ms_HandlersLoaded)
{
ms_HandlersLoaded = true;
ms_Handlers.DeleteContents(true);
NodeInfoArray& arr = NodesDb::Get()->GetNodesInfo();
NodeHandler *hnd;
for (size_t i = 0; i < arr.GetCount(); i++)
{
if (arr[i].NodeClass.IsEmpty() || arr[i].Abstract) continue;
if (arr[i].Type == _T("panel"))
hnd = new NodeHandlerPanel(&(arr[i]));
else if (arr[i].Type == _T("sizer"))
hnd = new NodeHandlerSizer(&(arr[i]));
else if (arr[i].Type == _T("sizeritem"))
hnd = new NodeHandlerSizerItem(&(arr[i]));
else if (arr[i].Type == _T("notebook"))
hnd = new NodeHandlerNotebook(&(arr[i]));
else if (arr[i].Type == _T("notebookpage"))
hnd = new NodeHandlerNotebookPage(&(arr[i]));
else
hnd = new NodeHandler(&(arr[i]));
if (hnd) ms_Handlers.Append(hnd);
}
ms_Handlers.Append(new NodeHandlerUnknown);
}
wxNode *n = ms_Handlers.GetFirst();
while (n)
{
NodeHandler *h = (NodeHandler*) n->GetData();
if (h->CanHandle(node))
return h;
n = n->GetNext();
}
return NULL;
}
NodeHandler::NodeHandler(NodeInfo *ni) :
m_NodeInfo(ni)
{
}
NodeHandler::~NodeHandler()
{
}
bool NodeHandler::CanHandle(wxXmlNode *node)
{
return (m_NodeInfo->NodeClass == XmlGetClass(node));
}
PropertyInfoArray& NodeHandler::GetPropsList(wxXmlNode *WXUNUSED(node))
{
return m_NodeInfo->Props;
}
wxTreeItemId NodeHandler::CreateTreeNode(wxTreeCtrl *treectrl,
wxTreeItemId parent,
wxXmlNode *node)
{
int icon = GetTreeIcon(node);
wxTreeItemId item =
treectrl->AppendItem(parent, GetTreeString(node),
icon, icon, new XmlTreeData(node));
if (parent == treectrl->GetRootItem())
treectrl->SetItemBold(item);
return item;
}
wxString NodeHandler::GetTreeString(wxXmlNode *node)
{
wxString xmlid = node->GetPropVal(_T("name"), wxEmptyString);
if (xmlid.IsEmpty())
return XmlGetClass(node);
else
return XmlGetClass(node) + _T(" '") + xmlid + _T("'");
}
wxArrayString& NodeHandler::GetChildTypes()
{
if (m_ChildTypes.IsEmpty())
{
wxString basetype = m_NodeInfo->ChildType;
NodeInfoArray& arr = NodesDb::Get()->GetNodesInfo();
for (size_t i = 0; i < arr.GetCount(); i++)
{
NodeInfo &ni = arr[i];
if (ni.NodeClass == basetype && !ni.Abstract)
m_ChildTypes.Add(ni.NodeClass);
if (ni.DerivedFrom.Index(basetype) != wxNOT_FOUND && !ni.Abstract)
m_ChildTypes.Add(ni.NodeClass);
}
m_ChildTypes.Sort();
}
return m_ChildTypes;
}
void NodeHandler::InsertNode(wxXmlNode *WXUNUSED(parent), wxXmlNode *node, wxXmlNode *WXUNUSED(insert_before))
{
delete node;
wxLogError(_("Cannot insert child into this type of node!"));
}
wxTreeItemId NodeHandlerPanel::CreateTreeNode(wxTreeCtrl *treectrl,
wxTreeItemId parent,
wxXmlNode *node)
{
wxTreeItemId root = NodeHandler::CreateTreeNode(treectrl, parent, node);
wxXmlNode *n = XmlFindNode(node, _T("object"));
while (n)
{
if (n->GetType() == wxXML_ELEMENT_NODE &&
n->GetName() == _T("object"))
Find(n)->CreateTreeNode(treectrl, root, n);
n = n->GetNext();
}
//treectrl->Expand(root);
return root;
}
void NodeHandlerPanel::InsertNode(wxXmlNode *parent, wxXmlNode *node, wxXmlNode *insert_before)
{
if (insert_before)
parent->InsertChild(node, insert_before);
else
parent->AddChild(node);
EditorFrame::Get()->NotifyChanged(CHANGED_TREE);
}
void NodeHandlerSizer::InsertNode(wxXmlNode *parent, wxXmlNode *node, wxXmlNode *insert_before)
{
if (XmlGetClass(node) == _T("spacer") || XmlGetClass(node) == _T("sizeritem"))
{
if (insert_before)
parent->InsertChild(node, insert_before);
else
parent->AddChild(node);
}
else
{
wxXmlNode *itemnode = new wxXmlNode(wxXML_ELEMENT_NODE, _T("object"));
itemnode->AddProperty(_T("class"), _T("sizeritem"));
itemnode->AddChild(node);
if (insert_before)
parent->InsertChild(itemnode, insert_before);
else
parent->AddChild(itemnode);
}
EditorFrame::Get()->NotifyChanged(CHANGED_TREE);
}
int NodeHandlerSizer::GetTreeIcon(wxXmlNode *node)
{
int orig = NodeHandler::GetTreeIcon(node);
if (orig == 0)
{
if (XmlReadValue(node, _T("orient")) == _T("wxVERTICAL")) return 2;
else return 3;
}
else return orig;
}
wxTreeItemId NodeHandlerSizerItem::CreateTreeNode(wxTreeCtrl *treectrl,
wxTreeItemId parent,
wxXmlNode *node)
{
wxTreeItemId root;
root = Find(GetRealNode(node))->CreateTreeNode(treectrl, parent, GetRealNode(node));
((XmlTreeData*)treectrl->GetItemData(root))->Node = node;
//treectrl->Expand(root);
return root;
}
PropertyInfoArray& NodeHandlerSizerItem::GetPropsList(wxXmlNode *node)
{
m_dummy = NodeHandler::GetPropsList(node);
wxXmlNode *nd = GetRealNode(node);
m_dummy.Add(PropertyInfo(wxEmptyString, wxEmptyString, wxEmptyString));
size_t pos = m_dummy.GetCount();
WX_APPEND_ARRAY(m_dummy,
Find(nd)->GetPropsList(nd));
for (size_t i = pos; i < m_dummy.GetCount(); i++)
m_dummy[i].Name = _T("object/") + m_dummy[i].Name;
return m_dummy;
}
wxString NodeHandlerSizerItem::GetTreeString(wxXmlNode *node)
{
wxXmlNode *n = GetRealNode(node);
return Find(n)->GetTreeString(n);
}
int NodeHandlerSizerItem::GetTreeIcon(wxXmlNode *node)
{
wxXmlNode *n = GetRealNode(node);
return Find(n)->GetTreeIcon(n);
}
wxXmlNode *NodeHandlerSizerItem::GetRealNode(wxXmlNode *node)
{
return XmlFindNode(node, _T("object"));
}
void NodeHandlerNotebook::InsertNode(wxXmlNode *parent, wxXmlNode *node, wxXmlNode *insert_before)
{
{
wxXmlNode *itemnode;
if (XmlGetClass(node) == _T("notebookpage"))
itemnode = node;
else
{
itemnode = new wxXmlNode(wxXML_ELEMENT_NODE, _T("object"));
itemnode->AddProperty(_T("class"), _T("notebookpage"));
itemnode->AddChild(node);
}
if (insert_before)
parent->InsertChild(itemnode, insert_before);
else
parent->AddChild(itemnode);
}
EditorFrame::Get()->NotifyChanged(CHANGED_TREE);
}