summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/console_gui.cpp4
-rw-r--r--src/gfx_func.h2
-rw-r--r--src/textbuf.cpp53
-rw-r--r--src/textbuf_type.h4
-rw-r--r--src/window.cpp8
-rw-r--r--src/window_gui.h2
6 files changed, 47 insertions, 26 deletions
diff --git a/src/console_gui.cpp b/src/console_gui.cpp
index 1e1fd069b..887dfda60 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 f720672f8..aa18f3f70 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 e99e89662..445ebe59d 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;
@@ -220,37 +230,34 @@ bool Textbuf::InsertClipboard()
}
/**
- * Discard any marked text.
+ * 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::DiscardMarkedText(bool update)
+void Textbuf::DeleteText(uint16 from, uint16 to, 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) {
+ const char *s = this->buf + from;
+ while (s < this->buf + to) {
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;
+ memmove(this->buf + from, this->buf + to, this->bytes - to);
+ this->bytes -= to - from;
this->chars -= c;
/* Fixup caret if needed. */
- if (this->caretpos > this->markpos) {
- if (this->caretpos <= this->markend) {
- this->caretpos = this->markpos;
+ if (this->caretpos > from) {
+ if (this->caretpos <= to) {
+ this->caretpos = from;
} else {
- this->caretpos -= this->markend - this->markpos;
+ this->caretpos -= to - from;
}
}
- this->markpos = this->markend = 0;
-
if (update) {
this->UpdateStringIter();
this->UpdateCaretPosition();
@@ -258,6 +265,18 @@ void Textbuf::DiscardMarkedText(bool update)
}
}
+/**
+ * Discard any marked text.
+ * @param update Set to true if the internal state should be updated.
+ */
+void Textbuf::DiscardMarkedText(bool update)
+{
+ if (this->markend == 0) return;
+
+ 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. */
void Textbuf::UpdateStringIter()
{
diff --git a/src/textbuf_type.h b/src/textbuf_type.h
index e34e2e2f4..1d927b72d 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 df7d6ef3d..ad97ddf7c 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 f17eb11d8..b6b994d52 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;