]> git.saurik.com Git - wxWidgets.git/blame - contrib/utils/wxrcedit/nodehnd.cpp
added new controls: wxBitmapButton, wxCalendarCtrl, wxListCtrl, wxScrollBar, wxStatic...
[wxWidgets.git] / contrib / utils / wxrcedit / nodehnd.cpp
CommitLineData
56d2f750
VS
1/////////////////////////////////////////////////////////////////////////////
2// Author: Vaclav Slavik
3// Created: 2000/05/05
4// RCS-ID: $Id$
5// Copyright: (c) 2000 Vaclav Slavik
6// Licence: wxWindows licence
7/////////////////////////////////////////////////////////////////////////////
8
9#ifdef __GNUG__
10 #pragma implementation "nodehnd.h"
11#endif
12
13// For compilers that support precompilation, includes "wx/wx.h".
14#include "wx/wxprec.h"
15
16#ifdef __BORLANDC__
17 #pragma hdrstop
18#endif
19
20#include "nodehnd.h"
21#include "wx/xml/xml.h"
22#include "wx/filefn.h"
23#include "wx/wx.h"
24#include "wx/arrimpl.cpp"
25#include "wx/textfile.h"
26#include "wx/tokenzr.h"
27#include "wx/listctrl.h"
28#include "editor.h"
29#include "treedt.h"
30#include "xmlhelpr.h"
31
32
33WX_DEFINE_OBJARRAY(NodeInfoArray);
34
35
36
37void NodeInfo::Read(const wxString& filename)
38{
39 HandlerType tp = HANDLER_NONE;
40 wxString nd, cht;
41 bool ab = FALSE;
42 long icn = -1;
43
44 Node.Empty();
45
46 wxPathList list;
2ada7c65
VS
47 // if modifying, don't forget to modify it in all places --
48 // search for wxINSTALL_PREFIX in editor.cpp
56d2f750
VS
49 list.Add(".");
50 list.Add("./df");
2ada7c65 51#ifdef __UNIX__
56d2f750 52 list.Add(wxGetHomeDir() + "/.wxrcedit");
2ada7c65
VS
53 #ifdef wxINSTALL_PREFIX
54 list.Add(wxINSTALL_PREFIX "/share/wx/wxrcedit");
56d2f750 55 #endif
2ada7c65 56#endif
56d2f750
VS
57
58 wxString path = list.FindValidPath(filename);
59 if (path.IsEmpty()) return;
60
61 wxTextFile tf;
62 tf.Open(path);
56d2f750 63
2ada7c65
VS
64 if (!tf.IsOpened()) return;
65
56d2f750
VS
66 for (size_t i = 0; i < tf.GetLineCount(); i++)
67 {
68 if (tf[i].IsEmpty() || tf[i][0] == '#') continue;
69 wxStringTokenizer tkn(tf[i], ' ');
70 wxString s = tkn.GetNextToken();
71 if (s == "node")
72 nd = tkn.GetNextToken();
73 else if (s == "childtype")
74 cht = tkn.GetNextToken();
75 else if (s == "icon")
76 tkn.GetNextToken().ToLong(&icn);
77 else if (s == "derived")
78 {
79 if (tkn.GetNextToken() == "from")
80 {
81 s = tkn.GetNextToken();
82 DerivedFrom.Add(s);
83 Read(s + ".df");
84 }
85 }
86 else if (s == "abstract")
87 ab = true;
88 else if (s == "type")
89 {
90 s = tkn.GetNextToken();
91 if (s == "sizer") tp = HANDLER_SIZER;
92 else if (s == "sizeritem") tp = HANDLER_SIZERITEM;
93 else if (s == "panel") tp = HANDLER_PANEL;
ab13d1c5
VS
94 else if (s == "notebook") tp = HANDLER_NOTEBOOK;
95 else if (s == "notebookpage") tp = HANDLER_NOTEBOOKPAGE;
56d2f750
VS
96 else /*if (s == "normal")*/ tp = HANDLER_NORMAL;
97 }
98 else if (s == "var")
99 {
100 PropertyInfo pi;
101 pi.Name = tkn.GetNextToken();
102 tkn.GetNextToken();
103 wxString typ = tkn.GetNextToken();
104 if (tkn.HasMoreTokens()) pi.MoreInfo = tkn.GetNextToken();
bebb14d5
VS
105 /* ADD NEW PROPERTY TYPES HERE
106 (search for other occurences of this comment in _all_ files) */
56d2f750
VS
107 if (typ == "color") pi.Type = PROP_COLOR;
108 else if (typ == "flags") pi.Type = PROP_FLAGS;
109 else if (typ == "bool") pi.Type = PROP_BOOL;
110 else if (typ == "integer") pi.Type = PROP_INTEGER;
ab13d1c5 111 else if (typ == "coord") pi.Type = PROP_COORD;
bebb14d5 112 else if (typ == "dimension") pi.Type = PROP_DIMENSION;
ab13d1c5 113 else if (typ == "not_implemented") pi.Type = PROP_NOT_IMPLEMENTED;
56d2f750
VS
114 else /*if (typ == "text")*/ pi.Type = PROP_TEXT;
115
116 bool fnd = FALSE;
117 for (size_t j = 0; j < Props.GetCount(); j++)
118 {
119 if (Props[j].Name == pi.Name)
120 {
121 if (Props[j].Type == pi.Type && pi.Type == PROP_FLAGS)
122 Props[j].MoreInfo << ',' << pi.MoreInfo;
123 else
124 Props[j] = pi;
125 fnd = TRUE;
126 }
127 }
128
129 if (!fnd) Props.Add(pi);
130 }
131 }
132
133 if (!nd.IsEmpty()) Node = nd;
134 if (!cht.IsEmpty()) ChildType = cht;
135 if (tp != HANDLER_NONE) Type = tp;
136 if (icn != -1) Icon = icn;
137 Abstract = ab;
138}
139
140
141
142NodeHandler *NodeHandler::CreateFromFile(const wxString& filename, EditorFrame *frame)
143{
144 NodeHandler *hnd = NULL;
145
146 if (s_AllNodes == NULL) s_AllNodes = new NodeInfoArray;
147
148 NodeInfo *ni = new NodeInfo;
149 ni->Type = HANDLER_NONE;
150 ni->Icon = 0;
151 ni->Read(filename);
152 s_AllNodes->Add(*ni); // add a copy
153
154 if (ni->Type == HANDLER_NONE || ni->Node.IsEmpty() || ni->Abstract)
155 return NULL;
156
157 switch (ni->Type)
158 {
159 case HANDLER_PANEL:
160 hnd = new NodeHandlerPanel(frame, ni);
161 break;
162 case HANDLER_SIZER:
163 hnd = new NodeHandlerSizer(frame, ni);
164 break;
165 case HANDLER_SIZERITEM:
166 hnd = new NodeHandlerSizerItem(frame, ni);
167 break;
ab13d1c5
VS
168 case HANDLER_NOTEBOOK:
169 hnd = new NodeHandlerNotebook(frame, ni);
170 break;
171 case HANDLER_NOTEBOOKPAGE:
172 hnd = new NodeHandlerNotebookPage(frame, ni);
173 break;
56d2f750
VS
174 default:
175 hnd = new NodeHandler(frame, ni);
176 break;
177 }
178
179 return hnd;
180}
181
182
183
184
185
186
187PropertyHandler* NodeHandler::s_PropHandlers[PROP_TYPES_CNT] = {NULL};
188int NodeHandler::s_RefCnt = 0;
189NodeInfoArray* NodeHandler::s_AllNodes = NULL;
190
191
192NodeHandler::NodeHandler(EditorFrame *frame, NodeInfo *ni) :
193 m_NodeInfo(ni)
194{
195 if (s_RefCnt++ == 0) CreatePropHandlers();
196}
197
198
199void NodeHandler::CreatePropHandlers()
200{
bebb14d5
VS
201 /* ADD NEW PROPERTY TYPES HERE
202 (search for other occurences of this comment in _all_ files) */
56d2f750
VS
203 s_PropHandlers[PROP_TEXT] = new TextPropertyHandler;
204 s_PropHandlers[PROP_FLAGS] = new FlagsPropertyHandler;
205 s_PropHandlers[PROP_COLOR] = new TextPropertyHandler;
206 s_PropHandlers[PROP_BOOL] = new BoolPropertyHandler;
207 s_PropHandlers[PROP_INTEGER] = new TextPropertyHandler;
208 s_PropHandlers[PROP_COORD] = new CoordPropertyHandler;
bebb14d5 209 s_PropHandlers[PROP_DIMENSION] = new DimensionPropertyHandler;
ab13d1c5 210 s_PropHandlers[PROP_NOT_IMPLEMENTED] = new NotImplPropertyHandler;
56d2f750
VS
211}
212
213
214NodeHandler::~NodeHandler()
215{
216 if (--s_RefCnt == 0)
217 {
218 for (int i = 0; i < PROP_TYPES_CNT; i++)
219 delete s_PropHandlers[i];
220 delete s_AllNodes; s_AllNodes = NULL;
221 }
222 delete m_NodeInfo;
223}
224
225
226
227bool NodeHandler::CanHandle(wxXmlNode *node)
228{
229 return (m_NodeInfo->Node == node->GetName());
230}
231
232
233
234wxTreeItemId NodeHandler::CreateTreeNode(wxTreeCtrl *treectrl,
235 wxTreeItemId parent,
236 wxXmlNode *node)
237{
238 int icon = GetTreeIcon(node);
239 wxTreeItemId item =
240 treectrl->AppendItem(parent, GetTreeString(node),
241 icon, icon, new XmlTreeData(node));
242 if (parent == treectrl->GetRootItem())
243 treectrl->SetItemBold(item);
244 return item;
245}
246
247
248
249wxString NodeHandler::GetTreeString(wxXmlNode *node)
250{
251 wxString xmlid = node->GetPropVal("name", "");
252 if (xmlid.IsEmpty())
253 return node->GetName();
254 else
255 return (node->GetName() + " '" + xmlid + "'");
256}
257
258
259
260void NodeHandler::CreatePropsList(wxListCtrl *listctrl, wxXmlNode *node)
261{
262 int index;
263
264 for (size_t i = 0; i < m_NodeInfo->Props.GetCount(); i++)
265 {
266 PropertyInfo *p = &(m_NodeInfo->Props[i]);
267 index = s_PropHandlers[p->Type]->CreateListItem(listctrl, node, p);
268 listctrl->SetItemData(index, (long)new PropsListInfo(
269 index, s_PropHandlers[p->Type], node,
270 p, listctrl));
271 }
272}
273
274
275
276wxPanel *NodeHandler::CreatePropEditPanel(wxWindow *parent, wxListCtrl *listctrl, int index)
277{
278 PropsListInfo *pli = (PropsListInfo*)listctrl->GetItemData(index);
279
280 return pli->m_Handler->CreateEditPanel(parent, pli);
281}
282
283
284
285wxArrayString& NodeHandler::GetChildTypes()
286{
287 if (m_ChildTypes.IsEmpty())
288 {
289 wxString basetype = m_NodeInfo->ChildType;
290
291 for (size_t i = 0; i < s_AllNodes->GetCount(); i++)
292 {
293 NodeInfo &ni = (*s_AllNodes)[i];
294
295 if (ni.Node == basetype && !ni.Abstract)
296 m_ChildTypes.Add(ni.Node);
297
298 if (ni.DerivedFrom.Index(basetype) != wxNOT_FOUND && !ni.Abstract)
299 m_ChildTypes.Add(ni.Node);
300 }
301 m_ChildTypes.Sort();
302 }
303
304 return m_ChildTypes;
305}
306
307
308
309void NodeHandler::InsertNode(wxXmlNode *parent, wxXmlNode *node, wxXmlNode *insert_before)
310{
311 delete node;
312 wxLogError(_("Cannot insert child into this type of node!"));
313}
314
315
316
317
318
319
320
321
322wxTreeItemId NodeHandlerPanel::CreateTreeNode(wxTreeCtrl *treectrl,
323 wxTreeItemId parent,
324 wxXmlNode *node)
325{
326 wxTreeItemId root = NodeHandler::CreateTreeNode(treectrl, parent, node);
327
328 wxXmlNode *n = XmlFindNode(node, "children");
329
330 if (n) n = n->GetChildren();
331
332 while (n)
333 {
334 if (n->GetType() == wxXML_ELEMENT_NODE)
335 EditorFrame::Get()->CreateTreeNode(treectrl, root, n);
336 n = n->GetNext();
337 }
338 treectrl->Expand(root);
339 return root;
340}
341
342
343
344void NodeHandlerPanel::InsertNode(wxXmlNode *parent, wxXmlNode *node, wxXmlNode *insert_before)
345{
346 wxXmlNode *cnd = XmlFindNode(parent, "children");
347 if (cnd == NULL)
348 {
349 cnd = new wxXmlNode(wxXML_ELEMENT_NODE, "children");
350 parent->AddChild(cnd);
351 }
352 if (insert_before)
353 cnd->InsertChild(node, insert_before);
354 else
355 cnd->AddChild(node);
356 EditorFrame::Get()->NotifyChanged(CHANGED_TREE);
357}
358
359
360
361
362
363void NodeHandlerSizer::InsertNode(wxXmlNode *parent, wxXmlNode *node, wxXmlNode *insert_before)
364{
365 wxXmlNode *cnd = XmlFindNode(parent, "children");
366 if (cnd == NULL)
367 {
368 cnd = new wxXmlNode(wxXML_ELEMENT_NODE, "children");
369 parent->AddChild(cnd);
370 }
371
2ada7c65 372 if (node->GetName() == "spacer" || node->GetName() == "sizeritem")
56d2f750
VS
373 {
374 if (insert_before)
375 cnd->InsertChild(node, insert_before);
376 else
377 cnd->AddChild(node);
378 }
379 else
380 {
381 wxXmlNode *itemnode = new wxXmlNode(wxXML_ELEMENT_NODE, "sizeritem");
382 wxXmlNode *winnode = new wxXmlNode(wxXML_ELEMENT_NODE, "window");
383 itemnode->AddChild(winnode);
384 winnode->AddChild(node);
385
386 if (insert_before)
387 cnd->InsertChild(itemnode, insert_before);
388 else
389 cnd->AddChild(itemnode);
390 }
391 EditorFrame::Get()->NotifyChanged(CHANGED_TREE);
392}
393
394
395
396int NodeHandlerSizer::GetTreeIcon(wxXmlNode *node)
397{
ab13d1c5
VS
398 int orig = NodeHandler::GetTreeIcon(node);
399 if (orig == 0)
400 {
401 if (XmlReadValue(node, "orient") == "wxVERTICAL") return 2;
402 else return 3;
403 }
404 else return orig;
56d2f750
VS
405}
406
407
408
409wxTreeItemId NodeHandlerSizerItem::CreateTreeNode(wxTreeCtrl *treectrl,
410 wxTreeItemId parent,
411 wxXmlNode *node)
412{
413 wxTreeItemId root;
414
415 root = EditorFrame::Get()->CreateTreeNode(treectrl, parent, GetRealNode(node));
416 ((XmlTreeData*)treectrl->GetItemData(root))->Node = node;
417
418 treectrl->Expand(root);
419 return root;
420}
421
422
423
424void NodeHandlerSizerItem::CreatePropsList(wxListCtrl *listctrl, wxXmlNode *node)
425{
426 NodeHandler::CreatePropsList(listctrl, node);
427 int item = listctrl->GetItemCount();
428 listctrl->InsertItem(item, "------");
429 listctrl->SetItemImage(item, 0, 0);
430 EditorFrame::Get()->CreatePropsList(listctrl, GetRealNode(node));
431}
432
433
434
435wxString NodeHandlerSizerItem::GetTreeString(wxXmlNode *node)
436{
437 wxXmlNode *n = GetRealNode(node);
438 return EditorFrame::Get()->FindHandler(n)->GetTreeString(n);
439}
440
441
442
443int NodeHandlerSizerItem::GetTreeIcon(wxXmlNode *node)
444{
445 wxXmlNode *n = GetRealNode(node);
446 return EditorFrame::Get()->FindHandler(n)->GetTreeIcon(n);
447}
448
449
450
451wxXmlNode *NodeHandlerSizerItem::GetRealNode(wxXmlNode *node)
452{
453 wxXmlNode *n = XmlFindNode(node, "window");
454
455 if (n) n = n->GetChildren();
456
457 while (n)
458 {
459 if (n->GetType() == wxXML_ELEMENT_NODE)
460 return n;
461 n = n->GetNext();
462 }
463 return NULL;
464}
ab13d1c5
VS
465
466
467
468
469
470
471void NodeHandlerNotebook::InsertNode(wxXmlNode *parent, wxXmlNode *node, wxXmlNode *insert_before)
472{
473 wxXmlNode *cnd = XmlFindNode(parent, "children");
474 if (cnd == NULL)
475 {
476 cnd = new wxXmlNode(wxXML_ELEMENT_NODE, "children");
477 parent->AddChild(cnd);
478 }
479
480 {
2ada7c65
VS
481 wxXmlNode *itemnode;
482
483 if (node->GetName() == "notebookpage")
484 itemnode = node;
485 else
486 {
487 itemnode = new wxXmlNode(wxXML_ELEMENT_NODE, "notebookpage");
488 wxXmlNode *winnode = new wxXmlNode(wxXML_ELEMENT_NODE, "window");
489 itemnode->AddChild(winnode);
490 winnode->AddChild(node);
491 }
ab13d1c5
VS
492
493 if (insert_before)
494 cnd->InsertChild(itemnode, insert_before);
495 else
496 cnd->AddChild(itemnode);
497 }
498 EditorFrame::Get()->NotifyChanged(CHANGED_TREE);
499}