From d15c1c5d4aacb74bbfd6d47700c5b2a2cec368ff Mon Sep 17 00:00:00 2001 From: michi_cc Date: Mon, 5 Aug 2013 20:37:57 +0000 Subject: [PATCH] (svn r25692) -Add: Replacement of a part of the edit box text with a new string. --- src/console_gui.cpp | 4 +-- src/gfx_func.h | 2 +- src/textbuf.cpp | 81 ++++++++++++++++++++++++++++----------------- src/textbuf_type.h | 4 ++- src/window.cpp | 8 ++--- src/window_gui.h | 2 +- 6 files changed, 61 insertions(+), 40 deletions(-) diff --git a/src/console_gui.cpp b/src/console_gui.cpp index 1e1fd069b3..887dfda60c 100644 --- a/src/console_gui.cpp +++ b/src/console_gui.cpp @@ -311,9 +311,9 @@ struct IConsoleWindow : Window return ES_HANDLED; } - virtual void InsertTextString(int wid, const char *str, bool marked, const char *caret) + virtual void InsertTextString(int wid, const char *str, bool marked, const char *caret, const char *insert_location, const char *replacement_end) { - if (_iconsole_cmdline.InsertString(str, marked, caret)) { + if (_iconsole_cmdline.InsertString(str, marked, caret, insert_location, replacement_end)) { IConsoleWindow::scroll = 0; IConsoleResetHistoryPos(); this->SetDirty(); diff --git a/src/gfx_func.h b/src/gfx_func.h index f720672f88..aa18f3f707 100644 --- a/src/gfx_func.h +++ b/src/gfx_func.h @@ -71,7 +71,7 @@ extern Dimension _cur_resolution; extern Palette _cur_palette; ///< Current palette void HandleKeypress(uint keycode, WChar key); -void HandleTextInput(const char *str, bool marked = false, const char *caret = NULL); +void HandleTextInput(const char *str, bool marked = false, const char *caret = NULL, const char *insert_location = NULL, const char *replacement_end = NULL); void HandleCtrlChanged(); void HandleMouseEvents(); void CSleep(int milliseconds); diff --git a/src/textbuf.cpp b/src/textbuf.cpp index e99e89662e..445ebe59d3 100644 --- a/src/textbuf.cpp +++ b/src/textbuf.cpp @@ -153,13 +153,23 @@ bool Textbuf::InsertChar(WChar key) * @param str String to insert. * @param marked Replace the currently marked text with the new text. * @param caret Move the caret to this point in the insertion string. + * @param insert_location Position at which to insert the string. + * @param replacement_end Replace all characters from #insert_location up to this location with the new string. * @return True on successful change of Textbuf, or false otherwise. */ -bool Textbuf::InsertString(const char *str, bool marked, const char *caret) +bool Textbuf::InsertString(const char *str, bool marked, const char *caret, const char *insert_location, const char *replacement_end) { uint16 insertpos = (marked && this->marklength != 0) ? this->markpos : this->caretpos; + if (insert_location != NULL) { + insertpos = insert_location - this->buf; + if (insertpos > this->bytes) return NULL; - if (marked) this->DiscardMarkedText(str == NULL); + if (replacement_end != NULL) { + this->DeleteText(insertpos, replacement_end - this->buf, str == NULL); + } + } else { + if (marked) this->DiscardMarkedText(str == NULL); + } if (str == NULL) return false; @@ -219,6 +229,42 @@ bool Textbuf::InsertClipboard() return this->InsertString(utf8_buf, false); } +/** + * Delete a part of the text. + * @param from Start of the text to delete. + * @param to End of the text to delete. + * @param update Set to true if the internal state should be updated. + */ +void Textbuf::DeleteText(uint16 from, uint16 to, bool update) +{ + uint c = 0; + const char *s = this->buf + from; + while (s < this->buf + to) { + Utf8Consume(&s); + c++; + } + + /* Strip marked characters from buffer. */ + memmove(this->buf + from, this->buf + to, this->bytes - to); + this->bytes -= to - from; + this->chars -= c; + + /* Fixup caret if needed. */ + if (this->caretpos > from) { + if (this->caretpos <= to) { + this->caretpos = from; + } else { + this->caretpos -= to - from; + } + } + + if (update) { + this->UpdateStringIter(); + this->UpdateCaretPosition(); + this->UpdateMarkedText(); + } +} + /** * Discard any marked text. * @param update Set to true if the internal state should be updated. @@ -227,35 +273,8 @@ void Textbuf::DiscardMarkedText(bool update) { if (this->markend == 0) return; - /* Count marked characters. */ - uint c = 0; - const char *s = this->buf + this->markpos; - while (s < this->buf + this->markend) { - Utf8Consume(&s); - c++; - } - - /* Strip marked characters from buffer. */ - memmove(this->buf + this->markpos, this->buf + this->markend, this->bytes - this->markend); - this->bytes -= this->markend - this->markpos; - this->chars -= c; - - /* Fixup caret if needed. */ - if (this->caretpos > this->markpos) { - if (this->caretpos <= this->markend) { - this->caretpos = this->markpos; - } else { - this->caretpos -= this->markend - this->markpos; - } - } - - this->markpos = this->markend = 0; - - if (update) { - this->UpdateStringIter(); - this->UpdateCaretPosition(); - this->UpdateMarkedText(); - } + this->DeleteText(this->markpos, this->markend, update); + this->markpos = this->markend = this->markxoffs = this->marklength = 0; } /** Update the character iter after the text has changed. */ diff --git a/src/textbuf_type.h b/src/textbuf_type.h index e34e2e2f4e..1d927b72d9 100644 --- a/src/textbuf_type.h +++ b/src/textbuf_type.h @@ -56,7 +56,7 @@ struct Textbuf { bool InsertClipboard(); bool InsertChar(uint32 key); - bool InsertString(const char *str, bool marked, const char *caret = NULL); + bool InsertString(const char *str, bool marked, const char *caret = NULL, const char *insert_location = NULL, const char *replacement_end = NULL); bool DeleteChar(uint16 keycode); bool MovePos(uint16 keycode); @@ -73,6 +73,8 @@ private: bool CanDelChar(bool backspace); + void DeleteText(uint16 from, uint16 to, bool update); + void UpdateStringIter(); void UpdateWidth(); void UpdateCaretPosition(); diff --git a/src/window.cpp b/src/window.cpp index df7d6ef3d5..ad97ddf7c7 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -2620,12 +2620,12 @@ void HandleCtrlChanged() * @param wid Edit box widget. * @param str Text string to insert. */ -/* virtual */ void Window::InsertTextString(int wid, const char *str, bool marked, const char *caret) +/* virtual */ void Window::InsertTextString(int wid, const char *str, bool marked, const char *caret, const char *insert_location, const char *replacement_end) { QueryString *query = this->GetQueryString(wid); if (query == NULL) return; - if (query->text.InsertString(str, marked, caret) || marked) { + if (query->text.InsertString(str, marked, caret, insert_location, replacement_end) || marked) { this->SetWidgetDirty(wid); this->OnEditboxChanged(wid); } @@ -2637,11 +2637,11 @@ void HandleCtrlChanged() * @param marked Is the input a marked composition string from an IME? * @param caret Move the caret to this point in the insertion string. */ -void HandleTextInput(const char *str, bool marked, const char *caret) +void HandleTextInput(const char *str, bool marked, const char *caret, const char *insert_location, const char *replacement_end) { if (!EditBoxInGlobalFocus()) return; - _focused_window->InsertTextString(_focused_window->window_class == WC_CONSOLE ? 0 : _focused_window->nested_focus->index, str, marked, caret); + _focused_window->InsertTextString(_focused_window->window_class == WC_CONSOLE ? 0 : _focused_window->nested_focus->index, str, marked, caret, insert_location, replacement_end); } /** diff --git a/src/window_gui.h b/src/window_gui.h index f17eb11d89..b6b994d520 100644 --- a/src/window_gui.h +++ b/src/window_gui.h @@ -496,7 +496,7 @@ public: bool SetFocusedWidget(int widget_index); EventState HandleEditBoxKey(int wid, WChar key, uint16 keycode); - virtual void InsertTextString(int wid, const char *str, bool marked, const char *caret); + virtual void InsertTextString(int wid, const char *str, bool marked, const char *caret, const char *insert_location, const char *replacement_end); void HandleButtonClick(byte widget); int GetRowFromWidget(int clickpos, int widget, int padding, int line_height = -1) const;