]> git.saurik.com Git - wxWidgets.git/blob - contrib/utils/wxrcedit/editor.cpp
Added a couple more numeric character references
[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 // change version:
259 wxXmlNode *root = m_Resource->GetRoot();
260 root->DeleteProperty(wxT("version"));
261 root->AddProperty(wxT("version"), wxT(WX_XMLRES_CURRENT_VERSION_STRING));
262
263 // save it:
264 if (!m_Resource->Save(filename))
265 wxLogError(_("Error saving ") + filename);
266 else
267 m_Modified = FALSE;
268
269 RefreshTitle();
270 }
271
272
273
274 void EditorFrame::NewFile()
275 {
276 if (!AskToSave()) return;
277
278 delete m_Resource;
279
280 m_FileName = "";
281 m_Resource = new wxXmlDocument;
282 m_Resource->SetRoot(new wxXmlNode(wxXML_ELEMENT_NODE, _("resource")));
283
284 m_Modified = FALSE;
285 RefreshTree();
286 RefreshTitle();
287 }
288
289
290
291 void EditorFrame::RefreshTitle()
292 {
293 wxString s;
294 if (m_Modified) s << _T("* ");
295 s << _("wxrcedit");
296 if (!m_FileName)
297 s << _T(" - ") << wxFileNameFromPath(m_FileName);
298 SetTitle(s);
299 }
300
301
302
303 void EditorFrame::RefreshTree()
304 {
305 wxXmlNode *sel = m_SelectedNode;
306
307 m_TreeCtrl->DeleteAllItems();
308 wxTreeItemId root = m_TreeCtrl->AddRoot("Resource: " + wxFileNameFromPath(m_FileName), 5, 5);
309
310 wxXmlNode *n = m_Resource->GetRoot()->GetChildren();
311 while (n)
312 {
313 if (n->GetType() == wxXML_ELEMENT_NODE)
314 CreateTreeNode(m_TreeCtrl, root, n);
315 n = n->GetNext();
316 }
317
318 m_TreeCtrl->Expand(root);
319 SelectNode(sel);
320 }
321
322
323
324
325 static void RecursivelyExpand(wxTreeCtrl *t, wxTreeItemId item)
326 {
327 t->Expand(item);
328 long cookie;
329 wxTreeItemId id = t->GetFirstChild(item, cookie);
330 while (id.IsOk())
331 {
332 RecursivelyExpand(t, id);
333 id = t->GetNextChild(item, cookie);
334 }
335 }
336
337 bool EditorFrame::SelectNode(wxXmlNode *node, wxTreeItemId *root)
338 {
339 if (root == NULL)
340 {
341 wxTreeItemId rootitem = m_TreeCtrl->GetRootItem();
342 return SelectNode(node, &rootitem);
343 }
344
345 wxTreeItemId item;
346 XmlTreeData *dt;
347 wxXmlNode *nd;
348 long cookie;
349
350 item = m_TreeCtrl->GetFirstChild(*root, cookie);
351 while (item.IsOk())
352 {
353 dt = (XmlTreeData*)(m_TreeCtrl->GetItemData(item));
354 nd = (dt) ? dt->Node : NULL;
355 if (nd == node)
356 {
357 RecursivelyExpand(m_TreeCtrl, *root);
358 m_TreeCtrl->SelectItem(item);
359 m_TreeCtrl->EnsureVisible(item);
360 return TRUE;
361 }
362 if (m_TreeCtrl->ItemHasChildren(item) && SelectNode(node, &item))
363 return TRUE;
364 item = m_TreeCtrl->GetNextChild(*root, cookie);
365 }
366
367 return FALSE;
368 }
369
370
371
372 wxTreeItemId EditorFrame::CreateTreeNode(wxTreeCtrl *treectrl, wxTreeItemId parent, wxXmlNode *node)
373 {
374 if (!node)
375 {
376 wxTreeItemId invalid;
377 return invalid;
378 }
379
380 return NodeHandler::Find(node)->CreateTreeNode(treectrl, parent, node);
381 }
382
383
384
385 void EditorFrame::NotifyChanged(int change_type)
386 {
387 if (change_type & CHANGED_TREE)
388 RefreshTree();
389
390 if (change_type & CHANGED_TREE_SELECTED)
391 {
392 wxTreeItemId sel = m_TreeCtrl->GetSelection();
393 m_TreeCtrl->SetItemText(sel,
394 NodeHandler::Find(m_SelectedNode)->GetTreeString(m_SelectedNode));
395 }
396
397 if (change_type & CHANGED_TREE_SELECTED_ICON)
398 {
399 wxTreeItemId sel = m_TreeCtrl->GetSelection();
400 int icon = NodeHandler::Find(m_SelectedNode)->GetTreeIcon(m_SelectedNode);
401 m_TreeCtrl->SetItemImage(sel, icon);
402 }
403
404 if (!m_Modified)
405 {
406 m_Modified = TRUE;
407 RefreshTitle();
408 }
409
410 PreviewFrame::Get()->MakeDirty();
411 }
412
413
414
415 void EditorFrame::OnTreeSel(wxTreeEvent& event)
416 {
417 XmlTreeData *dt = (XmlTreeData*)(m_TreeCtrl->GetItemData(event.GetItem()));
418 wxXmlNode *node = (dt) ? dt->Node : NULL;
419
420 m_SelectedNode = node;
421 if (node)
422 PropertiesFrame::Get()->ShowProps(node);
423
424 if (m_TreeCtrl->GetParent(event.GetItem()) == m_TreeCtrl->GetRootItem())
425 {
426 wxTreeItemId it = event.GetOldItem();
427
428 if (it.IsOk() && m_TreeCtrl->GetRootItem() != it)
429 {
430 while (m_TreeCtrl->GetParent(it) != m_TreeCtrl->GetRootItem())
431 it = m_TreeCtrl->GetParent(it);
432 m_TreeCtrl->Collapse(it);
433 }
434 RecursivelyExpand(m_TreeCtrl, event.GetItem());
435
436 PreviewFrame::Get()->Preview(node);
437 }
438 }
439
440
441
442 void EditorFrame::OnToolbar(wxCommandEvent& event)
443 {
444 switch (event.GetId())
445 {
446 case ID_PREVIEW :
447 {
448 XmlTreeData* dt = (XmlTreeData*)m_TreeCtrl->GetItemData(m_TreeCtrl->GetSelection());;
449 if (dt != NULL && dt->Node != NULL)
450 PreviewFrame::Get()->Preview(dt->Node);
451 break;
452 }
453
454 case ID_EXIT :
455 Close(TRUE);
456 break;
457
458 case ID_NEW :
459 NewFile();
460 break;
461
462 case ID_OPEN :
463 {
464 wxString cwd = wxGetCwd(); // workaround for 2.2
465 wxString name = wxFileSelector(_("Open XML resource"), _T(""), _T(""), _T(""), _("XML resources (*.xrc)|*.xrc"), wxOPEN | wxFILE_MUST_EXIST);
466 wxSetWorkingDirectory(cwd);
467 if (!name.IsEmpty())
468 LoadFile(name);
469 break;
470 }
471
472 case ID_SAVE :
473 if (m_FileName != "") { SaveFile(m_FileName); break;}
474 // else go to SAVEAS
475
476 case ID_SAVEAS :
477 {
478 wxString cwd = wxGetCwd(); // workaround for 2.2
479 wxString name = wxFileSelector(_("Save as"), _T(""), m_FileName, _T(""), _("XML resources (*.xrc)|*.xrc"), wxSAVE | wxOVERWRITE_PROMPT);
480 wxSetWorkingDirectory(cwd);
481 if (!name.IsEmpty())
482 SaveFile((m_FileName = name));
483 break;
484 }
485
486 case ID_DELETE_NODE :
487 {
488 DeleteSelectedNode();
489 break;
490 }
491 }
492 }
493
494
495
496 void EditorFrame::DeleteSelectedNode()
497 {
498 XmlTreeData *dt = (XmlTreeData*)
499 (m_TreeCtrl->GetItemData(m_TreeCtrl->GetParent(m_TreeCtrl->GetSelection())));
500 wxXmlNode *n = (dt) ? dt->Node : NULL;
501
502 m_SelectedNode->GetParent()->RemoveChild(m_SelectedNode);
503 NotifyChanged(CHANGED_TREE);
504 SelectNode(n);
505 }
506
507
508
509 void EditorFrame::OnNewNode(wxCommandEvent& event)
510 {
511 if (event.GetId() >= ID_NEWSYBNODE)
512 {
513 XmlTreeData *pardt =
514 (XmlTreeData*)(m_TreeCtrl->GetItemData(
515 m_TreeCtrl->GetParent(m_TreeCtrl->GetSelection())));
516
517 if (pardt && pardt->Node && pardt->Node != m_Resource->GetRoot())
518 {
519 wxXmlNode *nd = pardt->Node;
520
521 wxXmlNode *realnode = NodeHandler::Find(nd)->GetRealNode(nd);
522 NodeHandler *hnd = NodeHandler::Find(realnode);
523 wxString name = hnd->GetChildTypes()[event.GetId()-ID_NEWSYBNODE];
524
525 wxXmlNode *node = new wxXmlNode(wxXML_ELEMENT_NODE, _T("object"));
526 node->AddProperty(_T("class"), name);
527
528 hnd->InsertNode(realnode, node, m_SelectedNode);
529 wxTreeItemId root = m_TreeCtrl->GetSelection();
530 SelectNode(node, &root);
531 }
532
533 }
534
535 else if (event.GetId() >= ID_NEWNODE)
536 {
537 wxXmlNode *realnode = NodeHandler::Find(m_SelectedNode)->GetRealNode(m_SelectedNode);
538 NodeHandler *hnd = NodeHandler::Find(realnode);
539 wxString name = hnd->GetChildTypes()[event.GetId()-ID_NEWNODE];
540
541 wxXmlNode *node = new wxXmlNode(wxXML_ELEMENT_NODE, _T("object"));
542 node->AddProperty(_T("class"), name);
543
544 hnd->InsertNode(realnode, node);
545 wxTreeItemId root = m_TreeCtrl->GetSelection();
546 SelectNode(node, &root);
547 }
548
549 else
550 {
551 wxString name;
552 switch (event.GetId())
553 {
554 case ID_NEWDIALOG : name = _T("wxDialog"); break;
555 case ID_NEWPANEL : name = _T("wxPanel"); break;
556 case ID_NEWMENU : name = _T("wxMenu"); break;
557 case ID_NEWMENUBAR : name = _T("wxMenuBar"); break;
558 case ID_NEWTOOLBAR : name = _T("wxToolBar"); break;
559 default : return; // never occurs
560 }
561
562 wxXmlNode *node = new wxXmlNode(wxXML_ELEMENT_NODE, _T("object"));
563 node->AddProperty(_T("class"), name);
564 m_Resource->GetRoot()->AddChild(node);
565 NotifyChanged(CHANGED_TREE);
566 SelectNode(node);
567 }
568 }
569
570
571
572 void EditorFrame::OnRightClickTree(wxPoint pos)
573 {
574 wxMenu *popup = new wxMenu;
575
576 if (m_SelectedNode == NULL || m_SelectedNode == m_Resource->GetRoot())
577 {
578 popup->Append(ID_NEWDIALOG, _("New wxDialog"));
579 popup->Append(ID_NEWPANEL, _("New wxPanel"));
580 popup->Append(ID_NEWMENU, _("New wxMenu"));
581 popup->Append(ID_NEWMENUBAR, _("New wxMenuBar"));
582 popup->Append(ID_NEWTOOLBAR, _("New wxToolBar"));
583 }
584
585 else
586 {
587 bool has_children;
588 {
589 wxArrayString& arr =
590 NodeHandler::Find(NodeHandler::Find(m_SelectedNode)->GetRealNode(m_SelectedNode))->
591 GetChildTypes();
592
593 has_children = !arr.IsEmpty();
594 if (!arr.IsEmpty())
595 {
596 wxMenu *news = new wxMenu;
597 wxMenu *news2 = news;
598 for (size_t i = 0; i < arr.GetCount(); i++)
599 {
600 news2->Append(i + ID_NEWNODE, arr[i]);
601 #ifdef __WXGTK__ // doesn't support Break
602 if (i % 20 == 19)
603 {
604 wxMenu *m = new wxMenu;
605 news2->Append(ID_NEWNODE+arr.GetCount(), _("More..."), m);
606 news2 = m;
607 }
608 #else
609 if (i % 16 == 15) news2->Break();
610 #endif
611 }
612 popup->Append(ID_NEWNODE-1, _("New child"), news);
613 }
614 }
615
616
617 XmlTreeData *pardt =
618 (XmlTreeData*)(m_TreeCtrl->GetItemData(
619 m_TreeCtrl->GetParent(m_TreeCtrl->GetSelection())));
620 if (pardt && pardt->Node && pardt->Node != m_Resource->GetRoot())
621 {
622 wxXmlNode *nd = pardt->Node;
623 wxArrayString& arr =
624 NodeHandler::Find(NodeHandler::Find(nd)->GetRealNode(nd))->
625 GetChildTypes();
626
627 if (!arr.IsEmpty())
628 {
629 wxMenu *news = new wxMenu;
630 wxMenu *news2 = news;
631 for (size_t i = 0; i < arr.GetCount(); i++)
632 {
633 news2->Append(i + ID_NEWSYBNODE, arr[i]);
634 #ifdef __WXGTK__ // doesn't support Break
635 if (i % 20 == 19)
636 {
637 wxMenu *m = new wxMenu;
638 news2->Append(ID_NEWSYBNODE+arr.GetCount(), _("More..."), m);
639 news2 = m;
640 }
641 #else
642 if (i % 16 == 15) news2->Break();
643 #endif
644 }
645 popup->Append(ID_NEWSYBNODE-1, _("New sybling"), news);
646 }
647 }
648
649
650 popup->AppendSeparator();
651 popup->Append(ID_CUT, _("Cut"));
652 popup->Append(ID_COPY, _("Copy"));
653 popup->Append(ID_PASTE_SYBLING, _("Paste as sybling"));
654 popup->Append(ID_PASTE_CHILD, _("Paste as child"));
655 popup->AppendSeparator();
656 popup->Append(ID_DELETE_NODE, _("Delete"));
657 popup->Enable(ID_PASTE_SYBLING, m_Clipboard != NULL);
658 popup->Enable(ID_PASTE_CHILD, has_children && m_Clipboard != NULL);
659 }
660
661 m_TreeCtrl->PopupMenu(popup, pos);
662 delete popup;
663 }
664
665
666
667 void EditorFrame::OnClipboardAction(wxCommandEvent& event)
668 {
669 switch (event.GetId())
670 {
671 case ID_COPY:
672 case ID_CUT:
673 delete m_Clipboard;
674 m_Clipboard = new wxXmlNode(*m_SelectedNode);
675 GetMenuBar()->Enable(ID_PASTE_SYBLING, TRUE);
676 GetMenuBar()->Enable(ID_PASTE_CHILD, TRUE);
677 if (event.GetId() == ID_CUT) DeleteSelectedNode();
678 break;
679
680 case ID_PASTE_SYBLING:
681 {
682 XmlTreeData *pardt =
683 (XmlTreeData*)(m_TreeCtrl->GetItemData(
684 m_TreeCtrl->GetParent(m_TreeCtrl->GetSelection())));
685
686 if (pardt && pardt->Node && pardt->Node != m_Resource->GetRoot())
687 {
688 wxXmlNode *nd = pardt->Node;
689
690 wxXmlNode *realnode = NodeHandler::Find(nd)->GetRealNode(nd);
691 NodeHandler *hnd = NodeHandler::Find(realnode);
692 wxXmlNode *node = new wxXmlNode(*m_Clipboard);
693 hnd->InsertNode(realnode, node, m_SelectedNode);
694 wxTreeItemId root = m_TreeCtrl->GetSelection();
695 SelectNode(node, &root);
696 }
697 }
698 break;
699
700 case ID_PASTE_CHILD:
701 wxXmlNode *realnode = NodeHandler::Find(m_SelectedNode)->GetRealNode(m_SelectedNode);
702 NodeHandler *hnd = NodeHandler::Find(realnode);
703 wxXmlNode *node = new wxXmlNode(*m_Clipboard);
704 hnd->InsertNode(realnode, node);
705 wxTreeItemId root = m_TreeCtrl->GetSelection();
706 SelectNode(node, &root);
707 break;
708 }
709 }
710
711
712
713
714 bool EditorFrame::AskToSave()
715 // asks the user to save current document (if modified)
716 // returns FALSE if user cancelled the action, TRUE of he choosed
717 // 'yes' or 'no'
718 {
719 if (!m_Modified) return TRUE;
720
721 int res = wxMessageBox(_("File modified. Do you want to save changes?"), _("Save changes"),
722 wxYES_NO | wxCANCEL | wxCENTRE | wxICON_QUESTION);
723 if (res == wxYES)
724 SaveFile(m_FileName);
725 return (res != wxCANCEL);
726 }
727
728
729
730 void EditorFrame::OnCloseWindow(wxCloseEvent&)
731 {
732 if (!AskToSave()) return;
733 Destroy();
734 }