From bcf1cb1f9c9daa29cfd7df2eb0640f3f66e41f48 Mon Sep 17 00:00:00 2001 From: zuu Date: Mon, 10 Sep 2012 18:47:13 +0000 Subject: [PATCH] (svn r24521) -Feature [FS#5203]: Ctrl + Backspace/Delete to remove characters up to next word beginning in text edit boxes --- src/misc_gui.cpp | 1 + src/textbuf.cpp | 52 ++++++++++++++++++++++++++++++++++++++++++++++ src/textbuf_type.h | 1 + 3 files changed, 54 insertions(+) diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp index 7d21ad19e8..5ad6394b3f 100644 --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -740,6 +740,7 @@ HandleEditBoxResult QueryString::HandleEditBoxKey(Window *w, int wid, uint16 key break; case WKC_BACKSPACE: case WKC_DELETE: + case WKC_CTRL | WKC_BACKSPACE: case WKC_CTRL | WKC_DELETE: if (this->text.DeleteChar(keycode)) w->SetWidgetDirty(wid); break; diff --git a/src/textbuf.cpp b/src/textbuf.cpp index d9069755a8..dc1d7a7cb1 100644 --- a/src/textbuf.cpp +++ b/src/textbuf.cpp @@ -38,6 +38,29 @@ bool Textbuf::CanDelChar(bool backspace) return backspace ? this->caretpos != 0 : this->caretpos < this->bytes - 1; } +/** + * Get the next character that will be removed by DelChar. + * @param backspace if set, delete the character before the caret, + * otherwise, delete the character after it. + * @return the next character that will be removed by DelChar. + * @warning You should ensure Textbuf::CanDelChar returns true before calling this function. + */ +WChar Textbuf::GetNextDelChar(bool backspace) +{ + assert(this->CanDelChar(backspace)); + + const char *s; + if (backspace) { + s = Utf8PrevChar(this->buf + this->caretpos); + } else { + s = this->buf + this->caretpos; + } + + WChar c; + Utf8Decode(&c, s); + return c; +} + /** * Delete a character at the caret position in a text buf. * @param backspace if set, delete the character before the caret, @@ -85,6 +108,35 @@ bool Textbuf::DeleteChar(int delmode) return false; } + if (delmode == (WKC_CTRL | WKC_BACKSPACE) || delmode == (WKC_CTRL | WKC_DELETE)) { + bool backspace = delmode == (WKC_CTRL | WKC_BACKSPACE); + + if (!CanDelChar(backspace)) return false; + + /* Unconditionally delete one char to the left. */ + this->DelChar(backspace); + if (!CanDelChar(backspace)) return false; + WChar c = this->GetNextDelChar(backspace); + + /* Backspace: Delete left whitespaces. + * Delete: Delete right word. + */ + while (backspace ? IsWhitespace(c) : !IsWhitespace(c)) { + this->DelChar(backspace); + if (!this->CanDelChar(backspace)) return true; + c = this->GetNextDelChar(backspace); + } + /* Backspace: Delete left word. + * Delete: Delete right whitespaces. + */ + while (backspace ? !IsWhitespace(c) : IsWhitespace(c)) { + this->DelChar(backspace); + if (!this->CanDelChar(backspace)) return true; + c = this->GetNextDelChar(backspace); + } + return true; + } + return false; } diff --git a/src/textbuf_type.h b/src/textbuf_type.h index 1a404ad58e..363f016439 100644 --- a/src/textbuf_type.h +++ b/src/textbuf_type.h @@ -40,6 +40,7 @@ struct Textbuf { private: bool CanDelChar(bool backspace); + WChar GetNextDelChar(bool backspace); void DelChar(bool backspace); bool CanMoveCaretLeft(); WChar MoveCaretLeft();