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