aboutsummaryrefslogtreecommitdiffhomepage
path: root/gtk/ScintillaGTK.cxx
diff options
context:
space:
mode:
authorColomban Wendling <ban@herbesfolles.org>2023-01-27 21:09:40 +0100
committerColomban Wendling <ban@herbesfolles.org>2023-01-27 21:09:40 +0100
commit33f32a76dae02591faddc763284cfe4d7264b0b7 (patch)
tree408f4298c64488e3ffa2d868ac5589a57c0ee372 /gtk/ScintillaGTK.cxx
parentf4985491061752c483eb6ec315049ec992f7ed29 (diff)
downloadscintilla-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.
Diffstat (limited to 'gtk/ScintillaGTK.cxx')
-rwxr-xr-xgtk/ScintillaGTK.cxx63
1 files changed, 63 insertions, 0 deletions
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);
}