gtk_source_undo_manager_begin_not_undoable_action/gtk_source_undo_manager_end_not_undoable_action не работает

Я пытаюсь написать свой собственный текстовый редактор на C, используя gtk+-2.0 и gtksourceview-2.0. Я использовал источник gedit, когда застрял, но они, по-видимому, не используют эту функцию, и я не могу найти пример ее использования в Интернете. Когда я открываю текстовый файл и помещаю его содержимое в текстовый буфер, это регистрируется как действие, которое невозможно выполнить. Я хотел бы, чтобы этот процесс нельзя было отменить, поэтому я разместил:

gtk_source_undo_manager_begin_not_undoable_action(гм);

в начале моей функции open_activated (приведенной ниже) и:

gtk_source_undo_manager_end_not_undoable_action(гм);

в конце этой же функции. Согласно справке, предоставленной в devHelp, говорится, что все, что находится между этими двумя строками, не должно быть отменено, но это так. Что мне не хватает? Есть ли лучший способ реализовать ту же функциональность?

GtkSourceUndoManager *um; (defined globally)

void open_activated(GtkWidget *widget, GtkWindow *parent)
{
  GtkSourceLanguage *lang;
  GtkSourceLanguageManager *lm;
  GtkWidget *dialog;
  int pages = 0;
  GtkWidget *tablabel;

  gtk_source_undo_manager_begin_not_undoable_action(um);

  /* create new tab */
  tablabel = gtk_label_new("New File");
  pages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(notebook));
  gtk_container_add(GTK_CONTAINER(scrollwin[pages]),txtinput[pages]);
  gtk_widget_show_all (scrollwin[pages]);
  gtk_notebook_append_page(GTK_NOTEBOOK(notebook),scrollwin[pages],tablabel);
  //gtk_source_view_set_show_line_numbers (GTK_SOURCE_VIEW (txtinput[pages]), TRUE);
  gtk_notebook_set_current_page (GTK_NOTEBOOK(notebook), pages);

  //gtk_text_buffer_set_modified (gtk_text_view_get_buffer((GTK_TEXT_VIEW(txtinput[pages]))), TRUE);

  dialog = gtk_file_chooser_dialog_new("Open File", parent, GTK_FILE_CHOOSER_ACTION_OPEN,GTK_STOCK_CANCEL,GTK_RESPONSE_CANCEL,GTK_STOCK_OPEN,GTK_RESPONSE_ACCEPT,NULL);
  GtkTextBuffer *buffer;
  //buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(txtinput[gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook))]));
  buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(txtinput[pages]));


  if(gtk_dialog_run(GTK_DIALOG(dialog))== GTK_RESPONSE_ACCEPT)
  {
    char *path,*string;
    const gchar *filename;
    char temp[40];
    gsize length = -1;
    path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
    paths[pages] = path;
    filename = filenameFromPath(path);
    //printf("%s\n",out);
    strcpy(temp,filename);
    tablabel = gtk_label_new(temp);
    g_file_get_contents(path,&string,&length,NULL);     
    gtk_text_buffer_set_text(buffer,string,-1);

    /* syntax highlighting */
    lm = gtk_source_language_manager_new();
    lang = gtk_source_language_manager_guess_language (lm, path, NULL);
    gtk_source_buffer_set_language (GTK_SOURCE_BUFFER(buffer), lang);

    /* change tab label */
    gtk_notebook_set_tab_label (GTK_NOTEBOOK(notebook), scrollwin[pages], tablabel);

    /* set some sourceview options */
    gtk_source_view_set_show_line_numbers (GTK_SOURCE_VIEW (txtinput[pages]), TRUE);
    gtk_source_view_set_tab_width (GTK_SOURCE_VIEW (txtinput[pages]), 2);

    /* Set the editor's font. */
    PangoFontDescription *font_desc = pango_font_description_new();
    pango_font_description_set_family (font_desc, "monospace");
    gtk_widget_modify_font (txtinput[pages], font_desc);

    g_free(path);
    g_free(string);

  }

  gtk_widget_destroy(dialog);
  gtk_text_buffer_set_modified (gtk_text_view_get_buffer((GTK_TEXT_VIEW(txtinput[pages]))), FALSE);
  changeLabelColor("black");

  gtk_source_undo_manager_end_not_undoable_action(um);

}

К сожалению, нет ни gtk_source_undo_manager_new(), ни gtk_source_undo_manager_get_default(), как для языкового менеджера. Документация для GtkSourceUndoManager:

Описание

Интерфейс GtkSourceUndoManager может быть реализован для предоставления пользовательского управления отменой в GtkSourceBuffer. Используйте gtk_source_buffer_set_undo_manager для установки пользовательского менеджера отмены для определенного исходного буфера.

Используйте gtk_source_undo_manager_can_undo_changed и gtk_source_undo_manager_can_redo_changed, когда соответственно изменилось состояние отмены или повтора стека отмены.

Подробности

GtkSourceUndoManager

