如何检测 GtkTextBuffer 中的文本何时被替换而不是先删除再插入?

How to detect when text is replaced in GtkTextBuffer instead of delete followed by insert?

我在 Objective-C 中为 macOS/iOS 的文本系统(例如 NSTextView、NSTextStorage 等)做了很多工作。我现在正在试验 GTK3,看看我能多好地翻译我的在 Linux 等

上使用的项目

我是 GTK 的新手,但经过几天的 Google 时间和试验后,我有了一个工作的文本编辑器原型,其中插入了我的自定义代码。

问题是这样的——我需要能够检测到用户何时突出显示一段文本,然后将其替换为其他文本(例如击键)。这不同于突出显示一段文本,按下删除键,然后键入新文本。一个具体的使用示例是突出显示一个词,然后输入双引号字符以将该词括在引号中(例如 foo 变为 "foo")。

在 Cocoa 中,将收到 replaceCharactersInRange: 指示最初选择的范围,以及用于替换它的新字符串。然后我可以根据收到的信息检测用户的推测意图。

在 GTK 中,我们似乎收到一个 delete-range 信号,然后是一个单独的 insert-text 信号。由于这种分离,"insert" 部分中的代码无法知道用户打算替换文本,而不是插入新文本。

我使用以下方式接收上面的信号:

g_signal_connect(buffer, "insert-text", G_CALLBACK(insert_text_cb), NULL);
g_signal_connect(buffer, "delete-range", G_CALLBACK(delete_range_cb), NULL);

还有什么我可以做的来告诉有一个删除,然后插入作为同一用户操作的一部分?

感谢您的指点!

与其尝试关联删除和插入事件,我建议为您想要的操作创建一个 GAction(例如切换选定文本周围的引号)并将其快捷键设置为 使用 gtk_application_set_accels_for_action()

有关详细信息,请查看此 HowDoI 维基页面。

上个月没有答案,所以我一直在集思广益和挖掘。我终于想到了这个,它有效,但并不像我希望的那样优雅。

  1. 像以前一样处理 delete-range 信号,但为以后跟踪删除的文本(例如在 char * deletedText 中)。

  2. 像以前一样处理 insert-text 信号,但是如果我们在 deletedText 中有一个字符串,则更改行为以执行替换而不是插入。就我而言,这实际上意味着将删除的文本重新插入,然后执行替换。

  3. end-user-action 信号添加一个回调,表示与特定操作关联的所有 delete/inserts 已完成。在此回调中,从上面释放 deletedText 并设置为 NULL(表示已处理所有内容)。

同样 -- 这有效,但感觉有点不雅。根据您的 delete/insert 例程的复杂程度,它可能会稍微降低性能,因为某些步骤必须重复。更好的解决方案是在 delete-range 回调期间检测到有待处理的 insert-text 回调并同时处理这两个步骤。到目前为止,我还无法做到这一点。