Mercurial > sumwars
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