Commit:  [33ma767c6dc3829bda8c0d46881547807809a05bbce
Author:  [32mSławomir Zborowski <slawomir.zborowski@nsn.com>
Date:    ([31m4 months ago[m) 2014-07-09 18:27:23 +0200
Subject:  #2642: Add Copy and Paste to the Edit menu in Atlas



diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp
index 0065c13..d30eac3 100644
--- a/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp
+++ b/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp
@@ -20,14 +20,17 @@
 #include "ScenarioEditor.h"
 
 #include "wx/busyinfo.h"
+#include "wx/clipbrd.h"
 #include "wx/config.h"
 #include "wx/dir.h"
 #include "wx/evtloop.h"
 #include "wx/ffile.h"
 #include "wx/filename.h"
 #include "wx/image.h"
+#include "wx/sstream.h"
 #include "wx/sysopt.h"
 #include "wx/tooltip.h"
+#include "wx/xml/xml.h"
 
 #include "General/AtlasEventLoop.h"
 #include "General/Datafile.h"
@@ -310,6 +313,9 @@ enum
 	ID_SaveAs,
 	ID_ImportHeightmap,
 
+    ID_Copy,
+    ID_Paste,
+
 	ID_Wireframe,
 	ID_MessageTrace,
 	ID_Screenshot,
@@ -338,6 +344,8 @@ BEGIN_EVENT_TABLE(ScenarioEditor, wxFrame)
 	EVT_MENU(ID_Quit, ScenarioEditor::OnQuit)
 	EVT_MENU(wxID_UNDO, ScenarioEditor::OnUndo)
 	EVT_MENU(wxID_REDO, ScenarioEditor::OnRedo)
+    EVT_MENU(ID_Copy, ScenarioEditor::OnCopy)
+    EVT_MENU(ID_Paste, ScenarioEditor::OnPaste)
 
 	EVT_MENU(ID_Wireframe, ScenarioEditor::OnWireframe)
 	EVT_MENU(ID_MessageTrace, ScenarioEditor::OnMessageTrace)
@@ -350,6 +358,8 @@ BEGIN_EVENT_TABLE(ScenarioEditor, wxFrame)
 	EVT_MENU(ID_RenderPathFixed, ScenarioEditor::OnRenderPath)
 	EVT_MENU(ID_RenderPathShader, ScenarioEditor::OnRenderPath)
 
+    EVT_MENU_OPEN(ScenarioEditor::OnMenuOpen)
+
 	EVT_IDLE(ScenarioEditor::OnIdle)
 END_EVENT_TABLE()
 
@@ -435,8 +445,15 @@ ScenarioEditor::ScenarioEditor(wxWindow* parent)
 	{
 		menuEdit->Append(wxID_UNDO, _("&Undo"));
 		menuEdit->Append(wxID_REDO, _("&Redo"));
+        menuEdit->AppendSeparator();
+        menuEdit->Append(ID_Copy, _("&Copy"));
+        menuEdit->Enable(ID_Copy, false);
+        menuEdit->Append(ID_Paste, _("&Paste"));
+        menuEdit->Enable(ID_Paste, false);
 	}
 
+    g_SelectedObjects.RegisterObserver(0, &ScenarioEditor::OnSelectedObjectsChange, this);
+
 	GetCommandProc().SetEditMenu(menuEdit);
 	GetCommandProc().Initialize();
 
@@ -621,6 +638,20 @@ void ScenarioEditor::OnRedo(wxCommandEvent&)
 	GetCommandProc().Redo();
 }
 
+void ScenarioEditor::OnCopy(wxCommandEvent& WXUNUSED(event))
+{
+    if (GetToolManager().GetCurrentToolName() == _T("TransformObject"))
+        GetToolManager().GetCurrentTool()->OnCommand(_T("copy"), NULL);
+}
+
+void ScenarioEditor::OnPaste(wxCommandEvent& WXUNUSED(event))
+{
+    if (GetToolManager().GetCurrentToolName() != _T("TransformObject"))
+        GetToolManager().SetCurrentTool(_T("TransformObject"), NULL);
+
+    GetToolManager().GetCurrentTool()->OnCommand(_T("paste"), NULL);
+}
+
 //////////////////////////////////////////////////////////////////////////
 
 void ScenarioEditor::OnNew(wxCommandEvent& WXUNUSED(event))
@@ -866,6 +897,54 @@ void ScenarioEditor::OnDumpState(wxCommandEvent& event)
 	}
 }
 
+void ScenarioEditor::OnSelectedObjectsChange(const std::vector<ObjectID>& selectedObjects)
+{
+    GetMenuBar()->Enable(ID_Copy, !selectedObjects.empty());
+}
+
+void ScenarioEditor::OnMenuOpen(wxMenuEvent& event)
+{
+    // This could be done far more elegantly if wxMenuItem had changeable id.
+    wxMenu* pasteMenuItem = NULL;
+    event.GetMenu()->FindItem(ID_Paste, &pasteMenuItem);
+
+    GetMenuBar()->Enable(ID_Paste, false);
+
+    if (!pasteMenuItem)
+        return;
+
+    wxString content;
+    if (wxTheClipboard->Open())
+    {
+        if (wxTheClipboard->IsSupported(wxDF_TEXT))
+        {
+            wxTextDataObject data;
+            wxTheClipboard->GetData(data);
+            content = data.GetText();
+        }
+
+        wxTheClipboard->Close();
+    }
+
+    if (content.empty())
+        return;
+
+    wxInputStream* is = new wxStringInputStream(content);
+    wxXmlDocument doc;
+    {
+        wxLogNull stopComplaining;
+        static_cast<void>(stopComplaining);
+        if (!doc.Load(*is))
+            return;
+    }
+
+    wxXmlNode* root = doc.GetRoot();
+    if (!root || root->GetName() != wxT("Entities"))
+        return;
+
+    GetMenuBar()->Enable(ID_Paste, true);
+}
+
 
 //////////////////////////////////////////////////////////////////////////
 
diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.h b/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.h
index e3c16ea..9eb95b8 100644
--- a/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.h
+++ b/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.h
@@ -46,6 +46,8 @@ public:
 	void OnQuit(wxCommandEvent& event);
 	void OnUndo(wxCommandEvent& event);
 	void OnRedo(wxCommandEvent& event);
+    void OnCopy(wxCommandEvent& event);
+    void OnPaste(wxCommandEvent& event);
 
 	void OnWireframe(wxCommandEvent& event);
 	void OnMessageTrace(wxCommandEvent& event);
@@ -55,6 +57,9 @@ public:
 	void OnCameraReset(wxCommandEvent& event);
 	void OnRenderPath(wxCommandEvent& event);
 	void OnDumpState(wxCommandEvent& event);
+    void OnSelectedObjectsChange(const std::vector<AtlasMessage::ObjectID>& selectedObjects);
+
+    void OnMenuOpen(wxMenuEvent& event);
 
 	bool OpenFile(const wxString& name, const wxString& filename);
 
diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Tools.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Tools.cpp
index 7327362..767a357 100644
--- a/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Tools.cpp
+++ b/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Tools.cpp
@@ -28,6 +28,7 @@ class DummyTool : public ITool
 	bool OnMouse(wxMouseEvent& WXUNUSED(evt)) { return false; }
 	bool OnKey(wxKeyEvent& WXUNUSED(evt), KeyEventType) { return false; }
 	void OnTick(float) {}
+    void OnCommand(const wxString& WXUNUSED(comand), void* WXUNUSED(userData)) {}
 } dummy;
 
 struct ToolManagerImpl
diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Tools.h b/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Tools.h
index de338f4..181666d 100644
--- a/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Tools.h
+++ b/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Tools.h
@@ -35,6 +35,7 @@ public:
 	virtual bool OnMouse(wxMouseEvent& evt) = 0; // return true if handled
 	virtual bool OnKey(wxKeyEvent& evt, KeyEventType dir) = 0; // return true if handled
 	virtual void OnTick(float dt) = 0; // dt in seconds
+    virtual void OnCommand(const wxString& command, void* userData) = 0;
 
 	virtual ~ITool() {};
 };
@@ -166,6 +167,10 @@ private:
 	{
 		m_CurrentState->OnTick(static_cast<T*>(this), dt);
 	}
+
+    virtual void OnCommand(const wxString& WXUNUSED(command), void* WXUNUSED(userData))
+    {
+    }
 };
 
 
diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/TransformObject.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/TransformObject.cpp
index 375e0c8..50f95b6 100644
--- a/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/TransformObject.cpp
+++ b/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/TransformObject.cpp
@@ -50,6 +50,14 @@ public:
 		SetState(&Waiting);
 	}
 
+    virtual void OnCommand(const wxString& command, void* WXUNUSED(userData))
+    {
+        if (command == _T("copy"))
+            OnCopy();
+        else if (command == _T("paste"))
+            OnPasteStart();
+    }
+
 	void OnDisable()
 	{
 		g_SelectedObjects.clear();
@@ -57,9 +65,26 @@ public:
 		POST_MESSAGE(SetSelectionPreview, (g_SelectedObjects));
 	}
 
