]> git.saurik.com Git - wxWidgets.git/blob - contrib/utils/wxrcedit/editor.cpp
f522ce1f818763bf3172b0fc8bd57be330afad5a
[wxWidgets.git] / contrib / utils / wxrcedit / editor.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 "editor.h"
11 #pragma implementation "treedt.h"
12 #endif
13
14 // For compilers that support precompilation, includes "wx/wx.h".
15 #include "wx/wxprec.h"
16
17 #ifdef __BORLANDC__
18 #pragma hdrstop
19 #endif
20
21 #include "wx/wx.h"
22 #include "wx/xml/xml.h"
23 #include "wx/xml/xmlres.h"
24 #include "wx/splitter.h"
25 #include "wx/config.h"
26 #include "wx/dir.h"
27 #include "wx/listctrl.h"
28 #include "wx/imaglist.h"
29
30 #include "treedt.h"
31 #include "editor.h"
32 #include "nodehnd.h"
33 #include "xmlhelpr.h"
34
35
36
37 class EditorTreeCtrl : public wxTreeCtrl
38 {
39 public:
40 EditorTreeCtrl(wxWindow *parent, int id, EditorFrame *frame)
41 : wxTreeCtrl(parent, id), m_EdFrame(frame) {}
42
43 private:
44 EditorFrame *m_EdFrame;
45
46 void OnRightClick(wxMouseEvent &event)
47 {
48 wxTreeItemId item =
49 m_EdFrame->m_TreeCtrl->HitTest(event.GetPosition());
50 if (item.IsOk())
51 {
52 m_EdFrame->m_TreeCtrl->SelectItem(item);
53 m_EdFrame->OnRightClickTree(event.GetPosition());
54 }
55 }
56 DECLARE_EVENT_TABLE()
57 };
58
59 BEGIN_EVENT_TABLE(EditorTreeCtrl, wxTreeCtrl)
60 EVT_RIGHT_DOWN(EditorTreeCtrl::OnRightClick)
61 END_EVENT_TABLE()
62
63
64 enum
65 {
66 ID_PREVIEW = wxID_HIGHEST + 100,
67 ID_NEW,
68 ID_OPEN,
69 ID_CLOSE,
70 ID_SAVE,
71 ID_SAVEAS,
72 ID_DELETE_NODE,
73 ID_EXIT,
74 ID_TREE,
75 ID_XMLIDEDIT,
76 ID_XMLIDPICK,
77 ID_EDITCODE,
78 ID_PROPSLIST,
79 ID_CLEARPROP,
80
81 ID_NEWDIALOG,
82 ID_NEWPANEL,
83 ID_NEWMENU,
84 ID_NEWMENUBAR,
85 ID_NEWTOOLBAR,
86 ID_NEWNODE = wxID_HIGHEST + 1000,
87 ID_NEWSYBNODE = ID_NEWNODE + 2000
88 };
89
90 #ifdef __UNIX__
91 #endif
92
93
94
95
96 BEGIN_EVENT_TABLE(EditorFrame, wxFrame)
97 EVT_TREE_SEL_CHANGED(ID_TREE, EditorFrame::OnTreeSel)
98 EVT_TOOL_RANGE(ID_PREVIEW, ID_EXIT, EditorFrame::OnToolbar)
99 EVT_MENU_RANGE(ID_NEWDIALOG, ID_NEWSYBNODE + 1000, EditorFrame::OnNewNode)
100 EVT_TEXT(ID_XMLIDEDIT, EditorFrame::OnXMLIDEdit)
101 EVT_BUTTON(ID_XMLIDPICK, EditorFrame::OnXMLIDPick)
102 EVT_BUTTON(ID_EDITCODE, EditorFrame::OnEditCode)
103 EVT_BUTTON(ID_CLEARPROP, EditorFrame::OnClearProp)
104 EVT_LIST_ITEM_SELECTED(ID_PROPSLIST, EditorFrame::OnPropSel)
105 END_EVENT_TABLE()
106
107
108
109 #if defined(__UNIX__) || wxUSE_XPM_IN_MSW
110 #include "bitmaps/preview.xpm"
111 #include "bitmaps/close.xpm"
112 #include "bitmaps/save.xpm"
113 #include "bitmaps/open.xpm"
114
115 #include "bitmaps/control.xpm"
116 #include "bitmaps/vsizer.xpm"
117 #include "bitmaps/hsizer.xpm"
118 #include "bitmaps/panel.xpm"
119 #include "bitmaps/gsizer.xpm"
120 #include "bitmaps/resicon.xpm"
121
122 #include "bitmaps/unused.xpm"
123 #include "bitmaps/used.xpm"
124 #endif
125
126 #if defined(__WXMSW__) && defined(wxUSE_XPM_IN_MSW)
127 #undef wxBITMAP
128 #define wxBITMAP(arg) wxBitmap(arg##_xpm)
129 #undef wxICON
130 #define wxICON(arg) wxIcon(arg##_xpm)
131 #endif
132
133
134 EditorFrame *EditorFrame::ms_Instance = NULL;
135
136 EditorFrame::EditorFrame(wxFrame *parent, const wxString& filename)
137 : wxFrame(parent, -1, filename + _("- wxWindows resources editor"))
138 {
139 ms_Instance = this;
140
141 wxConfigBase *cfg = wxConfigBase::Get();
142
143 SetSize(wxRect(wxPoint(cfg->Read("editor_x", -1), cfg->Read("editor_y", -1)),
144 wxSize(cfg->Read("editor_w", 400), cfg->Read("editor_h", 400))));
145
146 m_SelectedNode = NULL;
147 m_Resource = NULL;
148 m_FileName = wxEmptyString;
149 m_Preview = NULL;
150 m_SelectedProp = -1;
151
152 wxMenu *menuFile = new wxMenu;
153 menuFile->Append(ID_NEW, "&New");
154 menuFile->Append(ID_OPEN, "&Open\tCtrl-O");
155 menuFile->Append(ID_SAVE, "&Save\tCtrl-S");
156 menuFile->Append(ID_SAVEAS, "Save &as...");
157 menuFile->AppendSeparator();
158 menuFile->Append(ID_EXIT, "E&xit\tAlt-X");
159
160 wxMenuBar *menuBar = new wxMenuBar();
161 menuBar->Append(menuFile, "&File");
162 SetMenuBar(menuBar);
163
164 // handlers:
165 m_Handlers.DeleteContents(TRUE);
166 RegisterHandlers(".");
167 RegisterHandlers("./df");
168 m_Handlers.Append(new NodeHandlerUnknown(this));
169
170 #ifdef __UNIX__
171 RegisterHandlers(wxGetHomeDir() + "/.wxrcedit");
172 //FIXME - add $(prefix)/share/wx/wxrcedit
173 #endif
174
175 // Create toolbar:
176 wxToolBar *toolBar = CreateToolBar(wxNO_BORDER | wxTB_HORIZONTAL | wxTB_FLAT);
177 toolBar->SetMargins(2, 2);
178 toolBar->SetToolBitmapSize(wxSize(24, 24));
179 toolBar -> AddTool(ID_EXIT, wxBITMAP(close), wxNullBitmap,
180 FALSE, -1, -1, (wxObject *) NULL,
181 _("Quit the editor"));
182 toolBar -> AddTool(ID_OPEN, wxBITMAP(open), wxNullBitmap,
183 FALSE, -1, -1, (wxObject *) NULL,
184 _("Open XML resource file"));
185 toolBar -> AddTool(ID_SAVE, wxBITMAP(save), wxNullBitmap,
186 FALSE, -1, -1, (wxObject *) NULL,
187 _("Save XML file"));
188 toolBar -> AddTool(ID_PREVIEW, wxBITMAP(preview), wxNullBitmap,
189 FALSE, -1, -1, (wxObject *) NULL,
190 _("Preview"));
191 toolBar -> Realize();
192
193 // Create layout:
194 wxSizer *sizer = new wxBoxSizer(wxVERTICAL);
195 wxPanel *p = new wxPanel(this);
196 sizer->Add(p, 1, wxEXPAND);
197 wxSizer *sizer2 = new wxBoxSizer(wxVERTICAL);
198
199 m_Splitter = new wxSplitterWindow(p);
200 sizer2->Add(m_Splitter, 1, wxEXPAND);
201
202
203 // Create tree control:
204 m_TreeCtrl = new EditorTreeCtrl(m_Splitter, ID_TREE, this);
205 m_ImgList = new wxImageList(16, 16);
206 m_ImgList->Add(wxICON(control));
207 m_ImgList->Add(wxICON(panel));
208 m_ImgList->Add(wxICON(vsizer));
209 m_ImgList->Add(wxICON(hsizer));
210 m_ImgList->Add(wxICON(gsizer));
211 m_ImgList->Add(wxICON(resicon));
212
213 m_TreeCtrl->SetImageList(m_ImgList);
214
215
216 // Create properties panel:
217 m_Splitter2 = new wxSplitterWindow(m_Splitter);
218 m_PropsPanel = new wxPanel(m_Splitter2, -1, wxDefaultPosition,
219 wxDefaultSize, wxTAB_TRAVERSAL);
220
221 wxSizer *sizer3 = new wxBoxSizer(wxVERTICAL);
222
223 wxSizer *sz = new wxBoxSizer(wxHORIZONTAL);
224
225 sizer3->Add(new wxButton(m_PropsPanel, ID_EDITCODE, "Edit XML code"),
226 0, wxALL | wxEXPAND, 2);
227 sz->Add(new wxStaticText(m_PropsPanel, -1, _("XMLID name:")),
228 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 2);
229 m_XMLIDCtrl = new wxTextCtrl(m_PropsPanel, ID_XMLIDEDIT, "");
230 sz->Add(m_XMLIDCtrl, 1, wxLEFT|wxRIGHT, 2);
231 sz->Add(new wxButton(m_PropsPanel, ID_XMLIDPICK, "...", wxDefaultPosition, wxSize(16,-1)),
232 0, wxRIGHT, 2);
233 sizer3->Add(sz, 0, wxTOP|wxEXPAND, 2);
234
235 m_PropsList = new wxListCtrl(m_PropsPanel, ID_PROPSLIST, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxLC_SINGLE_SEL);
236
237 m_ImgListProp = new wxImageList(16, 16);
238 m_ImgListProp->Add(wxICON(unused));
239 m_ImgListProp->Add(wxICON(used));
240 m_PropsList->SetImageList(m_ImgListProp, wxIMAGE_LIST_SMALL);
241
242 m_PropsList->InsertColumn(0, _("Property"));
243 m_PropsList->InsertColumn(1, _("Value"));
244 m_PropsList->SetColumnWidth(0, cfg->Read("editor_col0", wxLIST_AUTOSIZE_USEHEADER));
245 m_PropsList->SetColumnWidth(1, cfg->Read("editor_col1", wxLIST_AUTOSIZE_USEHEADER));
246
247 sizer3->Add(m_PropsList, 1, wxALL | wxEXPAND, 2);
248
249 m_PropsPanel->SetAutoLayout(TRUE);
250 m_PropsPanel->SetSizer(sizer3);
251 m_PropsPanel->Layout();
252
253 m_PropsEditPanel = new wxScrolledWindow(m_Splitter2, -1, wxDefaultPosition,
254 wxDefaultSize, wxTAB_TRAVERSAL);
255
256 m_Splitter->SplitVertically(m_TreeCtrl, m_Splitter2);
257 m_Splitter->SetSashPosition(cfg->Read("editor_sash", 140));
258
259 m_Splitter2->SplitHorizontally(m_PropsPanel, m_PropsEditPanel);
260 m_Splitter2->SetSashPosition(cfg->Read("editor_sash2", 100));
261
262 p->SetAutoLayout(TRUE);
263 p->SetSizer(sizer2);
264
265
266
267 SetAutoLayout(TRUE);
268 SetSizer(sizer);
269
270 // Load file:
271 if (!filename)
272 NewFile();
273 else
274 LoadFile(filename);
275 }
276
277
278
279 EditorFrame::~EditorFrame()
280 {
281 wxConfigBase *cfg = wxConfigBase::Get();
282
283 cfg->Write("editor_x", (long)GetPosition().x);
284 cfg->Write("editor_y", (long)GetPosition().y);
285 cfg->Write("editor_w", (long)GetSize().x);
286 cfg->Write("editor_h", (long)GetSize().y);
287 cfg->Write("editor_sash", (long)m_Splitter->GetSashPosition());
288 cfg->Write("editor_sash2", (long)m_Splitter2->GetSashPosition());
289 cfg->Write("editor_col0", (long)m_PropsList->GetColumnWidth(0));
290 cfg->Write("editor_col1", (long)m_PropsList->GetColumnWidth(1));
291
292 delete m_ImgList;
293 delete m_ImgListProp;
294 RefreshProps(NULL);
295 }
296
297
298
299 NodeHandler *EditorFrame::FindHandler(wxXmlNode *node)
300 {
301 wxNode *n = m_Handlers.GetFirst();
302 while (n)
303 {
304 NodeHandler *h = (NodeHandler*) n->GetData();
305 if (h->CanHandle(node))
306 return h;
307 n = n->GetNext();
308 }
309 return NULL;
310 }
311
312
313
314 void EditorFrame::RegisterHandlers(const wxString& dirname)
315 {
316 if (!wxDirExists(dirname)) return;
317
318 wxDir dir(dirname);
319 wxString filename;
320 bool cont;
321 NodeHandler *hnd;
322
323 cont = dir.GetFirst(&filename, "*.df");
324 while (cont)
325 {
326 hnd = NodeHandler::CreateFromFile(filename, this);
327 if (hnd) m_Handlers.Append(hnd);
328 cont = dir.GetNext(&filename);
329 }
330
331 }
332
333
334
335 void EditorFrame::LoadFile(const wxString& filename)
336 {
337 delete m_Resource;
338
339 m_FileName = "";
340 m_Resource = new wxXmlDocument;
341
342 if (!m_Resource->Load(filename))
343 {
344 delete m_Resource;
345 m_Resource = NULL;
346 NewFile();
347 wxLogError("Error parsing " + filename);
348 }
349 else
350 {
351 m_FileName = filename;
352 RefreshTree();
353 SetTitle(m_FileName);
354 }
355 }
356
357
358
359 void EditorFrame::SaveFile(const wxString& filename)
360 {
361 m_FileName = filename;
362 SetTitle(filename);
363
364 if (!m_Resource->Save(filename, wxXML_IO_LIBXML))
365 wxLogError("Error saving " + filename);
366 }
367
368
369
370 void EditorFrame::NewFile()
371 {
372 delete m_Resource;
373
374 m_FileName = "";
375 m_Resource = new wxXmlDocument;
376 m_Resource->SetRoot(new wxXmlNode(wxXML_ELEMENT_NODE, "resource"));
377
378 RefreshTree();
379 SetTitle("unnamed");
380 }
381
382
383
384 void EditorFrame::RefreshPreview(wxXmlNode *node)
385 {
386 wxBusyCursor bcur;
387 wxXmlResource *res = new wxXmlResource;
388 wxString tempfile;
389 wxPoint pos = wxDefaultPosition;
390
391 while (node->GetParent() != m_Resource->GetRoot())
392 node = node->GetParent();
393
394 if (m_Preview) pos = m_Preview->GetPosition();
395
396 res->InitAllHandlers();
397
398 wxGetTempFileName("xmleditor", tempfile);
399 m_Resource->Save(tempfile, wxXML_IO_BIN);
400 res->Load(tempfile, wxXML_BINARY);
401
402 if (node->GetName() == "dialog")
403 {
404 wxDialog *dlg = new wxDialog;
405 if (res->LoadDialog(dlg, this, node->GetPropVal("name", "-1")))
406 {
407 if (pos.x != -1) dlg->Move(pos);
408 dlg->Show(TRUE);
409 if (m_Preview) m_Preview->Close(TRUE);
410 m_Preview = dlg;
411 }
412 else
413 {
414 delete dlg;
415 wxLogError(_("Cannot preview the dialog -- XML resource corrupted."));
416 }
417 }
418 delete res;
419 wxRemoveFile(tempfile);
420 }
421
422
423
424 void EditorFrame::RefreshTree()
425 {
426 wxXmlNode *sel = m_SelectedNode;
427
428 m_TreeCtrl->DeleteAllItems();
429 wxTreeItemId root = m_TreeCtrl->AddRoot("Resource: " + m_FileName, 5, 5);
430
431 wxXmlNode *n = m_Resource->GetRoot()->GetChildren();
432 while (n)
433 {
434 if (n->GetType() == wxXML_ELEMENT_NODE)
435 CreateTreeNode(m_TreeCtrl, root, n);
436 n = n->GetNext();
437 }
438
439 m_TreeCtrl->Expand(root);
440 SelectNode(sel);
441 }
442
443
444 void EditorFrame::RefreshProps(wxXmlNode *node)
445 {
446 m_SelectedProp = -1;
447
448 for (int i = 0; i < m_PropsList->GetItemCount(); i++)
449 delete (wxObject*)(m_PropsList->GetItemData(i));
450
451 m_PropsList->DeleteAllItems();
452
453 if (node == NULL) return;
454
455 m_XMLIDCtrl->SetValue(FindHandler(node)->GetRealNode(node)->
456 GetPropVal("name", "-1"));
457 CreatePropsList(m_PropsList, node);
458
459 RefreshPropsEdit();
460 }
461
462
463
464 void EditorFrame::RefreshPropsEdit()
465 {
466 m_PropsEditPanel->DestroyChildren();
467 m_PropsEditPanel->SetSizer(NULL);
468
469 if (!m_SelectedNode || m_SelectedProp == -1 ||
470 m_PropsList->GetItemData(m_SelectedProp) == 0) return;
471
472 wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL);
473
474 sizer->Add(new wxButton(m_PropsEditPanel, ID_CLEARPROP, _("Clear")),
475 0, wxALL, 5);
476
477 sizer->Add(
478 FindHandler(m_SelectedNode)->CreatePropEditPanel(m_PropsEditPanel, m_PropsList, m_SelectedProp),
479 1, wxEXPAND, 0);
480
481 m_PropsEditPanel->SetAutoLayout(TRUE);
482 m_PropsEditPanel->SetSizer(sizer);
483 m_PropsEditPanel->Layout();
484
485 wxSize winsz = m_PropsEditPanel->GetSize();
486 sizer->SetMinSize(winsz.x, winsz.y);
487
488 wxSize minsz = sizer->GetMinSize();
489
490 m_PropsEditPanel->SetScrollbars(8, 8, 1/*minsz.x/8*/, minsz.y/8);
491 }
492
493
494
495 bool EditorFrame::SelectNode(wxXmlNode *node, wxTreeItemId *root)
496 {
497 if (root == NULL)
498 {
499 wxTreeItemId rootitem = m_TreeCtrl->GetRootItem();
500 return SelectNode(node, &rootitem);
501 }
502
503 wxTreeItemId item;
504 XmlTreeData *dt;
505 wxXmlNode *nd;
506 long cookie;
507
508 item = m_TreeCtrl->GetFirstChild(*root, cookie);
509 while (item.IsOk())
510 {
511 dt = (XmlTreeData*)(m_TreeCtrl->GetItemData(item));
512 nd = (dt) ? dt->Node : NULL;
513 if (nd == node)
514 {
515 m_TreeCtrl->SelectItem(item);
516 m_TreeCtrl->EnsureVisible(item);
517 return TRUE;
518 }
519 if (m_TreeCtrl->ItemHasChildren(item) && SelectNode(node, &item))
520 return TRUE;
521 item = m_TreeCtrl->GetNextChild(*root, cookie);
522 }
523 return FALSE;
524 }
525
526
527
528 wxTreeItemId EditorFrame::CreateTreeNode(wxTreeCtrl *treectrl, wxTreeItemId parent, wxXmlNode *node)
529 {
530 if (!node)
531 {
532 wxTreeItemId invalid;
533 return invalid;
534 }
535
536 return FindHandler(node)->CreateTreeNode(treectrl, parent, node);
537 }
538
539
540
541 void EditorFrame::CreatePropsList(wxListCtrl *treectrl, wxXmlNode *node)
542 {
543 if (!node) return;
544
545 FindHandler(node)->CreatePropsList(treectrl, node);
546 }
547
548
549
550 void EditorFrame::NotifyChanged(int change_type)
551 {
552 if (change_type & CHANGED_TREE)
553 RefreshTree();
554
555 if (change_type & CHANGED_TREE_SELECTED)
556 {
557 wxTreeItemId sel = m_TreeCtrl->GetSelection();
558 m_TreeCtrl->SetItemText(sel,
559 FindHandler(m_SelectedNode)->GetTreeString(m_SelectedNode));
560 }
561
562 if (change_type & CHANGED_TREE_SELECTED_ICON)
563 {
564 wxTreeItemId sel = m_TreeCtrl->GetSelection();
565 int icon = FindHandler(m_SelectedNode)->GetTreeIcon(m_SelectedNode);
566 m_TreeCtrl->SetItemImage(sel, icon);
567 }
568
569 if (change_type & CHANGED_PROPS_PANEL)
570 RefreshProps(m_SelectedNode);
571 }
572
573
574
575 void EditorFrame::OnTreeSel(wxTreeEvent& event)
576 {
577 XmlTreeData *dt = (XmlTreeData*)(m_TreeCtrl->GetItemData(event.GetItem()));
578 wxXmlNode *node = (dt) ? dt->Node : NULL;
579
580 m_SelectedNode = node;
581 RefreshProps(node);
582 }
583
584
585
586 void EditorFrame::OnXMLIDEdit(wxCommandEvent& event)
587 {
588 if (!m_SelectedNode) return;
589 wxXmlNode *node = FindHandler(m_SelectedNode)->GetRealNode(m_SelectedNode);
590
591 node->DeleteProperty("name");
592 wxString s = m_XMLIDCtrl->GetValue();
593 if (!(s == "-1")) node->AddProperty("name", s);
594 NotifyChanged(CHANGED_TREE_SELECTED);
595 }
596
597
598
599 void EditorFrame::OnXMLIDPick(wxCommandEvent& event)
600 {
601 if (!m_SelectedNode) return;
602 wxXmlNode *node = FindHandler(m_SelectedNode)->GetRealNode(m_SelectedNode);
603
604 wxString choices[] = {wxString("-1")
605 #define stdID(id) , wxString(#id)
606 stdID(wxID_OK) stdID(wxID_CANCEL)
607 stdID(wxID_YES) stdID(wxID_NO)
608 stdID(wxID_APPLY) stdID(wxID_HELP)
609 stdID(wxID_HELP_CONTEXT)
610
611 stdID(wxID_OPEN) stdID(wxID_CLOSE) stdID(wxID_NEW)
612 stdID(wxID_SAVE) stdID(wxID_SAVEAS) stdID(wxID_REVERT)
613 stdID(wxID_EXIT) stdID(wxID_UNDO) stdID(wxID_REDO)
614 stdID(wxID_PRINT) stdID(wxID_PRINT_SETUP)
615 stdID(wxID_PREVIEW) stdID(wxID_ABOUT) stdID(wxID_HELP_CONTENTS)
616 stdID(wxID_HELP_COMMANDS) stdID(wxID_HELP_PROCEDURES)
617 stdID(wxID_CUT) stdID(wxID_COPY) stdID(wxID_PASTE)
618 stdID(wxID_CLEAR) stdID(wxID_FIND) stdID(wxID_DUPLICATE)
619 stdID(wxID_SELECTALL)
620 stdID(wxID_STATIC) stdID(wxID_FORWARD) stdID(wxID_BACKWARD)
621 stdID(wxID_DEFAULT) stdID(wxID_MORE) stdID(wxID_SETUP)
622 stdID(wxID_RESET)
623 #undef stdID
624 };
625
626 wxString s =
627 wxGetSingleChoice(_("Choose from predefined IDs:"), _("XMLID"),
628 38/*sizeof choices*/, choices);
629 if (!s) return;
630
631 m_XMLIDCtrl->SetValue(s);
632 node->DeleteProperty("name");
633 if (!(s == "-1")) node->AddProperty("name", s);
634 NotifyChanged(CHANGED_TREE_SELECTED);
635 }
636
637
638
639 void EditorFrame::OnEditCode(wxCommandEvent& event)
640 {
641 if (!m_SelectedNode) return;
642
643 wxBusyCursor bcur;
644 wxDialog dlg(this, -1, _("XML code editor"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER);
645 wxSizer *sizer = new wxBoxSizer(wxVERTICAL);
646 wxTextCtrl *tc = new wxTextCtrl(&dlg, -1, "", wxDefaultPosition,
647 wxDefaultSize, wxTE_MULTILINE);
648 sizer->Add(tc, 1, wxEXPAND | wxALL, 10);
649
650 wxSizer *sz2 = new wxBoxSizer(wxHORIZONTAL);
651
652 sz2->Add(new wxButton(&dlg, wxID_OK, _("Save")), 0);
653 sz2->Add(new wxButton(&dlg, wxID_CANCEL, _("Cancel")), 0, wxLEFT, 10);
654
655 sizer->Add(sz2, 0, wxALIGN_RIGHT | wxRIGHT|wxBOTTOM, 10);
656
657 dlg.SetAutoLayout(TRUE);
658 dlg.SetSizer(sizer);
659
660 wxConfigBase *cfg = wxConfigBase::Get();
661
662 dlg.SetSize(wxRect(wxPoint(cfg->Read("xmleditor_x", -1), cfg->Read("xmleditor_y", -1)),
663 wxSize(cfg->Read("xmleditor_w", 400), cfg->Read("xmleditor_h", 400))));
664
665 wxString tempfile;
666 wxGetTempFileName("xmleditor", tempfile);
667
668 {
669 wxXmlDocument doc;
670 doc.SetRoot(new wxXmlNode(*m_SelectedNode));
671 doc.Save(tempfile, wxXML_IO_LIBXML);
672 }
673 tc->LoadFile(tempfile);
674
675 if (dlg.ShowModal() == wxID_OK)
676 {
677 tc->SaveFile(tempfile);
678 wxXmlDocument doc;
679 if (doc.Load(tempfile))
680 {
681 (*m_SelectedNode) = *doc.GetRoot();
682 NotifyChanged(CHANGED_TREE);
683 //FIXME-instead, regenerate only children
684 }
685 else wxLogError(_("Illegal XML file, canceled."));
686 }
687 wxRemoveFile(tempfile);
688
689 cfg->Write("xmleditor_x", (long)dlg.GetPosition().x);
690 cfg->Write("xmleditor_y", (long)dlg.GetPosition().y);
691 cfg->Write("xmleditor_w", (long)dlg.GetSize().x);
692 cfg->Write("xmleditor_h", (long)dlg.GetSize().y);
693 }
694
695
696
697 void EditorFrame::OnClearProp(wxCommandEvent& event)
698 {
699 m_PropsList->SetItemImage(m_SelectedProp, 0, 0);
700 m_PropsList->SetItem(m_SelectedProp, 1, "");
701
702 PropsListInfo *pli = (PropsListInfo*)m_PropsList->GetItemData(m_SelectedProp);
703
704 wxXmlNode *nd = XmlFindNode(pli->m_Node, pli->m_PropInfo->Name);
705
706 if (nd == NULL) return;
707 nd->GetParent()->RemoveChild(nd);
708 delete nd;
709 RefreshPropsEdit();
710 }
711
712
713
714 void EditorFrame::OnPropSel(wxListEvent& event)
715 {
716 m_SelectedProp = event.GetIndex();
717 RefreshPropsEdit();
718 }
719
720
721
722 void EditorFrame::OnToolbar(wxCommandEvent& event)
723 {
724 switch (event.GetId())
725 {
726 case ID_PREVIEW :
727 {
728 XmlTreeData* dt = (XmlTreeData*)m_TreeCtrl->GetItemData(m_TreeCtrl->GetSelection());;
729 if (dt != NULL && dt->Node != NULL)
730 RefreshPreview(dt->Node);
731 break;
732 }
733
734 case ID_EXIT :
735 Close(TRUE);
736 break;
737
738 case ID_NEW :
739 NewFile();
740 break;
741
742 case ID_OPEN :
743 {
744 wxString name = wxFileSelector("Open XML resource", "", "", "", "XML resources|*.xml", wxOPEN | wxFILE_MUST_EXIST);
745 if (!name.IsEmpty())
746 LoadFile(name);
747 break;
748 }
749
750 case ID_SAVE :
751 if (m_FileName != "") { SaveFile(m_FileName); break;}
752 // else go to SAVEAS
753
754 case ID_SAVEAS :
755 {
756 wxString name = wxFileSelector("Save as", "", m_FileName, "", "XML resources|*.xml", wxSAVE | wxOVERWRITE_PROMPT);
757 if (!name.IsEmpty())
758 SaveFile((m_FileName = name));
759 break;
760 }
761
762 case ID_DELETE_NODE :
763 {
764 XmlTreeData *dt = (XmlTreeData*)
765 (m_TreeCtrl->GetItemData(m_TreeCtrl->GetParent(m_TreeCtrl->GetSelection())));
766 wxXmlNode *n = (dt) ? dt->Node : NULL;
767
768 m_SelectedNode->GetParent()->RemoveChild(m_SelectedNode);
769 NotifyChanged(CHANGED_TREE);
770 SelectNode(n);
771 break;
772 }
773 }
774 }
775
776
777
778 void EditorFrame::OnNewNode(wxCommandEvent& event)
779 {
780 if (event.GetId() >= ID_NEWSYBNODE)
781 {
782 XmlTreeData *pardt =
783 (XmlTreeData*)(m_TreeCtrl->GetItemData(
784 m_TreeCtrl->GetParent(m_TreeCtrl->GetSelection())));
785
786 if (pardt && pardt->Node && pardt->Node != m_Resource->GetRoot())
787 {
788 wxXmlNode *nd = pardt->Node;
789
790 wxXmlNode *realnode = FindHandler(nd)->GetRealNode(nd);
791 NodeHandler *hnd = FindHandler(realnode);
792 wxString name = hnd->GetChildTypes()[event.GetId()-ID_NEWSYBNODE];
793
794 wxXmlNode *node = new wxXmlNode(wxXML_ELEMENT_NODE, name);
795 hnd->InsertNode(realnode, node, m_SelectedNode);
796 wxTreeItemId root = m_TreeCtrl->GetSelection();
797 SelectNode(node, &root);
798 }
799
800 }
801
802 else if (event.GetId() >= ID_NEWNODE)
803 {
804 wxXmlNode *realnode = FindHandler(m_SelectedNode)->GetRealNode(m_SelectedNode);
805 NodeHandler *hnd = FindHandler(realnode);
806 wxString name = hnd->GetChildTypes()[event.GetId()-ID_NEWNODE];
807
808 wxXmlNode *node = new wxXmlNode(wxXML_ELEMENT_NODE, name);
809 hnd->InsertNode(realnode, node);
810 wxTreeItemId root = m_TreeCtrl->GetSelection();
811 SelectNode(node, &root);
812 }
813
814 else
815 {
816 wxString name;
817 switch (event.GetId())
818 {
819 case ID_NEWDIALOG : name = "dialog"; break;
820 case ID_NEWPANEL : name = "panel"; break;
821 case ID_NEWMENU : name = "menu"; break;
822 case ID_NEWMENUBAR : name = "menubar"; break;
823 case ID_NEWTOOLBAR : name = "toolbar"; break;
824 default : return; // never occurs
825 }
826
827 wxXmlNode *node = new wxXmlNode(wxXML_ELEMENT_NODE, name);
828 m_Resource->GetRoot()->AddChild(node);
829 NotifyChanged(CHANGED_TREE);
830 SelectNode(node);
831 }
832 }
833
834
835
836 void EditorFrame::OnRightClickTree(wxPoint pos)
837 {
838 wxMenu *popup = new wxMenu;
839
840 if (m_SelectedNode == NULL || m_SelectedNode == m_Resource->GetRoot())
841 {
842 popup->Append(ID_NEWDIALOG, _("New dialog"));
843 popup->Append(ID_NEWPANEL, _("New panel"));
844 popup->Append(ID_NEWMENU, _("New menu"));
845 popup->Append(ID_NEWMENUBAR, _("New menubar"));
846 popup->Append(ID_NEWTOOLBAR, _("New toolbar"));
847 }
848
849 else
850 {
851 {
852 wxArrayString& arr =
853 FindHandler(FindHandler(m_SelectedNode)->GetRealNode(m_SelectedNode))->
854 GetChildTypes();
855
856 if (!arr.IsEmpty())
857 {
858 wxMenu *news = new wxMenu;
859 for (size_t i = 0; i < arr.GetCount(); i++)
860 {
861 news->Append(i + ID_NEWNODE, arr[i]);
862 if (i % 16 == 15) news->Break();
863 }
864 popup->Append(ID_NEWNODE-1, _("New child"), news);
865 }
866 }
867
868
869 XmlTreeData *pardt =
870 (XmlTreeData*)(m_TreeCtrl->GetItemData(
871 m_TreeCtrl->GetParent(m_TreeCtrl->GetSelection())));
872 if (pardt && pardt->Node && pardt->Node != m_Resource->GetRoot())
873 {
874 wxXmlNode *nd = pardt->Node;
875 wxArrayString& arr =
876 FindHandler(FindHandler(nd)->GetRealNode(nd))->
877 GetChildTypes();
878
879 if (!arr.IsEmpty())
880 {
881 wxMenu *news = new wxMenu;
882 for (size_t i = 0; i < arr.GetCount(); i++)
883 {
884 news->Append(i + ID_NEWSYBNODE, arr[i]);
885 if (i % 16 == 15) news->Break();
886 }
887 popup->Append(ID_NEWSYBNODE-1, _("New sybling"), news);
888 }
889 }
890
891
892 popup->AppendSeparator();
893 popup->Append(ID_DELETE_NODE, _("Delete"));
894 }
895
896 m_TreeCtrl->PopupMenu(popup, pos);
897 delete popup;
898 }