diff --git a/BeefLibs/Beefy2D/src/BFApp.bf b/BeefLibs/Beefy2D/src/BFApp.bf index bfe08cf4..34dc1b5a 100644 --- a/BeefLibs/Beefy2D/src/BFApp.bf +++ b/BeefLibs/Beefy2D/src/BFApp.bf @@ -777,25 +777,41 @@ namespace Beefy public virtual bool GetClipboardText(String outStr) { - int32 aSize; - void* clipboardData = GetClipboardData("text", out aSize); - if (clipboardData == null) - return false; + return GetClipboardTextData("text", outStr); + } - outStr.Append((char8*)clipboardData); + public virtual bool GetClipboardText(String outStr, String extra) + { + GetClipboardTextData("bf_text", extra); + return GetClipboardTextData("text", outStr); + } + + public bool GetClipboardTextData(String format, String outStr) + { + int32 aSize; + void* clipboardData = GetClipboardData(format, out aSize); + if (clipboardData == null) + return false; + + outStr.Append((char8*)clipboardData); ReleaseClipboardData(clipboardData); return true; - } + } public virtual void SetClipboardData(String format, void* ptr, int32 size, bool resetClipboard) { BFApp_SetClipboardData(format, ptr, size, resetClipboard ? 1 : 0); } + public void SetClipboardText(String text, String extra) + { + SetClipboardData("text", text.CStr(), (int32)text.Length + 1, true); + SetClipboardData("bf_text", extra.CStr(), (int32)extra.Length + 1, false); + } + public virtual void SetClipboardText(String text) { - //IntPtr aPtr = Marshal.StringToCoTaskMemUni(text); - SetClipboardData("text", text.CStr(), (int32)text.Length + 1, true); + SetClipboardText(text, ""); } #if STUDIO_CLIENT diff --git a/BeefLibs/Beefy2D/src/widgets/EditWidget.bf b/BeefLibs/Beefy2D/src/widgets/EditWidget.bf index 3dcba33a..33bdb942 100644 --- a/BeefLibs/Beefy2D/src/widgets/EditWidget.bf +++ b/BeefLibs/Beefy2D/src/widgets/EditWidget.bf @@ -2001,35 +2001,93 @@ namespace Beefy.widgets InsertAtCursor(text); } - public void CutText() + void CopyText(bool cut) { if (!CheckReadOnly()) { + bool selectedLine = false; + String extra = scope .(); + if (!HasSelection()) + { + selectedLine = true; + GetLinePosition(CursorLineAndColumn.mLine, var lineStart, var lineEnd); + mSelection = .(lineStart, lineEnd); + extra.Append("line"); + } + String selText = scope String(); GetSelectionText(selText); - if (!selText.IsEmpty) - { - BFApp.sApp.SetClipboardText(selText); - DeleteSelection(); + BFApp.sApp.SetClipboardText(selText, extra); + if (cut) + { + if (selectedLine) + { + // Remove \n + if (mSelection.Value.mEndPos < mData.mTextLength) + mSelection.ValueRef.mEndPos++; + } + DeleteSelection(); } + + if (selectedLine) + mSelection = null; } } + public void CutText() + { + CopyText(true); + } + public void CopyText() { - String selText = scope String(); - GetSelectionText(selText); - if (!selText.IsEmpty) - BFApp.sApp.SetClipboardText(selText); + CopyText(false); + } + + public void PasteText(String text, String extra) + { + if (extra == "line") + { + UndoBatchStart undoBatchStart = new UndoBatchStart("paste"); + mData.mUndoManager.Add(undoBatchStart); + var origPosition = CursorLineAndColumn; + CursorLineAndColumn = .(origPosition.mLine, 0); + var lineStartPosition = CursorLineAndColumn; + InsertAtCursor("\n"); + CursorLineAndColumn = lineStartPosition; + CursorToLineStart(false); + + // Adjust to requested column + if (CursorLineAndColumn.mColumn != 0) + { + for (let c in text.RawChars) + { + if (!c.IsWhiteSpace) + { + text.Remove(0, @c.Index); + break; + } + } + } + + PasteText(text); + CursorLineAndColumn = origPosition; + mData.mUndoManager.Add(undoBatchStart.mBatchEnd); + } + else + PasteText(text); } public void PasteText() { String aText = scope String(); - BFApp.sApp.GetClipboardText(aText); + String extra = scope .(); + BFApp.sApp.GetClipboardText(aText, extra); aText.Replace("\r", ""); if ((aText != null) && (!CheckReadOnly())) - PasteText(aText); + { + PasteText(aText, extra); + } } protected void SelectLeft(int lineIdx, int lineChar, bool isChunkMove, bool isWordMove) @@ -3593,7 +3651,7 @@ namespace Beefy.widgets public void FinishScroll() { - mVertPos.mPct = 1.0f; + mVertPos.mPct = 1.0f; UpdateContentPosition(); } } diff --git a/BeefySysLib/platform/win/WinBFApp.cpp b/BeefySysLib/platform/win/WinBFApp.cpp index a046f28b..b307e395 100644 --- a/BeefySysLib/platform/win/WinBFApp.cpp +++ b/BeefySysLib/platform/win/WinBFApp.cpp @@ -1528,49 +1528,38 @@ uint32 WinBFApp::GetClipboardFormat(const StringImpl& format) else if (format == "atext") return CF_TEXT; -// StringToUIntMap::iterator itr = mClipboardFormatMap.find(format); -// if (itr != mClipboardFormatMap.end()) -// return itr->second; - uint32 aFormat; if (mClipboardFormatMap.TryGetValue(format, &aFormat)) return aFormat; - - String sysFormatName = "BF_" + format; - aFormat = ::RegisterClipboardFormatA(sysFormatName.c_str()); - mClipboardFormatMap[sysFormatName] = aFormat; + + aFormat = ::RegisterClipboardFormatA(format.c_str()); + mClipboardFormatMap[format] = aFormat; return aFormat; } +static String gClipboardData; + void* WinBFApp::GetClipboardData(const StringImpl& format, int* size) { HWND aWindow = NULL; if (!mWindowList.empty()) - aWindow = ((WinBFWindow*) mWindowList.front())->mHWnd; + aWindow = ((WinBFWindow*)mWindowList.front())->mHWnd; uint32 aFormat = GetClipboardFormat(format); if (aFormat != 0) { if (OpenClipboard(aWindow)) - { + { HGLOBAL globalHandle = ::GetClipboardData(aFormat); + if (globalHandle == NULL) { - if (format == "text") + if (aFormat == CF_UNICODETEXT) { - int aSize = 0; - char* charPtr = (char*) GetClipboardData("atext", &aSize); - if (charPtr == NULL) - return NULL; - - *size = (int)::GlobalSize(globalHandle); - void* aPtr = ::GlobalLock(globalHandle); - - mLockedHGlobalMap[aPtr] = globalHandle; - CloseClipboard(); - return aPtr; + // Return ascii text + return (char*)GetClipboardData("atext", size); } CloseClipboard(); @@ -1580,26 +1569,31 @@ void* WinBFApp::GetClipboardData(const StringImpl& format, int* size) *size = (int)::GlobalSize(globalHandle); void* aPtr = ::GlobalLock(globalHandle); - - static String utf8String; - utf8String = UTF8Encode((WCHAR*)aPtr); - ::GlobalUnlock(globalHandle); + + if (aFormat == CF_UNICODETEXT) + { + gClipboardData = UTF8Encode((WCHAR*)aPtr); + *size = (int)gClipboardData.length() + 1; + } + else + { + gClipboardData.Clear(); + gClipboardData.Insert(0, (char*)aPtr, *size); + } + + ::GlobalUnlock(globalHandle); CloseClipboard(); - return (void*)utf8String.c_str(); + return (void*)gClipboardData.c_str(); } } - + *size = 0; return NULL; } void WinBFApp::ReleaseClipboardData(void* ptr) { - HGLOBAL globalHandle; - if (mLockedHGlobalMap.Remove(ptr, &globalHandle)) - { - ::GlobalUnlock(globalHandle); - } + } void WinBFApp::SetClipboardData(const StringImpl& format, const void* ptr, int size, bool resetClipboard) @@ -1638,25 +1632,18 @@ void WinBFApp::SetClipboardData(const StringImpl& format, const void* ptr, int s GlobalUnlock(globalHandle); ::SetClipboardData(CF_UNICODETEXT, globalHandle); } - else if (format == "atext") + else { HGLOBAL globalHandle = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, size); char* data = (char*)GlobalLock(globalHandle); memcpy(data, ptr, size); GlobalUnlock(globalHandle); - ::SetClipboardData(CF_TEXT, globalHandle); + ::SetClipboardData(aFormat, globalHandle); } CloseClipboard(); } } - - /*if (format == "text") - { - //String aString = ToString((const WCHAR*) ptr); - String aString = (const char*)ptr; - SetClipboardData("atext", aString.c_str(), (int)aString.length() + 1, false); - }*/ } BFMenu* WinBFWindow::AddMenuItem(BFMenu* parent, int insertIdx, const char* text, const char* hotKey, BFSysBitmap* sysBitmap, bool enabled, int checkState, bool radioCheck) diff --git a/BeefySysLib/platform/win/WinBFApp.h b/BeefySysLib/platform/win/WinBFApp.h index 9cd8b3d5..ce779de7 100644 --- a/BeefySysLib/platform/win/WinBFApp.h +++ b/BeefySysLib/platform/win/WinBFApp.h @@ -88,7 +88,6 @@ class WinBFApp : public BFApp { public: bool mInMsgProc; - PtrToHGlobalMap mLockedHGlobalMap; StringToUIntMap mClipboardFormatMap; DSoundManager* mDSoundManager; diff --git a/IDE/src/ui/SourceEditWidgetContent.bf b/IDE/src/ui/SourceEditWidgetContent.bf index 018ca37e..170d5619 100644 --- a/IDE/src/ui/SourceEditWidgetContent.bf +++ b/IDE/src/ui/SourceEditWidgetContent.bf @@ -2132,9 +2132,8 @@ namespace IDE.ui var str = scope String(); GetLineText(lineNum, str); mSelection = null; - str.Append("\n"); CursorLineAndColumn = LineAndColumn(lineNum, 0); - InsertAtCursor(str); + PasteText(str, "line"); CursorLineAndColumn = LineAndColumn(prevCursorLineAndColumn.mLine + 1, prevCursorLineAndColumn.mColumn); mData.mUndoManager.Add(undoBatchStart.mBatchEnd);