[dia] app: DiaBuilder, utilities for working with ui files



commit d50d6787fced87d953881ba7aa26d11aad7f472f
Author: Zander Brown <zbrown gnome org>
Date:   Fri May 1 02:57:27 2020 +0100

    app: DiaBuilder, utilities for working with ui files

 app/dia-builder.c                | 365 +++++++++++++++++++++++++++++++++++++++
 app/dia-builder.h                |  57 ++++++
 app/dia-props.c                  |  70 +++-----
 app/menus.c                      | 115 ++++++------
 app/menus.h                      |  31 ++--
 app/meson.build                  |   4 +-
 app/preferences.h                |  12 +-
 app/sheet-editor/sheets_dialog.c | 156 ++++++++++++-----
 data/ui/properties-dialog.ui     |   3 +
 docs/dia-app/dia-app-docs.xml    |   1 +
 10 files changed, 651 insertions(+), 163 deletions(-)
---
diff --git a/app/dia-builder.c b/app/dia-builder.c
new file mode 100644
index 00000000..e3c95ca1
--- /dev/null
+++ b/app/dia-builder.c
@@ -0,0 +1,365 @@
+/* Dia -- an diagram creation/manipulation program
+ * Copyright (C) 1998 Alexander Larsson
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Copyright © 2020 Zander Brown <zbrown gnome org>
+ */
+
+#include "dia-builder.h"
+#include "dia_dirs.h"
+
+
+typedef struct _DiaBuilderPrivate DiaBuilderPrivate;
+struct _DiaBuilderPrivate {
+  GHashTable *callbacks;
+
+  gboolean already_connected;
+};
+
+
+G_DEFINE_TYPE_WITH_PRIVATE (DiaBuilder, dia_builder, GTK_TYPE_BUILDER)
+
+
+/**
+ * SECTION:dia-builder
+ * @title: DiaBuilder
+ * @short_description: Enhanced GtkBuilder
+ *
+ * DiaBuilder extends #GtkBuilder with utilities for faking templates in gtk2
+ */
+
+
+static void
+dia_builder_finalize (GObject *object)
+{
+  DiaBuilder *self = DIA_BUILDER (object);
+  DiaBuilderPrivate *priv = dia_builder_get_instance_private (self);
+
+  g_clear_pointer (&priv->callbacks, g_hash_table_destroy);
+
+  G_OBJECT_CLASS (dia_builder_parent_class)->finalize (object);
+}
+
+
+static void
+dia_builder_class_init (DiaBuilderClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = dia_builder_finalize;
+}
+
+
+static void
+dia_builder_init (DiaBuilder *self)
+{
+
+}
+
+
+/**
+ * dia_builder_new:
+ * @path: path to load, relative to the datadir
+ *
+ * Returns: The new #DiaBuilder
+ *
+ * Since: 0.98
+ */
+DiaBuilder *
+dia_builder_new (const char *path)
+{
+  GError *error = NULL;
+  char *uifile;
+  DiaBuilder *builder;
+
+  builder = g_object_new (DIA_TYPE_BUILDER, NULL);
+  uifile = dia_builder_path (path);
+  if (!gtk_builder_add_from_file (GTK_BUILDER (builder), uifile, &error)) {
+    g_warning ("Couldn't load builder file: %s", error->message);
+  }
+
+  g_clear_error (&error);
+  g_clear_pointer (&uifile, g_free);
+
+  return builder;
+}
+
+
+/**
+ * dia_builder_get:
+ * @self: the #DiaBuilder
+ * @first_object_name: the name of the first object to get
+ * @...: where to put the first object, followed optionally by more
+ * name/target pairs, followed by %NULL
+ *
+ * Get various objects from @self
+ *
+ * |[<!-- language="C" -->
+ * GtkWidget *widget;
+ * GtkWidget *other_widget;
+ *
+ * dia_builder_get (builder,
+ *                  "widget", &widget,
+ *                  "other-widget", &other_widget,
+ *                  NULL);
+ * ]|
+ *
+ * Since: 0.98
+ */
+void
+dia_builder_get (DiaBuilder *self,
+                 const char *first_object_name,
+                 ...)
+{
+  va_list var_args;
+  const char *object_name;
+  GObject **object_target;
+
+  g_return_if_fail (DIA_IS_BUILDER (self));
+  g_return_if_fail (first_object_name && first_object_name[0]);
+
+  object_name = first_object_name;
+
+  va_start (var_args, first_object_name);
+
+  object_target = va_arg (var_args, GObject **);
+
+  do {
+    *object_target = gtk_builder_get_object (GTK_BUILDER (self),
+                                             object_name);
+
+    object_name = va_arg (var_args, const char *);
+
+    if (object_name) {
+      object_target = va_arg (var_args, GObject **);
+    }
+  } while (object_name != NULL);
+
+  va_end (var_args);
+}
+
+
+/**
+ * dia_builder_connect:
+ * @self: the #DiaBuilder
+ * @data: the user_data passed to handlers
+ * @first_signal_name: the name of the first signal handler
+ * @first_signal_symbol: the first signal handler
+ * @...: additional signal/handler pairs, followed by %NULL
+ *
+ * Bind handlers to callbacks defined in the source file
+ *
+ * Once dia_builder_connect_signals() has been called (including by this
+ * method) you cannot call it again on @self
+ *
+ * |[<!-- language="C" -->
+ * dia_builder_connect (builder,
+ *                      "widget_changed", G_CALLBACK (widget_changed),
+ *                      "other_widget_clicked", G_CALLBACK (other_widget_clicked),
+ *                      NULL);
+ * ]|
+ *
+ * Since: 0.98
+ */
+void
+dia_builder_connect (DiaBuilder *self,
+                     gpointer    data,
+                     const char *first_signal_name,
+                     GCallback   first_signal_symbol,
+                     ...)
+{
+  va_list var_args;
+  const char *signal_name;
+  GCallback signal_symbol;
+
+  g_return_if_fail (DIA_IS_BUILDER (self));
+  g_return_if_fail (first_signal_name && first_signal_name[0]);
+  g_return_if_fail (first_signal_symbol != NULL);
+
+  signal_name = first_signal_name;
+  signal_symbol = first_signal_symbol;
+
+  va_start (var_args, first_signal_symbol);
+
+  do {
+    dia_builder_add_callback_symbol (self,
+                                     signal_name,
+                                     signal_symbol);
+
+    signal_name = va_arg (var_args, const char *);
+
+    if (signal_name) {
+      signal_symbol = va_arg (var_args, GCallback);
+    }
+
+  } while (signal_name != NULL);
+
+  va_end (var_args);
+
+  dia_builder_connect_signals (self, data);
+}
+
+
+/**
+ * dia_builder_add_callback_symbol:
+ * @self: the #DiaBuilder
+ * @callback_name: the name of the signal handler
+ * @callback_symbol: the signal handler
+ *
+ * Bind a handlers to a callback defined in the source file
+ *
+ * Since: 0.98
+ */
+void
+dia_builder_add_callback_symbol (DiaBuilder *self,
+                                 const char *callback_name,
+                                 GCallback   callback_symbol)
+{
+  DiaBuilderPrivate *priv;
+
+  g_return_if_fail (DIA_IS_BUILDER (self));
+  g_return_if_fail (callback_name && callback_name[0]);
+  g_return_if_fail (callback_symbol != NULL);
+
+  priv = dia_builder_get_instance_private (self);
+
+  if (!priv->callbacks) {
+    priv->callbacks = g_hash_table_new_full (g_str_hash, g_str_equal,
+                                                      g_free, NULL);
+  }
+
+  g_hash_table_insert (priv->callbacks,
+                       g_strdup (callback_name),
+                       callback_symbol);
+}
+
+
+/**
+ * dia_builder_lookup_callback_symbol:
+ * @self: the #DiaBuilder
+ * @callback_name: the name of the signal handler
+ *
+ * Get the #GCallback associated with @callback_name
+ *
+ * Returns: The #GCallback previously set for @callback_name, or %NULL
+ *
+ * Since: 0.98
+ */
+GCallback
+dia_builder_lookup_callback_symbol (DiaBuilder *self,
+                                    const char *callback_name)
+{
+  DiaBuilderPrivate *priv;
+
+  g_return_val_if_fail (DIA_IS_BUILDER (self), NULL);
+  g_return_val_if_fail (callback_name && callback_name[0], NULL);
+
+  priv = dia_builder_get_instance_private (self);
+
+  if (!priv->callbacks)
+    return NULL;
+
+  return g_hash_table_lookup (priv->callbacks, callback_name);
+}
+
+
+static void
+connect_signals (GtkBuilder    *builder,
+                 GObject       *object,
+                 const char    *signal_name,
+                 const char    *handler_name,
+                 GObject       *connect_object,
+                 GConnectFlags  flags,
+                 gpointer       data)
+{
+  GCallback func;
+
+  func = dia_builder_lookup_callback_symbol (DIA_BUILDER (builder),
+                                             handler_name);
+
+  if (!func) {
+    g_warning ("Could not find signal handler “%s”", handler_name);
+    return;
+  }
+
+  if (connect_object) {
+    g_signal_connect_object (object, signal_name, func, connect_object, flags);
+  } else {
+    g_signal_connect_data (object, signal_name, func, data, NULL, flags);
+  }
+}
+
+
+/**
+ * dia_builder_connect_signals:
+ * @self: the #DiaBuilder
+ * @user_data: the user_data to pass to handlers
+ *
+ * Connect all the handlers previously set with
+ * dia_builder_lookup_callback_symbol() to their various objects
+ *
+ * This can only be called once on @self ( dia_builder_connect() uses this
+ * method internally)
+ *
+ * Since: 0.98
+ */
+void
+dia_builder_connect_signals (DiaBuilder *self,
+                             gpointer    user_data)
+{
+  DiaBuilderPrivate *priv;
+
+  g_return_if_fail (DIA_IS_BUILDER (self));
+
+  priv = dia_builder_get_instance_private (self);
+
+  g_return_if_fail (!priv->already_connected);
+
+  gtk_builder_connect_signals_full (GTK_BUILDER (self),
+                                    connect_signals,
+                                    user_data);
+
+  priv->already_connected = TRUE;
+}
+
+
+/**
+ * dia_builder_path:
+ * @name: the filename to get a path for
+ *
+ * Get the fallpath to @name located in the datadir
+ *
+ * Note: dia_builder_new will call this for you
+ *
+ * Returns: the newly allocated path
+ *
+ * Since: 0.98
+ */
+char *
+dia_builder_path (const char* name)
+{
+  char* uifile;
+
+  if (g_getenv ("DIA_BASE_PATH") != NULL) {
+    uifile = g_build_filename (g_getenv ("DIA_BASE_PATH"), "data", name, NULL);
+  } else {
+    uifile = dia_get_data_directory (name);
+  }
+
+  return uifile;
+}
diff --git a/app/dia-builder.h b/app/dia-builder.h
new file mode 100644
index 00000000..37096654
--- /dev/null
+++ b/app/dia-builder.h
@@ -0,0 +1,57 @@
+/* Dia -- an diagram creation/manipulation program
+ * Copyright (C) 1998 Alexander Larsson
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Copyright © 2020 Zander Brown <zbrown gnome org>
+ */
+
+#pragma once
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+struct _DiaBuilder {
+  GtkBuilder parent;
+};
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (GtkBuilder, g_object_unref)
+
+#define DIA_TYPE_BUILDER dia_builder_get_type()
+G_DECLARE_FINAL_TYPE (DiaBuilder, dia_builder, DIA, BUILDER, GtkBuilder)
+
+
+DiaBuilder *dia_builder_new                    (const char *path);
+void        dia_builder_get                    (DiaBuilder *self,
+                                                const char *first_object_name,
+                                                ...);
+void        dia_builder_connect                (DiaBuilder *self,
+                                                gpointer    data,
+                                                const char *first_signal_name,
+                                                GCallback   first_signal_symbol,
+                                                ...);
+void        dia_builder_add_callback_symbol    (DiaBuilder *self,
+                                                const char *callback_name,
+                                                GCallback   callback_symbol);
+GCallback   dia_builder_lookup_callback_symbol (DiaBuilder *self,
+                                                const char *callback_name);
+void        dia_builder_connect_signals        (DiaBuilder *self,
+                                                gpointer    user_data);
+char       *dia_builder_path                   (const char *name);
+
+G_END_DECLS
diff --git a/app/dia-props.c b/app/dia-props.c
index d0534ac1..17ac2920 100644
--- a/app/dia-props.c
+++ b/app/dia-props.c
@@ -30,7 +30,7 @@
 #include "widgets.h"
 #include "display.h"
 #include "undo.h"
-#include "menus.h"
+#include "dia-builder.h"
 
 
 typedef struct _DiaDiagramPropertiesDialogPrivate DiaDiagramPropertiesDialogPrivate;
@@ -264,9 +264,7 @@ dia_diagram_properties_dialog_init (DiaDiagramPropertiesDialog *self)
   DiaDiagramPropertiesDialogPrivate *priv = dia_diagram_properties_dialog_get_instance_private (self);
   GtkWidget *dialog_vbox;
   GtkWidget *notebook;
-  GError *error = NULL;
-  gchar *uifile;
-  GtkBuilder *builder;
+  DiaBuilder *builder;
 
   gtk_dialog_add_buttons (GTK_DIALOG (self),
                           _("_Close"), GTK_RESPONSE_CANCEL,
@@ -283,48 +281,34 @@ dia_diagram_properties_dialog_init (DiaDiagramPropertiesDialog *self)
                     G_CALLBACK (gtk_widget_destroyed), &self);
 
   /* Load UI */
-  builder = gtk_builder_new ();
-  uifile = build_ui_filename ("ui/properties-dialog.ui");
-  if (!gtk_builder_add_from_file (builder, uifile, &error)) {
-    g_warning ("Couldn't load builder file: %s", error->message);
-    g_clear_error (&error);
-  }
-  g_clear_pointer (&uifile, g_free);
+  builder = dia_builder_new ("ui/properties-dialog.ui");
+
+  dia_builder_get (builder,
+                   "notebook", &notebook,
+                   /* Grid Page */
+                   "dynamic", &priv->dynamic,
+                   "manual", &priv->manual,
+                   "manual_props", &priv->manual_props,
+                   "hex", &priv->hex,
+                   "hex_props", &priv->hex_props,
+                   "spacing_x", &priv->spacing_x,
+                   "spacing_y", &priv->spacing_y,
+                   "vis_spacing_x", &priv->vis_spacing_x,
+                   "vis_spacing_y", &priv->vis_spacing_y,
+                   "hex_size", &priv->hex_size,
+                   /* The background page */
+                   "background", &priv->background,
+                   "grid_lines", &priv->grid_lines,
+                   "page_lines", &priv->page_lines,
+                   "guide_lines", &priv->guide_lines,
+                   NULL);
 
