[dia] [restructuring] Separate Toolbox from interface.c



commit 96bc529306f065d35dca26fcf1e51bb50fbbb978
Author: Hans Breuer <hans breuer org>
Date:   Sun May 6 15:50:52 2012 +0200

    [restructuring] Separate Toolbox from interface.c
    
    Reduce code duplication caused by different user interface options.
    Also some header cleanup to reduce coupling.

 app/Makefile.am      |    2 +
 app/commands.c       |    1 +
 app/create_object.c  |    1 +
 app/diagram.h        |    1 -
 app/disp_callbacks.c |    5 +-
 app/display.c        |    2 +-
 app/display.h        |    1 -
 app/interface.c      |  853 +++-----------------------------------------------
 app/interface.h      |   34 --
 app/linewidth_area.c |    9 +-
 app/makefile.msc     |    1 +
 app/menus.c          |    1 +
 app/modify_tool.c    |    6 +-
 app/sheets.c         |    1 +
 app/toolbox.c        |  796 ++++++++++++++++++++++++++++++++++++++++++++++
 app/toolbox.h        |   33 ++
 16 files changed, 894 insertions(+), 853 deletions(-)
---
diff --git a/app/Makefile.am b/app/Makefile.am
index 3e71260..9ca4013 100644
--- a/app/Makefile.am
+++ b/app/Makefile.am
@@ -127,6 +127,8 @@ dia_core_files = \
 	handle_ops.h \
 	interface.c \
 	interface.h \
+	toolbox.c \
+	toolbox.h \
 	dia-app-icons.h \
 	modify_tool.c \
 	modify_tool.h \
diff --git a/app/commands.c b/app/commands.c
index 45b6e17..4cc316d 100644
--- a/app/commands.c
+++ b/app/commands.c
@@ -38,6 +38,7 @@
 #include <focus.h>
 #include "confirm.h"
 #include "dia-application.h"
+#include "menus.h"
 
 /** Functions called on menu selects.
  *  Note that GTK (at least up to 2.12) doesn't disable the keyboard shortcuts
diff --git a/app/create_object.c b/app/create_object.c
index 6ae66d7..84058c6 100644
--- a/app/create_object.c
+++ b/app/create_object.c
@@ -30,6 +30,7 @@
 #include "message.h"
 #include "object.h"
 #include "intl.h"
+#include "menus.h"
 
 static void create_object_button_press(CreateObjectTool *tool, GdkEventButton *event,
 				     DDisplay *ddisp);
diff --git a/app/diagram.h b/app/diagram.h
index f5ecd42..7bc2b51 100644
--- a/app/diagram.h
+++ b/app/diagram.h
@@ -25,7 +25,6 @@ typedef struct _Diagram Diagram;
 #include "geometry.h"
 #include "diagramdata.h"
 #include "undo.h"
-#include "menus.h"
 #include "diagrid.h"
 
 G_BEGIN_DECLS
diff --git a/app/disp_callbacks.c b/app/disp_callbacks.c
index f4d3302..4005228 100644
--- a/app/disp_callbacks.c
+++ b/app/disp_callbacks.c
@@ -41,7 +41,6 @@
 #include "preferences.h"
 #include "scroll_tool.h"
 #include "commands.h"
-#include "highlight.h"
 #include "textedit.h"
 #include "lib/parent.h"
 #include "dia_dirs.h"
@@ -376,7 +375,7 @@ ddisplay_realize(GtkWidget *widget, gpointer data)
   ddisp = (DDisplay *)data;
 
   gtk_im_context_set_client_window(GTK_IM_CONTEXT(ddisp->im_context),
-                                   gtk_widget_get_window(ddisp->shell));
+                                   gtk_widget_get_window(widget));
 }
 
 void
@@ -391,7 +390,7 @@ ddisplay_unrealize (GtkWidget *widget, gpointer data)
 
   if (ddisp->im_context)
     gtk_im_context_set_client_window(GTK_IM_CONTEXT(ddisp->im_context),
-                                     gtk_widget_get_window(ddisp->shell));
+                                     gtk_widget_get_window(widget));
 }
 
 void
diff --git a/app/display.c b/app/display.c
index a4ec94e..816be9d 100644
--- a/app/display.c
+++ b/app/display.c
@@ -29,7 +29,7 @@
 #include "intl.h"
 
 #include "display.h"
-#include "group.h"
+#include "disp_callbacks.h"
 #include "interface.h"
 #include "focus.h"
 #include "color.h"
diff --git a/app/display.h b/app/display.h
index 871389c..4bf9541 100644
--- a/app/display.h
+++ b/app/display.h
@@ -26,7 +26,6 @@ typedef struct _DDisplay DDisplay;
 #include "geometry.h"
 #include "diagram.h"
 #include "grid.h"
-#include "menus.h"
 #include "diarenderer.h"
 
 G_BEGIN_DECLS
diff --git a/app/interface.c b/app/interface.c
index d984873..1767eeb 100644
--- a/app/interface.c
+++ b/app/interface.c
@@ -29,8 +29,6 @@
  */
 #include <gtk/gtk.h>
 #endif
-#include "gtkwrapbox.h"
-#include "gtkhwrapbox.h"
 
 #include <stdio.h>
 #include <string.h>
@@ -40,43 +38,20 @@
 #include "layer_dialog.h"
 #include "interface.h"
 #include "display.h"
-#include "preferences.h"
+#include "disp_callbacks.h"
+#include "menus.h"
+#include "toolbox.h"
 #include "commands.h"
 #include "dia_dirs.h"
 #include "intl.h"
 #include "navigation.h"
 #include "persistence.h"
-#include "diaarrowchooser.h"
-#include "dialinechooser.h"
-#include "diadynamicmenu.h"
 #include "widgets.h"
 #include "message.h"
-#include "attributes.h"
 
 #include <gdk-pixbuf/gdk-pixbuf.h>
 #include "dia-app-icons.h"
 
-#include "pixmaps/swap.xpm"
-#include "pixmaps/default.xpm"
-#include "pixmaps/missing.xpm"
-
-/* HB: file dnd stuff lent by The Gimp, not fully understood but working ...
- */
-enum
-{
-  DIA_DND_TYPE_URI_LIST,
-  DIA_DND_TYPE_TEXT_PLAIN,
-};
-
-static GtkTargetEntry toolbox_target_table[] =
-{
-  { "text/uri-list", 0, DIA_DND_TYPE_URI_LIST },
-  { "text/plain", 0, DIA_DND_TYPE_TEXT_PLAIN }
-};
-
-static guint toolbox_n_targets = (sizeof (toolbox_target_table) /
-                                 sizeof (toolbox_target_table[0]));
-
 static void
 use_integrated_ui_for_display_shell(DDisplay *ddisp, char *title);
 
@@ -144,123 +119,7 @@ dia_dnd_file_drag_data_received (GtkWidget        *widget,
   return;
 }
 
-static const GtkTargetEntry display_target_table[] = {
-  { "application/x-dia-object", 0, 0 },
-  { "text/uri-list", 0, DIA_DND_TYPE_URI_LIST },
-  { "text/plain", 0, DIA_DND_TYPE_TEXT_PLAIN }
-};
-static int display_n_targets = sizeof(display_target_table)/sizeof(display_target_table[0]);
-
-ToolButton tool_data[] =
-{
-  { (char **) dia_modify_tool_icon,
-    N_("Modify object(s)\nUse <Space> to toggle between this and other tools"),
-    NULL,
-    "ToolsModify",
-    { MODIFY_TOOL, NULL, NULL}
-  },
-  { (char **) dia_textedit_tool_icon,
-    N_("Text edit(s)\nUse <Esc> to leave this tool"),
-    "F2",
-    "ToolsTextedit",
-    { TEXTEDIT_TOOL, NULL, NULL}
-  },
-  { (char **) dia_zoom_tool_icon,
-    N_("Magnify"),
-    "M",
-    "ToolsMagnify",
-    { MAGNIFY_TOOL, NULL, NULL}
-  },
-  { (char **) dia_scroll_tool_icon,
-    N_("Scroll around the diagram"),
-    "S",
-    "ToolsScroll",
-    { SCROLL_TOOL, NULL, NULL}
-  },
-  { NULL,
-    N_("Text"),
-    "T",
-    "ToolsText",
-    { CREATE_OBJECT_TOOL, "Standard - Text", NULL }
-  },
-  { NULL,
-    N_("Box"),
-    "R",
-    "ToolsBox",
-    { CREATE_OBJECT_TOOL, "Standard - Box", NULL }
-  },
-  { NULL,
-    N_("Ellipse"),
-    "E",
-    "ToolsEllipse",
-    { CREATE_OBJECT_TOOL, "Standard - Ellipse", NULL }
-  },
-  { NULL,
-    N_("Polygon"),
-    "P",
-    "ToolsPolygon",
-    { CREATE_OBJECT_TOOL, "Standard - Polygon", NULL }
-  },
-  { NULL,
-    N_("Beziergon"),
-    "B",
-    "ToolsBeziergon",
-    { CREATE_OBJECT_TOOL, "Standard - Beziergon", NULL }
-  },
-  { NULL,
-    N_("Line"),
-    "L",
-    "ToolsLine",
-    { CREATE_OBJECT_TOOL, "Standard - Line", NULL }
-  },
-  { NULL,
-    N_("Arc"),
-    "A",
-    "ToolsArc",
-    { CREATE_OBJECT_TOOL, "Standard - Arc", NULL }
-  },
-  { NULL,
-    N_("Zigzagline"),
-    "Z",
-    "ToolsZigzagline",
-    { CREATE_OBJECT_TOOL, "Standard - ZigZagLine", NULL }
-  },
-  { NULL,
-    N_("Polyline"),
-    NULL,
-    "ToolsPolyline",
-    { CREATE_OBJECT_TOOL, "Standard - PolyLine", NULL }
-  },
-  { NULL,
-    N_("Bezierline"),
-    "C",
-    "ToolsBezierline",
-    { CREATE_OBJECT_TOOL, "Standard - BezierLine", NULL }
-  },
-  { NULL,
-    N_("Image"),
-    "I",
-    "ToolsImage",
-    { CREATE_OBJECT_TOOL, "Standard - Image", NULL }
-#ifdef HAVE_CAIRO
-  },
-  { NULL,
-    N_("Outline"),
-    NULL,
-    "ToolsOutline",
-    { CREATE_OBJECT_TOOL, "Standard - Outline", NULL }
-#endif
-  }
-};
-
-#define NUM_TOOLS (sizeof (tool_data) / sizeof (ToolButton))
-const int num_tools = NUM_TOOLS;
-
-#define COLUMNS   4
-#define ROWS      3
-
 static GtkWidget *toolbox_shell = NULL;
