diff options
author | Colomban Wendling <ban@herbesfolles.org> | 2023-01-27 21:09:40 +0100 |
---|---|---|
committer | Colomban Wendling <ban@herbesfolles.org> | 2023-01-27 21:09:40 +0100 |
commit | 33f32a76dae02591faddc763284cfe4d7264b0b7 (patch) | |
tree | 408f4298c64488e3ffa2d868ac5589a57c0ee372 | |
parent | f4985491061752c483eb6ec315049ec992f7ed29 (diff) | |
download | scintilla-mirror-33f32a76dae02591faddc763284cfe4d7264b0b7.tar.gz |
Feature [feature-requests:#1476] Add support for surrounding text in GTK input methods
Add support for retrieving and deleting surrounding text from input
methods on GTK.
-rw-r--r-- | doc/ScintillaHistory.html | 4 | ||||
-rwxr-xr-x | gtk/ScintillaGTK.cxx | 63 | ||||
-rwxr-xr-x | gtk/ScintillaGTK.h | 5 |
3 files changed, 72 insertions, 0 deletions
diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html index c6a31a526..beb28cb4c 100644 --- a/doc/ScintillaHistory.html +++ b/doc/ScintillaHistory.html @@ -605,6 +605,10 @@ <a href="https://sourceforge.net/p/scintilla/bugs/2374/">Bug #2374</a>. </li> <li> + On GTK, support IME context. + <a href="https://sourceforge.net/p/scintilla/feature-requests/1476/">Feature #1476</a>. + </li> + <li> On GTK on Win32, fix scrolling speed to not be too fast. <a href="https://sourceforge.net/p/scintilla/bugs/2375/">Bug #2375</a>. </li> diff --git a/gtk/ScintillaGTK.cxx b/gtk/ScintillaGTK.cxx index 168416bb7..fb852e637 100755 --- a/gtk/ScintillaGTK.cxx +++ b/gtk/ScintillaGTK.cxx @@ -322,6 +322,10 @@ void ScintillaGTK::RealizeThis(GtkWidget *widget) { G_CALLBACK(Commit), this); g_signal_connect(G_OBJECT(im_context.get()), "preedit_changed", G_CALLBACK(PreeditChanged), this); + g_signal_connect(G_OBJECT(im_context.get()), "retrieve-surrounding", + G_CALLBACK(RetrieveSurrounding), this); + g_signal_connect(G_OBJECT(im_context.get()), "delete-surrounding", + G_CALLBACK(DeleteSurrounding), this); gtk_im_context_set_client_window(im_context.get(), WindowFromWidget(widget)); GtkWidget *widtxt = PWidget(wText); // // No code inside the G_OBJECT macro @@ -2605,6 +2609,65 @@ void ScintillaGTK::PreeditChanged(GtkIMContext *, ScintillaGTK *sciThis) { } } +bool ScintillaGTK::RetrieveSurroundingThis(GtkIMContext *context) { + try { + const Sci::Position pos = CurrentPosition(); + const int line = pdoc->LineFromPosition(pos); + const Sci::Position startByte = pdoc->LineStart(line); + const Sci::Position endByte = pdoc->LineEnd(line); + + std::string utf8Text; + gint cursorIndex; // index of the cursor inside utf8Text, in bytes + const char *charSetBuffer; + + if (IsUnicodeMode() || ! *(charSetBuffer = CharacterSetID())) { + utf8Text = RangeText(startByte, endByte); + cursorIndex = pos - startByte; + } else { + // Need to convert + std::string tmpbuf = RangeText(startByte, pos); + utf8Text = ConvertText(&tmpbuf[0], tmpbuf.length(), "UTF-8", charSetBuffer, false); + cursorIndex = utf8Text.length(); + if (endByte > pos) { + tmpbuf = RangeText(pos, endByte); + utf8Text += ConvertText(&tmpbuf[0], tmpbuf.length(), "UTF-8", charSetBuffer, false); + } + } + + gtk_im_context_set_surrounding(context, &utf8Text[0], utf8Text.length(), cursorIndex); + + return true; + } catch (...) { + errorStatus = Status::Failure; + } + return false; +} + +gboolean ScintillaGTK::RetrieveSurrounding(GtkIMContext *context, ScintillaGTK *sciThis) { + return sciThis->RetrieveSurroundingThis(context); +} + +bool ScintillaGTK::DeleteSurroundingThis(GtkIMContext *, gint characterOffset, gint characterCount) { + try { + const Sci::Position startByte = pdoc->GetRelativePosition(CurrentPosition(), characterOffset); + if (startByte == INVALID_POSITION) + return false; + + const Sci::Position endByte = pdoc->GetRelativePosition(startByte, characterCount); + if (endByte == INVALID_POSITION) + return false; + + return pdoc->DeleteChars(startByte, endByte - startByte); + } catch (...) { + errorStatus = Status::Failure; + } + return false; +} + +gboolean ScintillaGTK::DeleteSurrounding(GtkIMContext *context, gint characterOffset, gint characterCount, ScintillaGTK *sciThis) { + return sciThis->DeleteSurroundingThis(context, characterOffset, characterCount); +} + void ScintillaGTK::StyleSetText(GtkWidget *widget, GtkStyle *, void *) { RealizeText(widget, nullptr); } diff --git a/gtk/ScintillaGTK.h b/gtk/ScintillaGTK.h index 5db4ed3a5..a1ce05969 100755 --- a/gtk/ScintillaGTK.h +++ b/gtk/ScintillaGTK.h @@ -235,6 +235,11 @@ private: void PreeditChangedInlineThis(); void PreeditChangedWindowedThis(); static void PreeditChanged(GtkIMContext *context, ScintillaGTK *sciThis); + bool RetrieveSurroundingThis(GtkIMContext *context); + static gboolean RetrieveSurrounding(GtkIMContext *context, ScintillaGTK *sciThis); + bool DeleteSurroundingThis(GtkIMContext *context, gint characterOffset, gint characterCount); + static gboolean DeleteSurrounding(GtkIMContext *context, gint characterOffset, gint characterCount, + ScintillaGTK *sciThis); void MoveImeCarets(Sci::Position pos); void DrawImeIndicator(int indicator, Sci::Position len); void SetCandidateWindowPos(); |