-  notebook = GTK_WIDGET (gtk_builder_get_object (builder, "notebook"));
   gtk_box_pack_start (GTK_BOX (dialog_vbox), notebook, TRUE, TRUE, 0);
 
-  /* Grid Page */
-  priv->dynamic = GTK_WIDGET (gtk_builder_get_object (builder, "dynamic"));
-  g_signal_connect (G_OBJECT (priv->dynamic),
-                    "toggled",
-                    G_CALLBACK (update_sensitivity),
-                    self);
-  priv->manual = GTK_WIDGET (gtk_builder_get_object (builder, "manual"));
-  g_signal_connect (G_OBJECT (priv->manual),
-                    "toggled",
-                    G_CALLBACK (update_sensitivity),
-                    self);
-  priv->manual_props = GTK_WIDGET (gtk_builder_get_object (builder, "manual_props"));
-  priv->hex = GTK_WIDGET (gtk_builder_get_object (builder, "hex"));
-  g_signal_connect (G_OBJECT (priv->hex),
-                    "toggled",
-                    G_CALLBACK (update_sensitivity),
-                    self);
-  priv->hex_props = GTK_WIDGET (gtk_builder_get_object (builder, "hex_props"));
-
-  priv->spacing_x = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "spacing_x"));
-  priv->spacing_y = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "spacing_y"));
-  priv->vis_spacing_x = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "vis_spacing_x"));
-  priv->vis_spacing_y = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "vis_spacing_y"));
-  priv->hex_size = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "hex_size"));
-
-  /* The background page */
-
-  priv->background = GTK_WIDGET (gtk_builder_get_object (builder, "background"));
-  priv->grid_lines = GTK_WIDGET (gtk_builder_get_object (builder, "grid_lines"));
-  priv->page_lines = GTK_WIDGET (gtk_builder_get_object (builder, "page_lines"));
-  priv->guide_lines = GTK_WIDGET (gtk_builder_get_object (builder, "guide_lines"));
+  dia_builder_connect (builder,
+                       self,
+                       "update_sensitivity", G_CALLBACK (update_sensitivity),
+                       NULL);
 
   g_clear_object (&builder);
 }
diff --git a/app/menus.c b/app/menus.c
index 369cf582..dcc1ef1d 100644
--- a/app/menus.c
+++ b/app/menus.c
@@ -42,6 +42,8 @@
 #include "objchange.h"
 #include "toolbox.h"
 #include "diagram_tree.h"
+#include "dia-builder.h"
+
 
 #define DIA_STOCK_GROUP "dia-stock-group"
 #define DIA_STOCK_UNGROUP "dia-stock-ungroup"
@@ -63,8 +65,6 @@ static GtkWidget *create_integrated_ui_toolbar (void);
 
 static void add_plugin_actions (GtkUIManager *ui_manager, const char *base_path);
 
-gchar *build_ui_filename (const gchar* name);
-
 /* Active/inactive state is set in diagram_update_menu_sensitivity()
  * in diagram.c */
 
@@ -351,9 +351,12 @@ load_accels (void)
   }
 }
 
+
 /**
+ * integrated_ui_toolbar_object_snap_synchronize_to_display:
+ * @param: #DDisplay to synchronize to.
+ *
  * Synchronized the Object snap property button with the display.
- * @param param Display to synchronize to.
  */
 void
 integrated_ui_toolbar_object_snap_synchronize_to_display (gpointer param)
