如何检测 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 维基页面。
上个月没有答案,所以我一直在集思广益和挖掘。我终于想到了这个,它有效,但并不像我希望的那样优雅。
像以前一样处理 delete-range
信号,但为以后跟踪删除的文本(例如在 char * deletedText
中)。
像以前一样处理 insert-text
信号,但是如果我们在 deletedText
中有一个字符串,则更改行为以执行替换而不是插入。就我而言,这实际上意味着将删除的文本重新插入,然后执行替换。
为 end-user-action
信号添加一个回调,表示与特定操作关联的所有 delete/inserts 已完成。在此回调中,从上面释放 deletedText
并设置为 NULL
(表示已处理所有内容)。
同样 -- 这有效,但感觉有点不雅。根据您的 delete/insert 例程的复杂程度,它可能会稍微降低性能,因为某些步骤必须重复。更好的解决方案是在 delete-range
回调期间检测到有待处理的 insert-text
回调并同时处理这两个步骤。到目前为止,我还无法做到这一点。
我在 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 维基页面。
上个月没有答案,所以我一直在集思广益和挖掘。我终于想到了这个,它有效,但并不像我希望的那样优雅。
像以前一样处理
delete-range
信号,但为以后跟踪删除的文本(例如在char * deletedText
中)。像以前一样处理
insert-text
信号,但是如果我们在deletedText
中有一个字符串,则更改行为以执行替换而不是插入。就我而言,这实际上意味着将删除的文本重新插入,然后执行替换。为
end-user-action
信号添加一个回调,表示与特定操作关联的所有 delete/inserts 已完成。在此回调中,从上面释放deletedText
并设置为NULL
(表示已处理所有内容)。
同样 -- 这有效,但感觉有点不雅。根据您的 delete/insert 例程的复杂程度,它可能会稍微降低性能,因为某些步骤必须重复。更好的解决方案是在 delete-range
回调期间检测到有待处理的 insert-text
回调并同时处理这两个步骤。到目前为止,我还无法做到这一点。