From 472b41175a53583ca88b0b8d2876557635094206 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 6 Nov 2000 00:54:23 +0000 Subject: [PATCH] undo/redo seem to work in wxTextCtrl git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/wxUNIVERSAL@8699 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- samples/univ/univ.cpp | 6 +-- src/univ/textctrl.cpp | 88 ++++++++++++++++++++++++++++++------------- 2 files changed, 65 insertions(+), 29 deletions(-) diff --git a/samples/univ/univ.cpp b/samples/univ/univ.cpp index 99a5b28785..e00aa20cfa 100644 --- a/samples/univ/univ.cpp +++ b/samples/univ/univ.cpp @@ -395,18 +395,18 @@ MyUnivFrame::MyUnivFrame(const wxString& title) sizeText.x = 200; text->SetSize(sizeText); #else - wxTextCtrl *text = new wxTextCtrl(this, -1, //_T("Hello,\nMultiverse!"), - //"0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n", - "", + wxTextCtrl *text = new wxTextCtrl(this, -1, _T("Hello,\nMultiverse!"), wxPoint(10, 30), wxSize(-1, 150), wxTE_MULTILINE); +#if 0 // test wxTextCtrl::Replace() TestTextCtrlReplace(text, ""); TestTextCtrlReplace(text, "0\n1\n2\n3"); TestTextCtrlReplace(text, "0\n1\n2\n3\n"); TestTextCtrlReplace(text, "first\nsecond\n\nthird line"); +#endif #endif text->SetFocus(); //text->SetEditable(FALSE); diff --git a/src/univ/textctrl.cpp b/src/univ/textctrl.cpp index 2fc8929428..3c51883d19 100644 --- a/src/univ/textctrl.cpp +++ b/src/univ/textctrl.cpp @@ -132,16 +132,22 @@ public: wxTextCtrlInsertCommand(const wxString& textToInsert) : wxTextCtrlCommand(wxTEXT_COMMAND_INSERT), m_text(textToInsert) { + m_from = -1; } // combine the 2 commands together void Append(wxTextCtrlInsertCommand *other); + virtual bool CanUndo() const; virtual bool Do(wxTextCtrl *text); virtual bool Undo(wxTextCtrl *text); private: + // the text we insert wxString m_text; + + // the position where we inserted the text + long m_from; }; // remove text command @@ -155,6 +161,7 @@ public: m_to = to; } + virtual bool CanUndo() const; virtual bool Do(wxTextCtrl *text); virtual bool Undo(wxTextCtrl *text); @@ -1518,24 +1525,24 @@ void wxTextCtrlCommandProcessor::Store(wxCommand *command) wxTextCtrlInsertCommand * cmdInsLast = IsInsertCommand(GetCurrentCommand()); - // this would be a logic error in the code here as the flag is only - // set after adding insert command and reset after adding any other - // one - wxCHECK_RET( cmdInsLast, - _T("when compressing commands last must be insert") ); + // it is possible that we don't have any last command at all if, + // for example, it was undone since the last Store(), so deal with + // this case too + if ( cmdInsLast ) + { + cmdInsLast->Append(cmdIns); - cmdInsLast->Append(cmdIns); + delete cmdIns; - delete cmdIns; - - // don't need to call the base class version - return; - } - else // not compressing - { - // append the following insert commands to this one - m_compressInserts = TRUE; + // don't need to call the base class version + return; + } } + + // append the following insert commands to this one + m_compressInserts = TRUE; + + // let the base class version will do the job normally } else // not an insert command { @@ -1543,7 +1550,7 @@ void wxTextCtrlCommandProcessor::Store(wxCommand *command) // command not being an insert one anyhow StopCompressing(); - // the base class version will do the job normally + // let the base class version will do the job normally } wxCommandProcessor::Store(command); @@ -1554,8 +1561,18 @@ void wxTextCtrlInsertCommand::Append(wxTextCtrlInsertCommand *other) m_text += other->m_text; } +bool wxTextCtrlInsertCommand::CanUndo() const +{ + return m_from != -1; +} + bool wxTextCtrlInsertCommand::Do(wxTextCtrl *text) { + // the text is going to be inserted at the current position, remember where + // exactly it is + m_from = text->GetInsertionPoint(); + + // and now do insert it text->WriteText(m_text); return TRUE; @@ -1563,9 +1580,18 @@ bool wxTextCtrlInsertCommand::Do(wxTextCtrl *text) bool wxTextCtrlInsertCommand::Undo(wxTextCtrl *text) { - wxFAIL_MSG(_T("TODO")); + wxCHECK_MSG( CanUndo(), FALSE, _T("impossible to undo insert cmd") ); - return FALSE; + // remove the text from where we inserted it + text->Remove(m_from, m_from + m_text.length()); + + return TRUE; +} + +bool wxTextCtrlRemoveCommand::CanUndo() const +{ + // if we were executed, we should have the text we removed + return !m_textDeleted.empty(); } bool wxTextCtrlRemoveCommand::Do(wxTextCtrl *text) @@ -1579,9 +1605,10 @@ bool wxTextCtrlRemoveCommand::Do(wxTextCtrl *text) bool wxTextCtrlRemoveCommand::Undo(wxTextCtrl *text) { - wxFAIL_MSG(_T("TODO")); + text->SetInsertionPoint(m_from); + text->WriteText(m_textDeleted); - return FALSE; + return TRUE; } void wxTextCtrl::Undo() @@ -2924,20 +2951,29 @@ bool wxStdTextCtrlInputHandler::HandleKey(wxControl *control, const wxKeyEvent& event, bool pressed) { - // we're only interested in key presses without Alt modifier - if ( !pressed || event.AltDown() ) + // we're only interested in key presses + if ( !pressed ) return FALSE; + int keycode = event.GetKeyCode(); + wxControlAction action; wxString str; - bool ctrlDown = event.ControlDown(); - if ( event.ShiftDown() ) + bool ctrlDown = event.ControlDown(), + shiftDown = event.ShiftDown(); + if ( shiftDown ) { action = wxACTION_TEXT_PREFIX_SEL; } - int keycode = event.GetKeyCode(); - switch ( keycode ) + // the only key combination with Alt we recognize is Alt-Bksp for undo, so + // treat it first separately + if ( event.AltDown() ) + { + if ( keycode == WXK_BACK && !ctrlDown && !shiftDown ) + action = wxACTION_TEXT_UNDO; + } + else switch ( keycode ) { // cursor movement case WXK_HOME: