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"
38 class EditorTreeCtrl
: public wxTreeCtrl
41 EditorTreeCtrl(wxWindow
*parent
, int id
, EditorFrame
*frame
)
42 : wxTreeCtrl(parent
, id
), m_EdFrame(frame
) {}
45 EditorFrame
*m_EdFrame
;
47 void OnRightClick(wxMouseEvent
&event
)
50 m_EdFrame
->m_TreeCtrl
->HitTest(event
.GetPosition());
53 m_EdFrame
->m_TreeCtrl
->SelectItem(item
);
54 m_EdFrame
->OnRightClickTree(event
.GetPosition());
60 BEGIN_EVENT_TABLE(EditorTreeCtrl
, wxTreeCtrl
)
61 EVT_RIGHT_DOWN(EditorTreeCtrl::OnRightClick
)
67 ID_PREVIEW
= wxID_HIGHEST
+ 100,
92 ID_NEWNODE
= wxID_HIGHEST
+ 1000,
93 ID_NEWSYBNODE
= ID_NEWNODE
+ 2000
100 BEGIN_EVENT_TABLE(EditorFrame
, wxFrame
)
101 EVT_TREE_SEL_CHANGED(ID_TREE
, EditorFrame::OnTreeSel
)
102 EVT_TOOL_RANGE(ID_PREVIEW
, ID_EXIT
, EditorFrame::OnToolbar
)
103 EVT_MENU_RANGE(ID_NEWDIALOG
, ID_NEWSYBNODE
+ 1000, EditorFrame::OnNewNode
)
104 EVT_MENU_RANGE(ID_CUT
, ID_COPY
, EditorFrame::OnClipboardAction
)
105 EVT_TEXT(ID_XMLIDEDIT
, EditorFrame::OnXMLIDEdit
)
106 EVT_BUTTON(ID_XMLIDPICK
, EditorFrame::OnXMLIDPick
)
107 EVT_BUTTON(ID_EDITCODE
, EditorFrame::OnEditCode
)
108 EVT_BUTTON(ID_CLEARPROP
, EditorFrame::OnClearProp
)
109 EVT_LIST_ITEM_SELECTED(ID_PROPSLIST
, EditorFrame::OnPropSel
)
114 #if defined(__UNIX__)
115 #include "bitmaps/preview.xpm"
116 #include "bitmaps/close.xpm"
117 #include "bitmaps/save.xpm"
118 #include "bitmaps/open.xpm"
120 #include "bitmaps/control.xpm"
121 #include "bitmaps/vsizer.xpm"
122 #include "bitmaps/hsizer.xpm"
123 #include "bitmaps/panel.xpm"
124 #include "bitmaps/gsizer.xpm"
125 #include "bitmaps/resicon.xpm"
127 #include "bitmaps/unused.xpm"
128 #include "bitmaps/used.xpm"
133 EditorFrame
*EditorFrame::ms_Instance
= NULL
;
135 EditorFrame::EditorFrame(wxFrame
*parent
, const wxString
& filename
)
136 : wxFrame(parent
, -1, filename
+ _("- wxWindows resources editor"))
142 wxConfigBase
*cfg
= wxConfigBase::Get();
144 SetSize(wxRect(wxPoint(cfg
->Read("editor_x", -1), cfg
->Read("editor_y", -1)),
145 wxSize(cfg
->Read("editor_w", 400), cfg
->Read("editor_h", 400))));
147 m_SelectedNode
= NULL
;
149 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));
192 wxToolBar
*toolBar
= CreateToolBar(wxNO_BORDER
| wxTB_HORIZONTAL
| wxTB_FLAT
);
193 toolBar
->SetMargins(2, 2);
194 toolBar
->SetToolBitmapSize(wxSize(24, 24));
195 toolBar
-> AddTool(ID_EXIT
, wxBITMAP(close
), wxNullBitmap
,
196 FALSE
, -1, -1, (wxObject
*) NULL
,
197 _("Quit the editor"));
198 toolBar
-> AddTool(ID_OPEN
, wxBITMAP(open
), wxNullBitmap
,
199 FALSE
, -1, -1, (wxObject
*) NULL
,
200 _("Open XML resource file"));
201 toolBar
-> AddTool(ID_SAVE
, wxBITMAP(save
), wxNullBitmap
,
202 FALSE
, -1, -1, (wxObject
*) NULL
,
204 toolBar
-> AddTool(ID_PREVIEW
, wxBITMAP(preview
), wxNullBitmap
,
205 FALSE
, -1, -1, (wxObject
*) NULL
,
207 toolBar
-> Realize();
210 wxSizer
*sizer
= new wxBoxSizer(wxVERTICAL
);
211 wxPanel
*p
= new wxPanel(this);
212 sizer
->Add(p
, 1, wxEXPAND
);
213 wxSizer
*sizer2
= new wxBoxSizer(wxVERTICAL
);
215 m_Splitter
= new wxSplitterWindow(p
);
216 sizer2
->Add(m_Splitter
, 1, wxEXPAND
);
219 // Create tree control:
220 m_TreeCtrl
= new EditorTreeCtrl(m_Splitter
, ID_TREE
, this);
221 m_ImgList
= new wxImageList(16, 16);
222 m_ImgList
->Add(wxICON(control
));
223 m_ImgList
->Add(wxICON(panel
));
224 m_ImgList
->Add(wxICON(vsizer
));
225 m_ImgList
->Add(wxICON(hsizer
));
226 m_ImgList
->Add(wxICON(gsizer
));
227 m_ImgList
->Add(wxICON(resicon
));
229 m_TreeCtrl
->SetImageList(m_ImgList
);
232 // Create properties panel:
233 m_Splitter2
= new wxSplitterWindow(m_Splitter
);
234 m_PropsPanel
= new wxPanel(m_Splitter2
, -1, wxDefaultPosition
,
235 wxDefaultSize
, wxTAB_TRAVERSAL
);
237 wxSizer
*sizer3
= new wxBoxSizer(wxVERTICAL
);
239 wxSizer
*sz
= new wxBoxSizer(wxHORIZONTAL
);
241 sizer3
->Add(new wxButton(m_PropsPanel
, ID_EDITCODE
, "Edit XML code"),
242 0, wxALL
| wxEXPAND
, 2);
243 sz
->Add(new wxStaticText(m_PropsPanel
, -1, _("XMLID name:")),
244 0, wxLEFT
| wxALIGN_CENTER_VERTICAL
, 2);
245 m_XMLIDCtrl
= new wxTextCtrl(m_PropsPanel
, ID_XMLIDEDIT
, "");
246 sz
->Add(m_XMLIDCtrl
, 1, wxLEFT
|wxRIGHT
, 2);
247 sz
->Add(new wxButton(m_PropsPanel
, ID_XMLIDPICK
, "...", wxDefaultPosition
, wxSize(16,-1)),
249 sizer3
->Add(sz
, 0, wxTOP
|wxEXPAND
, 2);
251 m_PropsList
= new wxListCtrl(m_PropsPanel
, ID_PROPSLIST
, wxDefaultPosition
, wxDefaultSize
, wxLC_REPORT
| wxLC_SINGLE_SEL
);
253 m_ImgListProp
= new wxImageList(16, 16);
254 m_ImgListProp
->Add(wxICON(unused
));
255 m_ImgListProp
->Add(wxICON(used
));
256 m_PropsList
->SetImageList(m_ImgListProp
, wxIMAGE_LIST_SMALL
);
258 m_PropsList
->InsertColumn(0, _("Property"));
259 m_PropsList
->InsertColumn(1, _("Value"));
260 m_PropsList
->SetColumnWidth(0, cfg
->Read("editor_col0", wxLIST_AUTOSIZE_USEHEADER
));
261 m_PropsList
->SetColumnWidth(1, cfg
->Read("editor_col1", wxLIST_AUTOSIZE_USEHEADER
));
263 sizer3
->Add(m_PropsList
, 1, wxALL
| wxEXPAND
, 2);
265 m_PropsPanel
->SetAutoLayout(TRUE
);
266 m_PropsPanel
->SetSizer(sizer3
);
267 m_PropsPanel
->Layout();
269 m_PropsEditPanel
= new wxScrolledWindow(m_Splitter2
, -1, wxDefaultPosition
,
270 wxDefaultSize
, wxTAB_TRAVERSAL
);
272 m_Splitter
->SplitVertically(m_TreeCtrl
, m_Splitter2
);
273 m_Splitter
->SetSashPosition(cfg
->Read("editor_sash", 140));
275 m_Splitter2
->SplitHorizontally(m_PropsPanel
, m_PropsEditPanel
);
276 m_Splitter2
->SetSashPosition(cfg
->Read("editor_sash2", 100));
278 p
->SetAutoLayout(TRUE
);
295 EditorFrame::~EditorFrame()
297 PreviewFrame::Get()->Close();
299 wxConfigBase
*cfg
= wxConfigBase::Get();
301 cfg
->Write("editor_x", (long)GetPosition().x
);
302 cfg
->Write("editor_y", (long)GetPosition().y
);
303 cfg
->Write("editor_w", (long)GetSize().x
);
304 cfg
->Write("editor_h", (long)GetSize().y
);
305 cfg
->Write("editor_sash", (long)m_Splitter
->GetSashPosition());
306 cfg
->Write("editor_sash2", (long)m_Splitter2
->GetSashPosition());
307 cfg
->Write("editor_col0", (long)m_PropsList
->GetColumnWidth(0));
308 cfg
->Write("editor_col1", (long)m_PropsList
->GetColumnWidth(1));
311 delete m_ImgListProp
;
319 NodeHandler
*EditorFrame::FindHandler(wxXmlNode
*node
)
321 wxNode
*n
= m_Handlers
.GetFirst();
324 NodeHandler
*h
= (NodeHandler
*) n
->GetData();
325 if (h
->CanHandle(node
))
334 void EditorFrame::RegisterHandlers(const wxString
& dirname
)
336 if (!wxDirExists(dirname
)) return;
343 cont
= dir
.GetFirst(&filename
, "*.df");
346 hnd
= NodeHandler::CreateFromFile(filename
, this);
347 if (hnd
) m_Handlers
.Append(hnd
);
348 cont
= dir
.GetNext(&filename
);
355 void EditorFrame::LoadFile(const wxString
& filename
)
360 m_Resource
= new wxXmlDocument
;
362 if (!m_Resource
->Load(filename
))
367 wxLogError("Error parsing " + filename
);
371 m_FileName
= filename
;
373 SetTitle("wxrcedit - " + wxFileNameFromPath(m_FileName
));
379 void EditorFrame::SaveFile(const wxString
& filename
)
381 m_FileName
= filename
;
382 SetTitle("wxrcedit - " + wxFileNameFromPath(m_FileName
));
384 if (!m_Resource
->Save(filename
, wxXML_IO_LIBXML
))
385 wxLogError("Error saving " + filename
);
390 void EditorFrame::NewFile()
395 m_Resource
= new wxXmlDocument
;
396 m_Resource
->SetRoot(new wxXmlNode(wxXML_ELEMENT_NODE
, "resource"));
404 void EditorFrame::RefreshTree()
406 wxXmlNode
*sel
= m_SelectedNode
;
408 m_TreeCtrl
->DeleteAllItems();
409 wxTreeItemId root
= m_TreeCtrl
->AddRoot("Resource: " + wxFileNameFromPath(m_FileName
), 5, 5);
411 wxXmlNode
*n
= m_Resource
->GetRoot()->GetChildren();
414 if (n
->GetType() == wxXML_ELEMENT_NODE
)
415 CreateTreeNode(m_TreeCtrl
, root
, n
);
419 m_TreeCtrl
->Expand(root
);
424 void EditorFrame::RefreshProps(wxXmlNode
*node
)
428 for (int i
= 0; i
< m_PropsList
->GetItemCount(); i
++)
429 delete (wxObject
*)(m_PropsList
->GetItemData(i
));
431 m_PropsList
->DeleteAllItems();
433 if (node
== NULL
) return;
435 m_XMLIDCtrl
->SetValue(FindHandler(node
)->GetRealNode(node
)->
436 GetPropVal("name", "-1"));
437 CreatePropsList(m_PropsList
, node
);
444 void EditorFrame::RefreshPropsEdit()
446 m_PropsEditPanel
->DestroyChildren();
447 m_PropsEditPanel
->SetSizer(NULL
);
449 if (!m_SelectedNode
|| m_SelectedProp
== -1 ||
450 m_PropsList
->GetItemData(m_SelectedProp
) == 0) return;
452 wxBoxSizer
*sizer
= new wxBoxSizer(wxVERTICAL
);
454 sizer
->Add(new wxButton(m_PropsEditPanel
, ID_CLEARPROP
, _("Clear")),
458 FindHandler(m_SelectedNode
)->CreatePropEditPanel(m_PropsEditPanel
, m_PropsList
, m_SelectedProp
),
461 m_PropsEditPanel
->SetAutoLayout(TRUE
);
462 m_PropsEditPanel
->SetSizer(sizer
);
463 m_PropsEditPanel
->Layout();
465 wxSize winsz
= m_PropsEditPanel
->GetSize();
466 sizer
->SetMinSize(winsz
.x
, winsz
.y
);
468 wxSize minsz
= sizer
->GetMinSize();
470 m_PropsEditPanel
->SetScrollbars(8, 8, 1/*minsz.x/8*/, minsz
.y
/8);
475 bool EditorFrame::SelectNode(wxXmlNode
*node
, wxTreeItemId
*root
)
479 wxTreeItemId rootitem
= m_TreeCtrl
->GetRootItem();
480 return SelectNode(node
, &rootitem
);
488 item
= m_TreeCtrl
->GetFirstChild(*root
, cookie
);
491 dt
= (XmlTreeData
*)(m_TreeCtrl
->GetItemData(item
));
492 nd
= (dt
) ? dt
->Node
: NULL
;
495 m_TreeCtrl
->SelectItem(item
);
496 m_TreeCtrl
->EnsureVisible(item
);
499 if (m_TreeCtrl
->ItemHasChildren(item
) && SelectNode(node
, &item
))
501 item
= m_TreeCtrl
->GetNextChild(*root
, cookie
);
508 wxTreeItemId
EditorFrame::CreateTreeNode(wxTreeCtrl
*treectrl
, wxTreeItemId parent
, wxXmlNode
*node
)
512 wxTreeItemId invalid
;
516 return FindHandler(node
)->CreateTreeNode(treectrl
, parent
, node
);
521 void EditorFrame::CreatePropsList(wxListCtrl
*treectrl
, wxXmlNode
*node
)
525 FindHandler(node
)->CreatePropsList(treectrl
, node
);
530 void EditorFrame::NotifyChanged(int change_type
)
532 if (change_type
& CHANGED_TREE
)
535 if (change_type
& CHANGED_TREE_SELECTED
)
537 wxTreeItemId sel
= m_TreeCtrl
->GetSelection();
538 m_TreeCtrl
->SetItemText(sel
,
539 FindHandler(m_SelectedNode
)->GetTreeString(m_SelectedNode
));
542 if (change_type
& CHANGED_TREE_SELECTED_ICON
)
544 wxTreeItemId sel
= m_TreeCtrl
->GetSelection();
545 int icon
= FindHandler(m_SelectedNode
)->GetTreeIcon(m_SelectedNode
);
546 m_TreeCtrl
->SetItemImage(sel
, icon
);
549 if (change_type
& CHANGED_PROPS_PANEL
)
550 RefreshProps(m_SelectedNode
);
555 void EditorFrame::OnTreeSel(wxTreeEvent
& event
)
557 XmlTreeData
*dt
= (XmlTreeData
*)(m_TreeCtrl
->GetItemData(event
.GetItem()));
558 wxXmlNode
*node
= (dt
) ? dt
->Node
: NULL
;
560 m_SelectedNode
= node
;
566 void EditorFrame::OnXMLIDEdit(wxCommandEvent
& event
)
568 if (!m_SelectedNode
) return;
569 wxXmlNode
*node
= FindHandler(m_SelectedNode
)->GetRealNode(m_SelectedNode
);
571 node
->DeleteProperty("name");
572 wxString s
= m_XMLIDCtrl
->GetValue();
573 if (!(s
== "-1")) node
->AddProperty("name", s
);
574 NotifyChanged(CHANGED_TREE_SELECTED
);
579 void EditorFrame::OnXMLIDPick(wxCommandEvent
& event
)
581 if (!m_SelectedNode
) return;
582 wxXmlNode
*node
= FindHandler(m_SelectedNode
)->GetRealNode(m_SelectedNode
);
584 wxString choices
[] = {wxString("-1")
585 #define stdID(id) , wxString(#id)
586 stdID(wxID_OK
) stdID(wxID_CANCEL
)
587 stdID(wxID_YES
) stdID(wxID_NO
)
588 stdID(wxID_APPLY
) stdID(wxID_HELP
)
589 stdID(wxID_HELP_CONTEXT
)
591 stdID(wxID_OPEN
) stdID(wxID_CLOSE
) stdID(wxID_NEW
)
592 stdID(wxID_SAVE
) stdID(wxID_SAVEAS
) stdID(wxID_REVERT
)
593 stdID(wxID_EXIT
) stdID(wxID_UNDO
) stdID(wxID_REDO
)
594 stdID(wxID_PRINT
) stdID(wxID_PRINT_SETUP
)
595 stdID(wxID_PREVIEW
) stdID(wxID_ABOUT
) stdID(wxID_HELP_CONTENTS
)
596 stdID(wxID_HELP_COMMANDS
) stdID(wxID_HELP_PROCEDURES
)
597 stdID(wxID_CUT
) stdID(wxID_COPY
) stdID(wxID_PASTE
)
598 stdID(wxID_CLEAR
) stdID(wxID_FIND
) stdID(wxID_DUPLICATE
)
599 stdID(wxID_SELECTALL
)
600 stdID(wxID_STATIC
) stdID(wxID_FORWARD
) stdID(wxID_BACKWARD
)
601 stdID(wxID_DEFAULT
) stdID(wxID_MORE
) stdID(wxID_SETUP
)
607 wxGetSingleChoice(_("Choose from predefined IDs:"), _("XMLID"),
608 38/*sizeof choices*/, choices
);
611 m_XMLIDCtrl
->SetValue(s
);
612 node
->DeleteProperty("name");
613 if (!(s
== "-1")) node
->AddProperty("name", s
);
614 NotifyChanged(CHANGED_TREE_SELECTED
);
619 void EditorFrame::OnEditCode(wxCommandEvent
& event
)
621 if (!m_SelectedNode
) return;
624 wxDialog
dlg(this, -1, _("XML code editor"), wxDefaultPosition
, wxDefaultSize
, wxDEFAULT_DIALOG_STYLE
| wxRESIZE_BORDER
);
625 wxSizer
*sizer
= new wxBoxSizer(wxVERTICAL
);
626 wxTextCtrl
*tc
= new wxTextCtrl(&dlg
, -1, "", wxDefaultPosition
,
627 wxDefaultSize
, wxTE_MULTILINE
);
628 sizer
->Add(tc
, 1, wxEXPAND
| wxALL
, 10);
630 wxSizer
*sz2
= new wxBoxSizer(wxHORIZONTAL
);
632 sz2
->Add(new wxButton(&dlg
, wxID_OK
, _("Save")), 0);
633 sz2
->Add(new wxButton(&dlg
, wxID_CANCEL
, _("Cancel")), 0, wxLEFT
, 10);
635 sizer
->Add(sz2
, 0, wxALIGN_RIGHT
| wxRIGHT
|wxBOTTOM
, 10);
637 dlg
.SetAutoLayout(TRUE
);
640 wxConfigBase
*cfg
= wxConfigBase::Get();
642 dlg
.SetSize(wxRect(wxPoint(cfg
->Read("xmleditor_x", -1), cfg
->Read("xmleditor_y", -1)),
643 wxSize(cfg
->Read("xmleditor_w", 400), cfg
->Read("xmleditor_h", 400))));
646 wxGetTempFileName("xmleditor", tempfile
);
650 doc
.SetRoot(new wxXmlNode(*m_SelectedNode
));
651 doc
.Save(tempfile
, wxXML_IO_LIBXML
);
653 tc
->LoadFile(tempfile
);
655 if (dlg
.ShowModal() == wxID_OK
)
657 tc
->SaveFile(tempfile
);
659 if (doc
.Load(tempfile
))
661 (*m_SelectedNode
) = *doc
.GetRoot();
662 NotifyChanged(CHANGED_TREE
);
663 //FIXME-instead, regenerate only children
665 else wxLogError(_("Illegal XML file, canceled."));
667 wxRemoveFile(tempfile
);
669 cfg
->Write("xmleditor_x", (long)dlg
.GetPosition().x
);
670 cfg
->Write("xmleditor_y", (long)dlg
.GetPosition().y
);
671 cfg
->Write("xmleditor_w", (long)dlg
.GetSize().x
);
672 cfg
->Write("xmleditor_h", (long)dlg
.GetSize().y
);
677 void EditorFrame::OnClearProp(wxCommandEvent
& event
)
679 m_PropsList
->SetItemImage(m_SelectedProp
, 0, 0);
680 m_PropsList
->SetItem(m_SelectedProp
, 1, "");
682 PropsListInfo
*pli
= (PropsListInfo
*)m_PropsList
->GetItemData(m_SelectedProp
);
684 wxXmlNode
*nd
= XmlFindNode(pli
->m_Node
, pli
->m_PropInfo
->Name
);
686 if (nd
== NULL
) return;
687 nd
->GetParent()->RemoveChild(nd
);
694 void EditorFrame::OnPropSel(wxListEvent
& event
)
696 m_SelectedProp
= event
.GetIndex();
702 void EditorFrame::OnToolbar(wxCommandEvent
& event
)
704 switch (event
.GetId())
708 XmlTreeData
* dt
= (XmlTreeData
*)m_TreeCtrl
->GetItemData(m_TreeCtrl
->GetSelection());;
709 if (dt
!= NULL
&& dt
->Node
!= NULL
)
710 PreviewFrame::Get()->Preview(dt
->Node
);
724 wxString name
= wxFileSelector("Open XML resource", "", "", "", "XML resources|*.xml", wxOPEN
| wxFILE_MUST_EXIST
);
731 if (m_FileName
!= "") { SaveFile(m_FileName
); break;}
736 wxString name
= wxFileSelector("Save as", "", m_FileName
, "", "XML resources|*.xml", wxSAVE
| wxOVERWRITE_PROMPT
);
738 SaveFile((m_FileName
= name
));
742 case ID_DELETE_NODE
:
744 DeleteSelectedNode();
752 void EditorFrame::DeleteSelectedNode()
754 XmlTreeData
*dt
= (XmlTreeData
*)
755 (m_TreeCtrl
->GetItemData(m_TreeCtrl
->GetParent(m_TreeCtrl
->GetSelection())));
756 wxXmlNode
*n
= (dt
) ? dt
->Node
: NULL
;
758 m_SelectedNode
->GetParent()->RemoveChild(m_SelectedNode
);
759 NotifyChanged(CHANGED_TREE
);
765 void EditorFrame::OnNewNode(wxCommandEvent
& event
)
767 if (event
.GetId() >= ID_NEWSYBNODE
)
770 (XmlTreeData
*)(m_TreeCtrl
->GetItemData(
771 m_TreeCtrl
->GetParent(m_TreeCtrl
->GetSelection())));
773 if (pardt
&& pardt
->Node
&& pardt
->Node
!= m_Resource
->GetRoot())
775 wxXmlNode
*nd
= pardt
->Node
;
777 wxXmlNode
*realnode
= FindHandler(nd
)->GetRealNode(nd
);
778 NodeHandler
*hnd
= FindHandler(realnode
);
779 wxString name
= hnd
->GetChildTypes()[event
.GetId()-ID_NEWSYBNODE
];
781 wxXmlNode
*node
= new wxXmlNode(wxXML_ELEMENT_NODE
, _T("object"));
782 node
->AddProperty(_T("class"), name
);
784 hnd
->InsertNode(realnode
, node
, m_SelectedNode
);
785 wxTreeItemId root
= m_TreeCtrl
->GetSelection();
786 SelectNode(node
, &root
);
791 else if (event
.GetId() >= ID_NEWNODE
)
793 wxXmlNode
*realnode
= FindHandler(m_SelectedNode
)->GetRealNode(m_SelectedNode
);
794 NodeHandler
*hnd
= FindHandler(realnode
);
795 wxString name
= hnd
->GetChildTypes()[event
.GetId()-ID_NEWNODE
];
797 wxXmlNode
*node
= new wxXmlNode(wxXML_ELEMENT_NODE
, _T("object"));
798 node
->AddProperty(_T("class"), name
);
800 hnd
->InsertNode(realnode
, node
);
801 wxTreeItemId root
= m_TreeCtrl
->GetSelection();
802 SelectNode(node
, &root
);
808 switch (event
.GetId())
810 case ID_NEWDIALOG
: name
= _T("wxDialog"); break;
811 case ID_NEWPANEL
: name
= _T("wxPanel"); break;
812 case ID_NEWMENU
: name
= _T("wxMenu"); break;
813 case ID_NEWMENUBAR
: name
= _T("wxMenuBar"); break;
814 case ID_NEWTOOLBAR
: name
= _T("wxToolBar"); break;
815 default : return; // never occurs
818 wxXmlNode
*node
= new wxXmlNode(wxXML_ELEMENT_NODE
, _T("object"));
819 node
->AddProperty(_T("class"), name
);
820 m_Resource
->GetRoot()->AddChild(node
);
821 NotifyChanged(CHANGED_TREE
);
828 void EditorFrame::OnRightClickTree(wxPoint pos
)
830 wxMenu
*popup
= new wxMenu
;
832 if (m_SelectedNode
== NULL
|| m_SelectedNode
== m_Resource
->GetRoot())
834 popup
->Append(ID_NEWDIALOG
, _("New wxDialog"));
835 popup
->Append(ID_NEWPANEL
, _("New wxPanel"));
836 popup
->Append(ID_NEWMENU
, _("New wxMenu"));
837 popup
->Append(ID_NEWMENUBAR
, _("New wxMenuBar"));
838 popup
->Append(ID_NEWTOOLBAR
, _("New wxToolBar"));
846 FindHandler(FindHandler(m_SelectedNode
)->GetRealNode(m_SelectedNode
))->
849 has_children
= !arr
.IsEmpty();
852 wxMenu
*news
= new wxMenu
;
853 wxMenu
*news2
= news
;
854 for (size_t i
= 0; i
< arr
.GetCount(); i
++)
856 news2
->Append(i
+ ID_NEWNODE
, arr
[i
]);
857 #ifdef __WXGTK__ // doesn't support Break
860 wxMenu
*m
= new wxMenu
;
861 news2
->Append(ID_NEWNODE
+arr
.GetCount(), _("More..."), m
);
865 if (i
% 16 == 15) news2
->Break();
868 popup
->Append(ID_NEWNODE
-1, _("New child"), news
);
874 (XmlTreeData
*)(m_TreeCtrl
->GetItemData(
875 m_TreeCtrl
->GetParent(m_TreeCtrl
->GetSelection())));
876 if (pardt
&& pardt
->Node
&& pardt
->Node
!= m_Resource
->GetRoot())
878 wxXmlNode
*nd
= pardt
->Node
;
880 FindHandler(FindHandler(nd
)->GetRealNode(nd
))->
885 wxMenu
*news
= new wxMenu
;
886 wxMenu
*news2
= news
;
887 for (size_t i
= 0; i
< arr
.GetCount(); i
++)
889 news2
->Append(i
+ ID_NEWSYBNODE
, arr
[i
]);
890 #ifdef __WXGTK__ // doesn't support Break
893 wxMenu
*m
= new wxMenu
;
894 news2
->Append(ID_NEWSYBNODE
+arr
.GetCount(), _("More..."), m
);
898 if (i
% 16 == 15) news2
->Break();
901 popup
->Append(ID_NEWSYBNODE
-1, _("New sybling"), news
);
906 popup
->AppendSeparator();
907 popup
->Append(ID_CUT
, _("Cut"));
908 popup
->Append(ID_COPY
, _("Copy"));
909 popup
->Append(ID_PASTE_SYBLING
, _("Paste as sybling"));
910 popup
->Append(ID_PASTE_CHILD
, _("Paste as child"));
911 popup
->AppendSeparator();
912 popup
->Append(ID_DELETE_NODE
, _("Delete"));
913 popup
->Enable(ID_PASTE_SYBLING
, m_Clipboard
!= NULL
);
914 popup
->Enable(ID_PASTE_CHILD
, has_children
&& m_Clipboard
!= NULL
);
917 m_TreeCtrl
->PopupMenu(popup
, pos
);
923 void EditorFrame::OnClipboardAction(wxCommandEvent
& event
)
925 switch (event
.GetId())
930 m_Clipboard
= new wxXmlNode(*m_SelectedNode
);
931 GetMenuBar()->Enable(ID_PASTE_SYBLING
, TRUE
);
932 GetMenuBar()->Enable(ID_PASTE_CHILD
, TRUE
);
933 if (event
.GetId() == ID_CUT
) DeleteSelectedNode();
936 case ID_PASTE_SYBLING
:
939 (XmlTreeData
*)(m_TreeCtrl
->GetItemData(
940 m_TreeCtrl
->GetParent(m_TreeCtrl
->GetSelection())));
942 if (pardt
&& pardt
->Node
&& pardt
->Node
!= m_Resource
->GetRoot())
944 wxXmlNode
*nd
= pardt
->Node
;
946 wxXmlNode
*realnode
= FindHandler(nd
)->GetRealNode(nd
);
947 NodeHandler
*hnd
= FindHandler(realnode
);
948 wxXmlNode
*node
= new wxXmlNode(*m_Clipboard
);
949 hnd
->InsertNode(realnode
, node
, m_SelectedNode
);
950 wxTreeItemId root
= m_TreeCtrl
->GetSelection();
951 SelectNode(node
, &root
);
957 wxXmlNode
*realnode
= FindHandler(m_SelectedNode
)->GetRealNode(m_SelectedNode
);
958 NodeHandler
*hnd
= FindHandler(realnode
);
959 wxXmlNode
*node
= new wxXmlNode(*m_Clipboard
);
960 hnd
->InsertNode(realnode
, node
);
961 wxTreeItemId root
= m_TreeCtrl
->GetSelection();
962 SelectNode(node
, &root
);