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