@@ -369,8 +372,12 @@ integrated_ui_toolbar_object_snap_synchronize_to_display (gpointer param)
 
 
 /**
+ * integrated_ui_toolbar_guides_snap_synchronize_to_display:
+ * @param: #DDisplay to synchronize to.
+ *
  * Synchronized the snap-to-guide property button with the display.
- * @param param Display to synchronize to.
+ *
+ * Since: dawn-of-time
  */
 void
 integrated_ui_toolbar_guides_snap_synchronize_to_display (gpointer param)
@@ -386,9 +393,13 @@ integrated_ui_toolbar_guides_snap_synchronize_to_display (gpointer param)
 
 
 /**
+ * integrated_ui_toolbar_object_snap_toggle:
+ * @b: Object snap toggle button.
+ * @not_used: unused
+ *
  * Sets the Object-snap property for the active display.
- * @param b Object snap toggle button.
- * @param not_used
+ *
+ * Since: dawn-of-time
  */
 static void
 integrated_ui_toolbar_object_snap_toggle (GtkToggleButton *b,
@@ -402,12 +413,16 @@ integrated_ui_toolbar_object_snap_toggle (GtkToggleButton *b,
 
 
 /**
+ * integrated_ui_toolbar_guide_snap_toggle:
+ * @b: Guide snap toggle button.
+ * @not_used: unused
+ *
  * Sets the Guide-snap property for the active display.
- * @param b Guide snap toggle button.
- * @param not_used
+ *
+ * Since: dawn-of-time
  */
 static void
-integrated_ui_toolbar_guide_snap_toggle(GtkToggleButton *b, gpointer *not_used)
+integrated_ui_toolbar_guide_snap_toggle (GtkToggleButton *b, gpointer *not_used)
 {
   DDisplay *ddisp = ddisplay_active ();
   if (ddisp) {
@@ -417,8 +432,12 @@ integrated_ui_toolbar_guide_snap_toggle(GtkToggleButton *b, gpointer *not_used)
 
 
 /**
+ * integrated_ui_toolbar_grid_snap_synchronize_to_display:
+ * @param: #DDisplay to synchronize to.
+ *
  * Synchronizes the Snap-to-grid property button with the display.
- * @param param Display to synchronize to.
+ *
+ * Since: dawn-of-time
  */
 void
 integrated_ui_toolbar_grid_snap_synchronize_to_display (gpointer param)
@@ -432,10 +451,15 @@ integrated_ui_toolbar_grid_snap_synchronize_to_display (gpointer param)
   }
 }
 
+
 /**
+ * integrated_ui_toolbar_grid_snap_toggle:
+ * @b: Snap to grid toggle button.
+ * @not_used: unused
+ *
  * Sets the Snap-to-grid property for the active display.
- * @param b Snap to grid toggle button.
- * @param not_used
+ *
+ * Since: dawn-of-time
  */
 static void
 integrated_ui_toolbar_grid_snap_toggle (GtkToggleButton *b, gpointer *not_used)
@@ -446,13 +470,18 @@ integrated_ui_toolbar_grid_snap_toggle (GtkToggleButton *b, gpointer *not_used)
   }
 }
 
+
 /**
+ * integrated_ui_toolbar_set_zoom_text:
+ * @toolbar: Integrated UI toolbar.
+ * @text: Current zoom percentage for the active window
+ *
  * Sets the zoom text for the toolbar
- * @param toolbar Integrated UI toolbar.
- * @param text Current zoom percentage for the active window
+ *
+ * Since: dawn-of-time
  */
 void
