Log note :
changed:
-
Proposal to add support for UIManager in libglade

  Here I'll describe a proposal about what changes need to be made in the <a href="http://glade.gnome.org/glade-2.0.dtd">Glade DTD</a> specification in order to support UIManager. Obviously these changes will need modifications in libglade in order to work.

Motivation

  A UIManager object is a new GTK+ 2.4 feature designed to make Menubars and Toolbars easier to use in GTK+ Programs but, as they are not supported yet in <a href="http://glade.gnome.org/">Glade-2</a>, which is the most used program for designing GTK+ User Interfaces, we are stuck in two situations:

- People don't use UIManager at all and keep using old style Menubars and Toolbars (the ones supported by Glade-2)

- People don't use Glade-2 to design their Menubars and Toolbars and write that code in their programs

So neither of these solutions looks good

Technical problems

  Currently, libglade (the glue between Glade-like-programs and applications that use .glade files) has some limitations about the objects it can handle. The DTD of the .glade files only knows about GtkWidget objects. UIManager is GObject but not a GtkWidget so this is the biggest issue here. Note that UIManager is not the only affected here: GtkSizeGroup, GtkTreeViewColumn, GtkCellRenderer are only some more examples.

Fortunately there are some bugs in bugzilla.gnome.org about this issue:

- <a href="http://bugzilla.gnome.org/show_bug.cgi?id=69639">#69639</a>

- <a href="http://bugzilla.gnome.org/show_bug.cgi?id=161903">#161903</a>

- <a href="http://bugzilla.gnome.org/show_bug.cgi?id=161874">#161874</a>

Possible solution for UIManager

  An UIManager object has basically two types of data:

- A list of GtkActionGroups which contains GtkActions

- A XML representation of the User Interface

So, what I suggest is saving the list of GtkActionGroups in the .glade file and the XML representation in another file to avoid big changes in the Glade DTD and libglade. Let's see the example glade file *uimanager-example.glade*:

