1 /////////////////////////////////////////////////////////////////////////////
2 // Author: Vaclav Slavik
5 // Copyright: (c) 2000 Vaclav Slavik
6 // Licence: wxWindows licence
7 /////////////////////////////////////////////////////////////////////////////
10 #pragma implementation "editor.h"
11 #pragma implementation "treedt.h"
14 // For compilers that support precompilation, includes "wx/wx.h".
15 #include "wx/wxprec.h"
22 #include "wx/xml/xml.h"
23 #include "wx/xml/xmlres.h"
24 #include "wx/splitter.h"
25 #include "wx/config.h"
27 #include "wx/listctrl.h"
28 #include "wx/imaglist.h"
37 class EditorTreeCtrl
: public wxTreeCtrl
40 EditorTreeCtrl(wxWindow
*parent
, int id
, EditorFrame
*frame
)
41 : wxTreeCtrl(parent
, id
), m_EdFrame(frame
) {}
44 EditorFrame
*m_EdFrame
;
46 void OnRightClick(wxMouseEvent
&event
)
49 m_EdFrame
->m_TreeCtrl
->HitTest(event
.GetPosition());
52 m_EdFrame
->m_TreeCtrl
->SelectItem(item
);
53 m_EdFrame
->OnRightClickTree(event
.GetPosition());
59 BEGIN_EVENT_TABLE(EditorTreeCtrl
, wxTreeCtrl
)
60 EVT_RIGHT_DOWN(EditorTreeCtrl::OnRightClick
)
66 ID_PREVIEW
= wxID_HIGHEST
+ 100,
91 ID_NEWNODE
= wxID_HIGHEST
+ 1000,
92 ID_NEWSYBNODE
= ID_NEWNODE
+ 2000
99 BEGIN_EVENT_TABLE(EditorFrame
, wxFrame
)
100 EVT_TREE_SEL_CHANGED(ID_TREE
, EditorFrame::OnTreeSel
)
101 EVT_TOOL_RANGE(ID_PREVIEW
, ID_EXIT
, EditorFrame::OnToolbar
)
102 EVT_MENU_RANGE(ID_NEWDIALOG
, ID_NEWSYBNODE
+ 1000, EditorFrame::OnNewNode
)
103 EVT_MENU_RANGE(ID_CUT
, ID_COPY
, EditorFrame::OnClipboardAction
)
104 EVT_TEXT(ID_XMLIDEDIT
, EditorFrame::OnXMLIDEdit
)
105 EVT_BUTTON(ID_XMLIDPICK
, EditorFrame::OnXMLIDPick
)
106 EVT_BUTTON(ID_EDITCODE
, EditorFrame::OnEditCode
)
107 EVT_BUTTON(ID_CLEARPROP
, EditorFrame::OnClearProp
)
108 EVT_LIST_ITEM_SELECTED(ID_PROPSLIST
, EditorFrame::OnPropSel
)
113 #if defined(__UNIX__)
114 #include "bitmaps/preview.xpm"
115 #include "bitmaps/close.xpm"
116 #include "bitmaps/save.xpm"
117 #include "bitmaps/open.xpm"
119 #include "bitmaps/control.xpm"
120 #include "bitmaps/vsizer.xpm"
121 #include "bitmaps/hsizer.xpm"
122 #include "bitmaps/panel.xpm"
123 #include "bitmaps/gsizer.xpm"
124 #include "bitmaps/resicon.xpm"
126 #include "bitmaps/unused.xpm"
127 #include "bitmaps/used.xpm"
132 EditorFrame
*EditorFrame::ms_Instance
= NULL
;
134 EditorFrame::EditorFrame(wxFrame
*parent
, const wxString
& filename
)
135 : wxFrame(parent
, -1, filename
+ _("- wxWindows resources editor"))
141 wxConfigBase
*cfg
= wxConfigBase::Get();
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))));
146 m_SelectedNode
= NULL
;
148 m_FileName
= wxEmptyString
;
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");
160 wxMenu
*menuEdit
= new wxMenu
;
161 menuEdit
->Append(ID_CUT
, "Cut\tCtrl-X");
162 menuEdit
->Append(ID_COPY
, "Copy\tCtrl-C");
163 menuEdit
->Append(ID_PASTE_SYBLING
, "Paste as sybling\tCtrl-V");
164 menuEdit
->Append(ID_PASTE_CHILD
, "Paste as child");
165 menuEdit
->AppendSeparator();
166 menuEdit
->Append(ID_DELETE_NODE
, "Delete");
168 menuEdit
->Enable(ID_PASTE_SYBLING
, FALSE
);
169 menuEdit
->Enable(ID_PASTE_CHILD
, FALSE
);
171 wxMenuBar
*menuBar
= new wxMenuBar();
172 menuBar
->Append(menuFile
, "&File");
173 menuBar
->Append(menuEdit
, "&Edit");
177 m_Handlers
.DeleteContents(TRUE
);
178 RegisterHandlers(".");
179 RegisterHandlers("./df");
180 // if modifying, don't forget to modify other places --
181 // search for wxINSTALL_PREFIX in nodehnd.cpp
183 RegisterHandlers(wxGetHomeDir() + "/.wxrcedit");
184 #ifdef wxINSTALL_PREFIX
185 RegisterHandlers(wxINSTALL_PREFIX
"/share/wx/wxrcedit");
189 m_Handlers
.Append(new NodeHandlerUnknown(this));
193 wxToolBar
*toolBar
= CreateToolBar(wxNO_BORDER
| wxTB_HORIZONTAL
| wxTB_FLAT
);
194 toolBar
->SetMargins(2, 2);
195 toolBar
->SetToolBitmapSize(wxSize(24, 24));
196 toolBar
-> AddTool(ID_EXIT
, wxBITMAP(close
), wxNullBitmap
,
197 FALSE
, -1, -1, (wxObject
*) NULL
,
198 _("Quit the editor"));
199 toolBar
-> AddTool(ID_OPEN
, wxBITMAP(open
), wxNullBitmap
,
200 FALSE
, -1, -1, (wxObject
*) NULL
,
201 _("Open XML resource file"));
202 toolBar
-> AddTool(ID_SAVE
, wxBITMAP(save
), wxNullBitmap
,
203 FALSE
, -1, -1, (wxObject
*) NULL
,
205 toolBar
-> AddTool(ID_PREVIEW
, wxBITMAP(preview
), wxNullBitmap
,
206 FALSE
, -1, -1, (wxObject
*) NULL
,
208 toolBar
-> Realize();
211 wxSizer
*sizer
= new wxBoxSizer(wxVERTICAL
);
212 wxPanel
*p
= new wxPanel(this);
213 sizer
->Add(p
, 1, wxEXPAND
);
214 wxSizer
*sizer2
= new wxBoxSizer(wxVERTICAL
);
216 m_Splitter
= new wxSplitterWindow(p
);
217 sizer2
->Add(m_Splitter
, 1, wxEXPAND
);
220 // Create tree control:
221 m_TreeCtrl
= new EditorTreeCtrl(m_Splitter
, ID_TREE
, this);
222 m_ImgList
= new wxImageList(16, 16);
223 m_ImgList
->Add(wxICON(control
));
224 m_ImgList
->Add(wxICON(panel
));
225 m_ImgList
->Add(wxICON(vsizer
));
226 m_ImgList
->Add(wxICON(hsizer
));
227 m_ImgList
->Add(wxICON(gsizer
));
228 m_ImgList
->Add(wxICON(resicon
));
230 m_TreeCtrl
->SetImageList(m_ImgList
);
233 // Create properties panel:
234 m_Splitter2
= new wxSplitterWindow(m_Splitter
);
235 m_PropsPanel
= new wxPanel(m_Splitter2
, -1, wxDefaultPosition
,
236 wxDefaultSize
, wxTAB_TRAVERSAL
);
238 wxSizer
*sizer3
= new wxBoxSizer(wxVERTICAL
);
240 wxSizer
*sz
= new wxBoxSizer(wxHORIZONTAL
);
242 sizer3
->Add(new wxButton(m_PropsPanel
, ID_EDITCODE
, "Edit XML code"),
243 0, wxALL
| wxEXPAND
, 2);
244 sz
->Add(new wxStaticText(m_PropsPanel
, -1, _("XMLID name:")),
245 0, wxLEFT
| wxALIGN_CENTER_VERTICAL
, 2);
246 m_XMLIDCtrl
= new wxTextCtrl(m_PropsPanel
, ID_XMLIDEDIT
, "");
247 sz
->Add(m_XMLIDCtrl
, 1, wxLEFT
|wxRIGHT
, 2);
248 sz
->Add(new wxButton(m_PropsPanel
, ID_XMLIDPICK
, "...", wxDefaultPosition
, wxSize(16,-1)),
250 sizer3
->Add(sz
, 0, wxTOP
|wxEXPAND
, 2);
252 m_PropsList
= new wxListCtrl(m_PropsPanel
, ID_PROPSLIST
, wxDefaultPosition
, wxDefaultSize
, wxLC_REPORT
| wxLC_SINGLE_SEL
);
254 m_ImgListProp
= new wxImageList(16, 16);
255 m_ImgListProp
->Add(wxICON(unused
));
256 m_ImgListProp
->Add(wxICON(used
));
257 m_PropsList
->SetImageList(m_ImgListProp
, wxIMAGE_LIST_SMALL
);
259 m_PropsList
->InsertColumn(0, _("Property"));
260 m_PropsList
->InsertColumn(1, _("Value"));
261 m_PropsList
->SetColumnWidth(0, cfg
->Read("editor_col0", wxLIST_AUTOSIZE_USEHEADER
));
262 m_PropsList
->SetColumnWidth(1, cfg
->Read("editor_col1", wxLIST_AUTOSIZE_USEHEADER
));
264 sizer3
->Add(m_PropsList
, 1, wxALL
| wxEXPAND
, 2);
266 m_PropsPanel
->SetAutoLayout(TRUE
);
267 m_PropsPanel
->SetSizer(sizer3
);
268 m_PropsPanel
->Layout();
270 m_PropsEditPanel
= new wxScrolledWindow(m_Splitter2
, -1, wxDefaultPosition
,
271 wxDefaultSize
, wxTAB_TRAVERSAL
);
273 m_Splitter
->SplitVertically(m_TreeCtrl
, m_Splitter2
);
274 m_Splitter
->SetSashPosition(cfg
->Read("editor_sash", 140));
276 m_Splitter2
->SplitHorizontally(m_PropsPanel
, m_PropsEditPanel
);
277 m_Splitter2
->SetSashPosition(cfg
->Read("editor_sash2", 100));
279 p
->SetAutoLayout(TRUE
);
296 EditorFrame::~EditorFrame()
298 wxConfigBase
*cfg
= wxConfigBase::Get();
300 cfg
->Write("editor_x", (long)GetPosition().x
);
301 cfg
->Write("editor_y", (long)GetPosition().y
);
302 cfg
->Write("editor_w", (long)GetSize().x
);
303 cfg
->Write("editor_h", (long)GetSize().y
);
304 cfg
->Write("editor_sash", (long)m_Splitter
->GetSashPosition());
305 cfg
->Write("editor_sash2", (long)m_Splitter2
->GetSashPosition());
306 cfg
->Write("editor_col0", (long)m_PropsList
->GetColumnWidth(0));
307 cfg
->Write("editor_col1", (long)m_PropsList
->GetColumnWidth(1));
310 delete m_ImgListProp
;
318 NodeHandler
*EditorFrame::FindHandler(wxXmlNode
*node
)
320 wxNode
*n
= m_Handlers
.GetFirst();
323 NodeHandler
*h
= (NodeHandler
*) n
->GetData();
324 if (h
->CanHandle(node
))
333 void EditorFrame::RegisterHandlers(const wxString
& dirname
)
335 if (!wxDirExists(dirname
)) return;
342 cont
= dir
.GetFirst(&filename
, "*.df");
345 hnd
= NodeHandler::CreateFromFile(filename
, this);
346 if (hnd
) m_Handlers
.Append(hnd
);
347 cont
= dir
.GetNext(&filename
);
354 void EditorFrame::LoadFile(const wxString
& filename
)
359 m_Resource
= new wxXmlDocument
;
361 if (!m_Resource
->Load(filename
))
366 wxLogError("Error parsing " + filename
);
370 m_FileName
= filename
;
372 SetTitle("wxrcedit - " + wxFileNameFromPath(m_FileName
));
378 void EditorFrame::SaveFile(const wxString
& filename
)
380 m_FileName
= filename
;
381 SetTitle("wxrcedit - " + wxFileNameFromPath(m_FileName
));
383 if (!m_Resource
->Save(filename
, wxXML_IO_LIBXML
))
384 wxLogError("Error saving " + filename
);
389 void EditorFrame::NewFile()
394 m_Resource
= new wxXmlDocument
;
395 m_Resource
->SetRoot(new wxXmlNode(wxXML_ELEMENT_NODE
, "resource"));
403 void EditorFrame::RefreshPreview(wxXmlNode
*node
)
405 wxConfigBase
*cfg
= wxConfigBase::Get();
408 wxXmlResource
*res
= new wxXmlResource
;
410 wxPoint pos
= wxPoint(cfg
->Read("preview_x", -1), cfg
->Read("preview_y", -1));
411 wxSize size
= wxSize(cfg
->Read("preview_w", 50), cfg
->Read("preview_h", 300));
413 while (node
->GetParent() != m_Resource
->GetRoot())
414 node
= node
->GetParent();
416 m_Preview
= wxFindWindowByName("preview_window");
419 pos
= m_Preview
->GetPosition();
420 size
= m_Preview
->GetSize();
422 cfg
->Write("preview_x", (long)pos
.x
);
423 cfg
->Write("preview_y", (long)pos
.y
);
424 cfg
->Write("preview_w", (long)size
.x
);
425 cfg
->Write("preview_h", (long)size
.y
);
428 res
->InitAllHandlers();
430 wxGetTempFileName("xmleditor", tempfile
);
431 m_Resource
->Save(tempfile
, wxXML_IO_BIN
);
434 if (node
->GetName() == "dialog")
436 wxDialog
*dlg
= new wxDialog
;
437 if (res
->LoadDialog(dlg
, NULL
, node
->GetPropVal("name", "-1")))
439 if (pos
.x
!= -1) dlg
->Move(pos
);
441 if (m_Preview
) m_Preview
->Close(TRUE
);
443 m_Preview
->SetName("preview_window");
444 m_Preview
->SetFocus();
449 wxLogError(_("Cannot preview the dialog -- XML resource corrupted."));
453 else if (node
->GetName() == "menubar" || node
->GetName() == "menu")
457 if (node
->GetName() == "menubar")
458 mbar
= res
->LoadMenuBar(node
->GetPropVal("name", "-1"));
461 mbar
= new wxMenuBar
;
462 wxMenu
*m
= res
->LoadMenu(node
->GetPropVal("name", "-1"));
463 if (m
!= NULL
) mbar
->Append(m
, node
->GetPropVal("name", "-1"));
464 else { delete mbar
; mbar
= NULL
; }
467 wxLogError(_("Cannot preview the menu -- XML resource corrupted."));
470 wxFrame
*frame
= new wxFrame(NULL
, -1, _("Menu preview"), pos
, size
);
471 frame
->SetMenuBar(mbar
);
472 frame
->CreateStatusBar();
473 if (m_Preview
) m_Preview
->Close(TRUE
);
475 m_Preview
->SetName("preview_window");
476 m_Preview
->Show(TRUE
);
477 m_Preview
->SetFocus();
481 else if (node
->GetName() == "toolbar")
483 wxFrame
*frame
= new wxFrame(NULL
, -1, _("Menu preview"), pos
, size
);
484 frame
->SetToolBar(res
->LoadToolBar(frame
, node
->GetPropVal("name", "-1")));
485 frame
->CreateStatusBar();
486 if (m_Preview
) m_Preview
->Close(TRUE
);
488 m_Preview
->SetName("preview_window");
489 m_Preview
->Show(TRUE
);
490 m_Preview
->SetFocus();
494 wxRemoveFile(tempfile
);
499 void EditorFrame::RefreshTree()
501 wxXmlNode
*sel
= m_SelectedNode
;
503 m_TreeCtrl
->DeleteAllItems();
504 wxTreeItemId root
= m_TreeCtrl
->AddRoot("Resource: " + wxFileNameFromPath(m_FileName
), 5, 5);
506 wxXmlNode
*n
= m_Resource
->GetRoot()->GetChildren();
509 if (n
->GetType() == wxXML_ELEMENT_NODE
)
510 CreateTreeNode(m_TreeCtrl
, root
, n
);
514 m_TreeCtrl
->Expand(root
);
519 void EditorFrame::RefreshProps(wxXmlNode
*node
)
523 for (int i
= 0; i
< m_PropsList
->GetItemCount(); i
++)
524 delete (wxObject
*)(m_PropsList
->GetItemData(i
));
526 m_PropsList
->DeleteAllItems();
528 if (node
== NULL
) return;
530 m_XMLIDCtrl
->SetValue(FindHandler(node
)->GetRealNode(node
)->
531 GetPropVal("name", "-1"));
532 CreatePropsList(m_PropsList
, node
);
539 void EditorFrame::RefreshPropsEdit()
541 m_PropsEditPanel
->DestroyChildren();
542 m_PropsEditPanel
->SetSizer(NULL
);
544 if (!m_SelectedNode
|| m_SelectedProp
== -1 ||
545 m_PropsList
->GetItemData(m_SelectedProp
) == 0) return;
547 wxBoxSizer
*sizer
= new wxBoxSizer(wxVERTICAL
);
549 sizer
->Add(new wxButton(m_PropsEditPanel
, ID_CLEARPROP
, _("Clear")),
553 FindHandler(m_SelectedNode
)->CreatePropEditPanel(m_PropsEditPanel
, m_PropsList
, m_SelectedProp
),
556 m_PropsEditPanel
->SetAutoLayout(TRUE
);
557 m_PropsEditPanel
->SetSizer(sizer
);
558 m_PropsEditPanel
->Layout();
560 wxSize winsz
= m_PropsEditPanel
->GetSize();
561 sizer
->SetMinSize(winsz
.x
, winsz
.y
);
563 wxSize minsz
= sizer
->GetMinSize();
565 m_PropsEditPanel
->SetScrollbars(8, 8, 1/*minsz.x/8*/, minsz
.y
/8);
570 bool EditorFrame::SelectNode(wxXmlNode
*node
, wxTreeItemId
*root
)
574 wxTreeItemId rootitem
= m_TreeCtrl
->GetRootItem();
575 return SelectNode(node
, &rootitem
);
583 item
= m_TreeCtrl
->GetFirstChild(*root
, cookie
);
586 dt
= (XmlTreeData
*)(m_TreeCtrl
->GetItemData(item
));
587 nd
= (dt
) ? dt
->Node
: NULL
;
590 m_TreeCtrl
->SelectItem(item
);
591 m_TreeCtrl
->EnsureVisible(item
);
594 if (m_TreeCtrl
->ItemHasChildren(item
) && SelectNode(node
, &item
))
596 item
= m_TreeCtrl
->GetNextChild(*root
, cookie
);
603 wxTreeItemId
EditorFrame::CreateTreeNode(wxTreeCtrl
*treectrl
, wxTreeItemId parent
, wxXmlNode
*node
)
607 wxTreeItemId invalid
;
611 return FindHandler(node
)->CreateTreeNode(treectrl
, parent
, node
);
616 void EditorFrame::CreatePropsList(wxListCtrl
*treectrl
, wxXmlNode
*node
)
620 FindHandler(node
)->CreatePropsList(treectrl
, node
);
625 void EditorFrame::NotifyChanged(int change_type
)
627 if (change_type
& CHANGED_TREE
)
630 if (change_type
& CHANGED_TREE_SELECTED
)
632 wxTreeItemId sel
= m_TreeCtrl
->GetSelection();
633 m_TreeCtrl
->SetItemText(sel
,
634 FindHandler(m_SelectedNode
)->GetTreeString(m_SelectedNode
));
637 if (change_type
& CHANGED_TREE_SELECTED_ICON
)
639 wxTreeItemId sel
= m_TreeCtrl
->GetSelection();
640 int icon
= FindHandler(m_SelectedNode
)->GetTreeIcon(m_SelectedNode
);
641 m_TreeCtrl
->SetItemImage(sel
, icon
);
644 if (change_type
& CHANGED_PROPS_PANEL
)
645 RefreshProps(m_SelectedNode
);
650 void EditorFrame::OnTreeSel(wxTreeEvent
& event
)
652 XmlTreeData
*dt
= (XmlTreeData
*)(m_TreeCtrl
->GetItemData(event
.GetItem()));
653 wxXmlNode
*node
= (dt
) ? dt
->Node
: NULL
;
655 m_SelectedNode
= node
;
661 void EditorFrame::OnXMLIDEdit(wxCommandEvent
& event
)
663 if (!m_SelectedNode
) return;
664 wxXmlNode
*node
= FindHandler(m_SelectedNode
)->GetRealNode(m_SelectedNode
);
666 node
->DeleteProperty("name");
667 wxString s
= m_XMLIDCtrl
->GetValue();
668 if (!(s
== "-1")) node
->AddProperty("name", s
);
669 NotifyChanged(CHANGED_TREE_SELECTED
);
674 void EditorFrame::OnXMLIDPick(wxCommandEvent
& event
)
676 if (!m_SelectedNode
) return;
677 wxXmlNode
*node
= FindHandler(m_SelectedNode
)->GetRealNode(m_SelectedNode
);
679 wxString choices
[] = {wxString("-1")
680 #define stdID(id) , wxString(#id)
681 stdID(wxID_OK
) stdID(wxID_CANCEL
)
682 stdID(wxID_YES
) stdID(wxID_NO
)
683 stdID(wxID_APPLY
) stdID(wxID_HELP
)
684 stdID(wxID_HELP_CONTEXT
)
686 stdID(wxID_OPEN
) stdID(wxID_CLOSE
) stdID(wxID_NEW
)
687 stdID(wxID_SAVE
) stdID(wxID_SAVEAS
) stdID(wxID_REVERT
)
688 stdID(wxID_EXIT
) stdID(wxID_UNDO
) stdID(wxID_REDO
)
689 stdID(wxID_PRINT
) stdID(wxID_PRINT_SETUP
)
690 stdID(wxID_PREVIEW
) stdID(wxID_ABOUT
) stdID(wxID_HELP_CONTENTS
)
691 stdID(wxID_HELP_COMMANDS
) stdID(wxID_HELP_PROCEDURES
)
692 stdID(wxID_CUT
) stdID(wxID_COPY
) stdID(wxID_PASTE
)
693 stdID(wxID_CLEAR
) stdID(wxID_FIND
) stdID(wxID_DUPLICATE
)
694 stdID(wxID_SELECTALL
)
695 stdID(wxID_STATIC
) stdID(wxID_FORWARD
) stdID(wxID_BACKWARD
)
696 stdID(wxID_DEFAULT
) stdID(wxID_MORE
) stdID(wxID_SETUP
)
702 wxGetSingleChoice(_("Choose from predefined IDs:"), _("XMLID"),
703 38/*sizeof choices*/, choices
);
706 m_XMLIDCtrl
->SetValue(s
);
707 node
->DeleteProperty("name");
708 if (!(s
== "-1")) node
->AddProperty("name", s
);
709 NotifyChanged(CHANGED_TREE_SELECTED
);
714 void EditorFrame::OnEditCode(wxCommandEvent
& event
)
716 if (!m_SelectedNode
) return;
719 wxDialog
dlg(this, -1, _("XML code editor"), wxDefaultPosition
, wxDefaultSize
, wxDEFAULT_DIALOG_STYLE
| wxRESIZE_BORDER
);
720 wxSizer
*sizer
= new wxBoxSizer(wxVERTICAL
);
721 wxTextCtrl
*tc
= new wxTextCtrl(&dlg
, -1, "", wxDefaultPosition
,
722 wxDefaultSize
, wxTE_MULTILINE
);
723 sizer
->Add(tc
, 1, wxEXPAND
| wxALL
, 10);
725 wxSizer
*sz2
= new wxBoxSizer(wxHORIZONTAL
);
727 sz2
->Add(new wxButton(&dlg
, wxID_OK
, _("Save")), 0);
728 sz2
->Add(new wxButton(&dlg
, wxID_CANCEL
, _("Cancel")), 0, wxLEFT
, 10);
730 sizer
->Add(sz2
, 0, wxALIGN_RIGHT
| wxRIGHT
|wxBOTTOM
, 10);
732 dlg
.SetAutoLayout(TRUE
);
735 wxConfigBase
*cfg
= wxConfigBase::Get();
737 dlg
.SetSize(wxRect(wxPoint(cfg
->Read("xmleditor_x", -1), cfg
->Read("xmleditor_y", -1)),
738 wxSize(cfg
->Read("xmleditor_w", 400), cfg
->Read("xmleditor_h", 400))));
741 wxGetTempFileName("xmleditor", tempfile
);
745 doc
.SetRoot(new wxXmlNode(*m_SelectedNode
));
746 doc
.Save(tempfile
, wxXML_IO_LIBXML
);
748 tc
->LoadFile(tempfile
);
750 if (dlg
.ShowModal() == wxID_OK
)
752 tc
->SaveFile(tempfile
);
754 if (doc
.Load(tempfile
))
756 (*m_SelectedNode
) = *doc
.GetRoot();
757 NotifyChanged(CHANGED_TREE
);
758 //FIXME-instead, regenerate only children
760 else wxLogError(_("Illegal XML file, canceled."));
762 wxRemoveFile(tempfile
);
764 cfg
->Write("xmleditor_x", (long)dlg
.GetPosition().x
);
765 cfg
->Write("xmleditor_y", (long)dlg
.GetPosition().y
);
766 cfg
->Write("xmleditor_w", (long)dlg
.GetSize().x
);
767 cfg
->Write("xmleditor_h", (long)dlg
.GetSize().y
);
772 void EditorFrame::OnClearProp(wxCommandEvent
& event
)
774 m_PropsList
->SetItemImage(m_SelectedProp
, 0, 0);
775 m_PropsList
->SetItem(m_SelectedProp
, 1, "");
777 PropsListInfo
*pli
= (PropsListInfo
*)m_PropsList
->GetItemData(m_SelectedProp
);
779 wxXmlNode
*nd
= XmlFindNode(pli
->m_Node
, pli
->m_PropInfo
->Name
);
781 if (nd
== NULL
) return;
782 nd
->GetParent()->RemoveChild(nd
);
789 void EditorFrame::OnPropSel(wxListEvent
& event
)
791 m_SelectedProp
= event
.GetIndex();
797 void EditorFrame::OnToolbar(wxCommandEvent
& event
)
799 switch (event
.GetId())
803 XmlTreeData
* dt
= (XmlTreeData
*)m_TreeCtrl
->GetItemData(m_TreeCtrl
->GetSelection());;
804 if (dt
!= NULL
&& dt
->Node
!= NULL
)
805 RefreshPreview(dt
->Node
);
819 wxString name
= wxFileSelector("Open XML resource", "", "", "", "XML resources|*.xml", wxOPEN
| wxFILE_MUST_EXIST
);
826 if (m_FileName
!= "") { SaveFile(m_FileName
); break;}
831 wxString name
= wxFileSelector("Save as", "", m_FileName
, "", "XML resources|*.xml", wxSAVE
| wxOVERWRITE_PROMPT
);
833 SaveFile((m_FileName
= name
));
837 case ID_DELETE_NODE
:
839 DeleteSelectedNode();
847 void EditorFrame::DeleteSelectedNode()
849 XmlTreeData
*dt
= (XmlTreeData
*)
850 (m_TreeCtrl
->GetItemData(m_TreeCtrl
->GetParent(m_TreeCtrl
->GetSelection())));
851 wxXmlNode
*n
= (dt
) ? dt
->Node
: NULL
;
853 m_SelectedNode
->GetParent()->RemoveChild(m_SelectedNode
);
854 NotifyChanged(CHANGED_TREE
);
860 void EditorFrame::OnNewNode(wxCommandEvent
& event
)
862 if (event
.GetId() >= ID_NEWSYBNODE
)
865 (XmlTreeData
*)(m_TreeCtrl
->GetItemData(
866 m_TreeCtrl
->GetParent(m_TreeCtrl
->GetSelection())));
868 if (pardt
&& pardt
->Node
&& pardt
->Node
!= m_Resource
->GetRoot())
870 wxXmlNode
*nd
= pardt
->Node
;
872 wxXmlNode
*realnode
= FindHandler(nd
)->GetRealNode(nd
);
873 NodeHandler
*hnd
= FindHandler(realnode
);
874 wxString name
= hnd
->GetChildTypes()[event
.GetId()-ID_NEWSYBNODE
];
876 wxXmlNode
*node
= new wxXmlNode(wxXML_ELEMENT_NODE
, name
);
877 hnd
->InsertNode(realnode
, node
, m_SelectedNode
);
878 wxTreeItemId root
= m_TreeCtrl
->GetSelection();
879 SelectNode(node
, &root
);
884 else if (event
.GetId() >= ID_NEWNODE
)
886 wxXmlNode
*realnode
= FindHandler(m_SelectedNode
)->GetRealNode(m_SelectedNode
);
887 NodeHandler
*hnd
= FindHandler(realnode
);
888 wxString name
= hnd
->GetChildTypes()[event
.GetId()-ID_NEWNODE
];
890 wxXmlNode
*node
= new wxXmlNode(wxXML_ELEMENT_NODE
, name
);
891 hnd
->InsertNode(realnode
, node
);
892 wxTreeItemId root
= m_TreeCtrl
->GetSelection();
893 SelectNode(node
, &root
);
899 switch (event
.GetId())
901 case ID_NEWDIALOG
: name
= "dialog"; break;
902 case ID_NEWPANEL
: name
= "panel"; break;
903 case ID_NEWMENU
: name
= "menu"; break;
904 case ID_NEWMENUBAR
: name
= "menubar"; break;
905 case ID_NEWTOOLBAR
: name
= "toolbar"; break;
906 default : return; // never occurs
909 wxXmlNode
*node
= new wxXmlNode(wxXML_ELEMENT_NODE
, name
);
910 m_Resource
->GetRoot()->AddChild(node
);
911 NotifyChanged(CHANGED_TREE
);
918 void EditorFrame::OnRightClickTree(wxPoint pos
)
920 wxMenu
*popup
= new wxMenu
;
922 if (m_SelectedNode
== NULL
|| m_SelectedNode
== m_Resource
->GetRoot())
924 popup
->Append(ID_NEWDIALOG
, _("New dialog"));
925 popup
->Append(ID_NEWPANEL
, _("New panel"));
926 popup
->Append(ID_NEWMENU
, _("New menu"));
927 popup
->Append(ID_NEWMENUBAR
, _("New menubar"));
928 popup
->Append(ID_NEWTOOLBAR
, _("New toolbar"));
936 FindHandler(FindHandler(m_SelectedNode
)->GetRealNode(m_SelectedNode
))->
939 has_children
= !arr
.IsEmpty();
942 wxMenu
*news
= new wxMenu
;
943 for (size_t i
= 0; i
< arr
.GetCount(); i
++)
945 news
->Append(i
+ ID_NEWNODE
, arr
[i
]);
946 if (i
% 16 == 15) news
->Break();
948 popup
->Append(ID_NEWNODE
-1, _("New child"), news
);
954 (XmlTreeData
*)(m_TreeCtrl
->GetItemData(
955 m_TreeCtrl
->GetParent(m_TreeCtrl
->GetSelection())));
956 if (pardt
&& pardt
->Node
&& pardt
->Node
!= m_Resource
->GetRoot())
958 wxXmlNode
*nd
= pardt
->Node
;
960 FindHandler(FindHandler(nd
)->GetRealNode(nd
))->
965 wxMenu
*news
= new wxMenu
;
966 for (size_t i
= 0; i
< arr
.GetCount(); i
++)
968 news
->Append(i
+ ID_NEWSYBNODE
, arr
[i
]);
969 if (i
% 16 == 15) news
->Break();
971 popup
->Append(ID_NEWSYBNODE
-1, _("New sybling"), news
);
976 popup
->AppendSeparator();
977 popup
->Append(ID_CUT
, "Cut");
978 popup
->Append(ID_COPY
, "Copy");
979 popup
->Append(ID_PASTE_SYBLING
, "Paste as sybling");
980 popup
->Append(ID_PASTE_CHILD
, "Paste as child");
981 popup
->AppendSeparator();
982 popup
->Append(ID_DELETE_NODE
, _("Delete"));
983 popup
->Enable(ID_PASTE_SYBLING
, m_Clipboard
!= NULL
);
984 popup
->Enable(ID_PASTE_CHILD
, has_children
&& m_Clipboard
!= NULL
);
987 m_TreeCtrl
->PopupMenu(popup
, pos
);
993 void EditorFrame::OnClipboardAction(wxCommandEvent
& event
)
995 switch (event
.GetId())
1000 m_Clipboard
= new wxXmlNode(*m_SelectedNode
);
1001 GetMenuBar()->Enable(ID_PASTE_SYBLING
, TRUE
);
1002 GetMenuBar()->Enable(ID_PASTE_CHILD
, TRUE
);
1003 if (event
.GetId() == ID_CUT
) DeleteSelectedNode();
1006 case ID_PASTE_SYBLING
:
1008 XmlTreeData
*pardt
=
1009 (XmlTreeData
*)(m_TreeCtrl
->GetItemData(
1010 m_TreeCtrl
->GetParent(m_TreeCtrl
->GetSelection())));
1012 if (pardt
&& pardt
->Node
&& pardt
->Node
!= m_Resource
->GetRoot())
1014 wxXmlNode
*nd
= pardt
->Node
;
1016 wxXmlNode
*realnode
= FindHandler(nd
)->GetRealNode(nd
);
1017 NodeHandler
*hnd
= FindHandler(realnode
);
1018 wxXmlNode
*node
= new wxXmlNode(*m_Clipboard
);
1019 hnd
->InsertNode(realnode
, node
, m_SelectedNode
);
1020 wxTreeItemId root
= m_TreeCtrl
->GetSelection();
1021 SelectNode(node
, &root
);
1026 case ID_PASTE_CHILD
:
1027 wxXmlNode
*realnode
= FindHandler(m_SelectedNode
)->GetRealNode(m_SelectedNode
);
1028 NodeHandler
*hnd
= FindHandler(realnode
);
1029 wxXmlNode
*node
= new wxXmlNode(*m_Clipboard
);
1030 hnd
->InsertNode(realnode
, node
);
1031 wxTreeItemId root
= m_TreeCtrl
->GetSelection();
1032 SelectNode(node
, &root
);