]> git.saurik.com Git - wxWidgets.git/blob - contrib/utils/wxrcedit/editor.cpp
wxrcedit bugfixes
[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 #include "preview.h"
35 #include "propframe.h"
36
37
38
39 class EditorTreeCtrl : public wxTreeCtrl
40 {
41 public:
42 EditorTreeCtrl(wxWindow *parent, int id, EditorFrame *frame)
43 : wxTreeCtrl(parent, id), m_EdFrame(frame) {}
44
45 private:
46 EditorFrame *m_EdFrame;
47
48 void OnRightClick(wxMouseEvent &event)
49 {
50 wxTreeItemId item =
51 m_EdFrame->m_TreeCtrl->HitTest(event.GetPosition());
52 if (item.IsOk())
53 {
54 m_EdFrame->m_TreeCtrl->SelectItem(item);
55 m_EdFrame->OnRightClickTree(event.GetPosition());
56 }
57 }
58 DECLARE_EVENT_TABLE()
59 };
60
61 BEGIN_EVENT_TABLE(EditorTreeCtrl, wxTreeCtrl)
62 EVT_RIGHT_DOWN(EditorTreeCtrl::OnRightClick)
63 END_EVENT_TABLE()
64
65
66 enum
67 {
68 ID_PREVIEW = wxID_HIGHEST + 100,
69 ID_NEW,
70 ID_OPEN,
71 ID_CLOSE,
72 ID_SAVE,
73 ID_SAVEAS,
74 ID_DELETE_NODE,
75 ID_EXIT,
76 ID_TREE,
77
78 ID_CUT,
79 ID_PASTE_SYBLING,
80 ID_PASTE_CHILD,
81 ID_COPY,
82
83 ID_NEWDIALOG,
84 ID_NEWPANEL,
85 ID_NEWMENU,
86 ID_NEWMENUBAR,
87 ID_NEWTOOLBAR,
88 ID_NEWNODE = wxID_HIGHEST + 10000, // safely out of XMLID range :)
89 ID_NEWSYBNODE = ID_NEWNODE + 20000
90 };
91
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_MENU_RANGE(ID_CUT, ID_COPY, EditorFrame::OnClipboardAction)
101 EVT_CLOSE(EditorFrame::OnCloseWindow)
102 END_EVENT_TABLE()
103
104
105
106 #if defined(__UNIX__)
107 #include "bitmaps/preview.xpm"
108 #include "bitmaps/close.xpm"
109 #include "bitmaps/save.xpm"
110 #include "bitmaps/open.xpm"
111
112 #include "bitmaps/control.xpm"
113 #include "bitmaps/vsizer.xpm"
114 #include "bitmaps/hsizer.xpm"
115 #include "bitmaps/panel.xpm"
116 #include "bitmaps/gsizer.xpm"
117 #include "bitmaps/resicon.xpm"
118 #endif
119
120
121
122 EditorFrame *EditorFrame::ms_Instance = NULL;
123
124 EditorFrame::EditorFrame(wxFrame *parent, const wxString& filename)
125 : wxFrame(parent, -1, filename + _("- wxWindows resources editor"))
126 {
127 ms_Instance = this;
128
129 m_Clipboard = NULL;
130 m_Modified = FALSE;
131
132 wxConfigBase *cfg = wxConfigBase::Get();
133
134 SetSize(wxRect(wxPoint(cfg->Read("editor_x", -1), cfg->Read("editor_y", -1)),
135 wxSize(cfg->Read("editor_w", 400), cfg->Read("editor_h", 400))));
136
137 m_SelectedNode = NULL;
138 m_Resource = NULL;
139 m_FileName = wxEmptyString;
140
141 wxMenu *menuFile = new wxMenu;
142 menuFile->Append(ID_NEW, "&New");
143 menuFile->Append(ID_OPEN, "&Open\tCtrl-O");
144 menuFile->Append(ID_SAVE, "&Save\tCtrl-S");
145 menuFile->Append(ID_SAVEAS, "Save &as...");
146 menuFile->AppendSeparator();
147 menuFile->Append(ID_EXIT, "E&xit\tAlt-X");
148
149 wxMenu *menuEdit = new wxMenu;
150 menuEdit->Append(ID_CUT, "Cut\tCtrl-X");
151 menuEdit->Append(ID_COPY, "Copy\tCtrl-C");
152 menuEdit->Append(ID_PASTE_SYBLING, "Paste as sybling\tCtrl-V");
153 menuEdit->Append(ID_PASTE_CHILD, "Paste as child");
154 menuEdit->AppendSeparator();
155 menuEdit->Append(ID_DELETE_NODE, "Delete");
156
157 menuEdit->Enable(ID_PASTE_SYBLING, FALSE);
158 menuEdit->Enable(ID_PASTE_CHILD, FALSE);
159
160 wxMenuBar *menuBar = new wxMenuBar();
161 menuBar->Append(menuFile, "&File");
162 menuBar->Append(menuEdit, "&Edit");
163 SetMenuBar(menuBar);
164
165 // Create toolbar:
166 wxToolBar *toolBar = CreateToolBar(wxNO_BORDER | wxTB_HORIZONTAL | wxTB_FLAT);
167 toolBar->SetMargins(2, 2);
168 toolBar->SetToolBitmapSize(wxSize(24, 24));
169 toolBar -> AddTool(ID_EXIT, wxBITMAP(close), wxNullBitmap,
170 FALSE, -1, -1, (wxObject *) NULL,
171 _("Quit the editor"));
172 toolBar -> AddTool(ID_OPEN, wxBITMAP(open), wxNullBitmap,
173 FALSE, -1, -1, (wxObject *) NULL,
174 _("Open XML resource file"));
175 toolBar -> AddTool(ID_SAVE, wxBITMAP(save), wxNullBitmap,
176 FALSE, -1, -1, (wxObject *) NULL,
177 _("Save XML file"));
178 toolBar -> AddTool(ID_PREVIEW, wxBITMAP(preview), wxNullBitmap,
179 FALSE, -1, -1, (wxObject *) NULL,
180 _("Preview"));
181 toolBar -> Realize();
182
183 wxSizer *sizer = new wxBoxSizer(wxHORIZONTAL);
184
185 // Create tree control:
186 m_TreeCtrl = new EditorTreeCtrl(this, ID_TREE, this);
187 wxImageList *imgList = new wxImageList(16, 16);
188 imgList->Add(wxICON(control));
189 imgList->Add(wxICON(panel));
190 imgList->Add(wxICON(vsizer));
191 imgList->Add(wxICON(hsizer));
192 imgList->Add(wxICON(gsizer));
193 imgList->Add(wxICON(resicon));
194 m_TreeCtrl->AssignImageList(imgList);
195 sizer->Add(m_TreeCtrl, 1, wxEXPAND);
196
197 SetAutoLayout(TRUE);
198 SetSizer(sizer);
199
200 // Load file:
201 if (!filename)
202 NewFile();
203 else
204 LoadFile(filename);
205 }
206
207
208
209 EditorFrame::~EditorFrame()
210 {
211 PreviewFrame::Get()->Close();
212 PropertiesFrame::Get()->Close();
213
214 wxConfigBase *cfg = wxConfigBase::Get();
215
216 cfg->Write(_T("editor_x"), (long)GetPosition().x);
217 cfg->Write(_T("editor_y"), (long)GetPosition().y);
218 cfg->Write(_T("editor_w"), (long)GetSize().x);
219 cfg->Write(_T("editor_h"), (long)GetSize().y);
220
221 delete m_Clipboard;
222 }
223
224
225
226
227 void EditorFrame::LoadFile(const wxString& filename)
228 {
229 if (!AskToSave()) return;
230
231 delete m_Resource;
232
233 m_FileName = "";
234 m_Resource = new wxXmlDocument;
235 m_Modified = FALSE;
236
237 if (!m_Resource->Load(filename))
238 {
239 delete m_Resource;
240 m_Resource = NULL;
241 NewFile();
242 wxLogError("Error parsing " + filename);
243 }
244 else
245 {
246 m_FileName = filename;
247 RefreshTree();
248 }
249 RefreshTitle();
250 }
251
252
253
254 void EditorFrame::SaveFile(const wxString& filename)
255 {
256 m_FileName = filename;
257
258 if (!m_Resource->Save(filename, wxXML_IO_LIBXML))
259 wxLogError(_("Error saving ") + filename);
260 else
261 m_Modified = FALSE;
262
263 RefreshTitle();
264 }
265
266
267
268 void EditorFrame::NewFile()
269 {
270 if (!AskToSave()) return;
271
272 delete m_Resource;
273
274 m_FileName = "";
275 m_Resource = new wxXmlDocument;
276 m_Resource->SetRoot(new wxXmlNode(wxXML_ELEMENT_NODE, _("resource")));
277
278 m_Modified = FALSE;
279 RefreshTree();
280 RefreshTitle();
281 }
282
283
284
285 void EditorFrame::RefreshTitle()
286 {
287 wxString s;
288 if (m_Modified) s << _T("* ");
289 s << _("wxrcedit");
290 if (!m_FileName)
291 s << _T(" - ") << wxFileNameFromPath(m_FileName);
292 SetTitle(s);
293 }
294
295
296
297 void EditorFrame::RefreshTree()
298 {
299 wxXmlNode *sel = m_SelectedNode;
300
301 m_TreeCtrl->DeleteAllItems();
302 wxTreeItemId root = m_TreeCtrl->AddRoot("Resource: " + wxFileNameFromPath(m_FileName), 5, 5);
303
304 wxXmlNode *n = m_Resource->GetRoot()->GetChildren();
305 while (n)
306 {
307 if (n->GetType() == wxXML_ELEMENT_NODE)
308 CreateTreeNode(m_TreeCtrl, root, n);
309 n = n->GetNext();
310 }
311
312 m_TreeCtrl->Expand(root);
313 SelectNode(sel);
314 }
315
316
317
318 bool EditorFrame::SelectNode(wxXmlNode *node, wxTreeItemId *root)
319 {
320 if (root == NULL)
321 {
322 wxTreeItemId rootitem = m_TreeCtrl->GetRootItem();
323 return SelectNode(node, &rootitem);
324 }
325
326 wxTreeItemId item;
327 XmlTreeData *dt;
328 wxXmlNode *nd;
329 long cookie;
330
331 item = m_TreeCtrl->GetFirstChild(*root, cookie);
332 while (item.IsOk())
333 {
334 dt = (XmlTreeData*)(m_TreeCtrl->GetItemData(item));
335 nd = (dt) ? dt->Node : NULL;
336 if (nd == node)
337 {
338 m_TreeCtrl->SelectItem(item);
339 m_TreeCtrl->EnsureVisible(item);
340 return TRUE;
341 }
342 if (m_TreeCtrl->ItemHasChildren(item) && SelectNode(node, &item))
343 return TRUE;
344 item = m_TreeCtrl->GetNextChild(*root, cookie);
345 }
346 return FALSE;
347 }
348
349
350
351 wxTreeItemId EditorFrame::CreateTreeNode(wxTreeCtrl *treectrl, wxTreeItemId parent, wxXmlNode *node)
352 {
353 if (!node)
354 {
355 wxTreeItemId invalid;
356 return invalid;
357 }
358
359 return NodeHandler::Find(node)->CreateTreeNode(treectrl, parent, node);
360 }
361
362
363
364 void EditorFrame::NotifyChanged(int change_type)
365 {
366 if (change_type & CHANGED_TREE)
367 RefreshTree();
368
369 if (change_type & CHANGED_TREE_SELECTED)
370 {
371 wxTreeItemId sel = m_TreeCtrl->GetSelection();
372 m_TreeCtrl->SetItemText(sel,
373 NodeHandler::Find(m_SelectedNode)->GetTreeString(m_SelectedNode));
374 }
375
376 if (change_type & CHANGED_TREE_SELECTED_ICON)
377 {
378 wxTreeItemId sel = m_TreeCtrl->GetSelection();
379 int icon = NodeHandler::Find(m_SelectedNode)->GetTreeIcon(m_SelectedNode);
380 m_TreeCtrl->SetItemImage(sel, icon);
381 }
382
383 if (!m_Modified)
384 {
385 m_Modified = TRUE;
386 RefreshTitle();
387 }
388
389 PreviewFrame::Get()->MakeDirty();
390 }
391
392
393
394 static void RecursivelyExpand(wxTreeCtrl *t, wxTreeItemId item)
395 {
396 t->Expand(item);
397 long cookie;
398 wxTreeItemId id = t->GetFirstChild(item, cookie);
399 while (id.IsOk())
400 {
401 RecursivelyExpand(t, id);
402 id = t->GetNextChild(item, cookie);
403 }
404 }
405
406 void EditorFrame::OnTreeSel(wxTreeEvent& event)
407 {
408 XmlTreeData *dt = (XmlTreeData*)(m_TreeCtrl->GetItemData(event.GetItem()));
409 wxXmlNode *node = (dt) ? dt->Node : NULL;
410
411 m_SelectedNode = node;
412 if (node)
413 PropertiesFrame::Get()->ShowProps(node);
414
415 if (m_TreeCtrl->GetParent(event.GetItem()) == m_TreeCtrl->GetRootItem())
416 {
417 wxTreeItemId it = event.GetOldItem();
418
419 if (it.IsOk() && m_TreeCtrl->GetRootItem() != it)
420 {
421 while (m_TreeCtrl->GetParent(it) != m_TreeCtrl->GetRootItem())
422 it = m_TreeCtrl->GetParent(it);
423 m_TreeCtrl->Collapse(it);
424 }
425 RecursivelyExpand(m_TreeCtrl, event.GetItem());
426
427 PreviewFrame::Get()->Preview(node);
428 }
429 }
430
431
432
433 void EditorFrame::OnToolbar(wxCommandEvent& event)
434 {
435 switch (event.GetId())
436 {
437 case ID_PREVIEW :
438 {
439 XmlTreeData* dt = (XmlTreeData*)m_TreeCtrl->GetItemData(m_TreeCtrl->GetSelection());;
440 if (dt != NULL && dt->Node != NULL)
441 PreviewFrame::Get()->Preview(dt->Node);
442 break;
443 }
444
445 case ID_EXIT :
446 Close(TRUE);
447 break;
448
449 case ID_NEW :
450 NewFile();
451 break;
452
453 case ID_OPEN :
454 {
455 wxString cwd = wxGetCwd(); // workaround for 2.2
456 wxString name = wxFileSelector(_("Open XML resource"), _T(""), _T(""), _T(""), _("XML resources (*.xrc)|*.xrc"), wxOPEN | wxFILE_MUST_EXIST);
457 wxSetWorkingDirectory(cwd);
458 if (!name.IsEmpty())
459 LoadFile(name);
460 break;
461 }
462
463 case ID_SAVE :
464 if (m_FileName != "") { SaveFile(m_FileName); break;}
465 // else go to SAVEAS
466
467 case ID_SAVEAS :
468 {
469 wxString cwd = wxGetCwd(); // workaround for 2.2
470 wxString name = wxFileSelector(_("Save as"), _T(""), m_FileName, _T(""), _("XML resources (*.xrc)|*.xrc"), wxSAVE | wxOVERWRITE_PROMPT);
471 wxSetWorkingDirectory(cwd);
472 if (!name.IsEmpty())
473 SaveFile((m_FileName = name));
474 break;
475 }
476
477 case ID_DELETE_NODE :
478 {
479 DeleteSelectedNode();
480 break;
481 }
482 }
483 }
484
485
486
487 void EditorFrame::DeleteSelectedNode()
488 {
489 XmlTreeData *dt = (XmlTreeData*)
490 (m_TreeCtrl->GetItemData(m_TreeCtrl->GetParent(m_TreeCtrl->GetSelection())));
491 wxXmlNode *n = (dt) ? dt->Node : NULL;
492
493 m_SelectedNode->GetParent()->RemoveChild(m_SelectedNode);
494 NotifyChanged(CHANGED_TREE);
495 SelectNode(n);
496 }
497
498
499
500 void EditorFrame::OnNewNode(wxCommandEvent& event)
501 {
502 if (event.GetId() >= ID_NEWSYBNODE)
503 {
504 XmlTreeData *pardt =
505 (XmlTreeData*)(m_TreeCtrl->GetItemData(
506 m_TreeCtrl->GetParent(m_TreeCtrl->GetSelection())));
507
508 if (pardt && pardt->Node && pardt->Node != m_Resource->GetRoot())
509 {
510 wxXmlNode *nd = pardt->Node;
511
512 wxXmlNode *realnode = NodeHandler::Find(nd)->GetRealNode(nd);
513 NodeHandler *hnd = NodeHandler::Find(realnode);
514 wxString name = hnd->GetChildTypes()[event.GetId()-ID_NEWSYBNODE];
515
516 wxXmlNode *node = new wxXmlNode(wxXML_ELEMENT_NODE, _T("object"));
517 node->AddProperty(_T("class"), name);
518
519 hnd->InsertNode(realnode, node, m_SelectedNode);
520 wxTreeItemId root = m_TreeCtrl->GetSelection();
521 SelectNode(node, &root);
522 }
523
524 }
525
526 else if (event.GetId() >= ID_NEWNODE)
527 {
528 wxXmlNode *realnode = NodeHandler::Find(m_SelectedNode)->GetRealNode(m_SelectedNode);
529 NodeHandler *hnd = NodeHandler::Find(realnode);
530 wxString name = hnd->GetChildTypes()[event.GetId()-ID_NEWNODE];
531
532 wxXmlNode *node = new wxXmlNode(wxXML_ELEMENT_NODE, _T("object"));
533 node->AddProperty(_T("class"), name);
534
535 hnd->InsertNode(realnode, node);
536 wxTreeItemId root = m_TreeCtrl->GetSelection();
537 SelectNode(node, &root);
538 }
539
540 else
541 {
542 wxString name;
543 switch (event.GetId())
544 {
545 case ID_NEWDIALOG : name = _T("wxDialog"); break;
546 case ID_NEWPANEL : name = _T("wxPanel"); break;
547 case ID_NEWMENU : name = _T("wxMenu"); break;
548 case ID_NEWMENUBAR : name = _T("wxMenuBar"); break;
549 case ID_NEWTOOLBAR : name = _T("wxToolBar"); break;
550 default : return; // never occurs
551 }
552
553 wxXmlNode *node = new wxXmlNode(wxXML_ELEMENT_NODE, _T("object"));
554 node->AddProperty(_T("class"), name);
555 m_Resource->GetRoot()->AddChild(node);
556 NotifyChanged(CHANGED_TREE);
557 SelectNode(node);
558 }
559 }
560
561
562
563 void EditorFrame::OnRightClickTree(wxPoint pos)
564 {
565 wxMenu *popup = new wxMenu;
566
567 if (m_SelectedNode == NULL || m_SelectedNode == m_Resource->GetRoot())
568 {
569 popup->Append(ID_NEWDIALOG, _("New wxDialog"));
570 popup->Append(ID_NEWPANEL, _("New wxPanel"));
571 popup->Append(ID_NEWMENU, _("New wxMenu"));
572 popup->Append(ID_NEWMENUBAR, _("New wxMenuBar"));
573 popup->Append(ID_NEWTOOLBAR, _("New wxToolBar"));
574 }
575
576 else
577 {
578 bool has_children;
579 {
580 wxArrayString& arr =
581 NodeHandler::Find(NodeHandler::Find(m_SelectedNode)->GetRealNode(m_SelectedNode))->
582 GetChildTypes();
583
584 has_children = !arr.IsEmpty();
585 if (!arr.IsEmpty())
586 {
587 wxMenu *news = new wxMenu;
588 wxMenu *news2 = news;
589 for (size_t i = 0; i < arr.GetCount(); i++)
590 {
591 news2->Append(i + ID_NEWNODE, arr[i]);
592 #ifdef __WXGTK__ // doesn't support Break
593 if (i % 20 == 19)
594 {
595 wxMenu *m = new wxMenu;
596 news2->Append(ID_NEWNODE+arr.GetCount(), _("More..."), m);
597 news2 = m;
598 }
599 #else
600 if (i % 16 == 15) news2->Break();
601 #endif
602 }
603 popup->Append(ID_NEWNODE-1, _("New child"), news);
604 }
605 }
606
607
608 XmlTreeData *pardt =
609 (XmlTreeData*)(m_TreeCtrl->GetItemData(
610 m_TreeCtrl->GetParent(m_TreeCtrl->GetSelection())));
611 if (pardt && pardt->Node && pardt->Node != m_Resource->GetRoot())
612 {
613 wxXmlNode *nd = pardt->Node;
614 wxArrayString& arr =
615 NodeHandler::Find(NodeHandler::Find(nd)->GetRealNode(nd))->
616 GetChildTypes();
617
618 if (!arr.IsEmpty())
619 {
620 wxMenu *news = new wxMenu;
621 wxMenu *news2 = news;
622 for (size_t i = 0; i < arr.GetCount(); i++)
623 {
624 news2->Append(i + ID_NEWSYBNODE, arr[i]);
625 #ifdef __WXGTK__ // doesn't support Break
626 if (i % 20 == 19)
627 {
628 wxMenu *m = new wxMenu;
629 news2->Append(ID_NEWSYBNODE+arr.GetCount(), _("More..."), m);
630 news2 = m;
631 }
632 #else
633 if (i % 16 == 15) news2->Break();
634 #endif
635 }
636 popup->Append(ID_NEWSYBNODE-1, _("New sybling"), news);
637 }
638 }
639
640
641 popup->AppendSeparator();
642 popup->Append(ID_CUT, _("Cut"));
643 popup->Append(ID_COPY, _("Copy"));
644 popup->Append(ID_PASTE_SYBLING, _("Paste as sybling"));
645 popup->Append(ID_PASTE_CHILD, _("Paste as child"));
646 popup->AppendSeparator();
647 popup->Append(ID_DELETE_NODE, _("Delete"));
648 popup->Enable(ID_PASTE_SYBLING, m_Clipboard != NULL);
649 popup->Enable(ID_PASTE_CHILD, has_children && m_Clipboard != NULL);
650 }
651
652 m_TreeCtrl->PopupMenu(popup, pos);
653 delete popup;
654 }
655
656
657
658 void EditorFrame::OnClipboardAction(wxCommandEvent& event)
659 {
660 switch (event.GetId())
661 {
662 case ID_COPY:
663 case ID_CUT:
664 delete m_Clipboard;
665 m_Clipboard = new wxXmlNode(*m_SelectedNode);
666 GetMenuBar()->Enable(ID_PASTE_SYBLING, TRUE);
667 GetMenuBar()->Enable(ID_PASTE_CHILD, TRUE);
668 if (event.GetId() == ID_CUT) DeleteSelectedNode();
669 break;
670
671 case ID_PASTE_SYBLING:
672 {
673 XmlTreeData *pardt =
674 (XmlTreeData*)(m_TreeCtrl->GetItemData(
675 m_TreeCtrl->GetParent(m_TreeCtrl->GetSelection())));
676
677 if (pardt && pardt->Node && pardt->Node != m_Resource->GetRoot())
678 {
679 wxXmlNode *nd = pardt->Node;
680
681 wxXmlNode *realnode = NodeHandler::Find(nd)->GetRealNode(nd);
682 NodeHandler *hnd = NodeHandler::Find(realnode);
683 wxXmlNode *node = new wxXmlNode(*m_Clipboard);
684 hnd->InsertNode(realnode, node, m_SelectedNode);
685 wxTreeItemId root = m_TreeCtrl->GetSelection();
686 SelectNode(node, &root);
687 }
688 }
689 break;
690
691 case ID_PASTE_CHILD:
692 wxXmlNode *realnode = NodeHandler::Find(m_SelectedNode)->GetRealNode(m_SelectedNode);
693 NodeHandler *hnd = NodeHandler::Find(realnode);
694 wxXmlNode *node = new wxXmlNode(*m_Clipboard);
695 hnd->InsertNode(realnode, node);
696 wxTreeItemId root = m_TreeCtrl->GetSelection();
697 SelectNode(node, &root);
698 break;
699 }
700 }
701
702
703
704
705 bool EditorFrame::AskToSave()
706 // asks the user to save current document (if modified)
707 // returns FALSE if user cancelled the action, TRUE of he choosed
708 // 'yes' or 'no'
709 {
710 if (!m_Modified) return TRUE;
711
712 int res = wxMessageBox(_("File modified. Do you want to save changes?"), _("Save changes"),
713 wxYES_NO | wxCANCEL | wxCENTRE | wxICON_QUESTION);
714 if (res == wxYES)
715 SaveFile(m_FileName);
716 return (res != wxCANCEL);
717 }
718
719
720
721 void EditorFrame::OnCloseWindow(wxCloseEvent&)
722 {
723 if (!AskToSave()) return;
724 Destroy();
725 }