]>
Commit | Line | Data |
---|---|---|
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 | ||
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, | |
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 | ||
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) | |
2ada7c65 | 100 | EVT_MENU_RANGE(ID_CUT, ID_COPY, EditorFrame::OnClipboardAction) |
26607f41 | 101 | EVT_CLOSE(EditorFrame::OnCloseWindow) |
56d2f750 VS |
102 | END_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 | ||
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; | |
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 | ||
209 | EditorFrame::~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 | |
227 | void 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 | ||
254 | void 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 | ||
274 | void 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 | ||
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); | |
56d2f750 VS |
299 | } |
300 | ||
301 | ||
302 | ||
56d2f750 VS |
303 | void 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 | |
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 | ||
56d2f750 VS |
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 | { | |
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 | ||
372 | wxTreeItemId 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 | ||
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, | |
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 | 415 | void 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 | ||
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) | |
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 |
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 | ||
56d2f750 VS |
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 | ||
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 | ||
572 | void 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 | ||
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 | ||
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 | ||
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 | } |