]> git.saurik.com Git - wxWidgets.git/blob - contrib/utils/wxrcedit/nodehnd.cpp
22e9da81c4ca9acb68d7c6648b9ff3c862863cd1
[wxWidgets.git] / contrib / utils / wxrcedit / nodehnd.cpp
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
33 WX_DEFINE_OBJARRAY(NodeInfoArray);
34
35
36
37 void 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;
47 // if modifying, don't forget to modify it in all places --
48 // search for wxINSTALL_PREFIX in editor.cpp
49 list.Add(".");
50 list.Add("./df");
51 #ifdef __UNIX__
52 list.Add(wxGetHomeDir() + "/.wxrcedit");
53 #ifdef wxINSTALL_PREFIX
54 list.Add(wxINSTALL_PREFIX "/share/wx/wxrcedit");
55 #endif
56 #endif
57
58 wxString path = list.FindValidPath(filename);
59 if (path.IsEmpty()) return;
60
61 wxTextFile tf;
62 tf.Open(path);
63
64 if (!tf.IsOpened()) return;
65
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;
94 else if (s == "notebook") tp = HANDLER_NOTEBOOK;
95 else if (s == "notebookpage") tp = HANDLER_NOTEBOOKPAGE;
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();
105 if (typ == "color") pi.Type = PROP_COLOR;
106 else if (typ == "flags") pi.Type = PROP_FLAGS;
107 else if (typ == "bool") pi.Type = PROP_BOOL;
108 else if (typ == "integer") pi.Type = PROP_INTEGER;
109 else if (typ == "coord") pi.Type = PROP_COORD;
110 else if (typ == "not_implemented") pi.Type = PROP_NOT_IMPLEMENTED;
111 else /*if (typ == "text")*/ pi.Type = PROP_TEXT;
112
113 bool fnd = FALSE;
114 for (size_t j = 0; j < Props.GetCount(); j++)
115 {
116 if (Props[j].Name == pi.Name)
117 {
118 if (Props[j].Type == pi.Type && pi.Type == PROP_FLAGS)
119 Props[j].MoreInfo << ',' << pi.MoreInfo;
120 else
121 Props[j] = pi;
122 fnd = TRUE;
123 }
124 }
125
126 if (!fnd) Props.Add(pi);
127 }
128 }
129
130 if (!nd.IsEmpty()) Node = nd;
131 if (!cht.IsEmpty()) ChildType = cht;
132 if (tp != HANDLER_NONE) Type = tp;
133 if (icn != -1) Icon = icn;
134 Abstract = ab;
135 }
136
137
138
139 NodeHandler *NodeHandler::CreateFromFile(const wxString& filename, EditorFrame *frame)
140 {
141 NodeHandler *hnd = NULL;
142
143 if (s_AllNodes == NULL) s_AllNodes = new NodeInfoArray;
144
145 NodeInfo *ni = new NodeInfo;
146 ni->Type = HANDLER_NONE;
147 ni->Icon = 0;
148 ni->Read(filename);
149 s_AllNodes->Add(*ni); // add a copy
150
151 if (ni->Type == HANDLER_NONE || ni->Node.IsEmpty() || ni->Abstract)
152 return NULL;
153
154 switch (ni->Type)
155 {
156 case HANDLER_PANEL:
157 hnd = new NodeHandlerPanel(frame, ni);
158 break;
159 case HANDLER_SIZER:
160 hnd = new NodeHandlerSizer(frame, ni);
161 break;
162 case HANDLER_SIZERITEM:
163 hnd = new NodeHandlerSizerItem(frame, ni);
164 break;
165 case HANDLER_NOTEBOOK:
166 hnd = new NodeHandlerNotebook(frame, ni);
167 break;
168 case HANDLER_NOTEBOOKPAGE:
169 hnd = new NodeHandlerNotebookPage(frame, ni);
170 break;
171 default:
172 hnd = new NodeHandler(frame, ni);
173 break;
174 }
175
176 return hnd;
177 }
178
179
180
181
182
183
184 PropertyHandler* NodeHandler::s_PropHandlers[PROP_TYPES_CNT] = {NULL};
185 int NodeHandler::s_RefCnt = 0;
186 NodeInfoArray* NodeHandler::s_AllNodes = NULL;
187
188
189 NodeHandler::NodeHandler(EditorFrame *frame, NodeInfo *ni) :
190 m_NodeInfo(ni)
191 {
192 if (s_RefCnt++ == 0) CreatePropHandlers();
193 }
194
195
196 void NodeHandler::CreatePropHandlers()
197 {
198 s_PropHandlers[PROP_TEXT] = new TextPropertyHandler;
199 s_PropHandlers[PROP_FLAGS] = new FlagsPropertyHandler;
200 s_PropHandlers[PROP_COLOR] = new TextPropertyHandler;
201 s_PropHandlers[PROP_BOOL] = new BoolPropertyHandler;
202 s_PropHandlers[PROP_INTEGER] = new TextPropertyHandler;
203 s_PropHandlers[PROP_COORD] = new CoordPropertyHandler;
204 s_PropHandlers[PROP_NOT_IMPLEMENTED] = new NotImplPropertyHandler;
205 }
206
207
208 NodeHandler::~NodeHandler()
209 {
210 if (--s_RefCnt == 0)
211 {
212 for (int i = 0; i < PROP_TYPES_CNT; i++)
213 delete s_PropHandlers[i];
214 delete s_AllNodes; s_AllNodes = NULL;
215 }
216 delete m_NodeInfo;
217 }
218
219
220
221 bool NodeHandler::CanHandle(wxXmlNode *node)
222 {
223 return (m_NodeInfo->Node == node->GetName());
224 }
225
226
227
228 wxTreeItemId NodeHandler::CreateTreeNode(wxTreeCtrl *treectrl,
229 wxTreeItemId parent,
230 wxXmlNode *node)
231 {
232 int icon = GetTreeIcon(node);
233 wxTreeItemId item =
234 treectrl->AppendItem(parent, GetTreeString(node),
235 icon, icon, new XmlTreeData(node));
236 if (parent == treectrl->GetRootItem())
237 treectrl->SetItemBold(item);
238 return item;
239 }
240
241
242
243 wxString NodeHandler::GetTreeString(wxXmlNode *node)
244 {
245 wxString xmlid = node->GetPropVal("name", "");
246 if (xmlid.IsEmpty())
247 return node->GetName();
248 else
249 return (node->GetName() + " '" + xmlid + "'");
250 }
251
252
253
254 void NodeHandler::CreatePropsList(wxListCtrl *listctrl, wxXmlNode *node)
255 {
256 int index;
257
258 for (size_t i = 0; i < m_NodeInfo->Props.GetCount(); i++)
259 {
260 PropertyInfo *p = &(m_NodeInfo->Props[i]);
261 index = s_PropHandlers[p->Type]->CreateListItem(listctrl, node, p);
262 listctrl->SetItemData(index, (long)new PropsListInfo(
263 index, s_PropHandlers[p->Type], node,
264 p, listctrl));
265 }
266 }
267
268
269
270 wxPanel *NodeHandler::CreatePropEditPanel(wxWindow *parent, wxListCtrl *listctrl, int index)
271 {
272 PropsListInfo *pli = (PropsListInfo*)listctrl->GetItemData(index);
273
274 return pli->m_Handler->CreateEditPanel(parent, pli);
275 }
276
277
278
279 wxArrayString& NodeHandler::GetChildTypes()
280 {
281 if (m_ChildTypes.IsEmpty())
282 {
283 wxString basetype = m_NodeInfo->ChildType;
284
285 for (size_t i = 0; i < s_AllNodes->GetCount(); i++)
286 {
287 NodeInfo &ni = (*s_AllNodes)[i];
288
289 if (ni.Node == basetype && !ni.Abstract)
290 m_ChildTypes.Add(ni.Node);
291
292 if (ni.DerivedFrom.Index(basetype) != wxNOT_FOUND && !ni.Abstract)
293 m_ChildTypes.Add(ni.Node);
294 }
295 m_ChildTypes.Sort();
296 }
297
298 return m_ChildTypes;
299 }
300
301
302
303 void NodeHandler::InsertNode(wxXmlNode *parent, wxXmlNode *node, wxXmlNode *insert_before)
304 {
305 delete node;
306 wxLogError(_("Cannot insert child into this type of node!"));
307 }
308
309
310
311
312
313
314
315
316 wxTreeItemId NodeHandlerPanel::CreateTreeNode(wxTreeCtrl *treectrl,
317 wxTreeItemId parent,
318 wxXmlNode *node)
319 {
320 wxTreeItemId root = NodeHandler::CreateTreeNode(treectrl, parent, node);
321
322 wxXmlNode *n = XmlFindNode(node, "children");
323
324 if (n) n = n->GetChildren();
325
326 while (n)
327 {
328 if (n->GetType() == wxXML_ELEMENT_NODE)
329 EditorFrame::Get()->CreateTreeNode(treectrl, root, n);
330 n = n->GetNext();
331 }
332 treectrl->Expand(root);
333 return root;
334 }
335
336
337
338 void NodeHandlerPanel::InsertNode(wxXmlNode *parent, wxXmlNode *node, wxXmlNode *insert_before)
339 {
340 wxXmlNode *cnd = XmlFindNode(parent, "children");
341 if (cnd == NULL)
342 {
343 cnd = new wxXmlNode(wxXML_ELEMENT_NODE, "children");
344 parent->AddChild(cnd);
345 }
346 if (insert_before)
347 cnd->InsertChild(node, insert_before);
348 else
349 cnd->AddChild(node);
350 EditorFrame::Get()->NotifyChanged(CHANGED_TREE);
351 }
352
353
354
355
356
357 void NodeHandlerSizer::InsertNode(wxXmlNode *parent, wxXmlNode *node, wxXmlNode *insert_before)
358 {
359 wxXmlNode *cnd = XmlFindNode(parent, "children");
360 if (cnd == NULL)
361 {
362 cnd = new wxXmlNode(wxXML_ELEMENT_NODE, "children");
363 parent->AddChild(cnd);
364 }
365
366 if (node->GetName() == "spacer" || node->GetName() == "sizeritem")
367 {
368 if (insert_before)
369 cnd->InsertChild(node, insert_before);
370 else
371 cnd->AddChild(node);
372 }
373 else
374 {
375 wxXmlNode *itemnode = new wxXmlNode(wxXML_ELEMENT_NODE, "sizeritem");
376 wxXmlNode *winnode = new wxXmlNode(wxXML_ELEMENT_NODE, "window");
377 itemnode->AddChild(winnode);
378 winnode->AddChild(node);
379
380 if (insert_before)
381 cnd->InsertChild(itemnode, insert_before);
382 else
383 cnd->AddChild(itemnode);
384 }
385 EditorFrame::Get()->NotifyChanged(CHANGED_TREE);
386 }
387
388
389
390 int NodeHandlerSizer::GetTreeIcon(wxXmlNode *node)
391 {
392 int orig = NodeHandler::GetTreeIcon(node);
393 if (orig == 0)
394 {
395 if (XmlReadValue(node, "orient") == "wxVERTICAL") return 2;
396 else return 3;
397 }
398 else return orig;
399 }
400
401
402
403 wxTreeItemId NodeHandlerSizerItem::CreateTreeNode(wxTreeCtrl *treectrl,
404 wxTreeItemId parent,
405 wxXmlNode *node)
406 {
407 wxTreeItemId root;
408
409 root = EditorFrame::Get()->CreateTreeNode(treectrl, parent, GetRealNode(node));
410 ((XmlTreeData*)treectrl->GetItemData(root))->Node = node;
411
412 treectrl->Expand(root);
413 return root;
414 }
415
416
417
418 void NodeHandlerSizerItem::CreatePropsList(wxListCtrl *listctrl, wxXmlNode *node)
419 {
420 NodeHandler::CreatePropsList(listctrl, node);
421 int item = listctrl->GetItemCount();
422 listctrl->InsertItem(item, "------");
423 listctrl->SetItemImage(item, 0, 0);
424 EditorFrame::Get()->CreatePropsList(listctrl, GetRealNode(node));
425 }
426
427
428
429 wxString NodeHandlerSizerItem::GetTreeString(wxXmlNode *node)
430 {
431 wxXmlNode *n = GetRealNode(node);
432 return EditorFrame::Get()->FindHandler(n)->GetTreeString(n);
433 }
434
435
436
437 int NodeHandlerSizerItem::GetTreeIcon(wxXmlNode *node)
438 {
439 wxXmlNode *n = GetRealNode(node);
440 return EditorFrame::Get()->FindHandler(n)->GetTreeIcon(n);
441 }
442
443
444
445 wxXmlNode *NodeHandlerSizerItem::GetRealNode(wxXmlNode *node)
446 {
447 wxXmlNode *n = XmlFindNode(node, "window");
448
449 if (n) n = n->GetChildren();
450
451 while (n)
452 {
453 if (n->GetType() == wxXML_ELEMENT_NODE)
454 return n;
455 n = n->GetNext();
456 }
457 return NULL;
458 }
459
460
461
462
463
464
465 void NodeHandlerNotebook::InsertNode(wxXmlNode *parent, wxXmlNode *node, wxXmlNode *insert_before)
466 {
467 wxXmlNode *cnd = XmlFindNode(parent, "children");
468 if (cnd == NULL)
469 {
470 cnd = new wxXmlNode(wxXML_ELEMENT_NODE, "children");
471 parent->AddChild(cnd);
472 }
473
474 {
475 wxXmlNode *itemnode;
476
477 if (node->GetName() == "notebookpage")
478 itemnode = node;
479 else
480 {
481 itemnode = new wxXmlNode(wxXML_ELEMENT_NODE, "notebookpage");
482 wxXmlNode *winnode = new wxXmlNode(wxXML_ELEMENT_NODE, "window");
483 itemnode->AddChild(winnode);
484 winnode->AddChild(node);
485 }
486
487 if (insert_before)
488 cnd->InsertChild(itemnode, insert_before);
489 else
490 cnd->AddChild(itemnode);
491 }
492 EditorFrame::Get()->NotifyChanged(CHANGED_TREE);
493 }