]> git.saurik.com Git - wxWidgets.git/blame - contrib/utils/wxrcedit/editor.cpp
fixed 'patch' #422993 (Error in wxConfigBase::Write for doubles)
[wxWidgets.git] / contrib / utils / wxrcedit / editor.cpp
CommitLineData
56d2f750
VS
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"
35a0184e
VS
27#include "wx/listctrl.h"
28#include "wx/imaglist.h"
56d2f750
VS
29
30#include "treedt.h"
31#include "editor.h"
32#include "nodehnd.h"
33#include "xmlhelpr.h"
e066e256 34#include "preview.h"
12d9e308 35#include "propframe.h"
56d2f750
VS
36
37
38
39class 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
61BEGIN_EVENT_TABLE(EditorTreeCtrl, wxTreeCtrl)
62 EVT_RIGHT_DOWN(EditorTreeCtrl::OnRightClick)
63END_EVENT_TABLE()
64
65
66enum
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,
2ada7c65
VS
77
78 ID_CUT,
79 ID_PASTE_SYBLING,
80 ID_PASTE_CHILD,
81 ID_COPY,
56d2f750
VS
82
83 ID_NEWDIALOG,
84 ID_NEWPANEL,
85 ID_NEWMENU,
86 ID_NEWMENUBAR,
87 ID_NEWTOOLBAR,
12d9e308
VS
88 ID_NEWNODE = wxID_HIGHEST + 10000, // safely out of XMLID range :)
89 ID_NEWSYBNODE = ID_NEWNODE + 20000
56d2f750
VS
90};
91
56d2f750
VS
92
93
94
95
96BEGIN_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)
2ada7c65 100 EVT_MENU_RANGE(ID_CUT, ID_COPY, EditorFrame::OnClipboardAction)
26607f41 101 EVT_CLOSE(EditorFrame::OnCloseWindow)
56d2f750
VS
102END_EVENT_TABLE()
103
104
105
7f393832 106#if defined(__UNIX__)
56d2f750
VS
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"
35a0184e
VS
116#include "bitmaps/gsizer.xpm"
117#include "bitmaps/resicon.xpm"
56d2f750
VS
118#endif
119
120
121
122EditorFrame *EditorFrame::ms_Instance = NULL;
123
124EditorFrame::EditorFrame(wxFrame *parent, const wxString& filename)
125 : wxFrame(parent, -1, filename + _("- wxWindows resources editor"))
126{
127 ms_Instance = this;
2ada7c65
VS
128
129 m_Clipboard = NULL;
26607f41 130 m_Modified = FALSE;
56d2f750
VS
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;
56d2f750
VS
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");
2ada7c65
VS
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);
56d2f750
VS
159
160 wxMenuBar *menuBar = new wxMenuBar();
161 menuBar->Append(menuFile, "&File");
2ada7c65 162 menuBar->Append(menuEdit, "&Edit");
56d2f750 163 SetMenuBar(menuBar);
2ada7c65 164
56d2f750
VS
165 // Create toolbar:
166 wxToolBar *toolBar = CreateToolBar(wxNO_BORDER | wxTB_HORIZONTAL | wxTB_FLAT);
167 toolBar->SetMargins(2, 2);
35a0184e 168 toolBar->SetToolBitmapSize(wxSize(24, 24));
56d2f750
VS
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();
56d2f750 182
12d9e308 183 wxSizer *sizer = new wxBoxSizer(wxHORIZONTAL);
56d2f750 184
12d9e308
VS
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);
56d2f750
VS
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
209EditorFrame::~EditorFrame()
210{
e066e256 211 PreviewFrame::Get()->Close();
12d9e308 212 PropertiesFrame::Get()->Close();
e066e256 213
56d2f750
VS
214 wxConfigBase *cfg = wxConfigBase::Get();
215
12d9e308
VS
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
2ada7c65 221 delete m_Clipboard;
56d2f750
VS
222}
223
224
225
56d2f750
VS
226
227void EditorFrame::LoadFile(const wxString& filename)
228{
26607f41
VS
229 if (!AskToSave()) return;
230
56d2f750
VS
231 delete m_Resource;
232
233 m_FileName = "";
234 m_Resource = new wxXmlDocument;
26607f41 235 m_Modified = FALSE;
56d2f750
VS
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();
56d2f750 248 }
26607f41 249 RefreshTitle();
56d2f750
VS
250}
251
252
253
254void EditorFrame::SaveFile(const wxString& filename)
255{
256 m_FileName = filename;
ccb22060
VS
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:
75e01429 264 if (!m_Resource->Save(filename))
26607f41
VS
265 wxLogError(_("Error saving ") + filename);
266 else
267 m_Modified = FALSE;
268
269 RefreshTitle();
56d2f750
VS
270}
271
272
273
274void EditorFrame::NewFile()
275{
26607f41
VS
276 if (!AskToSave()) return;
277
56d2f750
VS
278 delete m_Resource;
279
280 m_FileName = "";
281 m_Resource = new wxXmlDocument;
26607f41 282 m_Resource->SetRoot(new wxXmlNode(wxXML_ELEMENT_NODE, _("resource")));
56d2f750 283
26607f41 284 m_Modified = FALSE;
56d2f750 285 RefreshTree();
26607f41
VS
286 RefreshTitle();
287}
288
289
290
291void 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);
56d2f750
VS
299}
300
301
302
56d2f750
VS
303void EditorFrame::RefreshTree()
304{
305 wxXmlNode *sel = m_SelectedNode;
306
307 m_TreeCtrl->DeleteAllItems();
2ada7c65 308 wxTreeItemId root = m_TreeCtrl->AddRoot("Resource: " + wxFileNameFromPath(m_FileName), 5, 5);
56d2f750
VS
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
56d2f750 323
93548148
VS
324
325static 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
56d2f750
VS
337bool 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 {
93548148 357 RecursivelyExpand(m_TreeCtrl, *root);
56d2f750
VS
358 m_TreeCtrl->SelectItem(item);
359 m_TreeCtrl->EnsureVisible(item);
93548148 360 return TRUE;
56d2f750
VS
361 }
362 if (m_TreeCtrl->ItemHasChildren(item) && SelectNode(node, &item))
93548148 363 return TRUE;
56d2f750
VS
364 item = m_TreeCtrl->GetNextChild(*root, cookie);
365 }
93548148 366
56d2f750
VS
367 return FALSE;
368}
369
370
371
372wxTreeItemId EditorFrame::CreateTreeNode(wxTreeCtrl *treectrl, wxTreeItemId parent, wxXmlNode *node)
373{
374 if (!node)
375 {
376 wxTreeItemId invalid;
377 return invalid;
378 }
379
12d9e308 380 return NodeHandler::Find(node)->CreateTreeNode(treectrl, parent, node);
56d2f750
VS
381}
382
383
384
385void 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,
12d9e308 394 NodeHandler::Find(m_SelectedNode)->GetTreeString(m_SelectedNode));
56d2f750
VS
395 }
396
397 if (change_type & CHANGED_TREE_SELECTED_ICON)
398 {
399 wxTreeItemId sel = m_TreeCtrl->GetSelection();
12d9e308 400 int icon = NodeHandler::Find(m_SelectedNode)->GetTreeIcon(m_SelectedNode);
56d2f750
VS
401 m_TreeCtrl->SetItemImage(sel, icon);
402 }
26607f41
VS
403
404 if (!m_Modified)
405 {
406 m_Modified = TRUE;
407 RefreshTitle();
408 }
409
410 PreviewFrame::Get()->MakeDirty();
56d2f750
VS
411}
412
413
414
12d9e308 415void EditorFrame::OnTreeSel(wxTreeEvent& event)
56d2f750 416{
12d9e308
VS
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);
56d2f750 423
12d9e308 424 if (m_TreeCtrl->GetParent(event.GetItem()) == m_TreeCtrl->GetRootItem())
56d2f750 425 {
12d9e308 426 wxTreeItemId it = event.GetOldItem();
56d2f750 427
12d9e308 428 if (it.IsOk() && m_TreeCtrl->GetRootItem() != it)
56d2f750 429 {
12d9e308
VS
430 while (m_TreeCtrl->GetParent(it) != m_TreeCtrl->GetRootItem())
431 it = m_TreeCtrl->GetParent(it);
432 m_TreeCtrl->Collapse(it);
56d2f750 433 }
12d9e308 434 RecursivelyExpand(m_TreeCtrl, event.GetItem());
56d2f750 435
12d9e308
VS
436 PreviewFrame::Get()->Preview(node);
437 }
56d2f750
VS
438}
439
440
441
442void 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)
e066e256 450 PreviewFrame::Get()->Preview(dt->Node);
56d2f750
VS
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 {
26607f41 464 wxString cwd = wxGetCwd(); // workaround for 2.2
12d9e308 465 wxString name = wxFileSelector(_("Open XML resource"), _T(""), _T(""), _T(""), _("XML resources (*.xrc)|*.xrc"), wxOPEN | wxFILE_MUST_EXIST);
26607f41 466 wxSetWorkingDirectory(cwd);
56d2f750
VS
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 {
26607f41 478 wxString cwd = wxGetCwd(); // workaround for 2.2
12d9e308 479 wxString name = wxFileSelector(_("Save as"), _T(""), m_FileName, _T(""), _("XML resources (*.xrc)|*.xrc"), wxSAVE | wxOVERWRITE_PROMPT);
26607f41 480 wxSetWorkingDirectory(cwd);
56d2f750
VS
481 if (!name.IsEmpty())
482 SaveFile((m_FileName = name));
483 break;
484 }
485
486 case ID_DELETE_NODE :
487 {
2ada7c65 488 DeleteSelectedNode();
56d2f750
VS
489 break;
490 }
491 }
492}
493
494
495
2ada7c65
VS
496void 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
56d2f750
VS
509void 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
12d9e308
VS
521 wxXmlNode *realnode = NodeHandler::Find(nd)->GetRealNode(nd);
522 NodeHandler *hnd = NodeHandler::Find(realnode);
56d2f750
VS
523 wxString name = hnd->GetChildTypes()[event.GetId()-ID_NEWSYBNODE];
524
e066e256
VS
525 wxXmlNode *node = new wxXmlNode(wxXML_ELEMENT_NODE, _T("object"));
526 node->AddProperty(_T("class"), name);
527
56d2f750
VS
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 {
12d9e308
VS
537 wxXmlNode *realnode = NodeHandler::Find(m_SelectedNode)->GetRealNode(m_SelectedNode);
538 NodeHandler *hnd = NodeHandler::Find(realnode);
56d2f750
VS
539 wxString name = hnd->GetChildTypes()[event.GetId()-ID_NEWNODE];
540
e066e256
VS
541 wxXmlNode *node = new wxXmlNode(wxXML_ELEMENT_NODE, _T("object"));
542 node->AddProperty(_T("class"), name);
543
56d2f750
VS
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 {
e066e256
VS
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;
56d2f750
VS
559 default : return; // never occurs
560 }
561
e066e256
VS
562 wxXmlNode *node = new wxXmlNode(wxXML_ELEMENT_NODE, _T("object"));
563 node->AddProperty(_T("class"), name);
56d2f750
VS
564 m_Resource->GetRoot()->AddChild(node);
565 NotifyChanged(CHANGED_TREE);
566 SelectNode(node);
567 }
568}
569
570
571
572void EditorFrame::OnRightClickTree(wxPoint pos)
573{
574 wxMenu *popup = new wxMenu;
575
576 if (m_SelectedNode == NULL || m_SelectedNode == m_Resource->GetRoot())
577 {
e066e256
VS
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"));
56d2f750
VS
583 }
584
585 else
586 {
2ada7c65 587 bool has_children;
56d2f750
VS
588 {
589 wxArrayString& arr =
12d9e308 590 NodeHandler::Find(NodeHandler::Find(m_SelectedNode)->GetRealNode(m_SelectedNode))->
56d2f750
VS
591 GetChildTypes();
592
2ada7c65 593 has_children = !arr.IsEmpty();
56d2f750
VS
594 if (!arr.IsEmpty())
595 {
596 wxMenu *news = new wxMenu;
e066e256 597 wxMenu *news2 = news;
56d2f750
VS
598 for (size_t i = 0; i < arr.GetCount(); i++)
599 {
e066e256
VS
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
56d2f750
VS
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 =
12d9e308 624 NodeHandler::Find(NodeHandler::Find(nd)->GetRealNode(nd))->
56d2f750
VS
625 GetChildTypes();
626
627 if (!arr.IsEmpty())
628 {
629 wxMenu *news = new wxMenu;
e066e256 630 wxMenu *news2 = news;
56d2f750
VS
631 for (size_t i = 0; i < arr.GetCount(); i++)
632 {
e066e256
VS
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
56d2f750
VS
644 }
645 popup->Append(ID_NEWSYBNODE-1, _("New sybling"), news);
646 }
647 }
648
649
2ada7c65 650 popup->AppendSeparator();
e066e256
VS
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"));
56d2f750
VS
655 popup->AppendSeparator();
656 popup->Append(ID_DELETE_NODE, _("Delete"));
2ada7c65
VS
657 popup->Enable(ID_PASTE_SYBLING, m_Clipboard != NULL);
658 popup->Enable(ID_PASTE_CHILD, has_children && m_Clipboard != NULL);
56d2f750
VS
659 }
660
661 m_TreeCtrl->PopupMenu(popup, pos);
662 delete popup;
663}
2ada7c65
VS
664
665
666
667void 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
12d9e308
VS
690 wxXmlNode *realnode = NodeHandler::Find(nd)->GetRealNode(nd);
691 NodeHandler *hnd = NodeHandler::Find(realnode);
2ada7c65
VS
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:
12d9e308
VS
701 wxXmlNode *realnode = NodeHandler::Find(m_SelectedNode)->GetRealNode(m_SelectedNode);
702 NodeHandler *hnd = NodeHandler::Find(realnode);
2ada7c65
VS
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
26607f41
VS
711
712
713
714bool 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
730void EditorFrame::OnCloseWindow(wxCloseEvent&)
731{
732 if (!AskToSave()) return;
733 Destroy();
734}