From d8dd19e093575c2ee54ebe8ac8dce69f537d28fb Mon Sep 17 00:00:00 2001 From: Bartek Bok Date: Mon, 27 Feb 2012 21:05:36 +0100 Subject: [PATCH] Basic clipboard functionality --- Sources/Plasma/Apps/plClient/CMakeLists.txt | 1 + .../pfGameGUIMgr/pfGUIEditBoxMod.cpp | 25 ++++ .../pfGameGUIMgr/pfGUIMultiLineEditCtrl.cpp | 23 +++- Sources/Plasma/PubUtilLib/CMakeLists.txt | 1 + .../PubUtilLib/plClipboard/CMakeLists.txt | 17 +++ .../PubUtilLib/plClipboard/plClipboard.cpp | 115 ++++++++++++++++++ .../PubUtilLib/plClipboard/plClipboard.h | 64 ++++++++++ 7 files changed, 241 insertions(+), 5 deletions(-) create mode 100755 Sources/Plasma/PubUtilLib/plClipboard/CMakeLists.txt create mode 100755 Sources/Plasma/PubUtilLib/plClipboard/plClipboard.cpp create mode 100755 Sources/Plasma/PubUtilLib/plClipboard/plClipboard.h diff --git a/Sources/Plasma/Apps/plClient/CMakeLists.txt b/Sources/Plasma/Apps/plClient/CMakeLists.txt index 9a5bf0fa..c38be9da 100644 --- a/Sources/Plasma/Apps/plClient/CMakeLists.txt +++ b/Sources/Plasma/Apps/plClient/CMakeLists.txt @@ -97,6 +97,7 @@ target_link_libraries(plClient plAudio) target_link_libraries(plClient plAudioCore) target_link_libraries(plClient plAvatar) target_link_libraries(plClient plClientResMgr) +target_link_libraries(plClient plClipboard) #target_link_libraries(plClient plClientKey) target_link_libraries(plClient plCompression) target_link_libraries(plClient plContainer) diff --git a/Sources/Plasma/FeatureLib/pfGameGUIMgr/pfGUIEditBoxMod.cpp b/Sources/Plasma/FeatureLib/pfGameGUIMgr/pfGUIEditBoxMod.cpp index 7b6e8880..ea225a10 100644 --- a/Sources/Plasma/FeatureLib/pfGameGUIMgr/pfGUIEditBoxMod.cpp +++ b/Sources/Plasma/FeatureLib/pfGameGUIMgr/pfGUIEditBoxMod.cpp @@ -61,6 +61,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include "plgDispatch.h" #include "hsResMgr.h" #include "pnInputCore/plKeyMap.h" +#include "plClipboard/plClipboard.h" #include @@ -387,6 +388,30 @@ hsBool pfGUIEditBoxMod::HandleKeyEvent( pfGameGUIMgr::EventType event, plKeyDef DoSomething(); // Query WasEscaped() to see if it was escape vs enter return true; } + else if (modifiers & pfGameGUIMgr::kCtrlDown) + { + if (key == KEY_C) + { + plClipboard::GetInstance().SetClipboardText(_TEMP_CONVERT_FROM_WCHAR_T(fBuffer)); + } + else if (key == KEY_V) + { + plString contents = plClipboard::GetInstance().GetClipboardText(); + plStringBuffer tmp = contents.ToWchar(); + size_t len = tmp.GetSize(); + if (len > 0) { + --len; //skip \0 on end + wchar_t* insertTarget = fBuffer + fCursorPos; + size_t bufferTailLen = wcslen(insertTarget); + if (fCursorPos + len + bufferTailLen < fBufferSize) { + memmove(insertTarget + len, insertTarget, bufferTailLen * sizeof(wchar_t)); + memcpy(insertTarget, tmp.GetData(), len * sizeof(wchar_t)); + fCursorPos += len; + HandleExtendedEvent( kValueChanging ); + } + } + } + } else { fIgnoreNextKey = false; diff --git a/Sources/Plasma/FeatureLib/pfGameGUIMgr/pfGUIMultiLineEditCtrl.cpp b/Sources/Plasma/FeatureLib/pfGameGUIMgr/pfGUIMultiLineEditCtrl.cpp index ffd54868..959b7d6d 100644 --- a/Sources/Plasma/FeatureLib/pfGameGUIMgr/pfGUIMultiLineEditCtrl.cpp +++ b/Sources/Plasma/FeatureLib/pfGameGUIMgr/pfGUIMultiLineEditCtrl.cpp @@ -60,7 +60,8 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include "plGImage/plDynamicTextMap.h" #include "plgDispatch.h" #include "hsResMgr.h" - +#include "plClipboard/plClipboard.h" +#include "plString.h" //// Tiny Helper Class /////////////////////////////////////////////////////// @@ -1067,9 +1068,6 @@ hsBool pfGUIMultiLineEditCtrl::HandleKeyEvent( pfGameGUIMgr::EventType event, p if ((fPrevCtrl || fNextCtrl) && (fLineStarts.GetCount() <= GetFirstVisibleLine())) return true; // we're ignoring if we can't actually edit our visible frame (and we're linked) - if (modifiers & pfGameGUIMgr::kCtrlDown) - return true; // we're ignoring ctrl key events - if( event == pfGameGUIMgr::kKeyDown || event == pfGameGUIMgr::kKeyRepeat ) { // Use arrow keys to do our dirty work @@ -1109,13 +1107,28 @@ hsBool pfGUIMultiLineEditCtrl::HandleKeyEvent( pfGameGUIMgr::EventType event, p DeleteChar(); } - else if( key == KEY_ENTER ) + else if( key == KEY_ENTER ) { if( IsLocked() ) return true; InsertChar('\n'); } + else if (modifiers & pfGameGUIMgr::kCtrlDown) + { + // Not exactly safe way to do it, since there are control codes inside buffer. + // But what's the worst thing that can happen? Horribly colorful ki-mails? + // Too lazy to worry about that... + if (key == KEY_C) + { + plClipboard::GetInstance().SetClipboardText(_TEMP_CONVERT_FROM_WCHAR_T(fBuffer.AcquireArray())); + } + else if (key == KEY_V) + { + plString contents = plClipboard::GetInstance().GetClipboardText(); + InsertString(contents.ToWchar().GetData()); + } + } else if( key == KEY_ESCAPE ) { // fEscapedFlag = true; diff --git a/Sources/Plasma/PubUtilLib/CMakeLists.txt b/Sources/Plasma/PubUtilLib/CMakeLists.txt index 01f937bb..859d6d67 100644 --- a/Sources/Plasma/PubUtilLib/CMakeLists.txt +++ b/Sources/Plasma/PubUtilLib/CMakeLists.txt @@ -7,6 +7,7 @@ add_subdirectory(plAudio) add_subdirectory(plAudioCore) add_subdirectory(plAvatar) add_subdirectory(plClientResMgr) +add_subdirectory(plClipboard) add_subdirectory(plCompression) add_subdirectory(plContainer) #add_subdirectory(plDeviceSelector) # Not being used by any current slns diff --git a/Sources/Plasma/PubUtilLib/plClipboard/CMakeLists.txt b/Sources/Plasma/PubUtilLib/plClipboard/CMakeLists.txt new file mode 100755 index 00000000..4bfd6582 --- /dev/null +++ b/Sources/Plasma/PubUtilLib/plClipboard/CMakeLists.txt @@ -0,0 +1,17 @@ +include_directories("../../CoreLib") +include_directories("../../NucleusLib/inc") +include_directories("../../NucleusLib") +include_directories("../../PubUtilLib") + +set(plClipboard_SOURCES + plClipboard.cpp +) + +set(plClipboard_HEADERS + plClipboard.h +) + +add_library(plClipboard STATIC ${plClipboard_SOURCES} ${plClipboard_HEADERS}) + +source_group("Source Files" FILES ${plClipboard_SOURCES}) +source_group("Header Files" FILES ${plClipboard_HEADERS}) diff --git a/Sources/Plasma/PubUtilLib/plClipboard/plClipboard.cpp b/Sources/Plasma/PubUtilLib/plClipboard/plClipboard.cpp new file mode 100755 index 00000000..b9836a59 --- /dev/null +++ b/Sources/Plasma/PubUtilLib/plClipboard/plClipboard.cpp @@ -0,0 +1,115 @@ +/*==LICENSE==* + +CyanWorlds.com Engine - MMOG client, server and tools +Copyright (C) 2011 Cyan Worlds, Inc. + +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 . + +Additional permissions under GNU GPL version 3 section 7 + +If you modify this Program, or any covered work, by linking or +combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, +NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent +JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK +(or a modified version of those libraries), +containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, +PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG +JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the +licensors of this Program grant you additional +permission to convey the resulting work. Corresponding Source for a +non-source form of such a combination shall include the source code for +the parts of OpenSSL and IJG JPEG Library used as well as that of the covered +work. + +You can contact Cyan Worlds, Inc. by email legal@cyan.com +or by snail mail at: +Cyan Worlds, Inc. +14617 N Newport Hwy +Mead, WA 99021 + +*==LICENSE==*/ + +#include "HeadSpin.h" +#include "plClipboard.h" + +plClipboard& plClipboard::GetInstance() +{ + static plClipboard theInstance; + return theInstance; +} + +bool plClipboard::IsTextInClipboard() +{ +#ifdef HS_BUILD_FOR_WIN32 + return ::IsClipboardFormatAvailable(CF_UNICODETEXT); +#else + return false; +#endif +} + +plString plClipboard::GetClipboardText() +{ + if (!IsTextInClipboard()) + return plString::Null; + +#ifdef HS_BUILD_FOR_WIN32 + if (!::OpenClipboard(NULL)) + return plString::Null; + + HANDLE clipboardData = ::GetClipboardData(CF_UNICODETEXT); + size_t size = ::GlobalSize(clipboardData) / sizeof(wchar_t); + wchar_t* clipboardDataPtr = (wchar_t*)::GlobalLock(clipboardData); + + plString result = plString::FromWchar(clipboardDataPtr, size); + + ::GlobalUnlock(clipboardData); + ::CloseClipboard(); + + return result; +#else + return plString::Null; +#endif +} + +void plClipboard::SetClipboardText(const plString& text) +{ + if (text.IsEmpty()) + return; +#ifdef HS_BUILD_FOR_WIN32 + plStringBuffer buf = text.ToWchar(); + size_t len = buf.GetSize(); + + if (len == 0) + return; + + HGLOBAL copy = ::GlobalAlloc(GMEM_MOVEABLE, (len + 1) * sizeof(wchar_t)); + if (copy == NULL) + return; + + if (!::OpenClipboard(NULL)) + return; + + ::EmptyClipboard(); + + wchar_t* target = (wchar_t*)::GlobalLock(copy); + memcpy(target, buf.GetData(), (len + 1) * sizeof(wchar_t)); + target[len] = '\0'; + ::GlobalUnlock(copy); + + // Place the handle on the clipboard. + ::SetClipboardData(CF_UNICODETEXT, target); + ::CloseClipboard(); +#endif +} + diff --git a/Sources/Plasma/PubUtilLib/plClipboard/plClipboard.h b/Sources/Plasma/PubUtilLib/plClipboard/plClipboard.h new file mode 100755 index 00000000..fd19b4be --- /dev/null +++ b/Sources/Plasma/PubUtilLib/plClipboard/plClipboard.h @@ -0,0 +1,64 @@ +/*==LICENSE==* + +CyanWorlds.com Engine - MMOG client, server and tools +Copyright (C) 2011 Cyan Worlds, Inc. + +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 . + +Additional permissions under GNU GPL version 3 section 7 + +If you modify this Program, or any covered work, by linking or +combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, +NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent +JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK +(or a modified version of those libraries), +containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, +PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG +JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the +licensors of this Program grant you additional +permission to convey the resulting work. Corresponding Source for a +non-source form of such a combination shall include the source code for +the parts of OpenSSL and IJG JPEG Library used as well as that of the covered +work. + +You can contact Cyan Worlds, Inc. by email legal@cyan.com + or by snail mail at: + Cyan Worlds, Inc. + 14617 N Newport Hwy + Mead, WA 99021 + +*==LICENSE==*/ + +#ifndef _plClipboard_h +#define _plClipboard_h + +#include "plString.h" + +//// Class Definition ///////////////////////////////////////////////////////// + +class plClipboard +{ + private: + + plClipboard() {} + plClipboard(const plClipboard& rhs) {} + + public: + bool IsTextInClipboard(); + plString GetClipboardText(); + void SetClipboardText(const plString& text); + static plClipboard& GetInstance( void ); +}; + +#endif // _Clipboard_h