<pre>
&lt;?xml version="1.0" ?&gt;
&lt;glade-interface&gt;
    &lt;requires prefix="Gtk" lib="gtk"/&gt;
    &lt;object class="GtkUIManager" ui="uimanager" &gt;
        &lt;child&gt;
            &lt;object class="GtkActionGroup" id="DefaultActions"&gt;
                &lt;child&gt;
                    &lt;object class="GtkAction" id="FileMenu"&gt;
                        &lt;property name="label"&gt;_File&lt;/property&gt;
                    &lt;/object&gt;
                &lt;/child&gt;
                &lt;child&gt;
                    &lt;object class="GtkAction" id="New"&gt;
                        &lt;property name="label"&gt;_New&lt;/property&gt;
                        &lt;property name="tooltip"&gt;Create a new file&lt;/property&gt;
                        &lt;property name="stock_id"&gt;gtk-new&lt;/property&gt;
                    &lt;/object&gt;
                &lt;/child&gt;
                &lt;child&gt;
                    &lt;object class="GtkAction" id="Open"&gt;
                        &lt;property name="label"&gt;_Open&lt;/property&gt;
                        &lt;property name="tooltip"&gt;Open a file&lt;/property&gt;
                        &lt;property name="stock_id"&gt;gtk-open&lt;/property&gt;
                        &lt;property name="accelerator"&gt;&amp;lt;control&amp;gt;O&lt;/property&gt;
                    &lt;/object&gt;
                &lt;/child&gt;
                &lt;child&gt;
                    &lt;object class="GtkAction" id="Save"&gt;
                        &lt;property name="label"&gt;_Save&lt;/property&gt;
                        &lt;property name="tooltip"&gt;Save a file&lt;/property&gt;
                        &lt;property name="stock_id"&gt;gtk-save&lt;/property&gt;
                        &lt;property name="accelerator"&gt;&amp;lt;control&amp;gt;S&lt;/property&gt;
                    &lt;/object&gt;
                &lt;/child&gt;
                &lt;child&gt;
                    &lt;object class="GtkAction" id="SaveAs"&gt;
                        &lt;property name="label"&gt;Save _as&lt;/property&gt;
                        &lt;property name="tooltip"&gt;Save with a differente name&lt;/property&gt;
                        &lt;property name="stock_id"&gt;gtk-save-as&lt;/property&gt;
                    &lt;/object&gt;
                &lt;/child&gt;
                &lt;child&gt;
                    &lt;object class="GtkAction" id="Quit"&gt;
                        &lt;property name="label"&gt;_Quit&lt;/property&gt;
                        &lt;property name="tooltip"&gt;Quit the program&lt;/property&gt;
                        &lt;property name="stock_id"&gt;gtk-quit&lt;/property&gt;
                        &lt;property name="callback"&gt;on_qui__activated&lt;/property&gt;
                        &lt;property name="accelerator"&gt;&amp;lt;control&amp;gt;Q&lt;/property&gt;
                    &lt;/object&gt;
                &lt;/child&gt;
                &lt;child&gt;
                    &lt;object class="GtkAction" id="EditMenu"&gt;
                        &lt;property name="label"&gt;_Edit&lt;/property&gt;
                    &lt;/object&gt;
                &lt;/child&gt;
                &lt;child&gt;
                    &lt;object class="GtkAction" id="Copy"&gt;
                        &lt;property name="label"&gt;_Copy&lt;/property&gt;
                        &lt;property name="tooltip"&gt;Copy selected object into the clipboard&lt;/property&gt;
                        &lt;property name="stock_id"&gt;gtk-copy&lt;/property&gt;
                        &lt;property name="accelerator"&gt;&amp;lt;control&amp;gt;C&lt;/property&gt;
                    &lt;/object&gt;
                &lt;/child&gt;
                &lt;child&gt;
                    &lt;object class="GtkAction" id="Cut"&gt;
                        &lt;property name="label"&gt;C_ut&lt;/property&gt;
                        &lt;property name="tooltip"&gt;Cut selected object into the clipboard&lt;/property&gt;
                        &lt;property name="stock_id"&gt;gtk-cut&lt;/property&gt;
                        &lt;property name="accelerator"&gt;&amp;lt;control&amp;gt;X&lt;/property&gt;
                    &lt;/object&gt;
                &lt;/child&gt;
                &lt;child&gt;
                    &lt;object class="GtkAction" id="Paste"&gt;
                        &lt;property name="label"&gt;_Paste&lt;/property&gt;
                        &lt;property name="tooltip"&gt;Paste object from the Clipboard&lt;/property&gt;
                        &lt;property name="stock_id"&gt;gtk-paste&lt;/property&gt;
                        &lt;property name="accelerator"&gt;&amp;lt;control&amp;gt;V&lt;/property&gt;
                    &lt;/object&gt;
                &lt;/child&gt;
            &lt;/object&gt;
        &lt;/child&gt;
    &lt;/object&gt;
    &lt;widget class="GtkWindow" id="window1"&gt;
        &lt;child&gt;
            &lt;widget class="GtkMenuBar" id="menubar1"&gt;
                &lt;property name="ui"&gt;&lt;![CDATA[
      &lt;menubar action="menubar1" name="menubar1"&gt;
            &lt;menu action="FileMenu" name="FileMenu"&gt;
                  &lt;menuitem action="New" name="New"/&gt;
                  &lt;menuitem action="Open" name="Open"/&gt;
                  &lt;menuitem action="Save" name="Save"/&gt;
                  &lt;menuitem action="SaveAs" name="SaveAs"/&gt;
                  &lt;separator/&gt;
                  &lt;menuitem action="Quit" name="Quit"/&gt;
	    &lt;/menu&gt;
            &lt;menu action="EditMenu" name="EditMenu"&gt;
                  &lt;menuitem action="Copy" name="Copy"/&gt;
                  &lt;menuitem action="Cut" name="Cut"/&gt;
                  &lt;menuitem action="Paste" name="Paste"/&gt;
	    &lt;/menu&gt;
      &lt;menubar&gt;
                ]]&gt;&lt;/property&gt;
            &lt;/widget&gt;
        &lt;/child&gt;
    &lt;/widget&gt;
&lt;/glade-interface&gt;
</pre>

As you can see the *ui* property of the GtkMenuBar object has a CDATA section with the UI Definition for this widget. This way the whole UI
Definition of the UIManager is splited in the main components (Toolbars, Menubars, Context Menus) so the user can later merge and unmerge them
independently, which is one of the advantages of using UI Manager. Currently, Gazpacho implementation store the merge id of these widgets in a gobject data section called 'merge_id' using the GObject.set_data() method.

In this solution libglade would build the UIManager first and when it reaches to the GtkMenuBar object it would try to obtain it from the uimanager instead of creating it from scratch. Possibly some accessor for the uimanager would also be added.

Advantages and disadvantages of this approach

  Advantages:

- Does not need a lot of changes in libglade

- As result of the above, backward compatibility could be preserved

Disadvantages:

- The UIManager object need to be placed *before* all Menubars and Toolbars in the glade file