gtk_source_undo_manager_begin_not_undoable_action / gtk_source_undo_manager_end_not_undoable_action no funciona

I'm trying to write my own text editor in C using gtk+-2.0 & gtksourceview-2.0. I've been using the gedit source when I get stuck, but they apparently don't use this functionality and I can't find an example of its use online. When I open a text file and place its contents into the text buffer this is registered as an undoable action. I would like this process to be not undoable, so I have placed:

gtk_source_undo_manager_begin_not_undoable_action(um);

at the beginning of my open_activated function (provided below), and:

gtk_source_undo_manager_end_not_undoable_action(um);

at the end of this same function. According to the help provided in devHelp it says that everything in between these two lines should not be undoable, but it is. What am I missing? Is there a better way to accomplish this same functionality?

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);

}

Unfortunately there isn't any gtk_source_undo_manager_new () or gtk_source_undo_manager_get_default () like there is for the language manager. The documentation for the GtkSourceUndoManager is:

Descripción

The GtkSourceUndoManager interface can be implemented to provide custom undo management to a GtkSourceBuffer. Use gtk_source_buffer_set_undo_manager to install a custom undo manager for a particular source buffer.

Use gtk_source_undo_manager_can_undo_changed and gtk_source_undo_manager_can_redo_changed when respectively the undo state or redo state of the undo stack has changed.

Beneficios

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;

preguntado el 03 de mayo de 12 a las 20:05

Is your undo manager actually associated with the buffer somehow? -

@ptomato, That is where I think the problem lies. The documentation says: Use gtk_source_buffer_set_undo_manager to install a custom undo manager for a particular source buffer. However, there is no gtk_source_buffer_set_undo_manager in the devhelp docs. And I said before I can't find any example code for how to make that connection. The undo/redo actions are working properly for each buffer in the multiple notebook tabs without defining an undo manager (a default manager is used according to the docs) -

1 Respuestas

If you're not implementing a custom undo manager, then just use gtk_source_buffer_begin_not_undoable_action() preferiblemente.

contestado el 04 de mayo de 12 a las 07:05

thank you for your suggestions. I have tried what you suggest, I get the following output during compile: error: too few arguments to function ‘gtk_source_undo_manager_begin_not_undoable_action’ (same for the end statement). I can get it to compile without the parentheses (on both statements), but when I run the program it allows me to undo the populating the buffer step, so it doesn't appear to work despite allowing me to compile it this way. - nómadaME

Lo siento, el () is just a typographical convention for showing that it's the name of a function. It was a clue for you to look it up in your DevHelp. The function call should be something like gtk_source_buffer_begin_not_undoable_action(GTK_SOURCE_BUFFER(buffer)); - tomate

It compiles without parentheses because the name of a function without parentheses is the address of that function. Executing an expression without side effects does nothing, it's basically the same as the statement 2; - tomate

Thank you again for you help on this @ptomato. I wish this function were of the form you provided for example, with the source buffer as the argument. If it were I would not be here asking. I have looked up the function in devhelp the argument required is the undo manager: gtk_source_undo_manager_begin_not_undoable_action(GtkSourceUndoManager *manager); which brings us full circle to version that I originally posted in my question. It seems to use this function you need to explicitly define an undo manager, but the ways I have tried do not work. - nómadaME

when I compile and execute the program as I originally posted, I get the following error when the open_activate function is executed: GtkSourceView-CRITICAL **: gtk_source_undo_manager_end_not_undoable_action: assertion `GTK_IS_SOURCE_UNDO_MANAGER (manager)' failed, so again I am not defining the undo manager properly, but I don't know why I can't just use the default manager since it is working for all other undo operations. I just don't know how to prescribe that. - nómadaME

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.