+    bool OnCopy() const
+    {
+        if (g_SelectedObjects.empty())
+            return false;
+
+        AtlasMessage::qGetObjectMapSettings info(g_SelectedObjects);
+        info.Post();
+
+        if (wxTheClipboard->Open())
+        {
+            wxString text(info.xmldata.c_str());
+            wxTheClipboard->SetData(new wxTextDataObject(text));
+            wxTheClipboard->Close();
+        }
+
+        return true;
+    }
+
 	void OnPasteStart()
 	{
-		//PASTE
 		wxString entities;
 		if (wxTheClipboard->Open())
 		{
@@ -71,12 +96,8 @@ public:
 			}
 			wxTheClipboard->Close();
 		}
-		else
-		{
-			//TODO: Show something when the clipboard couldnt open
-		}
 
-		//First do we need to check if it is a correct xml string
+		// First do we need to check if it is a correct xml string
 		wxInputStream* is = new wxStringInputStream(entities);
 		wxXmlDocument doc;
 		if (!doc.Load(*is))
@@ -87,7 +108,7 @@ public:
 		if (root->GetName() != wxT("Entities"))
 			return;
 
-		//	Template, position,orientation
+		// Template, position,orientation
 		const wxXmlNode* child = root->GetChildren();
 
 		while (child)
@@ -95,11 +116,9 @@ public:
 			if (child->GetName() != wxT("Entity"))
 				return;
 
-			//TODO Validate all attributes
 			child = child->GetNext();
 		}
 
-		//Update selectedObjects??
 		g_SelectedObjects.clear();
 		POST_MESSAGE(SetSelectionPreview, (g_SelectedObjects));
 
@@ -329,26 +348,7 @@ public:
 			{
 				if (evt.GetKeyCode() == 'C')
 				{
-					if (!g_SelectedObjects.empty())
-					{
-						//COPY current selections
-						AtlasMessage::qGetObjectMapSettings info(g_SelectedObjects);
-						info.Post();
-
-						//In xmldata is the configuration
-						//now send to clipboard
-						if (wxTheClipboard->Open())
-						{
-							wxString text(info.xmldata.c_str());
-							wxTheClipboard->SetData(new wxTextDataObject(text));
-							wxTheClipboard->Close();
-						}
-						else
-						{
-							//TODO: Say something about couldnt open clipboard
-						}
-						return true;
-					}
+                    return obj->OnCopy();
 				}
 				else if (evt.GetKeyCode() == 'V')
 				{