typedef struct _GtkSourceUndoManager GtkSourceUndoManager;

GtkSourceUndoManagerIface

typedef struct {
GTypeInterface parent;

/* Interface functions */
gboolean (*can_undo)                  (GtkSourceUndoManager *manager);
gboolean (*can_redo)                  (GtkSourceUndoManager *manager);

void     (*undo)                      (GtkSourceUndoManager *manager);
void     (*redo)                      (GtkSourceUndoManager *manager);

void     (*begin_not_undoable_action) (GtkSourceUndoManager *manager);
void     (*end_not_undoable_action)   (GtkSourceUndoManager *manager);

/* Signals */
void     (*can_undo_changed)          (GtkSourceUndoManager *manager);
void     (*can_redo_changed)          (GtkSourceUndoManager *manager);
} GtkSourceUndoManagerIface;

person nomadicME    schedule 03.05.2012    source источник
comment
Действительно ли ваш менеджер отмен как-то связан с буфером?   -  person ptomato    schedule 04.05.2012
comment
@ptomato, я думаю, проблема именно в этом. В документации сказано: Используйте gtk_source_buffer_set_undo_manager для установки пользовательского менеджера отмены для определенного исходного буфера. Однако в документации devhelp нет gtk_source_buffer_set_undo_manager. И я уже говорил, что не могу найти ни одного примера кода, как установить это соединение. Действия отмены/возврата работают правильно для каждого буфера на нескольких вкладках записной книжки без определения менеджера отмены (менеджер по умолчанию используется в соответствии с документами)   -  person nomadicME    schedule 04.05.2012


Ответы (1)


Если вы не реализуете собственный менеджер отмены, просто используйте вместо него gtk_source_buffer_begin_not_undoable_action().

person ptomato    schedule 04.05.2012
comment
Спасибо вам за ваши предложения. Я попробовал то, что вы предлагаете, но во время компиляции я получаю следующий вывод: ошибка: слишком мало аргументов для функции «gtk_source_undo_manager_begin_not_undoable_action» (то же самое для оператора end). Я могу заставить его скомпилироваться без круглых скобок (в обоих утверждениях), но когда я запускаю программу, она позволяет мне отменить шаг заполнения буфера, поэтому он не работает, несмотря на то, что позволяет мне скомпилировать его таким образом. - person nomadicME; 04.05.2012
comment
Извините, () — это просто типографское соглашение, показывающее, что это имя функции. Это была подсказка для вас, чтобы найти ее в DevHelp. Вызов функции должен быть чем-то вроде gtk_source_buffer_begin_not_undoable_action(GTK_SOURCE_BUFFER(buffer)); - person ptomato; 04.05.2012
comment
Он компилируется без круглых скобок, потому что имя функции без круглых скобок является адресом этой функции. Выполнение выражения без побочных эффектов ничего не делает, это в основном то же самое, что и оператор 2; - person ptomato; 04.05.2012
comment
Еще раз спасибо за вашу помощь в этом @ptomato. Я бы хотел, чтобы эта функция имела форму, которую вы предоставили, например, с исходным буфером в качестве аргумента. Если бы это было так, я бы здесь не спрашивал. Я просмотрел функцию в devhelp, требуемый аргумент - менеджер отмены: gtk_source_undo_manager_begin_not_undoable_action(GtkSourceUndoManager *manager); что приводит нас к версии, которую я изначально опубликовал в своем вопросе. Кажется, что для использования этой функции вам нужно явно определить диспетчер отмены, но способы, которые я пробовал, не работают. - person nomadicME; 04.05.2012
comment
когда я компилирую и выполняю программу, как я первоначально опубликовал, я получаю следующую ошибку при выполнении функции open_activate: GtkSourceView-CRITICAL **: gtk_source_undo_manager_end_not_undoable_action: утверждение `GTK_IS_SOURCE_UNDO_MANAGER (manager)' не удалось, поэтому я снова не определяю диспетчер отмены правильно, но я не знаю, почему я не могу просто использовать диспетчер по умолчанию, поскольку он работает для всех других операций отмены. Я просто не знаю, как это прописать. - person nomadicME; 04.05.2012
comment
Уверяю вас, что функцию использовать gtk_source_buffer_begin_not_undoable_action(), а не gtk_source_undo_manager_begin_not_undoable_action(). Вот ссылка на документацию: developer.gnome.org/gtksourceview/stable/ Я думаю, вы могли пропустить страницу из своей документации DevHelp, потому что у вас, по-видимому, тоже нет gtk_source_buffer_set_undo_manager(). - person ptomato; 04.05.2012
comment
извините, я не присмотрелся к вашему ответу раньше. Это такое длинное имя функции, что я не увидел разницы между gtk_source_buffer_begin_not_undoable_action и gtk_source_undo_manager_begin_not_undoable_action, они оба есть в документации. Спасибо, что поправили меня. Я исправил свой код, и все ведет себя так, как ожидалось. Еще раз спасибо! - person nomadicME; 05.05.2012