Search code examples
cgtkgladegtksourceview

C Gtk+2 Glade3: how can i set a SourceBuffer to a GtkSourceView that was loaded from glade?


I'm trying to load a .c file into a GtkSourceView widget.

Using C Language, with Gtk+ 2.22.1 and Glade 3.6.7 and GtkSourceView 2.10.1.

I noticed that in Glade UI I can only configure a SourceView to hold a TextBuffer; I did not find a SourceBuffer component. So, I created a SourceView in Glade without a default buffer. Now I want to set the SourceBuffer to be the buffer of my SourceView component.

gtk_source_view_new_with_buffer() is the only way I found to attach a SourceBuffer to a SourceView. The problem is that this function is creating a SourceView and I want to attach a SourceBuffer to an already created SourceView built with Glade. How can I do that?

I didn't paste any code because there is no code to show. I just created a Glade file with some UI component plus the SourceView-2 component with ID gtk_sourceview.

In the C file I fetch the SourceView component with

GtkSourceView *sourceview = GTK_WIDGET (gtk_builder_get_object (builder, "gtk_sourceview"));

What's missing is how to create a SourceBuffer and attach it to the SourceView component.

Thanks!

Update: I tried using:

GtkSourceBuffer *sourcebuffer = GTK_SOURCE_BUFFER(gtk_text_view_get_buffer(GTK_TEXT_VIEW(sourceview)));

But I got the following assert error:

(tour_de_gtk:13884): Gtk-CRITICAL **: IA__gtk_text_view_get_buffer: assertion `GTK_IS_TEXT_VIEW (text_view)' failed

What can I do to resolve this ?

Thanks!


Solution

  • The GtkSourceView already has a buffer. Get it the same way you get a regular text buffer:

    GtkSourceBuffer *buffer = GTK_SOURCE_BUFFER(gtk_text_view_get_buffer(GTK_TEXT_VIEW(source_view)));
    

    This is because GtkSourceView is a subclass of GtkTextView, so text view functions work on it too.

    EDIT:

    Here is a program and glade file that works.

    Program:

    #include <gtk/gtk.h>
    #include <gtksourceview/gtksourceview.h>
    #include <gtksourceview/gtksourcebuffer.h>
    #include <gtksourceview/gtksourcelanguagemanager.h>
    
    int
    main(int argc, char **argv)
    {
        gtk_init(&argc, &argv);
    
        GtkBuilder *builder = gtk_builder_new();
        if(gtk_builder_add_from_file(builder, "sourceview.ui", NULL) == 0)
            g_error("In real code, you would handle an error here");
        gtk_builder_connect_signals(builder, NULL);
    
        GtkWidget *window = GTK_WIDGET(gtk_builder_get_object(builder, "window"));
        GtkSourceView *sourceview = GTK_SOURCE_VIEW(gtk_builder_get_object(builder, "gtk_sourceview"));
    
        /* Get the buffer */
        GtkSourceBuffer *sourcebuffer = GTK_SOURCE_BUFFER(gtk_text_view_get_buffer(GTK_TEXT_VIEW(sourceview)));
    
        /* Do stuff to the buffer, to prove we've really got the GtkSourceBuffer */
        gtk_text_buffer_set_text(GTK_TEXT_BUFFER(sourcebuffer),
            "def hello():\n\tprint 'This should be highlighted as Python'\n", -1);
        GtkSourceLanguageManager *manager = gtk_source_language_manager_get_default();
        GtkSourceLanguage *python = gtk_source_language_manager_get_language(manager, "python");
        gtk_source_buffer_set_language(sourcebuffer, python);
    
        /* Okay, that should prove it, now run the program */
        gtk_widget_show_all(window);
        gtk_main();
    
        return 0;
    }
    

    Glade file:

    <?xml version="1.0" encoding="UTF-8"?>
    <interface>
      <!-- interface-requires gtksourceview 3.0 -->
      <requires lib="gtk+" version="2.20"/>
      <!-- interface-naming-policy project-wide -->
      <object class="GtkSourceBuffer" id="gtksourcebuffer">
        <property name="max_undo_levels">0</property>
      </object>
      <object class="GtkWindow" id="window">
        <property name="default_width">300</property>
        <property name="default_height">300</property>
        <signal name="destroy" handler="gtk_main_quit" swapped="no"/>
        <child>
          <object class="GtkScrolledWindow" id="scrolledwindow">
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="hscrollbar_policy">automatic</property>
            <property name="vscrollbar_policy">automatic</property>
            <child>
              <object class="GtkSourceView" id="gtk_sourceview">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="left_margin">2</property>
                <property name="right_margin">2</property>
                <property name="buffer">gtksourcebuffer</property>
                <property name="tab_width">4</property>
                <property name="auto_indent">True</property>
                <property name="indent_on_tab">False</property>
              </object>
            </child>
          </object>
        </child>
      </object>
    </interface>