Как подключить GtkTextView к GtkMenuItem - PullRequest
2 голосов
/ 23 января 2010

Я создаю тривиальный текстовый редактор (как упражнение) в GTK, используя Glade, GtkBuilder и C. У меня есть меню редактирования с Cut, Copy и Paste, а также GtkTextView для текста. GtkTextView автоматически связывает последовательности вырезания / копирования / вставки для себя (и даже предоставляет пункты меню, если щелкнуть правой кнопкой мыши). Я хочу подключить элементы меню «Вырезать», «Копировать» и «Вставить» в строке меню к моему текстовому представлению, чтобы они работали как положено.

Обратите внимание, что это двустороннее соединение. (1) Когда один из GtkMenuItem's Cut, Copy или Paste активирован, он говорит GtkTextView что-то сделать. (2) Когда выбор сделан или очищен в GtkTextView, Cut и Copy включаются или отключаются соответственно (см. Пример gedit). Кроме того, (3) включение или отключение вставки зависит от состояния буфера обмена.

Как подключить пункты меню «Вырезать», «Копировать» и «Вставить» к текстовому представлению? Есть ли способ сделать это в Glade, или моей программе на C понадобится дополнительный код для этого? Есть ли упрощенный способ сделать это, или мне нужно вручную реализовать все три поведения, указанных в предыдущем параграфе?

1 Ответ

2 голосов
/ 23 января 2010

Вам понадобится дополнительный C-код, но не очень. В этом примере я предполагаю, что вы используете GtkAction s для своих пунктов меню, но если это не так, решение должно быть похожим.

Сначала выполните обратные вызовы для операций вырезания, копирования и вставки в Glade. Когда вы подключаете сигналы, передайте некоторую структуру данных, содержащую как минимум указатели, на действия вырезания, копирования и вставки, а также на представление текста в качестве пользовательских данных.

void
on_cut(GtkAction *action, SomeStruct *data)
{
    g_signal_emit_by_name(data->view, "cut-clipboard", NULL);
    gtk_action_set_sensitive(data->paste_action, TRUE);
}

void
on_copy(GtkAction *action, SomeStruct *data)
{
    g_signal_emit_by_name(data->view, "copy-clipboard", NULL);
    gtk_action_set_sensitive(data->paste_action, TRUE);
}

void
on_paste(GtkAction *action, SomeStruct *data)
{
    g_signal_emit_by_name(data->view, "paste-clipboard", NULL);
}

Далее подключитесь к сигналу notify::has-selection вашего GtkTextBuffer:

void
on_has_selection_notify(GtkTextBuffer *buffer, GParamSpec *pspec, SomeStruct *data)
{
    gboolean has_selection = gtk_text_buffer_get_has_selection(buffer);
    gtk_action_set_sensitive(data->cut_action, has_selection);
    gtk_action_set_sensitive(data->copy_action, has_selection);
}

Чтобы определить начальное состояние действия вставки (в случае, если при запуске приложения в буфере обмена есть текст), при создании интерфейса выполните следующий код:

gtk_action_set_sensitive(data->paste_action, 
    gtk_clipboard_wait_is_text_available(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD)));

Предполагается, что у пользователя нет возможности очистить буфер обмена вручную (большинство программ не позволяют вам сделать это.)

Предостерегающий лектор: код, введенный здесь, не проверен.

...