#include "editor.h"
#include "nodehnd.h"
#include "xmlhelpr.h"
+#include "preview.h"
ID_EDITCODE,
ID_PROPSLIST,
ID_CLEARPROP,
+
+ ID_CUT,
+ ID_PASTE_SYBLING,
+ ID_PASTE_CHILD,
+ ID_COPY,
ID_NEWDIALOG,
ID_NEWPANEL,
EVT_TREE_SEL_CHANGED(ID_TREE, EditorFrame::OnTreeSel)
EVT_TOOL_RANGE(ID_PREVIEW, ID_EXIT, EditorFrame::OnToolbar)
EVT_MENU_RANGE(ID_NEWDIALOG, ID_NEWSYBNODE + 1000, EditorFrame::OnNewNode)
+ EVT_MENU_RANGE(ID_CUT, ID_COPY, EditorFrame::OnClipboardAction)
EVT_TEXT(ID_XMLIDEDIT, EditorFrame::OnXMLIDEdit)
EVT_BUTTON(ID_XMLIDPICK, EditorFrame::OnXMLIDPick)
EVT_BUTTON(ID_EDITCODE, EditorFrame::OnEditCode)
: wxFrame(parent, -1, filename + _("- wxWindows resources editor"))
{
ms_Instance = this;
+
+ m_Clipboard = NULL;
wxConfigBase *cfg = wxConfigBase::Get();
m_SelectedNode = NULL;
m_Resource = NULL;
m_FileName = wxEmptyString;
- m_Preview = NULL;
m_SelectedProp = -1;
wxMenu *menuFile = new wxMenu;
menuFile->Append(ID_SAVEAS, "Save &as...");
menuFile->AppendSeparator();
menuFile->Append(ID_EXIT, "E&xit\tAlt-X");
+
+ wxMenu *menuEdit = new wxMenu;
+ menuEdit->Append(ID_CUT, "Cut\tCtrl-X");
+ menuEdit->Append(ID_COPY, "Copy\tCtrl-C");
+ menuEdit->Append(ID_PASTE_SYBLING, "Paste as sybling\tCtrl-V");
+ menuEdit->Append(ID_PASTE_CHILD, "Paste as child");
+ menuEdit->AppendSeparator();
+ menuEdit->Append(ID_DELETE_NODE, "Delete");
+
+ menuEdit->Enable(ID_PASTE_SYBLING, FALSE);
+ menuEdit->Enable(ID_PASTE_CHILD, FALSE);
wxMenuBar *menuBar = new wxMenuBar();
menuBar->Append(menuFile, "&File");
+ menuBar->Append(menuEdit, "&Edit");
SetMenuBar(menuBar);
// handlers:
m_Handlers.DeleteContents(TRUE);
RegisterHandlers(".");
RegisterHandlers("./df");
- m_Handlers.Append(new NodeHandlerUnknown(this));
-
- #ifdef __UNIX__
+ // if modifying, don't forget to modify other places --
+ // search for wxINSTALL_PREFIX in nodehnd.cpp
+#ifdef __UNIX__
RegisterHandlers(wxGetHomeDir() + "/.wxrcedit");
- //FIXME - add $(prefix)/share/wx/wxrcedit
+ #ifdef wxINSTALL_PREFIX
+ RegisterHandlers(wxINSTALL_PREFIX "/share/wx/wxrcedit");
#endif
-
+#endif
+ // must stay last:
+ m_Handlers.Append(new NodeHandlerUnknown(this));
+
// Create toolbar:
wxToolBar *toolBar = CreateToolBar(wxNO_BORDER | wxTB_HORIZONTAL | wxTB_FLAT);
toolBar->SetMargins(2, 2);
EditorFrame::~EditorFrame()
{
+ PreviewFrame::Get()->Close();
+
wxConfigBase *cfg = wxConfigBase::Get();
cfg->Write("editor_x", (long)GetPosition().x);
delete m_ImgList;
delete m_ImgListProp;
RefreshProps(NULL);
+
+ delete m_Clipboard;
}
{
m_FileName = filename;
RefreshTree();
- SetTitle(m_FileName);
+ SetTitle("wxrcedit - " + wxFileNameFromPath(m_FileName));
}
}
void EditorFrame::SaveFile(const wxString& filename)
{
m_FileName = filename;
- SetTitle(filename);
+ SetTitle("wxrcedit - " + wxFileNameFromPath(m_FileName));
if (!m_Resource->Save(filename, wxXML_IO_LIBXML))
wxLogError("Error saving " + filename);
-void EditorFrame::RefreshPreview(wxXmlNode *node)
-{
- wxBusyCursor bcur;
- wxXmlResource *res = new wxXmlResource;
- wxString tempfile;
- wxPoint pos = wxDefaultPosition;
-
- while (node->GetParent() != m_Resource->GetRoot())
- node = node->GetParent();
-
- if (m_Preview) pos = m_Preview->GetPosition();
-
- res->InitAllHandlers();
-
- wxGetTempFileName("xmleditor", tempfile);
- m_Resource->Save(tempfile, wxXML_IO_BIN);
- res->Load(tempfile, wxXML_BINARY);
-
- if (node->GetName() == "dialog")
- {
- wxDialog *dlg = new wxDialog;
- if (res->LoadDialog(dlg, this, node->GetPropVal("name", "-1")))
- {
- if (pos.x != -1) dlg->Move(pos);
- dlg->Show(TRUE);
- if (m_Preview) m_Preview->Close(TRUE);
- m_Preview = dlg;
- m_Preview->SetFocus();
- }
- else
- {
- delete dlg;
- wxLogError(_("Cannot preview the dialog -- XML resource corrupted."));
- }
- }
- delete res;
- wxRemoveFile(tempfile);
-}
-
-
-
void EditorFrame::RefreshTree()
{
wxXmlNode *sel = m_SelectedNode;
m_TreeCtrl->DeleteAllItems();
- wxTreeItemId root = m_TreeCtrl->AddRoot("Resource: " + m_FileName, 5, 5);
+ wxTreeItemId root = m_TreeCtrl->AddRoot("Resource: " + wxFileNameFromPath(m_FileName), 5, 5);
wxXmlNode *n = m_Resource->GetRoot()->GetChildren();
while (n)
{
XmlTreeData* dt = (XmlTreeData*)m_TreeCtrl->GetItemData(m_TreeCtrl->GetSelection());;
if (dt != NULL && dt->Node != NULL)
- RefreshPreview(dt->Node);
+ PreviewFrame::Get()->Preview(dt->Node);
break;
}
case ID_DELETE_NODE :
{
- XmlTreeData *dt = (XmlTreeData*)
- (m_TreeCtrl->GetItemData(m_TreeCtrl->GetParent(m_TreeCtrl->GetSelection())));
- wxXmlNode *n = (dt) ? dt->Node : NULL;
-
- m_SelectedNode->GetParent()->RemoveChild(m_SelectedNode);
- NotifyChanged(CHANGED_TREE);
- SelectNode(n);
+ DeleteSelectedNode();
break;
}
}
+void EditorFrame::DeleteSelectedNode()
+{
+ XmlTreeData *dt = (XmlTreeData*)
+ (m_TreeCtrl->GetItemData(m_TreeCtrl->GetParent(m_TreeCtrl->GetSelection())));
+ wxXmlNode *n = (dt) ? dt->Node : NULL;
+
+ m_SelectedNode->GetParent()->RemoveChild(m_SelectedNode);
+ NotifyChanged(CHANGED_TREE);
+ SelectNode(n);
+}
+
+
+
void EditorFrame::OnNewNode(wxCommandEvent& event)
{
if (event.GetId() >= ID_NEWSYBNODE)
NodeHandler *hnd = FindHandler(realnode);
wxString name = hnd->GetChildTypes()[event.GetId()-ID_NEWSYBNODE];
- wxXmlNode *node = new wxXmlNode(wxXML_ELEMENT_NODE, name);
+ wxXmlNode *node = new wxXmlNode(wxXML_ELEMENT_NODE, _T("object"));
+ node->AddProperty(_T("class"), name);
+
hnd->InsertNode(realnode, node, m_SelectedNode);
wxTreeItemId root = m_TreeCtrl->GetSelection();
SelectNode(node, &root);
NodeHandler *hnd = FindHandler(realnode);
wxString name = hnd->GetChildTypes()[event.GetId()-ID_NEWNODE];
- wxXmlNode *node = new wxXmlNode(wxXML_ELEMENT_NODE, name);
+ wxXmlNode *node = new wxXmlNode(wxXML_ELEMENT_NODE, _T("object"));
+ node->AddProperty(_T("class"), name);
+
hnd->InsertNode(realnode, node);
wxTreeItemId root = m_TreeCtrl->GetSelection();
SelectNode(node, &root);
wxString name;
switch (event.GetId())
{
- case ID_NEWDIALOG : name = "dialog"; break;
- case ID_NEWPANEL : name = "panel"; break;
- case ID_NEWMENU : name = "menu"; break;
- case ID_NEWMENUBAR : name = "menubar"; break;
- case ID_NEWTOOLBAR : name = "toolbar"; break;
+ case ID_NEWDIALOG : name = _T("wxDialog"); break;
+ case ID_NEWPANEL : name = _T("wxPanel"); break;
+ case ID_NEWMENU : name = _T("wxMenu"); break;
+ case ID_NEWMENUBAR : name = _T("wxMenuBar"); break;
+ case ID_NEWTOOLBAR : name = _T("wxToolBar"); break;
default : return; // never occurs
}
- wxXmlNode *node = new wxXmlNode(wxXML_ELEMENT_NODE, name);
+ wxXmlNode *node = new wxXmlNode(wxXML_ELEMENT_NODE, _T("object"));
+ node->AddProperty(_T("class"), name);
m_Resource->GetRoot()->AddChild(node);
NotifyChanged(CHANGED_TREE);
SelectNode(node);
if (m_SelectedNode == NULL || m_SelectedNode == m_Resource->GetRoot())
{
- popup->Append(ID_NEWDIALOG, _("New dialog"));
- popup->Append(ID_NEWPANEL, _("New panel"));
- popup->Append(ID_NEWMENU, _("New menu"));
- popup->Append(ID_NEWMENUBAR, _("New menubar"));
- popup->Append(ID_NEWTOOLBAR, _("New toolbar"));
+ popup->Append(ID_NEWDIALOG, _("New wxDialog"));
+ popup->Append(ID_NEWPANEL, _("New wxPanel"));
+ popup->Append(ID_NEWMENU, _("New wxMenu"));
+ popup->Append(ID_NEWMENUBAR, _("New wxMenuBar"));
+ popup->Append(ID_NEWTOOLBAR, _("New wxToolBar"));
}
else
{
+ bool has_children;
{
wxArrayString& arr =
FindHandler(FindHandler(m_SelectedNode)->GetRealNode(m_SelectedNode))->
GetChildTypes();
+ has_children = !arr.IsEmpty();
if (!arr.IsEmpty())
{
wxMenu *news = new wxMenu;
+ wxMenu *news2 = news;
for (size_t i = 0; i < arr.GetCount(); i++)
{
- news->Append(i + ID_NEWNODE, arr[i]);
- if (i % 16 == 15) news->Break();
+ news2->Append(i + ID_NEWNODE, arr[i]);
+#ifdef __WXGTK__ // doesn't support Break
+ if (i % 20 == 19)
+ {
+ wxMenu *m = new wxMenu;
+ news2->Append(ID_NEWNODE+arr.GetCount(), _("More..."), m);
+ news2 = m;
+ }
+#else
+ if (i % 16 == 15) news2->Break();
+#endif
}
popup->Append(ID_NEWNODE-1, _("New child"), news);
}
if (!arr.IsEmpty())
{
wxMenu *news = new wxMenu;
+ wxMenu *news2 = news;
for (size_t i = 0; i < arr.GetCount(); i++)
{
- news->Append(i + ID_NEWSYBNODE, arr[i]);
- if (i % 16 == 15) news->Break();
+ news2->Append(i + ID_NEWSYBNODE, arr[i]);
+#ifdef __WXGTK__ // doesn't support Break
+ if (i % 20 == 19)
+ {
+ wxMenu *m = new wxMenu;
+ news2->Append(ID_NEWSYBNODE+arr.GetCount(), _("More..."), m);
+ news2 = m;
+ }
+#else
+ if (i % 16 == 15) news2->Break();
+#endif
}
popup->Append(ID_NEWSYBNODE-1, _("New sybling"), news);
}
}
+ popup->AppendSeparator();
+ popup->Append(ID_CUT, _("Cut"));
+ popup->Append(ID_COPY, _("Copy"));
+ popup->Append(ID_PASTE_SYBLING, _("Paste as sybling"));
+ popup->Append(ID_PASTE_CHILD, _("Paste as child"));
popup->AppendSeparator();
popup->Append(ID_DELETE_NODE, _("Delete"));
+ popup->Enable(ID_PASTE_SYBLING, m_Clipboard != NULL);
+ popup->Enable(ID_PASTE_CHILD, has_children && m_Clipboard != NULL);
}
m_TreeCtrl->PopupMenu(popup, pos);
delete popup;
}
+
+
+
+void EditorFrame::OnClipboardAction(wxCommandEvent& event)
+{
+ switch (event.GetId())
+ {
+ case ID_COPY:
+ case ID_CUT:
+ delete m_Clipboard;
+ m_Clipboard = new wxXmlNode(*m_SelectedNode);
+ GetMenuBar()->Enable(ID_PASTE_SYBLING, TRUE);
+ GetMenuBar()->Enable(ID_PASTE_CHILD, TRUE);
+ if (event.GetId() == ID_CUT) DeleteSelectedNode();
+ break;
+
+ case ID_PASTE_SYBLING:
+ {
+ XmlTreeData *pardt =
+ (XmlTreeData*)(m_TreeCtrl->GetItemData(
+ m_TreeCtrl->GetParent(m_TreeCtrl->GetSelection())));
+
+ if (pardt && pardt->Node && pardt->Node != m_Resource->GetRoot())
+ {
+ wxXmlNode *nd = pardt->Node;
+
+ wxXmlNode *realnode = FindHandler(nd)->GetRealNode(nd);
+ NodeHandler *hnd = FindHandler(realnode);
+ wxXmlNode *node = new wxXmlNode(*m_Clipboard);
+ hnd->InsertNode(realnode, node, m_SelectedNode);
+ wxTreeItemId root = m_TreeCtrl->GetSelection();
+ SelectNode(node, &root);
+ }
+ }
+ break;
+
+ case ID_PASTE_CHILD:
+ wxXmlNode *realnode = FindHandler(m_SelectedNode)->GetRealNode(m_SelectedNode);
+ NodeHandler *hnd = FindHandler(realnode);
+ wxXmlNode *node = new wxXmlNode(*m_Clipboard);
+ hnd->InsertNode(realnode, node);
+ wxTreeItemId root = m_TreeCtrl->GetSelection();
+ SelectNode(node, &root);
+ break;
+ }
+}
+