Вопрос

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

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

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

Это было полезно?

Решение

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

Сначала создайте обратные вызовы для действий вырезания, копирования и вставки в 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)));

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top