From 76c526bcb084b3312d0f5b461ae3bc70435f7d27 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sun, 11 Oct 2020 10:12:42 +0200 Subject: [PATCH] Added basic (entire and single line only) text cut/copy and paste (partially implements #105) --- Changes.txt | 5 ++++ docs/index.html | 5 ++-- src/common/EventHandlerSDL2.cxx | 24 ++++++++++++++++ src/common/EventHandlerSDL2.hxx | 9 +++++- src/debugger/gui/PromptWidget.cxx | 47 +++++++++++++++++++++++++++++++ src/debugger/gui/PromptWidget.hxx | 1 + src/emucore/EventHandler.hxx | 7 +++++ src/gui/EditableWidget.cxx | 39 ++++++++++++++++--------- src/gui/EditableWidget.hxx | 3 +- 9 files changed, 122 insertions(+), 18 deletions(-) diff --git a/Changes.txt b/Changes.txt index 18444bb10..76d711721 100644 --- a/Changes.txt +++ b/Changes.txt @@ -12,6 +12,11 @@ Release History =========================================================================== +6.3 to 6.4 (XXXX XX, 202X) + + * Added basic (entire and single line only) text cut/copy and paste + + 6.2.1 to 6.3 (October 7, 2020) * Added adjustable autofire. diff --git a/docs/index.html b/docs/index.html index 4e939ebd3..d2d7b8e6f 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1883,8 +1883,9 @@ Control + wRemove entire word to left of cursor Control + LeftMove cursor to beginning of word to the left Control + RightMove cursor to beginning of word to the right - Control + cCopy entire line to clipboard (not complete) - Control + vPaste clipboard contents (not complete) + Control + cCopy entire line to clipboard + Control + vPaste clipboard contents + Control + xCut entire line to clipboard
diff --git a/src/common/EventHandlerSDL2.cxx b/src/common/EventHandlerSDL2.cxx index 2e8b60323..fa19303bc 100644 --- a/src/common/EventHandlerSDL2.cxx +++ b/src/common/EventHandlerSDL2.cxx @@ -58,6 +58,30 @@ void EventHandlerSDL2::enableTextEvents(bool enable) SDL_StopTextInput(); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EventHandlerSDL2::copyText(const string& text) const +{ + SDL_SetClipboardText(text.c_str()); +}; + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EventHandlerSDL2::cutText(string& text) const +{ + copyText(text); + text = ""; +}; + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string EventHandlerSDL2::pasteText(string& text) const +{ + if(SDL_HasClipboardText()) + text = SDL_GetClipboardText(); + else + text = ""; + + return text; +}; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EventHandlerSDL2::pollEvent() { diff --git a/src/common/EventHandlerSDL2.hxx b/src/common/EventHandlerSDL2.hxx index 2fea58371..c7f9c4a2f 100644 --- a/src/common/EventHandlerSDL2.hxx +++ b/src/common/EventHandlerSDL2.hxx @@ -38,12 +38,19 @@ class EventHandlerSDL2 : public EventHandler explicit EventHandlerSDL2(OSystem& osystem); ~EventHandlerSDL2() override; - private: +private: /** Enable/disable text events (distinct from single-key events). */ void enableTextEvents(bool enable) override; + /** + Clipboard methods. + */ + void copyText(const string& text) const override; + void cutText(string& text) const override; + string pasteText(string& text) const override; + /** Collects and dispatches any pending SDL2 events. */ diff --git a/src/debugger/gui/PromptWidget.cxx b/src/debugger/gui/PromptWidget.cxx index 7a1cd56f2..9b3c1bca9 100644 --- a/src/debugger/gui/PromptWidget.cxx +++ b/src/debugger/gui/PromptWidget.cxx @@ -24,12 +24,17 @@ #include "Debugger.hxx" #include "DebuggerDialog.hxx" #include "DebuggerParser.hxx" +#include "EventHandler.hxx" #include "PromptWidget.hxx" #include "CartDebug.hxx" #define PROMPT "> " +// Uncomment the following to give full-line cut/copy/paste +// Note that this will be removed eventually, when we implement proper cut/copy/paste +#define PSEUDO_CUT_COPY_PASTE + // TODO: Github issue #361 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - PromptWidget::PromptWidget(GuiObject* boss, const GUI::Font& font, @@ -673,19 +678,61 @@ void PromptWidget::textSelectAll() { } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string PromptWidget::getLine() +{ +#if defined(PSEUDO_CUT_COPY_PASTE) + assert(_promptEndPos >= _promptStartPos); + int len = _promptEndPos - _promptStartPos; + string text; + + // Copy current line to text + for(int i = 0; i < len; i++) + text += buffer(_promptStartPos + i) & 0x7f; + + return text; +#endif +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void PromptWidget::textCut() { +#if defined(PSEUDO_CUT_COPY_PASTE) + string text = getLine(); + + instance().eventHandler().cutText(text); + + // Remove the current line + _currentPos = _promptStartPos; + killLine(1); // to end of line + _promptEndPos = _currentPos; +#endif } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void PromptWidget::textCopy() { +#if defined(PSEUDO_CUT_COPY_PASTE) + string text = getLine(); + + instance().eventHandler().copyText(text); +#endif } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void PromptWidget::textPaste() { +#if defined(PSEUDO_CUT_COPY_PASTE) + string text; + + // Remove the current line + _currentPos = _promptStartPos; + killLine(1); // to end of line + + instance().eventHandler().pasteText(text); + print(text); + _promptEndPos = _currentPos; +#endif } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/debugger/gui/PromptWidget.hxx b/src/debugger/gui/PromptWidget.hxx index 0570f025f..925fee4e7 100644 --- a/src/debugger/gui/PromptWidget.hxx +++ b/src/debugger/gui/PromptWidget.hxx @@ -72,6 +72,7 @@ class PromptWidget : public Widget, public CommandSender // Clipboard void textSelectAll(); + string getLine(); void textCut(); void textCopy(); void textPaste(); diff --git a/src/emucore/EventHandler.hxx b/src/emucore/EventHandler.hxx index 35337b381..50d26b0ed 100644 --- a/src/emucore/EventHandler.hxx +++ b/src/emucore/EventHandler.hxx @@ -326,6 +326,13 @@ class EventHandler */ virtual void enableTextEvents(bool enable) = 0; + /** + Clipboard methods. + */ + virtual void copyText(const string& text) const = 0; + virtual void cutText(string& text) const = 0; + virtual string pasteText(string& text) const = 0; + /** Handle changing mouse modes. */ diff --git a/src/gui/EditableWidget.cxx b/src/gui/EditableWidget.cxx index 5218e6fc4..72b88d565 100644 --- a/src/gui/EditableWidget.cxx +++ b/src/gui/EditableWidget.cxx @@ -19,11 +19,13 @@ #include "StellaKeys.hxx" #include "FBSurface.hxx" #include "Font.hxx" +#include "OSystem.hxx" +#include "EventHandler.hxx" #include "EditableWidget.hxx" -// Uncomment the following to give full-line copy/paste -// Note that this will be removed eventually, when we implement proper copy/paste -//#define PSEUDO_COPY_PASTE +// Uncomment the following to give full-line cut/copy/paste +// Note that this will be removed eventually, when we implement proper cut/copy/paste +#define PSEUDO_CUT_COPY_PASTE // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - EditableWidget::EditableWidget(GuiObject* boss, const GUI::Font& font, @@ -260,7 +262,7 @@ bool EditableWidget::specialKeys(StellaKey key) { bool handled = true; - switch (key) + switch(key) { case KBDK_A: setCaretPos(0); @@ -268,7 +270,6 @@ bool EditableWidget::specialKeys(StellaKey key) case KBDK_C: copySelectedText(); - if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); break; case KBDK_E: @@ -292,7 +293,7 @@ bool EditableWidget::specialKeys(StellaKey key) case KBDK_V: pasteSelectedText(); - if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); + sendCommand(EditableWidget::kChangedCmd, key, _id); break; case KBDK_W: @@ -300,6 +301,11 @@ bool EditableWidget::specialKeys(StellaKey key) if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); break; + case KBDK_X: + cutSelectedText(); + sendCommand(EditableWidget::kChangedCmd, key, _id); + break; + case KBDK_LEFT: handled = moveWord(-1); break; @@ -445,21 +451,28 @@ bool EditableWidget::moveWord(int direction) return handled; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EditableWidget::cutSelectedText() +{ +#if defined(PSEUDO_CUT_COPY_PASTE) + instance().eventHandler().cutText(_editString); + _caretPos = 0; +#endif +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EditableWidget::copySelectedText() { -#if defined(PSEUDO_COPY_PASTE) - _clippedText = _editString; +#if defined(PSEUDO_CUT_COPY_PASTE) + instance().eventHandler().copyText(_editString); #endif } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EditableWidget::pasteSelectedText() { -#if defined(PSEUDO_COPY_PASTE) - _editString = _clippedText; +#if defined(PSEUDO_CUT_COPY_PASTE) + instance().eventHandler().pasteText(_editString); + _caretPos = int(_editString.length()); #endif } - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string EditableWidget::_clippedText = ""; diff --git a/src/gui/EditableWidget.hxx b/src/gui/EditableWidget.hxx index 933d033af..748f6074f 100644 --- a/src/gui/EditableWidget.hxx +++ b/src/gui/EditableWidget.hxx @@ -87,6 +87,7 @@ class EditableWidget : public Widget, public CommandSender bool moveWord(int direction); // Clipboard + void cutSelectedText(); void copySelectedText(); void pasteSelectedText(); @@ -107,8 +108,6 @@ class EditableWidget : public Widget, public CommandSender int _editScrollOffset{0}; - static string _clippedText; - private: TextFilter _filter;