-static GtkWidget *tool_widgets[NUM_TOOLS];
 
 static struct 
 {
@@ -271,10 +130,6 @@ static struct
     GtkWidget    * layer_view;
 } ui;
 
-static GSList *tool_group = NULL;
-
-GtkWidget *modify_tool_button;
-
 /** 
  * Used to determine if the current user interface is the integrated interface or 
  * the distributed interface.  This cannot presently be determined by the preferences
@@ -502,6 +357,30 @@ close_notebook_page_callback (GtkButton *button,
   ddisplay_close (ddisp);
 }
 
+static GtkWidget *
+create_canvas (DDisplay *ddisp)
+{
+  GtkWidget *canvas = gtk_drawing_area_new();
+  
+  /* Dia's canvas does it's double buffering alone so switch off GTK's */
+  gtk_widget_set_double_buffered (canvas, FALSE);
+
+  gtk_widget_set_events (canvas, CANVAS_EVENT_MASK);
+  GTK_WIDGET_SET_FLAGS (canvas, GTK_CAN_FOCUS);
+  g_signal_connect (GTK_OBJECT (canvas), "event",
+                    G_CALLBACK(ddisplay_canvas_events),
+                    ddisp);
+
+  toolbox_setup_drag_dest (canvas);
+  g_signal_connect (GTK_OBJECT (canvas), "drag_drop",
+		    G_CALLBACK(display_drop_callback), NULL);
+  g_signal_connect (GTK_OBJECT (canvas), "drag_data_received",
+		    G_CALLBACK(display_data_received_callback), ddisp);
+  g_object_set_data (G_OBJECT (canvas), "user_data", (gpointer) ddisp);
+
+  return canvas;
+}
+
 /**
  * @param ddisp The diagram display object that a window is created for
  * @param title
@@ -571,6 +450,19 @@ use_integrated_ui_for_display_shell(DDisplay *ddisp, char *title)
                          GDK_POINTER_MOTION_HINT_MASK |
                          GDK_FOCUS_CHANGE_MASK);
 
+  g_signal_connect (GTK_OBJECT (ddisp->container), "focus_out_event",
+		    G_CALLBACK (ddisplay_focus_out_event),
+		      ddisp);
+  g_signal_connect (GTK_OBJECT (ddisp->container), "focus_in_event",
+		    G_CALLBACK (ddisplay_focus_in_event),
+		      ddisp);
+  g_signal_connect (GTK_OBJECT (ddisp->container), "realize",
+		    G_CALLBACK (ddisplay_realize),
+                      ddisp);
+  g_signal_connect (GTK_OBJECT (ddisp->container), "unrealize",
+		    G_CALLBACK (ddisplay_unrealize),
+		      ddisp);
+
   notebook_page_index = gtk_notebook_append_page (GTK_NOTEBOOK(ui.diagram_notebook),
                                                   ddisp->container,
                                                   tab_label_container);
@@ -631,24 +523,7 @@ use_integrated_ui_for_display_shell(DDisplay *ddisp, char *title)
                        _("Pops up the Navigation window."));
   gtk_widget_show(navigation_button);
 
-  /*  Canvas  */
-  ddisp->canvas = gtk_drawing_area_new();
-  
-  /* Dia's canvas does it's double buffering alone so switch off GTK's */
-  gtk_widget_set_double_buffered (ddisp->canvas, FALSE);
-
-  gtk_widget_set_events (ddisp->canvas, CANVAS_EVENT_MASK);
-  GTK_WIDGET_SET_FLAGS (ddisp->canvas, GTK_CAN_FOCUS);
-  g_signal_connect (GTK_OBJECT (ddisp->canvas), "event",
-                    G_CALLBACK(ddisplay_canvas_events),
-                    ddisp);
-  
-  gtk_drag_dest_set(ddisp->canvas, GTK_DEST_DEFAULT_ALL,
-		    display_target_table, display_n_targets, GDK_ACTION_COPY);
-  g_signal_connect (GTK_OBJECT (ddisp->canvas), "drag_drop",
-		    G_CALLBACK(display_drop_callback), NULL);
-  g_signal_connect (GTK_OBJECT (ddisp->canvas), "drag_data_received",
-		    G_CALLBACK(display_data_received_callback), ddisp);
+  ddisp->canvas = create_canvas (ddisp);
 
   /*  place all the widgets  */
   gtk_table_attach (GTK_TABLE (table), ddisp->origin, 0, 1, 0, 1,
@@ -767,7 +642,6 @@ create_display_shell(DDisplay *ddisp,
     ddisp->shell = gtk_event_box_new ();
   }
   g_object_set_data (G_OBJECT (ddisp->shell), "user_data", (gpointer) ddisp);
-
   gtk_widget_set_events (ddisp->shell,
 			 GDK_POINTER_MOTION_MASK |
 			 GDK_POINTER_MOTION_HINT_MASK |
@@ -844,7 +718,6 @@ create_display_shell(DDisplay *ddisp,
   ddisp->vsb = gtk_vscrollbar_new (ddisp->vsbdata);
   GTK_WIDGET_UNSET_FLAGS (ddisp->vsb, GTK_CAN_FOCUS);
 
-
   /*  set up the scrollbar observers  */
   g_signal_connect (GTK_OBJECT (ddisp->hsbdata), "value_changed",
 		    G_CALLBACK(ddisplay_hsb_update),
@@ -859,25 +732,7 @@ create_display_shell(DDisplay *ddisp,
                        _("Pops up the Navigation window."));
   gtk_widget_show(navigation_button);
 
-  /*  Canvas  */
-  /*  ddisp->canvas = gtk_drawing_area_new ();*/
-  ddisp->canvas = gtk_drawing_area_new();
-  /* Dia's canvas does it' double buffering alone so switch off GTK's */
-  gtk_widget_set_double_buffered (ddisp->canvas, FALSE);
-  gtk_widget_set_events (ddisp->canvas, CANVAS_EVENT_MASK);
-  GTK_WIDGET_SET_FLAGS (ddisp->canvas, GTK_CAN_FOCUS);
-  g_signal_connect (GTK_OBJECT (ddisp->canvas), "event",
-		    G_CALLBACK(ddisplay_canvas_events),
-		      ddisp);
-  
-  gtk_drag_dest_set(ddisp->canvas, GTK_DEST_DEFAULT_ALL,
-		    display_target_table, display_n_targets, GDK_ACTION_COPY);
-  g_signal_connect (GTK_OBJECT (ddisp->canvas), "drag_drop",
-		    G_CALLBACK(display_drop_callback), NULL);
-  g_signal_connect (GTK_OBJECT (ddisp->canvas), "drag_data_received",
-		    G_CALLBACK(display_data_received_callback), ddisp);
-
-  g_object_set_data (G_OBJECT (ddisp->canvas), "user_data", (gpointer) ddisp);
+  ddisp->canvas = create_canvas (ddisp);
 
   /*  pack all the widgets  */
   gtk_table_attach (GTK_TABLE (table), ddisp->origin, 0, 1, 0, 1,
@@ -910,11 +765,6 @@ create_display_shell(DDisplay *ddisp,
   /* the statusbars */
   status_hbox = gtk_hbox_new (FALSE, 2);
 
-  /*
-    g_signal_connect(GTK_OBJECT(ddisp->origin), "button_press_event",
-    G_CALLBACK(origin_button_press), ddisp);
-  */
-
   /* Zoom status pseudo-optionmenu */
   ddisp->zoom_status = create_zoom_widget(ddisp);
   zoom_hbox = gtk_hbox_new(FALSE, 0);
@@ -1022,580 +872,6 @@ ddisplay_update_rulers (DDisplay        *ddisp,
 			MAX(extents->bottom, visible->bottom)/* max_size*/);
 }
 
-void
-tool_select_update (GtkWidget *w,
-		     gpointer   data)
-{
-  ToolButtonData *tooldata = (ToolButtonData *) data;
-
-  if (tooldata == NULL) {
-    g_warning("NULL tooldata in tool_select_update");
-    return;
-  }
-
-  if (tooldata->type != -1) {
-    gint x, y;
-    GdkModifierType mask;
-    /*  get the modifiers  */
-    gdk_window_get_pointer (gtk_widget_get_parent_window(w), &x, &y, &mask);
-    tool_select (tooldata->type, tooldata->extra_data, tooldata->user_data,
-                 w, mask&1);
-  }
-}
-
-static gint
-tool_button_press (GtkWidget      *w,
-		    GdkEventButton *event,
-		    gpointer        data)
-{
-  ToolButtonData *tooldata = (ToolButtonData *) data;
-
-  if ((event->type == GDK_2BUTTON_PRESS) &&
-      (event->button == 1)) {
-    tool_options_dialog_show (tooldata->type, tooldata->extra_data, 
-                              tooldata->user_data, w, event->state&1);
-    return TRUE;
-  }
-
-  return FALSE;
-}
-
-static void
-tool_drag_data_get (GtkWidget *widget, GdkDragContext *context,
-		    GtkSelectionData *selection_data, guint info,
-		    guint32 time, ToolButtonData *tooldata)
-{
-  if (info == 0) {
-    gtk_selection_data_set(selection_data, selection_data->target,
-			   8, (guchar *)&tooldata, sizeof(ToolButtonData *));
-  }
-}
-
-static void
-tool_setup_drag_source(GtkWidget *button, ToolButtonData *tooldata,
-		       GdkPixmap *pixmap, GdkBitmap *mask)
-{
-  g_return_if_fail(tooldata->type == CREATE_OBJECT_TOOL);
-
-  gtk_drag_source_set(button, GDK_BUTTON1_MASK,
-		      display_target_table, display_n_targets,
-		      GDK_ACTION_DEFAULT|GDK_ACTION_COPY);
-  g_signal_connect(GTK_OBJECT(button), "drag_data_get",
-		   G_CALLBACK(tool_drag_data_get), tooldata);
-  if (pixmap)
-    gtk_drag_source_set_icon(button, gtk_widget_get_colormap(button),
-			     pixmap, mask);
-}
-
-GdkPixbuf *
-tool_get_pixbuf (ToolButton *tb)
-{
-  GdkPixbuf *pixbuf;
-  gchar **icon_data;
-
-  if (tb->icon_data==NULL) {
-    DiaObjectType *type;
-    
-    type = object_get_type((char *)tb->callback_data.extra_data);
-    if (type == NULL)
-      icon_data = tool_data[0].icon_data;
-    else
-      icon_data = type->pixmap;
-  } else {
-    icon_data = tb->icon_data;
-  }
-  
-  if (strncmp((char*)icon_data, "GdkP", 4) == 0) {
-    pixbuf = gdk_pixbuf_new_from_inline(-1, (guint8*)icon_data, TRUE, NULL);
-  } else {
-    char **pixmap_data = icon_data;
-    pixbuf = gdk_pixbuf_new_from_xpm_data (pixmap_data);
-  }
-  return pixbuf;
-}
-
-/*
- * Don't look too deep into this function. It is doing bad things
- * with casts to conform to the historically interface. We know
- * the difference between char* and char** - most of the time ;)
- */
-static GtkWidget *
-create_widget_from_xpm_or_gdkp(gchar **icon_data, GtkWidget *button) 
-{
-  GtkWidget *pixmapwidget;
-
-  if (strncmp((char*)icon_data, "GdkP", 4) == 0) {
-    GdkPixbuf *p;
-    p = gdk_pixbuf_new_from_inline(-1, (guint8*)icon_data, TRUE, NULL);
-    pixmapwidget = gtk_image_new_from_pixbuf(p);
-  } else {
-    char **pixmap_data = icon_data;
-    pixmapwidget = gtk_image_new_from_pixbuf (gdk_pixbuf_new_from_xpm_data (pixmap_data));
-  }
-  return pixmapwidget;
-}
-
-static void
-create_tools(GtkWidget *parent)
-{
-  GtkWidget *button;
-  GtkWidget *pixmapwidget;
-  GdkPixmap *pixmap = NULL;
-  GdkBitmap *mask = NULL;
-  /* GtkStyle *style; */
-  char **pixmap_data;
-  int i;
-
-  for (i = 0; i < NUM_TOOLS; i++) {
-    tool_widgets[i] = button = gtk_radio_button_new (tool_group);
-    gtk_container_set_border_width (GTK_CONTAINER (button), 0);
-    gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_HALF);
-    tool_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button));
-    gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE);
-
-    gtk_wrap_box_pack(GTK_WRAP_BOX(parent), button,
-		      TRUE, TRUE, FALSE, TRUE);
-
-    if (tool_data[i].callback_data.type == MODIFY_TOOL) {
-      modify_tool_button = GTK_WIDGET(button);
-    }
-    
-    if (tool_data[i].icon_data==NULL) {
-      DiaObjectType *type;
-      type =
-	object_get_type((char *)tool_data[i].callback_data.extra_data);
-      if (type == NULL)
-	pixmap_data = tool_data[0].icon_data;
-      else
-	pixmap_data = type->pixmap;
-      pixmapwidget = create_widget_from_xpm_or_gdkp(pixmap_data, button);
-    } else {
-      pixmapwidget = create_widget_from_xpm_or_gdkp(tool_data[i].icon_data, button);
-    }
-    
-    /* GTKBUG:? padding changes */
-    gtk_misc_set_padding(GTK_MISC(pixmapwidget), 2, 2);
-    
-    gtk_container_add (GTK_CONTAINER (button), pixmapwidget);
-    
-    g_signal_connect (GTK_OBJECT (button), "clicked",
-		      G_CALLBACK (tool_select_update),
-			&tool_data[i].callback_data);
-    
-    g_signal_connect (GTK_OBJECT (button), "button_press_event",
-		      G_CALLBACK (tool_button_press),
-			&tool_data[i].callback_data);
-
-    if (tool_data[i].callback_data.type == CREATE_OBJECT_TOOL)
-      tool_setup_drag_source(button, &tool_data[i].callback_data,
-			     pixmap, mask);
-
-    if (pixmap) g_object_unref(pixmap);
-    if (mask) g_object_unref(mask);
-
-    tool_data[i].callback_data.widget = button;
-
-    if (tool_data[i].tool_accelerator) {
-	guint key;
-	GdkModifierType mods;
-	gchar *alabel, *atip;
-
-	gtk_accelerator_parse (tool_data[i].tool_accelerator, &key, &mods);
-
-	alabel = gtk_accelerator_get_label(key, mods);
-	atip = g_strconcat(gettext(tool_data[i].tool_desc), " (", alabel, ")", NULL);
-	gtk_widget_set_tooltip_text (button, atip);
-	g_free (atip);
-	g_free (alabel);
-
-    } else {
-	gtk_widget_set_tooltip_text (button,
-				gettext(tool_data[i].tool_desc));
-    }
-    
-    gtk_widget_show (pixmapwidget);
-    gtk_widget_show (button);
-  }
-}
-
-static GtkWidget *sheet_option_menu;
-static GtkWidget *sheet_wbox;
-
-gchar *interface_current_sheet_name;
-
-static Sheet *
-get_sheet_by_name(const gchar *name)
-{
-  GSList *tmp;
-  for (tmp = get_sheets_list(); tmp != NULL; tmp = tmp->next) {
-    Sheet *sheet = tmp->data;
-    /* There is something fishy with comparing both forms: the english and the localized one.
-     * But we should be on the safe side here, especially when bug #328570 gets tackled.
-     */
-    if (0 == g_ascii_strcasecmp(name, sheet->name) || 0 == g_ascii_strcasecmp(name, gettext(sheet->name)))
-      return sheet;
-  }
-  return NULL;
-}
-
-static void
-fill_sheet_wbox(Sheet *sheet)
-{
-  int rows;
-  GtkStyle *style;
-  GSList *tmp;
-  GtkWidget *first_button = NULL;
-
-  gtk_container_foreach(GTK_CONTAINER(sheet_wbox),
-			(GtkCallback)gtk_widget_destroy, NULL);
-  tool_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(tool_widgets[0]));
-
-  /* Remember sheet 'name' for 'Sheets and Objects' dialog */
-  interface_current_sheet_name = sheet->name;
-
-  /* set the aspect ratio on the wbox */
-  rows = ceil(g_slist_length(sheet->objects) / (double)COLUMNS);
-  if (rows<1) rows = 1;
-  gtk_wrap_box_set_aspect_ratio(GTK_WRAP_BOX(sheet_wbox),
-				COLUMNS * 1.0 / rows);
-  style = gtk_widget_get_style(sheet_wbox);
-  for (tmp = sheet->objects; tmp != NULL; tmp = tmp->next) {
-    SheetObject *sheet_obj = tmp->data;
-    GdkPixmap *pixmap = NULL;
-    GdkBitmap *mask = NULL;
-    GtkWidget *pixmapwidget;
-    GtkWidget *button;
-    ToolButtonData *data;
-
-    if (sheet_obj->pixmap != NULL) {
-      pixmap = gdk_pixmap_colormap_create_from_xpm_d(NULL,
-			gtk_widget_get_colormap(sheet_wbox), &mask, 
-			&style->bg[GTK_STATE_NORMAL], sheet_obj->pixmap);
-    } else if (sheet_obj->pixmap_file != NULL) {
-      GdkPixbuf *pixbuf;
-      GError* gerror = NULL;
-      
-      pixbuf = gdk_pixbuf_new_from_file(sheet_obj->pixmap_file, &gerror);
-      if (pixbuf != NULL) {
-          int width = gdk_pixbuf_get_width (pixbuf);
-          int height = gdk_pixbuf_get_height (pixbuf);
-          if (width > 22 && prefs.fixed_icon_size) {
-	    GdkPixbuf *cropped;
-	    g_warning ("Shape icon '%s' size wrong, cropped.", sheet_obj->pixmap_file);
-	    cropped = gdk_pixbuf_new_subpixbuf (pixbuf, 
-	                                       (width - 22) / 2, height > 22 ? (height - 22) / 2 : 0, 
-					       22, height > 22 ? 22 : height);
-	    g_object_unref (pixbuf);
-	    pixbuf = cropped;
-	  }
-          gdk_pixbuf_render_pixmap_and_mask_for_colormap(pixbuf, gtk_widget_get_colormap(sheet_wbox), &pixmap, &mask, 1.0);
-          g_object_unref(pixbuf);
-      } else {
-          pixmap = gdk_pixmap_colormap_create_from_xpm_d(NULL,
-			gtk_widget_get_colormap(sheet_wbox), &mask, 
-			&style->bg[GTK_STATE_NORMAL], missing);
-
-          message_warning("failed to load icon for file\n %s\n cause=%s",
-                          sheet_obj->pixmap_file,gerror?gerror->message:"[NULL]");
-      }
-    } else {
-      DiaObjectType *type;
-      type = object_get_type(sheet_obj->object_type);
-      pixmap = gdk_pixmap_colormap_create_from_xpm_d(NULL,
-			gtk_widget_get_colormap(sheet_wbox), &mask, 
-			&style->bg[GTK_STATE_NORMAL], type->pixmap);
-    }
-    if (pixmap) {
-      pixmapwidget = gtk_pixmap_new(pixmap, mask);
-      g_object_unref(pixmap);
-      if (mask) g_object_unref(mask);
-    } else {
-      pixmapwidget = g_object_new (gtk_pixmap_get_type(), NULL);
-    }
-
-    button = gtk_radio_button_new (tool_group);
-    gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE);
-    gtk_container_set_border_width (GTK_CONTAINER (button), 0);
-    tool_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button));
-
-    gtk_container_add (GTK_CONTAINER (button), pixmapwidget);
-    gtk_widget_show(pixmapwidget);
-
-    gtk_wrap_box_pack_wrapped(GTK_WRAP_BOX(sheet_wbox), button,
-		      FALSE, TRUE, FALSE, TRUE, sheet_obj->line_break);
-    gtk_widget_show(button);
-
-    data = g_new(ToolButtonData, 1);
-    data->type = CREATE_OBJECT_TOOL;
-    data->extra_data = sheet_obj->object_type;
-    data->user_data = sheet_obj->user_data;
-    g_object_set_data_full(G_OBJECT(button), "Dia::ToolButtonData",
-			   data, (GDestroyNotify)g_free);
-    if (first_button == NULL) first_button = button;
-    
-    g_signal_connect (GTK_OBJECT (button), "clicked",
-		      G_CALLBACK (tool_select_update), data);
-    g_signal_connect (GTK_OBJECT (button), "button_press_event",
-		      G_CALLBACK (tool_button_press), data);
-
-    tool_setup_drag_source(button, data, pixmap, mask);
-
-    gtk_widget_set_tooltip_text (button, gettext(sheet_obj->description));
-  }
-  /* If the selection is in the old sheet, steal it */
-  if (active_tool != NULL &&
-      active_tool->type == CREATE_OBJECT_TOOL &&
-      first_button != NULL)
-    g_signal_emit_by_name(G_OBJECT(first_button), "toggled",
-			  GTK_BUTTON(first_button), NULL);
-}
-
-static void
-sheet_option_menu_changed(DiaDynamicMenu *menu, gpointer user_data)
-{
-  char *string = dia_dynamic_menu_get_entry(menu);
-  Sheet *sheet = get_sheet_by_name(string);
-  if (sheet == NULL) {
-    message_warning(_("No sheet named %s"), string);
-  } else {
-    persistence_set_string("last-sheet-selected", string);
-    fill_sheet_wbox(sheet);
-  }
-  g_free(string);
-}
-
-static int
-cmp_names (const void *a, const void *b)
-{
-  return g_utf8_collate(gettext( (gchar *)a ), gettext( (gchar *)b ));
-}
-
-static GList *
-get_sheet_names()
-{
-  GSList *tmp;
-  GList *names = NULL;
-  for (tmp = get_sheets_list(); tmp != NULL; tmp = tmp->next) {
-    Sheet *sheet = tmp->data;
-    names = g_list_append(names, sheet->name);
-  }
-  /* Already sorted in lib/ but here we sort by the localized (display-)name */
-  return g_list_sort (names, cmp_names);
-}
-
-static void
-create_sheet_dropdown_menu(GtkWidget *parent)
-{
-  GList *sheet_names = get_sheet_names();
-
-  if (sheet_option_menu != NULL) {
-    gtk_container_remove(GTK_CONTAINER(parent), sheet_option_menu);
-    sheet_option_menu = NULL;
-  }
-
-  sheet_option_menu =
-    dia_dynamic_menu_new_stringlistbased(_("Other sheets"), sheet_names, 
-					 NULL, "sheets");
-  g_signal_connect(DIA_DYNAMIC_MENU(sheet_option_menu), "value-changed",
-		   G_CALLBACK(sheet_option_menu_changed), sheet_option_menu);
-  dia_dynamic_menu_add_default_entry(DIA_DYNAMIC_MENU(sheet_option_menu),
-				     "Assorted");
-  dia_dynamic_menu_add_default_entry(DIA_DYNAMIC_MENU(sheet_option_menu),
-				     "Flowchart");
-  dia_dynamic_menu_add_default_entry(DIA_DYNAMIC_MENU(sheet_option_menu),
-				     "UML");
-  /*    gtk_widget_set_size_request(sheet_option_menu, 20, -1);*/
-  gtk_wrap_box_pack_wrapped(GTK_WRAP_BOX(parent), sheet_option_menu,
-			    TRUE, TRUE, FALSE, FALSE, TRUE);    
-  /* 15 was a magic number that goes beyond the standard objects and the divider. */
-  gtk_wrap_box_reorder_child(GTK_WRAP_BOX(parent),
-			     sheet_option_menu, NUM_TOOLS+1);
-  gtk_widget_show(sheet_option_menu);
-}
-
-void
-fill_sheet_menu(void)
-{
-  gchar *selection = dia_dynamic_menu_get_entry(DIA_DYNAMIC_MENU(sheet_option_menu));
-  create_sheet_dropdown_menu(gtk_widget_get_parent(sheet_option_menu));
-  dia_dynamic_menu_select_entry(DIA_DYNAMIC_MENU(sheet_option_menu), selection);
-  g_free(selection);
-}
-
-void
-create_sheets(GtkWidget *parent)
-{
-  GtkWidget *separator;
-  GtkWidget *label;
-  GtkWidget *swin;
-  gchar *sheetname;
-  Sheet *sheet;
-  
-  separator = gtk_hseparator_new ();
-  /* add a bit of padding around the separator */
-  label = gtk_vbox_new(FALSE, 0);
-  gtk_box_pack_start(GTK_BOX(label), separator, TRUE, TRUE, 3);
-  gtk_widget_show(label);
-
-  gtk_wrap_box_pack_wrapped (GTK_WRAP_BOX(parent), label, TRUE,TRUE, FALSE,FALSE, TRUE);
-  gtk_widget_show(separator);
-
-  create_sheet_dropdown_menu(parent);
-
-  swin = gtk_scrolled_window_new(NULL, NULL);
-  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin),
-				 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
-  gtk_wrap_box_pack_wrapped(GTK_WRAP_BOX(parent), swin, TRUE, TRUE, TRUE, TRUE, TRUE);
-  gtk_widget_show(swin);
-
-  sheet_wbox = gtk_hwrap_box_new(FALSE);
-  gtk_wrap_box_set_justify(GTK_WRAP_BOX(sheet_wbox), GTK_JUSTIFY_TOP);
-  gtk_wrap_box_set_line_justify(GTK_WRAP_BOX(sheet_wbox), GTK_JUSTIFY_LEFT);
-  gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(swin), sheet_wbox);
-  gtk_widget_show(sheet_wbox);
-
-  sheetname = persistence_register_string("last-sheet-selected", _("Flowchart"));
-  sheet = get_sheet_by_name(sheetname);
-  if (sheet == NULL) {
-    /* Couldn't find it */
-  } else {
-    fill_sheet_wbox(sheet);
-    dia_dynamic_menu_select_entry(DIA_DYNAMIC_MENU(sheet_option_menu),
-				  sheetname);
-  }
-  g_free(sheetname);
-}
-
-static void
-create_color_area (GtkWidget *parent)
-{
-  GtkWidget *frame;
-  GtkWidget *alignment;
-  GtkWidget *col_area;
-  GtkWidget *line_area;
-  GdkPixmap *default_pixmap;
-  GdkBitmap *default_mask;
-  GdkPixmap *swap_pixmap;
-  GdkBitmap *swap_mask;
-  GtkStyle *style;
-  GtkWidget *hbox;
-
-  gtk_widget_ensure_style(parent);
-  style = gtk_widget_get_style(parent);
-
-  default_pixmap =
-    gdk_pixmap_colormap_create_from_xpm_d(NULL,
-		gtk_widget_get_colormap(parent), &default_mask, 
-		&style->bg[GTK_STATE_NORMAL], default_xpm);
-  swap_pixmap =
-    gdk_pixmap_colormap_create_from_xpm_d(NULL,
-		gtk_widget_get_colormap(parent), &swap_mask, 
-		&style->bg[GTK_STATE_NORMAL], swap_xpm);
-
-  frame = gtk_frame_new (NULL);
-  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
-  gtk_wrap_box_pack_wrapped(GTK_WRAP_BOX(parent), frame, TRUE, TRUE, FALSE, FALSE, TRUE);
-  gtk_widget_realize (frame);
-
-  hbox = gtk_hbox_new (FALSE, 1);
-  gtk_container_set_border_width (GTK_CONTAINER (hbox), 0);
-  gtk_container_add (GTK_CONTAINER (frame), hbox);
-  
-  /* Color area: */
-  alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
-  gtk_container_set_border_width (GTK_CONTAINER (alignment), 3);
-  
-  col_area = color_area_create (54, 42, 
-                                default_pixmap, default_mask, 
-                                swap_pixmap, swap_mask);
-  gtk_container_add (GTK_CONTAINER (alignment), col_area);
-
-
-  gtk_box_pack_start (GTK_BOX (hbox), alignment, TRUE, TRUE, 0);
-
-  gtk_widget_set_tooltip_text (col_area, 
-			_("Foreground & background colors for new objects.  "
-			  "The small black and white squares reset colors.  "
-			  "The small arrows swap colors.  Double-click to "
-			  "change colors."));
-
-  gtk_widget_show (alignment);
-  
-  /* Linewidth area: */
-  alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
-  gtk_container_set_border_width (GTK_CONTAINER (alignment), 3);
-  
-  line_area = linewidth_area_create ();
-  gtk_container_add (GTK_CONTAINER (alignment), line_area);
-  gtk_box_pack_start (GTK_BOX (hbox), alignment, TRUE, TRUE, 0);
-  gtk_widget_set_tooltip_text(line_area, _("Line widths.  Click on a line to set the default line width for new objects.  Double-click to set the line width more precisely."));
-  gtk_widget_show (alignment);
-
-  gtk_widget_show (col_area);
-  gtk_widget_show (line_area);
-  gtk_widget_show (hbox);
-  gtk_widget_show (frame);
-}
-
-static void
-change_start_arrow_style(Arrow arrow, gpointer user_data)
-{
-  attributes_set_default_start_arrow(arrow);
-}
-static void
-change_end_arrow_style(Arrow arrow, gpointer user_data)
-{
-  attributes_set_default_end_arrow(arrow);
-}
-static void
-change_line_style(LineStyle lstyle, real dash_length, gpointer user_data)
-{
-  attributes_set_default_line_style(lstyle, dash_length);
-}
-
-static void
-create_lineprops_area(GtkWidget *parent)
-{
-  GtkWidget *chooser;
-  Arrow arrow;
-  real dash_length;
-  LineStyle style;
-  gchar *arrow_name;
-
-  chooser = dia_arrow_chooser_new(TRUE, change_start_arrow_style, NULL);
-  gtk_wrap_box_pack_wrapped(GTK_WRAP_BOX(parent), chooser, FALSE, TRUE, FALSE, TRUE, TRUE);
-  arrow.width = persistence_register_real("start-arrow-width", DEFAULT_ARROW_WIDTH);
-  arrow.length = persistence_register_real("start-arrow-length", DEFAULT_ARROW_LENGTH);
-  arrow_name = persistence_register_string("start-arrow-type", "None");
-  arrow.type = arrow_type_from_name(arrow_name);
-  g_free(arrow_name);
-  dia_arrow_chooser_set_arrow(DIA_ARROW_CHOOSER(chooser), &arrow);
-  attributes_set_default_start_arrow(arrow);
-  gtk_widget_set_tooltip_text(chooser, _("Arrow style at the beginning of new lines.  Click to pick an arrow, or set arrow parameters with Details\342\200\246"));
-  gtk_widget_show(chooser);
-
-  chooser = dia_line_chooser_new(change_line_style, NULL);
-  gtk_wrap_box_pack(GTK_WRAP_BOX(parent), chooser, TRUE, TRUE, FALSE, TRUE);
-  gtk_widget_set_tooltip_text (chooser, _("Line style for new lines.  Click to pick a line style, or set line style parameters with Details\342\200\246"));
-  style = persistence_register_integer("line-style", LINESTYLE_SOLID);
-  dash_length = persistence_register_real("dash-length", DEFAULT_LINESTYLE_DASHLEN);
-  dia_line_chooser_set_line_style(DIA_LINE_CHOOSER(chooser), style, dash_length);
-  gtk_widget_show(chooser);
-
-  chooser = dia_arrow_chooser_new(FALSE, change_end_arrow_style, NULL);
-  arrow.width = persistence_register_real("end-arrow-width", DEFAULT_ARROW_WIDTH);
-  arrow.length = persistence_register_real("end-arrow-length", DEFAULT_ARROW_LENGTH);
-  arrow_name = persistence_register_string("end-arrow-type", "Filled Concave");
-  arrow.type = arrow_type_from_name(arrow_name);
-  g_free(arrow_name);
-  dia_arrow_chooser_set_arrow(DIA_ARROW_CHOOSER(chooser), &arrow);
-  attributes_set_default_end_arrow(arrow);
-
-  gtk_wrap_box_pack(GTK_WRAP_BOX(parent), chooser, FALSE, TRUE, FALSE, TRUE);
-  gtk_widget_set_tooltip_text(chooser, _("Arrow style at the end of new lines.  Click to pick an arrow, or set arrow parameters with Details\342\200\246"));
-  gtk_widget_show(chooser);
-}
-
 static void
 toolbox_destroy (GtkWidget *widget, gpointer data)
 {
@@ -1701,26 +977,10 @@ create_integrated_ui (void)
   gtk_notebook_set_scrollable (GTK_NOTEBOOK (notebook), TRUE); 
   gtk_widget_show (notebook);
 
-  wrapbox = gtk_hwrap_box_new(FALSE);
-  gtk_wrap_box_set_aspect_ratio(GTK_WRAP_BOX(wrapbox), 144.0 / 318.0);
-  gtk_wrap_box_set_justify(GTK_WRAP_BOX(wrapbox), GTK_JUSTIFY_TOP);
-  gtk_wrap_box_set_line_justify(GTK_WRAP_BOX(wrapbox), GTK_JUSTIFY_LEFT);
-
-  /* pack the rest of the stuff */
+  /* Toolbox widget */
+  wrapbox = toolbox_create();
   gtk_box_pack_start (GTK_BOX (hbox), wrapbox, FALSE, TRUE, 0);
-  gtk_container_set_border_width (GTK_CONTAINER (wrapbox), 0);
-  gtk_widget_show (wrapbox);
-
-  create_tools (wrapbox);
-  create_sheets (wrapbox);
-  create_color_area (wrapbox);
-  create_lineprops_area (wrapbox);
-
-  /* Setup toolbox area as file drop destination */
-  gtk_drag_dest_set (wrapbox,
-		     GTK_DEST_DEFAULT_ALL,
-		     toolbox_target_table, toolbox_n_targets,
-		     GDK_ACTION_COPY);
+
   g_signal_connect (GTK_OBJECT (wrapbox), "drag_data_received",
 		    G_CALLBACK (dia_dnd_file_drag_data_received),
                     NULL); /* userdata == NULL here intentionally */
@@ -1808,32 +1068,13 @@ create_toolbox ()
 #else
   gtk_container_add (GTK_CONTAINER (window), main_vbox);
 #endif
-  gtk_widget_show (main_vbox);
-
-  wrapbox = gtk_hwrap_box_new(FALSE);
-  gtk_wrap_box_set_aspect_ratio(GTK_WRAP_BOX(wrapbox), 144.0 / 318.0);
-  gtk_wrap_box_set_justify(GTK_WRAP_BOX(wrapbox), GTK_JUSTIFY_TOP);
-  gtk_wrap_box_set_line_justify(GTK_WRAP_BOX(wrapbox), GTK_JUSTIFY_LEFT);
 
-
-  /* pack the rest of the stuff */
+  wrapbox = toolbox_create();
   gtk_box_pack_end (GTK_BOX (main_vbox), wrapbox, TRUE, TRUE, 0);
-  gtk_container_set_border_width (GTK_CONTAINER (wrapbox), 0);
-  gtk_widget_show (wrapbox);
-
-  create_tools (wrapbox);
-  create_sheets (wrapbox);
-  create_color_area (wrapbox);
-  create_lineprops_area (wrapbox);
-
-  /* Setup toolbox area as file drop destination */
-  gtk_drag_dest_set (wrapbox,
-		     GTK_DEST_DEFAULT_ALL,
-		     toolbox_target_table, toolbox_n_targets,
-		     GDK_ACTION_COPY);
   g_signal_connect (GTK_OBJECT (wrapbox), "drag_data_received",
 		    G_CALLBACK (dia_dnd_file_drag_data_received),
                     NULL); /* userdata == NULL here intentionally */
+  gtk_widget_show (main_vbox);
 
   /* menus -- initialised afterwards, because initing the display menus
    * uses the tool buttons*/
diff --git a/app/interface.h b/app/interface.h
index 6115d91..c95ba5f 100644
--- a/app/interface.h
+++ b/app/interface.h
@@ -20,13 +20,7 @@
 
 #include "display.h"
 
-#include "menus.h"
-#include "disp_callbacks.h"
-#include "tool.h"
-#include "sheet.h"
 #include "app_procs.h"
-#include "color_area.h"
-#include "linewidth_area.h"
 
 /* Integrated UI Constants */
 #define  DIA_MAIN_WINDOW   "dia-main-window"
@@ -65,36 +59,8 @@ extern GtkWidget *modify_tool_button;
 
 void view_zoom_set (float zoom_factor); /* zoom_factor is 10 * percentage */
 
-typedef struct _ToolButton ToolButton;
-
-typedef struct _ToolButtonData ToolButtonData;
-
-struct _ToolButtonData
-{
-  ToolType type;
-  gpointer extra_data;
-  gpointer user_data; /* Used by create_object_tool */
-  GtkWidget *widget;
-};
-
-struct _ToolButton
-{
-  gchar **icon_data;
-  char  *tool_desc;
-  char	*tool_accelerator;
-  char  *action_name;
-  ToolButtonData callback_data;
-};
-
-extern const int num_tools;
-extern ToolButton tool_data[];
-extern gchar *interface_current_sheet_name;
-
-void tool_select_update (GtkWidget *w, gpointer   data);
 void fill_sheet_menu(void);
 
 void close_notebook_page_callback (GtkButton *button, gpointer user_data);
 
-GdkPixbuf *tool_get_pixbuf (ToolButton *tb);
-
 #endif /* INTERFACE_H */
diff --git a/app/linewidth_area.c b/app/linewidth_area.c
index c8b9d4b..f658e99 100644
--- a/app/linewidth_area.c
+++ b/app/linewidth_area.c
@@ -23,7 +23,6 @@
 #include "linewidth_area.h"
 #include "attributes.h"
 #include "persistence.h"
-#include "interface.h"
 #include "intl.h"
 
 #if !defined(rint)
@@ -40,7 +39,7 @@
 #define AREA_WIDTH X_OFFSET(NUMLINES+1)
 #define AREA_HEIGHT 42
 
-static void linewidth_create_dialog(void);
+static void linewidth_create_dialog(GtkWindow *toplevel);
 
 static int active_linewidth = 2;
 static GdkGC *linewidth_area_gc = NULL;
@@ -154,7 +153,7 @@ linewidth_area_events (GtkWidget *widget,
 
     case GDK_2BUTTON_PRESS:
       if (linewidth_dialog == NULL)
-        linewidth_create_dialog();
+        linewidth_create_dialog(gtk_widget_get_toplevel (widget));
       else
         gtk_widget_grab_focus(linewidth_button);
       gtk_spin_button_set_value(GTK_SPIN_BUTTON(linewidth_button), attributes_get_default_linewidth());
@@ -238,14 +237,14 @@ dialog_destroyed(GtkWidget *widget, gpointer data)
 }
 
 static void
-linewidth_create_dialog()
+linewidth_create_dialog(GtkWindow *toplevel)
 {
   GtkWidget *hbox;
   GtkWidget *label;
   GtkAdjustment *adj;
 
   linewidth_dialog = gtk_dialog_new_with_buttons(
-	_("Line width"), GTK_WINDOW(interface_get_toolbox_shell()),
+	_("Line width"), toplevel,
 	0,
 	GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
 	GTK_STOCK_OK, GTK_RESPONSE_OK, 
diff --git a/app/makefile.msc b/app/makefile.msc
index b0f6eab..1cad410 100644
--- a/app/makefile.msc
+++ b/app/makefile.msc
@@ -70,6 +70,7 @@ OBJECTS = \
 	textedit.obj \
 	textedit_tool.obj \
 	tool.obj \
+	toolbox.obj \
 	undo.obj \
 	\
 	diagram_tree_model.obj \
diff --git a/app/menus.c b/app/menus.c
index b902309..e18c9f0 100644
--- a/app/menus.c
+++ b/app/menus.c
@@ -43,6 +43,7 @@
 #include "preferences.h"
 #include "filter.h"
 #include "objchange.h"
+#include "toolbox.h"
 
 #define DIA_STOCK_GROUP "dia-stock-group"
 #define DIA_STOCK_UNGROUP "dia-stock-ungroup"
diff --git a/app/modify_tool.c b/app/modify_tool.c
index ad14736..e3f170b 100644
--- a/app/modify_tool.c
+++ b/app/modify_tool.c
@@ -34,6 +34,7 @@
 #include "highlight.h"
 #include "textedit.h"
 #include "textline.h"
+#include "menus.h"
 
 #include "parent.h"
 #include "prop_text.h"
@@ -75,7 +76,7 @@ create_modify_tool(void)
   tool->tool.double_click_func = (DoubleClickFunc) &modify_double_click;
   tool->gc = NULL;
   tool->state = STATE_NONE;
-  tool->break_connections = 0;
+  tool->break_connections = FALSE;
   tool->auto_scrolled = FALSE;
 
   tool->orig_pos = NULL;
@@ -240,7 +241,8 @@ modify_button_press(ModifyTool *tool, GdkEventButton *event,
     tool->object = clicked_obj;
     tool->move_compensate = clicked_obj->position;
     point_sub(&tool->move_compensate, &clickedpoint);
-    tool->break_connections = TRUE;
+    tool->break_connections = TRUE; /* unconnect when not grabbing handles, just setting to
+				      * FALSE is not enough. Need to refine the move op, too. */
     gdk_pointer_grab (gtk_widget_get_window(ddisp->canvas), FALSE,
                       GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
                       NULL, NULL, event->time);
diff --git a/app/sheets.c b/app/sheets.c
index f5851ff..57c3308 100644
--- a/app/sheets.c
+++ b/app/sheets.c
@@ -41,6 +41,7 @@
 #include "intl.h"
 #include "gtkhwrapbox.h"
 #include "preferences.h"
+#include "toolbox.h" /* just for interface_current_sheet_name */
 
 GtkWidget *sheets_dialog = NULL;
 GSList *sheets_mods_list = NULL;
diff --git a/app/toolbox.c b/app/toolbox.c
new file mode 100644
index 0000000..6e56250
--- /dev/null
+++ b/app/toolbox.c
@@ -0,0 +1,796 @@
+/* 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.
+ */
+
+#include <config.h>
+
+#undef GTK_DISABLE_DEPRECATED /* GtkPixmap */
+#include <gtk/gtk.h>
+#include "gtkwrapbox.h"
+#include "gtkhwrapbox.h"
+
+#include "diaarrowchooser.h"
+#include "dialinechooser.h"
+#include "diadynamicmenu.h"
+#include "attributes.h"
+#include "sheet.h"
+#include "color_area.h"
+#include "intl.h"
+#include "message.h"
+#include "object.h"
+#include "widgets.h"
+
+#include "linewidth_area.h"
+#include "preferences.h"
+#include "persistence.h"
+
+#include "toolbox.h"
+
+#include "pixmaps/swap.xpm"
+#include "pixmaps/default.xpm"
+#include "pixmaps/missing.xpm"
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include "dia-app-icons.h"
+
+/* HB: file dnd stuff lent by The Gimp, not fully understood but working ...
+ */
+enum
+{
+  DIA_DND_TYPE_URI_LIST,
+  DIA_DND_TYPE_TEXT_PLAIN,
+};
+
+static GtkTargetEntry toolbox_target_table[] =
+{
+  { "text/uri-list", 0, DIA_DND_TYPE_URI_LIST },
+  { "text/plain", 0, DIA_DND_TYPE_TEXT_PLAIN }
+};
+
+static guint toolbox_n_targets = (sizeof (toolbox_target_table) /
+                                 sizeof (toolbox_target_table[0]));
+
+static GtkWidget *sheet_option_menu;
+static GtkWidget *sheet_wbox;
+
+GtkWidget *modify_tool_button;
+gchar *interface_current_sheet_name;
+static GSList *tool_group = NULL;
+
+ToolButton tool_data[] =
+{
+  { (char **) dia_modify_tool_icon,
+    N_("Modify object(s)\nUse <Space> to toggle between this and other tools"),
+    NULL,
+    "ToolsModify",
+    { MODIFY_TOOL, NULL, NULL}
+  },
+  { (char **) dia_textedit_tool_icon,
+    N_("Text edit(s)\nUse <Esc> to leave this tool"),
+    "F2",
+    "ToolsTextedit",
+    { TEXTEDIT_TOOL, NULL, NULL}
+  },
+  { (char **) dia_zoom_tool_icon,
+    N_("Magnify"),
+    "M",
+    "ToolsMagnify",
+    { MAGNIFY_TOOL, NULL, NULL}
+  },
+  { (char **) dia_scroll_tool_icon,
+    N_("Scroll around the diagram"),
+    "S",
+    "ToolsScroll",
+    { SCROLL_TOOL, NULL, NULL}
+  },
+  { NULL,
+    N_("Text"),
+    "T",
+    "ToolsText",
+    { CREATE_OBJECT_TOOL, "Standard - Text", NULL }
+  },
+  { NULL,
+    N_("Box"),
+    "R",
+    "ToolsBox",
+    { CREATE_OBJECT_TOOL, "Standard - Box", NULL }
+  },
+  { NULL,
+    N_("Ellipse"),
+    "E",
+    "ToolsEllipse",
+    { CREATE_OBJECT_TOOL, "Standard - Ellipse", NULL }
+  },
+  { NULL,
+    N_("Polygon"),
+    "P",
+    "ToolsPolygon",
+    { CREATE_OBJECT_TOOL, "Standard - Polygon", NULL }
+  },
+  { NULL,
+    N_("Beziergon"),
+    "B",
+    "ToolsBeziergon",
+    { CREATE_OBJECT_TOOL, "Standard - Beziergon", NULL }
+  },
+  { NULL,
+    N_("Line"),
+    "L",
+    "ToolsLine",
+    { CREATE_OBJECT_TOOL, "Standard - Line", NULL }
+  },
+  { NULL,
+    N_("Arc"),
+    "A",
+    "ToolsArc",
+    { CREATE_OBJECT_TOOL, "Standard - Arc", NULL }
+  },
+  { NULL,
+    N_("Zigzagline"),
+    "Z",
+    "ToolsZigzagline",
+    { CREATE_OBJECT_TOOL, "Standard - ZigZagLine", NULL }
+  },
+  { NULL,
+    N_("Polyline"),
+    NULL,
+    "ToolsPolyline",
+    { CREATE_OBJECT_TOOL, "Standard - PolyLine", NULL }
+  },
+  { NULL,
+    N_("Bezierline"),
+    "C",
+    "ToolsBezierline",
+    { CREATE_OBJECT_TOOL, "Standard - BezierLine", NULL }
+  },
+  { NULL,
+    N_("Image"),
+    "I",
+    "ToolsImage",
+    { CREATE_OBJECT_TOOL, "Standard - Image", NULL }
+#ifdef HAVE_CAIRO
+  },
+  { NULL,
+    N_("Outline"),
+    NULL,
+    "ToolsOutline",
+    { CREATE_OBJECT_TOOL, "Standard - Outline", NULL }
+#endif
+  }
+};
+
+#define NUM_TOOLS (sizeof (tool_data) / sizeof (ToolButton))
+const int num_tools = NUM_TOOLS;
+
+#define COLUMNS   4
+#define ROWS      3
+
+static GtkWidget *tool_widgets[NUM_TOOLS];
+
+static Sheet *
+get_sheet_by_name(const gchar *name)
+{
+  GSList *tmp;
+  for (tmp = get_sheets_list(); tmp != NULL; tmp = tmp->next) {
+    Sheet *sheet = tmp->data;
+    /* There is something fishy with comparing both forms: the english and the localized one.
+     * But we should be on the safe side here, especially when bug #328570 gets tackled.
+     */
+    if (0 == g_ascii_strcasecmp(name, sheet->name) || 0 == g_ascii_strcasecmp(name, gettext(sheet->name)))
+      return sheet;
+  }
+  return NULL;
+}
+
+static gint
+tool_button_press (GtkWidget      *w,
+		    GdkEventButton *event,
+		    gpointer        data)
+{
+  ToolButtonData *tooldata = (ToolButtonData *) data;
+
+  if ((event->type == GDK_2BUTTON_PRESS) &&
+      (event->button == 1)) {
+    tool_options_dialog_show (tooldata->type, tooldata->extra_data, 
+                              tooldata->user_data, w, event->state&1);
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+static const GtkTargetEntry display_target_table[] = {
+  { "application/x-dia-object", 0, 0 },
+  { "text/uri-list", 0, DIA_DND_TYPE_URI_LIST },
+  { "text/plain", 0, DIA_DND_TYPE_TEXT_PLAIN }
+};
+static int display_n_targets = sizeof(display_target_table)/sizeof(display_target_table[0]);
+
+static void
+tool_drag_data_get (GtkWidget *widget, GdkDragContext *context,
+		    GtkSelectionData *selection_data, guint info,
+		    guint32 time, ToolButtonData *tooldata)
+{
+  if (info == 0) {
+    gtk_selection_data_set(selection_data, selection_data->target,
+			   8, (guchar *)&tooldata, sizeof(ToolButtonData *));
+  }
+}
+
+static void
+tool_setup_drag_source(GtkWidget *button, ToolButtonData *tooldata,
+		       GdkPixmap *pixmap, GdkBitmap *mask)
+{
+  g_return_if_fail(tooldata->type == CREATE_OBJECT_TOOL);
+
+  gtk_drag_source_set(button, GDK_BUTTON1_MASK,
+		      display_target_table, display_n_targets,
+		      GDK_ACTION_DEFAULT|GDK_ACTION_COPY);
+  g_signal_connect(GTK_OBJECT(button), "drag_data_get",
+		   G_CALLBACK(tool_drag_data_get), tooldata);
+  if (pixmap)
+    gtk_drag_source_set_icon(button, gtk_widget_get_colormap(button),
+			     pixmap, mask);
+}
+
+static void
+fill_sheet_wbox(Sheet *sheet)
+{
+  int rows;
+  GtkStyle *style;
+  GSList *tmp;
+  GtkWidget *first_button = NULL;
+
+  gtk_container_foreach(GTK_CONTAINER(sheet_wbox),
+			(GtkCallback)gtk_widget_destroy, NULL);
+  tool_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(tool_widgets[0]));
+
+  /* Remember sheet 'name' for 'Sheets and Objects' dialog */
+  interface_current_sheet_name = sheet->name;
+
+  /* set the aspect ratio on the wbox */
+  rows = ceil(g_slist_length(sheet->objects) / (double)COLUMNS);
+  if (rows<1) rows = 1;
+  gtk_wrap_box_set_aspect_ratio(GTK_WRAP_BOX(sheet_wbox),
+				COLUMNS * 1.0 / rows);
+  style = gtk_widget_get_style(sheet_wbox);
+  for (tmp = sheet->objects; tmp != NULL; tmp = tmp->next) {
+    SheetObject *sheet_obj = tmp->data;
+    GdkPixmap *pixmap = NULL;
+    GdkBitmap *mask = NULL;
+    GtkWidget *pixmapwidget;
+    GtkWidget *button;
+    ToolButtonData *data;
+
+    if (sheet_obj->pixmap != NULL) {
+      pixmap = gdk_pixmap_colormap_create_from_xpm_d(NULL,
+			gtk_widget_get_colormap(sheet_wbox), &mask, 
+			&style->bg[GTK_STATE_NORMAL], sheet_obj->pixmap);
+    } else if (sheet_obj->pixmap_file != NULL) {
+      GdkPixbuf *pixbuf;
+      GError* gerror = NULL;
+      
+      pixbuf = gdk_pixbuf_new_from_file(sheet_obj->pixmap_file, &gerror);
+      if (pixbuf != NULL) {
+          int width = gdk_pixbuf_get_width (pixbuf);
+          int height = gdk_pixbuf_get_height (pixbuf);
+          if (width > 22 && prefs.fixed_icon_size) {
+	    GdkPixbuf *cropped;
+	    g_warning ("Shape icon '%s' size wrong, cropped.", sheet_obj->pixmap_file);
+	    cropped = gdk_pixbuf_new_subpixbuf (pixbuf, 
+	                                       (width - 22) / 2, height > 22 ? (height - 22) / 2 : 0, 
+					       22, height > 22 ? 22 : height);
+	    g_object_unref (pixbuf);
+	    pixbuf = cropped;
+	  }
+          gdk_pixbuf_render_pixmap_and_mask_for_colormap(pixbuf, gtk_widget_get_colormap(sheet_wbox), &pixmap, &mask, 1.0);
+          g_object_unref(pixbuf);
+      } else {
+          pixmap = gdk_pixmap_colormap_create_from_xpm_d(NULL,
+			gtk_widget_get_colormap(sheet_wbox), &mask, 
+			&style->bg[GTK_STATE_NORMAL], missing);
+
+          message_warning("failed to load icon for file\n %s\n cause=%s",
+                          sheet_obj->pixmap_file,gerror?gerror->message:"[NULL]");
+      }
+    } else {
+      DiaObjectType *type;
+      type = object_get_type(sheet_obj->object_type);
+      pixmap = gdk_pixmap_colormap_create_from_xpm_d(NULL,
+			gtk_widget_get_colormap(sheet_wbox), &mask, 
+			&style->bg[GTK_STATE_NORMAL], type->pixmap);
+    }
+    if (pixmap) {
+      pixmapwidget = gtk_pixmap_new(pixmap, mask);
+      g_object_unref(pixmap);
+      if (mask) g_object_unref(mask);
+    } else {
+      pixmapwidget = g_object_new (gtk_pixmap_get_type(), NULL);
+    }
+
+    button = gtk_radio_button_new (tool_group);
+    gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE);
+    gtk_container_set_border_width (GTK_CONTAINER (button), 0);
+    tool_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button));
+
+    gtk_container_add (GTK_CONTAINER (button), pixmapwidget);
+    gtk_widget_show(pixmapwidget);
+
+    gtk_wrap_box_pack_wrapped(GTK_WRAP_BOX(sheet_wbox), button,
+		      FALSE, TRUE, FALSE, TRUE, sheet_obj->line_break);
+    gtk_widget_show(button);
+
+    data = g_new(ToolButtonData, 1);
+    data->type = CREATE_OBJECT_TOOL;
+    data->extra_data = sheet_obj->object_type;
+    data->user_data = sheet_obj->user_data;
+    g_object_set_data_full(G_OBJECT(button), "Dia::ToolButtonData",
+			   data, (GDestroyNotify)g_free);
+    if (first_button == NULL) first_button = button;
+    
+    g_signal_connect (GTK_OBJECT (button), "clicked",
+		      G_CALLBACK (tool_select_update), data);
+    g_signal_connect (GTK_OBJECT (button), "button_press_event",
+		      G_CALLBACK (tool_button_press), data);
+
+    tool_setup_drag_source(button, data, pixmap, mask);
+
+    gtk_widget_set_tooltip_text (button, gettext(sheet_obj->description));
+  }
+  /* If the selection is in the old sheet, steal it */
+  if (active_tool != NULL &&
+      active_tool->type == CREATE_OBJECT_TOOL &&
+      first_button != NULL)
+    g_signal_emit_by_name(G_OBJECT(first_button), "toggled",
+			  GTK_BUTTON(first_button), NULL);
+}
+
+static void
+sheet_option_menu_changed(DiaDynamicMenu *menu, gpointer user_data)
+{
+  char *string = dia_dynamic_menu_get_entry(menu);
+  Sheet *sheet = get_sheet_by_name(string);
+  if (sheet == NULL) {
+    message_warning(_("No sheet named %s"), string);
+  } else {
+    persistence_set_string("last-sheet-selected", string);
+    fill_sheet_wbox(sheet);
+  }
+  g_free(string);
+}
+
+static int
+cmp_names (const void *a, const void *b)
+{
+  return g_utf8_collate(gettext( (gchar *)a ), gettext( (gchar *)b ));
+}
+
+static GList *
+get_sheet_names()
+{
+  GSList *tmp;
+  GList *names = NULL;
+  for (tmp = get_sheets_list(); tmp != NULL; tmp = tmp->next) {
+    Sheet *sheet = tmp->data;
+    names = g_list_append(names, sheet->name);
+  }
+  /* Already sorted in lib/ but here we sort by the localized (display-)name */
+  return g_list_sort (names, cmp_names);
+}
+
+static void
+create_sheet_dropdown_menu(GtkWidget *parent)
+{
+  GList *sheet_names = get_sheet_names();
+
+  if (sheet_option_menu != NULL) {
+    gtk_container_remove(GTK_CONTAINER(parent), sheet_option_menu);
+    sheet_option_menu = NULL;
+  }
+
+  sheet_option_menu =
+    dia_dynamic_menu_new_stringlistbased(_("Other sheets"), sheet_names, 
+					 NULL, "sheets");
+  g_signal_connect(DIA_DYNAMIC_MENU(sheet_option_menu), "value-changed",
+		   G_CALLBACK(sheet_option_menu_changed), sheet_option_menu);
+  dia_dynamic_menu_add_default_entry(DIA_DYNAMIC_MENU(sheet_option_menu),
+				     "Assorted");
+  dia_dynamic_menu_add_default_entry(DIA_DYNAMIC_MENU(sheet_option_menu),
+				     "Flowchart");
+  dia_dynamic_menu_add_default_entry(DIA_DYNAMIC_MENU(sheet_option_menu),
+				     "UML");
+  /*    gtk_widget_set_size_request(sheet_option_menu, 20, -1);*/
+  gtk_wrap_box_pack_wrapped(GTK_WRAP_BOX(parent), sheet_option_menu,
+			    TRUE, TRUE, FALSE, FALSE, TRUE);    
+  /* 15 was a magic number that goes beyond the standard objects and the divider. */
+  gtk_wrap_box_reorder_child(GTK_WRAP_BOX(parent),
+			     sheet_option_menu, NUM_TOOLS+1);
+  gtk_widget_show(sheet_option_menu);
+}
+
+void
+fill_sheet_menu(void)
+{
+  gchar *selection = dia_dynamic_menu_get_entry(DIA_DYNAMIC_MENU(sheet_option_menu));
+  create_sheet_dropdown_menu(gtk_widget_get_parent(sheet_option_menu));
+  dia_dynamic_menu_select_entry(DIA_DYNAMIC_MENU(sheet_option_menu), selection);
+  g_free(selection);
+}
+
+void
+create_sheets(GtkWidget *parent)
+{
+  GtkWidget *separator;
+  GtkWidget *label;
+  GtkWidget *swin;
+  gchar *sheetname;
+  Sheet *sheet;
+  
+  separator = gtk_hseparator_new ();
+  /* add a bit of padding around the separator */
+  label = gtk_vbox_new(FALSE, 0);
+  gtk_box_pack_start(GTK_BOX(label), separator, TRUE, TRUE, 3);
+  gtk_widget_show(label);
+
+  gtk_wrap_box_pack_wrapped (GTK_WRAP_BOX(parent), label, TRUE,TRUE, FALSE,FALSE, TRUE);
+  gtk_widget_show(separator);
+
+  create_sheet_dropdown_menu(parent);
+
+  swin = gtk_scrolled_window_new(NULL, NULL);
+  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin),
+				 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+  gtk_wrap_box_pack_wrapped(GTK_WRAP_BOX(parent), swin, TRUE, TRUE, TRUE, TRUE, TRUE);
+  gtk_widget_show(swin);
+
+  sheet_wbox = gtk_hwrap_box_new(FALSE);
+  gtk_wrap_box_set_justify(GTK_WRAP_BOX(sheet_wbox), GTK_JUSTIFY_TOP);
+  gtk_wrap_box_set_line_justify(GTK_WRAP_BOX(sheet_wbox), GTK_JUSTIFY_LEFT);
+  gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(swin), sheet_wbox);
+  gtk_widget_show(sheet_wbox);
+
+  sheetname = persistence_register_string("last-sheet-selected", _("Flowchart"));
+  sheet = get_sheet_by_name(sheetname);
+  if (sheet == NULL) {
+    /* Couldn't find it */
+  } else {
+    fill_sheet_wbox(sheet);
+    dia_dynamic_menu_select_entry(DIA_DYNAMIC_MENU(sheet_option_menu),
+				  sheetname);
+  }
+  g_free(sheetname);
+}
+
+static void
+create_color_area (GtkWidget *parent)
+{
+  GtkWidget *frame;
+  GtkWidget *alignment;
+  GtkWidget *col_area;
+  GtkWidget *line_area;
+  GdkPixmap *default_pixmap;
+  GdkBitmap *default_mask;
+  GdkPixmap *swap_pixmap;
+  GdkBitmap *swap_mask;
+  GtkStyle *style;
+  GtkWidget *hbox;
+
+  gtk_widget_ensure_style(parent);
+  style = gtk_widget_get_style(parent);
+
+  default_pixmap =
+    gdk_pixmap_colormap_create_from_xpm_d(NULL,
+		gtk_widget_get_colormap(parent), &default_mask, 
+		&style->bg[GTK_STATE_NORMAL], default_xpm);
+  swap_pixmap =
+    gdk_pixmap_colormap_create_from_xpm_d(NULL,
+		gtk_widget_get_colormap(parent), &swap_mask, 
+		&style->bg[GTK_STATE_NORMAL], swap_xpm);
+
+  frame = gtk_frame_new (NULL);
+  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
+  gtk_wrap_box_pack_wrapped(GTK_WRAP_BOX(parent), frame, TRUE, TRUE, FALSE, FALSE, TRUE);
+  //gtk_widget_realize (frame);
+
+  hbox = gtk_hbox_new (FALSE, 1);
+  gtk_container_set_border_width (GTK_CONTAINER (hbox), 0);
+  gtk_container_add (GTK_CONTAINER (frame), hbox);
+  
+  /* Color area: */
+  alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
+  gtk_container_set_border_width (GTK_CONTAINER (alignment), 3);
+  
+  col_area = color_area_create (54, 42, 
+                                default_pixmap, default_mask, 
+                                swap_pixmap, swap_mask);
+  gtk_container_add (GTK_CONTAINER (alignment), col_area);
+
+
+  gtk_box_pack_start (GTK_BOX (hbox), alignment, TRUE, TRUE, 0);
+
+  gtk_widget_set_tooltip_text (col_area, 
+			_("Foreground & background colors for new objects.  "
+			  "The small black and white squares reset colors.  "
+			  "The small arrows swap colors.  Double-click to "
+			  "change colors."));
+
+  gtk_widget_show (alignment);
+  
+  /* Linewidth area: */
+  alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
+  gtk_container_set_border_width (GTK_CONTAINER (alignment), 3);
+  
+  line_area = linewidth_area_create ();
+  gtk_container_add (GTK_CONTAINER (alignment), line_area);
+  gtk_box_pack_start (GTK_BOX (hbox), alignment, TRUE, TRUE, 0);
+  gtk_widget_set_tooltip_text(line_area, _("Line widths.  Click on a line to set the default line width for new objects.  Double-click to set the line width more precisely."));
+  gtk_widget_show (alignment);
+
+  gtk_widget_show (col_area);
+  gtk_widget_show (line_area);
+  gtk_widget_show (hbox);
+  gtk_widget_show (frame);
+}
+
+static void
+change_start_arrow_style(Arrow arrow, gpointer user_data)
+{
+  attributes_set_default_start_arrow(arrow);
+}
+static void
+change_end_arrow_style(Arrow arrow, gpointer user_data)
+{
+  attributes_set_default_end_arrow(arrow);
+}
+static void
+change_line_style(LineStyle lstyle, real dash_length, gpointer user_data)
+{
+  attributes_set_default_line_style(lstyle, dash_length);
+}
+
+static void
+create_lineprops_area(GtkWidget *parent)
+{
+  GtkWidget *chooser;
+  Arrow arrow;
+  real dash_length;
+  LineStyle style;
+  gchar *arrow_name;
+
+  chooser = dia_arrow_chooser_new(TRUE, change_start_arrow_style, NULL);
+  gtk_wrap_box_pack_wrapped(GTK_WRAP_BOX(parent), chooser, FALSE, TRUE, FALSE, TRUE, TRUE);
+  arrow.width = persistence_register_real("start-arrow-width", DEFAULT_ARROW_WIDTH);
+  arrow.length = persistence_register_real("start-arrow-length", DEFAULT_ARROW_LENGTH);
+  arrow_name = persistence_register_string("start-arrow-type", "None");
+  arrow.type = arrow_type_from_name(arrow_name);
+  g_free(arrow_name);
+  dia_arrow_chooser_set_arrow(DIA_ARROW_CHOOSER(chooser), &arrow);
+  attributes_set_default_start_arrow(arrow);
+  gtk_widget_set_tooltip_text(chooser, _("Arrow style at the beginning of new lines.  Click to pick an arrow, or set arrow parameters with Details\342\200\246"));
+  gtk_widget_show(chooser);
+
+  chooser = dia_line_chooser_new(change_line_style, NULL);
+  gtk_wrap_box_pack(GTK_WRAP_BOX(parent), chooser, TRUE, TRUE, FALSE, TRUE);
+  gtk_widget_set_tooltip_text (chooser, _("Line style for new lines.  Click to pick a line style, or set line style parameters with Details\342\200\246"));
+  style = persistence_register_integer("line-style", LINESTYLE_SOLID);
+  dash_length = persistence_register_real("dash-length", DEFAULT_LINESTYLE_DASHLEN);
+  dia_line_chooser_set_line_style(DIA_LINE_CHOOSER(chooser), style, dash_length);
+  gtk_widget_show(chooser);
+
+  chooser = dia_arrow_chooser_new(FALSE, change_end_arrow_style, NULL);
+  arrow.width = persistence_register_real("end-arrow-width", DEFAULT_ARROW_WIDTH);
+  arrow.length = persistence_register_real("end-arrow-length", DEFAULT_ARROW_LENGTH);
+  arrow_name = persistence_register_string("end-arrow-type", "Filled Concave");
+  arrow.type = arrow_type_from_name(arrow_name);
+  g_free(arrow_name);
+  dia_arrow_chooser_set_arrow(DIA_ARROW_CHOOSER(chooser), &arrow);
+  attributes_set_default_end_arrow(arrow);
+
+  gtk_wrap_box_pack(GTK_WRAP_BOX(parent), chooser, FALSE, TRUE, FALSE, TRUE);
+  gtk_widget_set_tooltip_text(chooser, _("Arrow style at the end of new lines.  Click to pick an arrow, or set arrow parameters with Details\342\200\246"));
+  gtk_widget_show(chooser);
+}
+
+void
+tool_select_update (GtkWidget *w,
+		     gpointer   data)
+{
+  ToolButtonData *tooldata = (ToolButtonData *) data;
+
+  if (tooldata == NULL) {
+    g_warning("NULL tooldata in tool_select_update");
+    return;
+  }
+
+  if (tooldata->type != -1) {
+    gint x, y;
+    GdkModifierType mask;
+    /*  get the modifiers  */
+    gdk_window_get_pointer (gtk_widget_get_parent_window(w), &x, &y, &mask);
+    tool_select (tooldata->type, tooldata->extra_data, tooldata->user_data,
+                 w, mask&1);
+  }
+}
+
+GdkPixbuf *
+tool_get_pixbuf (ToolButton *tb)
+{
+  GdkPixbuf *pixbuf;
+  gchar **icon_data;
+
+  if (tb->icon_data==NULL) {
+    DiaObjectType *type;
+    
+    type = object_get_type((char *)tb->callback_data.extra_data);
+    if (type == NULL)
+      icon_data = tool_data[0].icon_data;
+    else
+      icon_data = type->pixmap;
+  } else {
+    icon_data = tb->icon_data;
+  }
+  
+  if (strncmp((char*)icon_data, "GdkP", 4) == 0) {
+    pixbuf = gdk_pixbuf_new_from_inline(-1, (guint8*)icon_data, TRUE, NULL);
+  } else {
+    char **pixmap_data = icon_data;
+    pixbuf = gdk_pixbuf_new_from_xpm_data (pixmap_data);
+  }
+  return pixbuf;
+}
+
+/*
+ * Don't look too deep into this function. It is doing bad things
+ * with casts to conform to the historically interface. We know
+ * the difference between char* and char** - most of the time ;)
+ */
+static GtkWidget *
+create_widget_from_xpm_or_gdkp(gchar **icon_data, GtkWidget *button) 
+{
+  GtkWidget *pixmapwidget;
+
+  if (strncmp((char*)icon_data, "GdkP", 4) == 0) {
+    GdkPixbuf *p;
+    p = gdk_pixbuf_new_from_inline(-1, (guint8*)icon_data, TRUE, NULL);
+    pixmapwidget = gtk_image_new_from_pixbuf(p);
+  } else {
+    char **pixmap_data = icon_data;
+    pixmapwidget = gtk_image_new_from_pixbuf (gdk_pixbuf_new_from_xpm_data (pixmap_data));
+  }
+  return pixmapwidget;
+}
+
+static void
+create_tools(GtkWidget *parent)
+{
+  GtkWidget *button;
+  GtkWidget *pixmapwidget;
+  GdkPixmap *pixmap = NULL;
+  GdkBitmap *mask = NULL;
+  /* GtkStyle *style; */
+  char **pixmap_data;
+  int i;
+
+  for (i = 0; i < NUM_TOOLS; i++) {
+    tool_widgets[i] = button = gtk_radio_button_new (tool_group);
+    gtk_container_set_border_width (GTK_CONTAINER (button), 0);
+    gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_HALF);
+    tool_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button));
+    gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE);
+
+    gtk_wrap_box_pack(GTK_WRAP_BOX(parent), button,
+		      TRUE, TRUE, FALSE, TRUE);
+
+    if (tool_data[i].callback_data.type == MODIFY_TOOL) {
+      modify_tool_button = GTK_WIDGET(button);
+    }
+    
+    if (tool_data[i].icon_data==NULL) {
+      DiaObjectType *type;
+      type =
+	object_get_type((char *)tool_data[i].callback_data.extra_data);
+      if (type == NULL)
+	pixmap_data = tool_data[0].icon_data;
+      else
+	pixmap_data = type->pixmap;
+      pixmapwidget = create_widget_from_xpm_or_gdkp(pixmap_data, button);
+    } else {
+      pixmapwidget = create_widget_from_xpm_or_gdkp(tool_data[i].icon_data, button);
+    }
+    
+    /* GTKBUG:? padding changes */
+    gtk_misc_set_padding(GTK_MISC(pixmapwidget), 2, 2);
+    
+    gtk_container_add (GTK_CONTAINER (button), pixmapwidget);
+    
+    g_signal_connect (GTK_OBJECT (button), "clicked",
+		      G_CALLBACK (tool_select_update),
+			&tool_data[i].callback_data);
+    
+    g_signal_connect (GTK_OBJECT (button), "button_press_event",
+		      G_CALLBACK (tool_button_press),
+			&tool_data[i].callback_data);
+
+    if (tool_data[i].callback_data.type == CREATE_OBJECT_TOOL)
+      tool_setup_drag_source(button, &tool_data[i].callback_data,
+			     pixmap, mask);
+
+    if (pixmap) g_object_unref(pixmap);
+    if (mask) g_object_unref(mask);
+
+    tool_data[i].callback_data.widget = button;
+
+    if (tool_data[i].tool_accelerator) {
+	guint key;
+	GdkModifierType mods;
+	gchar *alabel, *atip;
+
+	gtk_accelerator_parse (tool_data[i].tool_accelerator, &key, &mods);
+
+	alabel = gtk_accelerator_get_label(key, mods);
+	atip = g_strconcat(gettext(tool_data[i].tool_desc), " (", alabel, ")", NULL);
+	gtk_widget_set_tooltip_text (button, atip);
+	g_free (atip);
+	g_free (alabel);
+
+    } else {
+	gtk_widget_set_tooltip_text (button,
+				gettext(tool_data[i].tool_desc));
+    }
+    
+    gtk_widget_show (pixmapwidget);
+    gtk_widget_show (button);
+  }
+}
+
+//IUI
+GtkWidget *
+toolbox_create(void)
+{
+  GtkWidget *wrapbox;
+
+  wrapbox = gtk_hwrap_box_new(FALSE);
+  gtk_wrap_box_set_aspect_ratio(GTK_WRAP_BOX(wrapbox), 144.0 / 318.0);
+  gtk_wrap_box_set_justify(GTK_WRAP_BOX(wrapbox), GTK_JUSTIFY_TOP);
+  gtk_wrap_box_set_line_justify(GTK_WRAP_BOX(wrapbox), GTK_JUSTIFY_LEFT);
+
+
+  /* pack the rest of the stuff */
+  gtk_container_set_border_width (GTK_CONTAINER (wrapbox), 0);
+  gtk_widget_show (wrapbox);
+
+  create_tools (wrapbox);
+  create_sheets (wrapbox);
+  create_color_area (wrapbox);
+  create_lineprops_area (wrapbox);
+
+  /* Setup toolbox area as file drop destination */
+  gtk_drag_dest_set (wrapbox,
+		     GTK_DEST_DEFAULT_ALL,
+		     toolbox_target_table, toolbox_n_targets,
+		     GDK_ACTION_COPY);
+
+  return wrapbox;
+}
+
+void
+toolbox_setup_drag_dest (GtkWidget *canvas)
+{
+  gtk_drag_dest_set(canvas, GTK_DEST_DEFAULT_ALL,
+		    display_target_table, display_n_targets, GDK_ACTION_COPY);
+}
+
diff --git a/app/toolbox.h b/app/toolbox.h
new file mode 100644
index 0000000..112e5d2
--- /dev/null
+++ b/app/toolbox.h
@@ -0,0 +1,33 @@
+#include "tool.h"
+
+typedef struct _ToolButton ToolButton;
+
+typedef struct _ToolButtonData ToolButtonData;
+
+struct _ToolButtonData
+{
+  ToolType type;
+  gpointer extra_data;
+  gpointer user_data; /* Used by create_object_tool */
+  GtkWidget *widget;
+};
+
+struct _ToolButton
+{
+  gchar **icon_data;
+  char  *tool_desc;
+  char	*tool_accelerator;
+  char  *action_name;
+  ToolButtonData callback_data;
+};
+
+extern const int num_tools;
+extern ToolButton tool_data[];
+extern gchar *interface_current_sheet_name;
+
+void tool_select_update (GtkWidget *w, gpointer   data);
+GdkPixbuf *tool_get_pixbuf (ToolButton *tb);
+
+void toolbox_setup_drag_dest (GtkWidget *canvas);
+GtkWidget *toolbox_create(void);
+GtkActionGroup *create_or_ref_tool_actions (void);



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