-integrated_ui_toolbar_set_zoom_text (GtkToolbar *toolbar, const gchar * text)
+integrated_ui_toolbar_set_zoom_text (GtkToolbar *toolbar, const char * text)
 {
   if (toolbar) {
     GtkComboBox *combo_entry = g_object_get_data (G_OBJECT (toolbar),
@@ -466,11 +495,16 @@ integrated_ui_toolbar_set_zoom_text (GtkToolbar *toolbar, const gchar * text)
   }
 }
 
+
 /**
+ * integrated_ui_toolbar_add_custom_item:
+ * @toolbar: The #GtkToolbar to add the widget to.
+ * @w: The widget to add to the @toolbar.
+ *
  * Adds a widget to the toolbar making sure that it doesn't take any excess space, and
  * vertically centers it.
- * @param toolbar The toolbar to add the widget to.
- * @param w       The widget to add to the toolbar.
+ *
+ * Since: dawn-of-time
  */
 static void
 integrated_ui_toolbar_add_custom_item (GtkToolbar *toolbar, GtkWidget *w)
@@ -574,9 +608,15 @@ ensure_menu_path (GtkUIManager   *ui_manager,
   return id;
 }
 
+
 /**
+ * create_integrated_ui_toolbar:
+ *
  * Create the toolbar for the integrated UI
- * @return Main toolbar (GtkToolbar*) for the integrated UI main window
+ *
+ * Returns: Main toolbar #GtkToolbar for the integrated UI main window
+ *
+ * Since: dawn-of-time
  */
 static GtkWidget *
 create_integrated_ui_toolbar (void)
@@ -589,7 +629,7 @@ create_integrated_ui_toolbar (void)
   GError       *error = NULL;
   gchar        *uifile;
 
-  uifile = build_ui_filename ("ui/toolbar-ui.xml");
+  uifile = dia_builder_path ("ui/toolbar-ui.xml");
   if (!gtk_ui_manager_add_ui_from_file (_ui_manager, uifile, &error)) {
     g_critical ("building menus failed: %s", error->message);
     g_clear_error (&error);
@@ -901,35 +941,6 @@ register_stock_icons (void)
   g_clear_object (&factory);
 }
 
-gchar*
-build_ui_filename (const gchar* name)
-{
-  gchar* uifile;
-
-  if (g_getenv ("DIA_BASE_PATH") != NULL) {
-    uifile = g_build_filename (g_getenv ("DIA_BASE_PATH"), "data", name, NULL);
-  } else
-    uifile = dia_get_data_directory (name);
-
-  return uifile;
-}
-
-GtkBuilder *
-builder_new_from_file (const char *filename)
-{
-  GError *error = NULL;
-  gchar *uifile;
-  GtkBuilder *builder;
-
-  builder = gtk_builder_new ();
-  uifile = build_ui_filename (filename);
-  if (!gtk_builder_add_from_file (builder, uifile, &error)) {
-    g_warning ("Couldn't load builder file: %s", error->message);
-    g_clear_error (&error);
-  }
-  g_clear_pointer (&uifile, g_free);
-  return builder;
-}
 
 /*!
  * Not sure why this service is not provided by GTK+.
@@ -1056,7 +1067,7 @@ menus_init(void)
   initialise = FALSE;
   _setup_global_actions ();
 
-  uifile = build_ui_filename ("ui/toolbox-ui.xml");
+  uifile = dia_builder_path ("ui/toolbox-ui.xml");
   if (!gtk_ui_manager_add_ui_from_file (_ui_manager, uifile, &error)) {
     g_warning ("building menus failed: %s", error->message);
     g_clear_error (&error);
@@ -1078,7 +1089,7 @@ menus_init(void)
     g_clear_error (&error);
   }
 
-  uifile = build_ui_filename ("ui/popup-ui.xml");
+  uifile = dia_builder_path ("ui/popup-ui.xml");
   /* TODO it would be more elegant if we had only one definition of the
    * menu hierarchy and merge it into a popup somehow. */
   if (!gtk_ui_manager_add_ui_from_file (display_ui_manager, uifile, &error)) {
@@ -1123,7 +1134,7 @@ menus_get_integrated_ui_menubar (GtkWidget     **menubar,
   tool_actions = create_or_ref_tool_actions ();
   gtk_ui_manager_insert_action_group (_ui_manager, tool_actions, 0);
 
-  uifile = build_ui_filename ("ui/integrated-ui.xml");
+  uifile = dia_builder_path ("ui/integrated-ui.xml");
   if (!gtk_ui_manager_add_ui_from_file (_ui_manager, uifile, &error)) {
     g_warning ("building integrated ui menus failed: %s", error->message);
     g_clear_error (&error);
@@ -1198,7 +1209,7 @@ menus_create_display_menubar (GtkUIManager   **ui_manager,
   gtk_ui_manager_insert_action_group (*ui_manager, tool_actions, 0);
   g_clear_object (&tool_actions);
 
-  uifile = build_ui_filename ("ui/display-ui.xml");
+  uifile = dia_builder_path ("ui/display-ui.xml");
   if (!gtk_ui_manager_add_ui_from_file (*ui_manager, uifile, &error)) {
     g_warning ("building menus failed: %s", error->message);
     g_clear_error (&error);
diff --git a/app/menus.h b/app/menus.h
index ccaea805..0b94a69a 100644
--- a/app/menus.h
+++ b/app/menus.h
@@ -15,25 +15,27 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
-#ifndef MENUS_H
-#define MENUS_H
+
+#pragma once
 
 #include <gtk/gtk.h>
 
+G_BEGIN_DECLS
+
 #define TOOLBOX_MENU "/ToolboxMenu"
 #define DISPLAY_MENU "/DisplayMenu"
 #define INTEGRATED_MENU "/IntegratedUIMenu"
 #define INVISIBLE_MENU "/InvisibleMenu"
 
-struct zoom_pair { const gchar *string; const gint value; };
+struct zoom_pair { const char *string; const int value; };
 
 extern const struct zoom_pair zooms[10];
 
-void            integrated_ui_toolbar_set_zoom_text                      (GtkToolbar  *toolbar,
-                                                                          const gchar *text);
-void            integrated_ui_toolbar_grid_snap_synchronize_to_display   (gpointer     ddisp);
-void            integrated_ui_toolbar_object_snap_synchronize_to_display (gpointer     ddisp);
-void            integrated_ui_toolbar_guides_snap_synchronize_to_display (gpointer     ddisp);
+void            integrated_ui_toolbar_set_zoom_text                      (GtkToolbar *toolbar,
+                                                                          const char *text);
+void            integrated_ui_toolbar_grid_snap_synchronize_to_display   (gpointer    ddisp);
+void            integrated_ui_toolbar_object_snap_synchronize_to_display (gpointer    ddisp);
+void            integrated_ui_toolbar_guides_snap_synchronize_to_display (gpointer    ddisp);
 
 /* TODO: rename: menus_get_integrated_ui_menubar() */
 void            menus_get_integrated_ui_menubar  (GtkWidget      **menubar,
@@ -49,18 +51,13 @@ GtkWidget *     menus_create_display_menubar     (GtkUIManager   **ui_manager,
 GtkActionGroup *menus_get_tool_actions           (void);
 GtkActionGroup *menus_get_display_actions        (void);
 
-GtkAction *     menus_get_action                 (const gchar *name);
-GtkWidget *     menus_get_widget                 (const gchar *name);
-void            menus_set_recent                 (GtkActionGroup *actions);
+GtkAction *     menus_get_action                 (const char      *name);
+GtkWidget *     menus_get_widget                 (const char      *name);
+void            menus_set_recent                 (GtkActionGroup  *actions);
 void            menus_clear_recent               (void);
 
 #define VIEW_MAIN_TOOLBAR_ACTION     "ViewMainToolbar"
 #define VIEW_MAIN_STATUSBAR_ACTION   "ViewMainStatusbar"
 #define VIEW_LAYERS_ACTION           "ViewLayers"
 
-GtkBuilder *builder_new_from_file (const char *filename);
-gchar *build_ui_filename (const gchar* name);
-
-#endif /* MENUS_H */
-
-
+G_END_DECLS
diff --git a/app/meson.build b/app/meson.build
index 7b3b63a0..f416cc26 100644
--- a/app/meson.build
+++ b/app/meson.build
@@ -11,6 +11,9 @@ dia_sources = [
     'dia-change.h',
     'object_ops.c',
 
+    'dia-builder.c',
+    'dia-builder.h',
+
     'layer-editor/dia-layer-list.c',
     'layer-editor/dia-layer-list.h',
     'layer-editor/dia-layer-widget.c',
@@ -102,7 +105,6 @@ diaapp_lib = both_libraries('diaapp',
                             dia_sources + [diamarshal_h, config_h],
                             dependencies: [libgtk_dep, libxml_dep, libm_dep, libdia_dep, gtk_mac_dep],
                             link_args: dia_link_args,
-                            export_dynamic: true,  # some plugins require this.
                             include_directories: [configuration_inc])
 
 diaapp_dep = declare_dependency (sources: [config_h],
diff --git a/app/preferences.h b/app/preferences.h
index b6f32b7c..e0baa4c5 100644
--- a/app/preferences.h
+++ b/app/preferences.h
@@ -30,19 +30,19 @@ struct DiaPreferences {
     int visible;
     int snap;
     gboolean dynamic;
-    real x;
-    real y;
+    double x;
+    double y;
     int vis_x;
     int vis_y;
     int major_lines;
     int hex;
-    real hex_size;
+    double hex_size;
   } grid;
 
   struct {
     int width;
     int height;
-    real zoom;
+    double zoom;
     int use_menu_bar;
   } new_view;
 
@@ -57,8 +57,8 @@ struct DiaPreferences {
   int reverse_rubberbanding_intersects;
   guint recent_documents_list_size;
 
-  gchar* length_unit;
-  gchar* fontsize_unit;
+  char *length_unit;
+  char *fontsize_unit;
 
   struct {
     int visible;
diff --git a/app/sheet-editor/sheets_dialog.c b/app/sheet-editor/sheets_dialog.c
index ea7a9aa9..075a3adf 100644
--- a/app/sheet-editor/sheets_dialog.c
+++ b/app/sheet-editor/sheets_dialog.c
@@ -39,7 +39,7 @@
 
 #include "intl.h"
 #include "persistence.h"
-#include "menus.h"
+#include "dia-builder.h"
 
 
 static void
@@ -59,10 +59,11 @@ create_sheets_main_dialog (void)
   GtkWidget *sheets_main_dialog;
   GtkWidget *combo_left, *combo_right;
   GtkListStore *store;
-  GtkBuilder *builder;
+  DiaBuilder *builder;
 
-  builder = builder_new_from_file ("ui/sheets-main-dialog.ui");
-  sheets_main_dialog = GTK_WIDGET (gtk_builder_get_object (builder, "sheets_main_dialog"));
+  builder = dia_builder_new ("ui/sheets-main-dialog.ui");
+  sheets_main_dialog = GTK_WIDGET (gtk_builder_get_object (GTK_BUILDER (builder),
+                                                           "sheets_main_dialog"));
   g_object_set_data (G_OBJECT (sheets_main_dialog), "_sheet_dialogs_builder", builder);
 
   g_signal_connect (G_OBJECT (sheets_main_dialog), "destroy",
@@ -75,57 +76,85 @@ create_sheets_main_dialog (void)
 
   populate_store (store);
 
-  combo_left = GTK_WIDGET (gtk_builder_get_object (builder, "combo_left"));
+  combo_left = GTK_WIDGET (gtk_builder_get_object (GTK_BUILDER (builder),
+                                                   "combo_left"));
   gtk_combo_box_set_model (GTK_COMBO_BOX (combo_left), GTK_TREE_MODEL (store));
   g_signal_connect (combo_left,
                     "changed",
                     G_CALLBACK (on_sheets_dialog_combo_changed),
                     NULL);
 
-  combo_right = GTK_WIDGET (gtk_builder_get_object (builder, "combo_right"));
+  combo_right = GTK_WIDGET (gtk_builder_get_object (GTK_BUILDER (builder),
+                                                    "combo_right"));
   gtk_combo_box_set_model (GTK_COMBO_BOX (combo_right), GTK_TREE_MODEL (store));
   g_signal_connect (combo_right,
                     "changed",
                     G_CALLBACK (on_sheets_dialog_combo_changed),
                     NULL);
 
-  g_signal_connect (gtk_builder_get_object (builder, "sheets_main_dialog"), "delete_event",
+  g_signal_connect (gtk_builder_get_object (GTK_BUILDER (builder),
+                                            "sheets_main_dialog"),
+                    "delete_event",
                     G_CALLBACK (on_sheets_main_dialog_delete_event),
                     NULL);
-  g_signal_connect (gtk_builder_get_object (builder, "button_copy"), "clicked",
+  g_signal_connect (gtk_builder_get_object (GTK_BUILDER (builder),
+                                            "button_copy"),
+                    "clicked",
                     G_CALLBACK (on_sheets_dialog_button_copy_clicked),
                     NULL);
-  g_signal_connect (gtk_builder_get_object (builder, "button_copy_all"), "clicked",
+  g_signal_connect (gtk_builder_get_object (GTK_BUILDER (builder),
+                                            "button_copy_all"),
+                    "clicked",
                     G_CALLBACK (on_sheets_dialog_button_copy_all_clicked),
                     NULL);
-  g_signal_connect (gtk_builder_get_object (builder, "button_move"), "clicked",
+  g_signal_connect (gtk_builder_get_object (GTK_BUILDER (builder),
+                                            "button_move"),
+                    "clicked",
                     G_CALLBACK (on_sheets_dialog_button_move_clicked),
                     NULL);
-  g_signal_connect (gtk_builder_get_object (builder, "button_move_all"), "clicked",
+  g_signal_connect (gtk_builder_get_object (GTK_BUILDER (builder),
+                                            "button_move_all"),
+                    "clicked",
                     G_CALLBACK (on_sheets_dialog_button_move_all_clicked),
                     NULL);
-  g_signal_connect (gtk_builder_get_object (builder, "button_new"), "clicked",
+  g_signal_connect (gtk_builder_get_object (GTK_BUILDER (builder),
+                                            "button_new"),
+                    "clicked",
                     G_CALLBACK (on_sheets_dialog_button_new_clicked),
                     NULL);
-  g_signal_connect (gtk_builder_get_object (builder, "button_move_up"), "clicked",
+  g_signal_connect (gtk_builder_get_object (GTK_BUILDER (builder),
+                                            "button_move_up"),
+                    "clicked",
                     G_CALLBACK (on_sheets_dialog_button_move_up_clicked),
                     NULL);
-  g_signal_connect (gtk_builder_get_object (builder, "button_move_down"), "clicked",
+  g_signal_connect (gtk_builder_get_object (GTK_BUILDER (builder),
+                                            "button_move_down"),
+                    "clicked",
                     G_CALLBACK (on_sheets_dialog_button_move_down_clicked),
                     NULL);
-  g_signal_connect (gtk_builder_get_object (builder, "button_edit"), "clicked",
+  g_signal_connect (gtk_builder_get_object (GTK_BUILDER (builder),
+                                            "button_edit"),
+                    "clicked",
                     G_CALLBACK (on_sheets_dialog_button_edit_clicked),
                     NULL);
-  g_signal_connect (gtk_builder_get_object (builder, "button_remove"), "clicked",
+  g_signal_connect (gtk_builder_get_object (GTK_BUILDER (builder),
+                                            "button_remove"),
+                    "clicked",
                     G_CALLBACK (on_sheets_dialog_button_remove_clicked),
                     NULL);
-  g_signal_connect (gtk_builder_get_object (builder, "button_apply"), "clicked",
+  g_signal_connect (gtk_builder_get_object (GTK_BUILDER (builder),
+                                            "button_apply"),
+                    "clicked",
                     G_CALLBACK (on_sheets_dialog_button_apply_clicked),
                     NULL);
-  g_signal_connect (gtk_builder_get_object (builder, "button_revert"), "clicked",
+  g_signal_connect (gtk_builder_get_object (GTK_BUILDER (builder),
+                                            "button_revert"),
+                    "clicked",
                     G_CALLBACK (on_sheets_dialog_button_revert_clicked),
                     NULL);
-  g_signal_connect (gtk_builder_get_object (builder, "button_close"), "clicked",
+  g_signal_connect (gtk_builder_get_object (GTK_BUILDER (builder),
+                                            "button_close"),
+                    "clicked",
                     G_CALLBACK (on_sheets_dialog_button_close_clicked),
                     NULL);
 
@@ -138,88 +167,126 @@ GtkWidget*
 create_sheets_new_dialog (void)
 {
   GtkWidget *sheets_new_dialog;
-  GtkBuilder *builder;
+  DiaBuilder *builder;
 
-  builder = builder_new_from_file ("ui/sheets-new-dialog.ui");
-  sheets_new_dialog = GTK_WIDGET (gtk_builder_get_object (builder, "sheets_new_dialog"));
+  builder = dia_builder_new ("ui/sheets-new-dialog.ui");
+  sheets_new_dialog = GTK_WIDGET (gtk_builder_get_object (GTK_BUILDER (builder),
+                                                          "sheets_new_dialog"));
   g_object_set_data (G_OBJECT (sheets_new_dialog), "_sheet_dialogs_builder", builder);
 
   g_signal_connect (G_OBJECT (sheets_new_dialog), "destroy",
                     G_CALLBACK (sheets_dialog_destroyed), NULL);
 
-  g_signal_connect (gtk_builder_get_object (builder, "radiobutton_svg_shape"), "toggled",
+  g_signal_connect (gtk_builder_get_object (GTK_BUILDER (builder),
+                                            "radiobutton_svg_shape"),
+                    "toggled",
                     G_CALLBACK (on_sheets_new_dialog_radiobutton_svg_shape_toggled),
                     NULL);
-  g_signal_connect (gtk_builder_get_object (builder, "radiobutton_sheet"), "toggled",
+  g_signal_connect (gtk_builder_get_object (GTK_BUILDER (builder),
+                                            "radiobutton_sheet"),
+                    "toggled",
                     G_CALLBACK (on_sheets_new_dialog_radiobutton_sheet_toggled),
                     NULL);
-  g_signal_connect (gtk_builder_get_object (builder, "radiobutton_line_break"), "toggled",
+  g_signal_connect (gtk_builder_get_object (GTK_BUILDER (builder),
+                                            "radiobutton_line_break"),
+                    "toggled",
                     G_CALLBACK (on_sheets_new_dialog_radiobutton_line_break_toggled),
                     NULL);
-  g_signal_connect (gtk_builder_get_object (builder, "button_ok"), "clicked",
+  g_signal_connect (gtk_builder_get_object (GTK_BUILDER (builder),
+                                            "button_ok"),
+                    "clicked",
                     G_CALLBACK (on_sheets_new_dialog_button_ok_clicked),
                     NULL);
-  g_signal_connect (gtk_builder_get_object (builder, "button_cancel"), "clicked",
+  g_signal_connect (gtk_builder_get_object (GTK_BUILDER (builder),
+                                            "button_cancel"),
+                    "clicked",
                     G_CALLBACK (on_sheets_new_dialog_button_cancel_clicked),
                     NULL);
 
   return sheets_new_dialog;
 }
 
+
 GtkWidget*
 create_sheets_edit_dialog (void)
 {
   GtkWidget *sheets_edit_dialog;
-  GtkBuilder *builder;
+  DiaBuilder *builder;
 
-  builder = builder_new_from_file ("ui/sheets-edit-dialog.ui");
-  sheets_edit_dialog = GTK_WIDGET (gtk_builder_get_object (builder,"sheets_edit_dialog"));
-  g_object_set_data (G_OBJECT (sheets_edit_dialog), "_sheet_dialogs_builder", builder);
+  builder = dia_builder_new ("ui/sheets-edit-dialog.ui");
+  sheets_edit_dialog = GTK_WIDGET (gtk_builder_get_object (GTK_BUILDER (builder),
+                                                           "sheets_edit_dialog"));
+  g_object_set_data (G_OBJECT (sheets_edit_dialog),
+                     "_sheet_dialogs_builder",
+                     builder);
 
   g_signal_connect (G_OBJECT (sheets_edit_dialog), "destroy",
                     G_CALLBACK (sheets_dialog_destroyed), NULL);
 
-  g_signal_connect (gtk_builder_get_object (builder, "entry_object_description"), "changed",
+  g_signal_connect (gtk_builder_get_object (GTK_BUILDER (builder),
+                                            "entry_object_description"),
+                    "changed",
                     G_CALLBACK (on_sheets_edit_dialog_entry_object_description_changed),
                     NULL);
-  g_signal_connect (gtk_builder_get_object (builder, "entry_sheet_description"), "changed",
+  g_signal_connect (gtk_builder_get_object (GTK_BUILDER (builder),
+                                            "entry_sheet_description"),
+                    "changed",
                     G_CALLBACK (on_sheets_edit_dialog_entry_sheet_description_changed),
                     NULL);
-  g_signal_connect (gtk_builder_get_object (builder, "entry_sheet_name"), "changed",
+  g_signal_connect (gtk_builder_get_object (GTK_BUILDER (builder),
+                                            "entry_sheet_name"),
+                    "changed",
                     G_CALLBACK (on_sheets_edit_dialog_entry_sheet_name_changed),
                     NULL);
-  g_signal_connect (gtk_builder_get_object (builder, "button_ok"), "clicked",
+  g_signal_connect (gtk_builder_get_object (GTK_BUILDER (builder),
+                                            "button_ok"),
+                    "clicked",
                     G_CALLBACK (on_sheets_edit_dialog_button_ok_clicked),
                     NULL);
-  g_signal_connect (gtk_builder_get_object (builder, "button_cancel"), "clicked",
+  g_signal_connect (gtk_builder_get_object (GTK_BUILDER (builder),
+                                            "button_cancel"),
+                    "clicked",
                     G_CALLBACK (on_sheets_edit_dialog_button_cancel_clicked),
                     NULL);
 
   return sheets_edit_dialog;
 }
 
+
 GtkWidget*
 create_sheets_remove_dialog (void)
 {
   GtkWidget *sheets_remove_dialog;
-  GtkBuilder *builder;
+  DiaBuilder *builder;
 
-  builder = builder_new_from_file ("ui/sheets-remove-dialog.ui");
-  sheets_remove_dialog = GTK_WIDGET (gtk_builder_get_object (builder, "sheets_remove_dialog"));
-  g_object_set_data (G_OBJECT (sheets_remove_dialog), "_sheet_dialogs_builder", builder);
+  builder = dia_builder_new ("ui/sheets-remove-dialog.ui");
+  sheets_remove_dialog = GTK_WIDGET (gtk_builder_get_object (GTK_BUILDER (builder),
+                                                             "sheets_remove_dialog"));
+  g_object_set_data (G_OBJECT (sheets_remove_dialog),
+                     "_sheet_dialogs_builder",
+                     builder);
 
   g_signal_connect (G_OBJECT (sheets_remove_dialog), "destroy",
                     G_CALLBACK (sheets_dialog_destroyed), NULL);
-  g_signal_connect (gtk_builder_get_object (builder, "radiobutton_object"), "toggled",
+
+  g_signal_connect (gtk_builder_get_object (GTK_BUILDER (builder),
+                                            "radiobutton_object"),
+                    "toggled",
                     G_CALLBACK (on_sheets_remove_dialog_radiobutton_object_toggled),
                     NULL);
-  g_signal_connect (gtk_builder_get_object (builder, "radiobutton_sheet"), "toggled",
+  g_signal_connect (gtk_builder_get_object (GTK_BUILDER (builder),
+                                            "radiobutton_sheet"),
+                    "toggled",
                     G_CALLBACK (on_sheets_remove_dialog_radiobutton_sheet_toggled),
                     NULL);
-  g_signal_connect (gtk_builder_get_object (builder, "button_ok"), "clicked",
+  g_signal_connect (gtk_builder_get_object (GTK_BUILDER (builder),
+                                            "button_ok"),
+                    "clicked",
                     G_CALLBACK (on_sheets_remove_dialog_button_ok_clicked),
                     NULL);
-  g_signal_connect (gtk_builder_get_object (builder, "button_cancel"), "clicked",
+  g_signal_connect (gtk_builder_get_object (GTK_BUILDER (builder),
+                                            "button_cancel"),
+                    "clicked",
                     G_CALLBACK (on_sheets_remove_dialog_button_cancel_clicked),
                     NULL);
   /* FIXME:
@@ -228,6 +295,7 @@ create_sheets_remove_dialog (void)
   return sheets_remove_dialog;
 }
 
+
 GtkWidget*
 create_sheets_shapeselection_dialog (void)
 {
diff --git a/data/ui/properties-dialog.ui b/data/ui/properties-dialog.ui
index 16ddb820..96fe24d0 100644
--- a/data/ui/properties-dialog.ui
+++ b/data/ui/properties-dialog.ui
@@ -55,6 +55,7 @@
             <property name="active">True</property>
             <property name="draw_indicator">True</property>
             <property name="group">manual</property>
+            <signal name="toggled" handler="update_sensitivity" swapped="no"/>
           </object>
           <packing>
             <property name="right_attach">2</property>
@@ -71,6 +72,7 @@
             <property name="use_underline">True</property>
             <property name="active">True</property>
             <property name="draw_indicator">True</property>
+            <signal name="toggled" handler="update_sensitivity" swapped="no"/>
           </object>
           <packing>
             <property name="right_attach">2</property>
@@ -257,6 +259,7 @@
             <property name="active">True</property>
             <property name="draw_indicator">True</property>
             <property name="group">manual</property>
+            <signal name="toggled" handler="update_sensitivity" swapped="no"/>
           </object>
           <packing>
             <property name="right_attach">2</property>
diff --git a/docs/dia-app/dia-app-docs.xml b/docs/dia-app/dia-app-docs.xml
index 444f1a1a..cae5583b 100644
--- a/docs/dia-app/dia-app-docs.xml
+++ b/docs/dia-app/dia-app-docs.xml
@@ -64,6 +64,7 @@
         <xi:include href="xml/dia-layer-properties.xml" />
         <xi:include href="xml/layer_dialog.xml" />
     </chapter>
+    <xi:include href="xml/dia-builder.xml" />
     <xi:include href="xml/load_save.xml" />
     <xi:include href="xml/menus.xml" />
     <xi:include href="xml/navigation.xml" />



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]