changeset 1974:a8008e932a7a

New utility class Clipboard (interacts with the host OS clipboard.) Note: only Windows code implemented for now; code paths for Linux/Apple are empty.
author thegusty999
date Fri, 28 Oct 2011 07:58:06 +0000
parents 84c63abcdf06
children 611a1ae4457b
files src/gui/clipboard.cpp src/gui/clipboard.h
diffstat 2 files changed, 367 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gui/clipboard.cpp	Fri Oct 28 07:58:06 2011 +0000
@@ -0,0 +1,281 @@
+#include "clipboard.h"
+
+#include "debug.h"
+
+#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
+#include "tchar.h"
+#endif
+
+template<> SWUtil::Clipboard* Ogre::Singleton<SWUtil::Clipboard>::ms_Singleton = 0;
+
+namespace SWUtil
+{
+
+	Clipboard::Clipboard ()
+	{
+		DEBUG ("Clipboard costructor!");
+	}
+
+
+	bool Clipboard::copy (bool cutInsteadOfCopy) 
+	{
+		DEBUG ("Reached Clipboard copy; cut? %d", cutInsteadOfCopy);
+		CEGUI::Window* sheet = CEGUI::System::getSingleton().getGUISheet();
+		if (!sheet) return false;
+
+		CEGUI::Window* active = sheet->getActiveChild();
+		if (!active) return false;
+
+		CEGUI::String seltext;
+		const CEGUI::String& type = active->getType();
+
+		if (type.find("/MultiLineEditbox") != CEGUI::String::npos)
+		{
+			CEGUI::MultiLineEditbox* edit = static_cast<CEGUI::MultiLineEditbox*>(active);
+			CEGUI::String::size_type beg = edit->getSelectionStartIndex();
+			CEGUI::String::size_type len = edit->getSelectionLength();
+			seltext = edit->getText().substr( beg, len ).c_str();
+
+			// are we cutting or just copying?
+			if (cutInsteadOfCopy) 
+			{
+				if (edit->isReadOnly())
+				{
+					return false;
+				}
+				CEGUI::String newtext = edit->getText();
+				edit->setText( newtext.erase( beg, len ) );
+			}
+
+		}
+		else if (type.find("/Editbox") != CEGUI::String::npos)
+		{
+			CEGUI::Editbox* edit = static_cast<CEGUI::Editbox*>(active);
+			CEGUI::String::size_type beg = edit->getSelectionStartIndex();
+			CEGUI::String::size_type len = edit->getSelectionLength();
+			seltext = edit->getText().substr( beg, len ).c_str();
+
+			// are we cutting or just copying?
+			if (cutInsteadOfCopy) 
+			{
+				if (edit->isReadOnly())
+				{
+					return false;
+				}
+				CEGUI::String newtext = edit->getText();
+				edit->setText( newtext.erase( beg, len ) );
+			}
+
+		}
+		else 
+		{
+			return false;
+		}
+
+		_copyToClipboard (std::string (seltext.c_str ()));
+		return true;
+	}
+	
+
+	bool Clipboard::cut ()
+	{
+		return copy (true);
+	}
+
+
+	bool Clipboard::paste ()
+	{
+		DEBUG ("Reached clipboard paste...");
+		
+		std::string clipboardContents = _readFromClipboard ();
+		DEBUG ("Got clipboard text to be: %s", clipboardContents.c_str ());
+
+		CEGUI::Window* sheet = CEGUI::System::getSingleton().getGUISheet();
+		if (!sheet) return false;
+
+		CEGUI::Window* active = sheet->getActiveChild();
+		if (!active) return false;
+
+		const CEGUI::String& type = active->getType();
+
+		if (type.find("/MultiLineEditbox") != CEGUI::String::npos)
+		{
+			CEGUI::MultiLineEditbox* edit = static_cast<CEGUI::MultiLineEditbox*>(active);
+			if (edit->isReadOnly())
+			{
+				return false;
+			}
+
+			// Check to see if some text is selected; if pasting from selected text, remove selected text first.
+
+			CEGUI::String::size_type beg = edit->getSelectionStartIndex ();
+			CEGUI::String::size_type len = edit->getSelectionLength ();
+			
+			if (len > 0)
+			{
+				CEGUI::String newtext = edit->getText();
+				edit->setText( newtext.erase( beg, len ) );
+			}
+
+			// Now paste the new text.
+			// TODO: not at end;
+			CEGUI::String newtext = edit->getText();
+			newtext.append (clipboardContents);
+			edit->setText( newtext.erase( beg, len ) );
+		}
+		else if (type.find("/Editbox") != CEGUI::String::npos)
+		{
+			CEGUI::Editbox* edit = static_cast<CEGUI::Editbox*>(active);
+			if (edit->isReadOnly())
+			{
+				return false;
+			}
+
+			// Check to see if some text is selected; if pasting from selected text, remove selected text first.
+			CEGUI::String::size_type beg = edit->getSelectionStartIndex ();
+			CEGUI::String::size_type len = edit->getSelectionLength ();
+			if (len > 0)
+			{
+				CEGUI::String newtext = edit->getText();
+				edit->setText( newtext.erase( beg, len ) );
+			}
+			
+			DEBUG ("Selection start idx: %d", beg);
+
+			// Now paste the new text.
+			CEGUI::String newtext = edit->getText();
+			newtext.insert (beg, clipboardContents);
+			edit->setText (newtext);
+
+			// Also update the caret location, so that it is behind the pasted text.
+			edit->setCaratIndex (beg + clipboardContents.length ());
+
+			DEBUG ("updated edit box contents");
+		}
+		else 
+		{
+			return false;
+		}
+		return true;
+	}
+
+
+
+	bool Clipboard::_copyToClipboard (const std::string& textToCopy)
+	{
+		// Used as source example: http://msdn.microsoft.com/en-us/library/windows/desktop/ms649016%28v=vs.85%29.aspx#_win32_Copying_Information_to_the_Clipboard
+
+#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
+		// Open the clipboard for examination and prevent other applications from modifying the clipboard content.
+		// Sending the parameter to 0 (NULL), means that the open clipboard is associated with the current task. 
+		if (! OpenClipboard (0))
+		{
+			ERRORMSG ("Could not open clipboard");
+			return false;
+		}
+
+		if (! EmptyClipboard ())
+		{
+			ERRORMSG ("Could not empty clipboard");
+			CloseClipboard ();
+			return false;
+		}
+
+		HGLOBAL hglbText;
+
+		// TODO: check whether WCHAR is more appropriate (for unicode).
+		hglbText = GlobalAlloc (GMEM_MOVEABLE, (textToCopy.length () + 1) * sizeof(TCHAR)); 
+        if (hglbText == NULL) 
+        { 
+            CloseClipboard ();
+            return false; 
+        }
+
+		// Lock the handle and copy the text to the buffer. 
+ 
+		LPTSTR  lptstrText = 0;
+		lptstrText = (LPTSTR) GlobalLock (hglbText);
+		memcpy (lptstrText, textToCopy.data (), textToCopy.length () * sizeof(TCHAR)); 
+		lptstrText[textToCopy.length ()] = (TCHAR) 0;    // null character 
+
+		// Unlock the handle.
+		GlobalUnlock (hglbText); 
+
+		// Set the clipboard data.
+		SetClipboardData (CF_TEXT, hglbText);
+
+		// Regular clipboard close.
+		CloseClipboard ();
+
+#elif OGRE_PLATFORM == OGRE_PLATFORM_APPLE
+		return false;
+#elif OGRE_PLATFORM == OGRE_PLATFORM_LINUX
+		return false;
+#endif
+		return true;
+	}
+
+
+	/**
+	* \brief Internal operation of reading text from clipboard.
+	*/
+	std::string Clipboard::_readFromClipboard () const
+	{
+		std::string returnValue ("");
+
+#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
+
+		// Only allow pasting of text, no other data.
+		if (!IsClipboardFormatAvailable(CF_TEXT)) 
+		{
+			return returnValue; 
+		}
+
+		// Open the clipboard for examination and prevent other applications from modifying the clipboard content.
+		// Sending the parameter to 0 (NULL), means that the open clipboard is associated with the current task. 
+		if (! OpenClipboard (0))
+		{
+			ERRORMSG ("Could not open clipboard");
+			return returnValue;
+		}
+
+		HGLOBAL hglbText;
+		LPTSTR    lptstrText; 
+		hglbText = GetClipboardData (CF_TEXT); 
+		if (hglbText != NULL) 
+		{ 
+			lptstrText = (LPTSTR) GlobalLock (hglbText); 
+			if (lptstrText != NULL) 
+			{ 
+				// Call the application-defined ReplaceSelection 
+				// function to insert the text and repaint the 
+				// window. 
+ 
+				int len = _tcslen (lptstrText);
+				
+				// TODO: this is an arbitrarily chosen hard-coded limit; should make the component more configurable.
+				// Should also take into account the first newline maybe (and stop parsing there).
+				if (len > 500) 
+				{
+					returnValue = "too much data!";
+				}
+				else
+				{
+					returnValue = lptstrText;
+				}
+				GlobalUnlock (hglbText); 
+			} 
+		} 
+
+		// Regular clipboard close.
+		CloseClipboard();
+
+#elif OGRE_PLATFORM == OGRE_PLATFORM_APPLE
+#elif OGRE_PLATFORM == OGRE_PLATFORM_LINUX
+#endif
+
+		return returnValue;
+	}
+
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gui/clipboard.h	Fri Oct 28 07:58:06 2011 +0000
@@ -0,0 +1,86 @@
+/*
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef CLIPBOARD_H
+#define CLIPBOARD_H
+
+// The used singleton manager.
+#include "OgreSingleton.h"
+
+// CEGUI includes
+#include "CEGUI/CEGUI.h"
+
+#include <string>
+
+/**
+ * \brief Summoning Wars Utility namespace.
+ */
+namespace SWUtil
+{
+	/**
+	 * \brief Class to interract with the OS clipboard.
+	 * Initial commit: Augustin Preda, 2011.10.28... (man I hope this gets updated sometimes soom :)
+	 */
+	class Clipboard
+		: public Ogre::Singleton <Clipboard>
+	{
+	public:
+		/**
+		 * \brief Constructor.
+		 */
+		Clipboard ();
+
+		/**
+		 * \brief Copy operation (from CEGUI control into clipboard).
+		 * \return true if operation was successful, false otherwise.
+		 */
+		virtual bool copy (bool cutInsteadOfCopy = false);
+
+		/**
+		 * \brief Cut operation (from CEGUI control into clipboard).
+		 * \return true if operation was successful, false otherwise.
+		 */
+		virtual bool cut ();
+
+		/**
+		 * \brief Paste operation (from clipboard into CEGUI control).
+		 * \return true if operation was successful, false otherwise.
+		 */
+		virtual bool paste ();
+
+	protected:
+
+
+		/**
+		 * \brief Internal operation of writing text to clipboard.
+		 * This will be OS dependent, so the functionality may not be supported on all systems!
+		 * 
+		 * \param textToCopy The text to copy to the clipboard.
+		 * \return true if operation was successful, false otherwise.
+		 */
+		bool _copyToClipboard (const std::string& textToCopy);
+
+		/**
+		 * \brief Internal operation of reading text from clipboard.
+		 * This will be OS dependent, so the functionality may not be supported on all systems!
+		 *
+		 * \return string contained in clipboard, empty string if operation was unsuccessful.
+		 */
+		std::string _readFromClipboard () const;
+	};
+
+
+}
+#endif //CLIPBOARD_H