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

gEDA-cvs: pcb.git: branch: master updated (67de03c8e140500a517220e56dc3ddcff165088d)



The branch, master has been updated
       via  67de03c8e140500a517220e56dc3ddcff165088d (commit)
       via  06661490e4b112d277c14afe49d73460c2052baf (commit)
       via  ffe811f14d8db3aa4539b719b4212bb8f6bfd1d8 (commit)
       via  a914d5ba58104d8559395b66798b35761afb991a (commit)
       via  5ee21ef3feb0f40186617b8c7c5fd71d2902cc89 (commit)
       via  705febbdfc68c7638739287b6feb50d625409dc6 (commit)
      from  79159d64bff6b84bd7a6565eb517fc656a35156a (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


=========
 Summary
=========

 src/Makefile.am                         |    3 +-
 src/hid/gtk/ghid-main-menu.c            |   26 ++
 src/hid/gtk/ghid-main-menu.h            |    3 +
 src/hid/gtk/ghid-route-style-selector.c |  585 +++++++++++++++++++++++++++++++
 src/hid/gtk/ghid-route-style-selector.h |   41 +++
 src/hid/gtk/gtkhid-main.c               |   11 +-
 src/hid/gtk/gui-command-window.c        |   14 +-
 src/hid/gtk/gui-dialog-size.c           |  288 ---------------
 src/hid/gtk/gui-top-window.c            |  431 ++++-------------------
 src/hid/gtk/gui.h                       |   15 +-
 10 files changed, 741 insertions(+), 676 deletions(-)
 create mode 100644 src/hid/gtk/ghid-route-style-selector.c
 create mode 100644 src/hid/gtk/ghid-route-style-selector.h
 delete mode 100644 src/hid/gtk/gui-dialog-size.c


=================
 Commit Messages
=================

commit 67de03c8e140500a517220e56dc3ddcff165088d
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Implement RouteStylesChanged action
    
    This action looks at the actual route-style settings (i.e.,
    Settings.LineThickness), and gives these to the route style
    selector. The selector looks in its list and selects a style,
    if one matches. Otherwise, it does nothing.

:100644 100644 b3b5cc1... ad8c26f... M	src/hid/gtk/ghid-route-style-selector.c
:100644 100644 48ae032... 53c481f... M	src/hid/gtk/ghid-route-style-selector.h
:100644 100644 b1ea4ff... 1eed303... M	src/hid/gtk/gtkhid-main.c

commit 06661490e4b112d277c14afe49d73460c2052baf
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Add Ctrl+F1,F2,F3,... accelerators to route style selector
    
    Since we now have three accelerator groups to worry about (those
    of the layer selector, route style selector and main menu), I
    have moved the hooking/unhooking code into two functions:
    
      ghid_install_accel_groups ()
      ghid_remove_accel_groups ()
    
    These should be used whenever accelerators need to be disabled,
    for example, when the user has the command box active.

:100644 100644 9178645... b3b5cc1... M	src/hid/gtk/ghid-route-style-selector.c
:100644 100644 4823d74... 48ae032... M	src/hid/gtk/ghid-route-style-selector.h
:100644 100644 3701853... 310ace8... M	src/hid/gtk/gui-command-window.c
:100644 100644 56c31f0... 91572fb... M	src/hid/gtk/gui-top-window.c
:100644 100644 e9dbf26... 4fa67a7... M	src/hid/gtk/gui.h

commit ffe811f14d8db3aa4539b719b4212bb8f6bfd1d8
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Remove the last of ghidgui->toggle_holdoff

:100644 100644 bed4ea6... 56c31f0... M	src/hid/gtk/gui-top-window.c
:100644 100644 316d409... e9dbf26... M	src/hid/gtk/gui.h

commit a914d5ba58104d8559395b66798b35761afb991a
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Replace old route style selector with GHidRouteStyleSelector
    
    TODO: The RouteStylesChanged action is now very broken.
          Menu accelerators need to be installed

:100644 100644 2e01c31... 7adb424... M	src/Makefile.am
:100644 100644 7a6b8a8... b1ea4ff... M	src/hid/gtk/gtkhid-main.c
:100644 000000 e3047bb... 0000000... D	src/hid/gtk/gui-dialog-size.c
:100644 100644 1352be0... bed4ea6... M	src/hid/gtk/gui-top-window.c
:100644 100644 883e803... 316d409... M	src/hid/gtk/gui.h

commit 5ee21ef3feb0f40186617b8c7c5fd71d2902cc89
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Introduce functions for GHidRouteStyleSelector handling to menu

:100644 100644 ed4e2e8... 9ac0367... M	src/hid/gtk/ghid-main-menu.c
:100644 100644 d667e34... da1fd9c... M	src/hid/gtk/ghid-main-menu.h

commit 705febbdfc68c7638739287b6feb50d625409dc6
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Introduce GHidRouteStyleSelector widget, don't use it yet

:100644 100644 a9c51b2... 2e01c31... M	src/Makefile.am
:000000 100644 0000000... 9178645... A	src/hid/gtk/ghid-route-style-selector.c
:000000 100644 0000000... 4823d74... A	src/hid/gtk/ghid-route-style-selector.h

=========
 Changes
=========

commit 67de03c8e140500a517220e56dc3ddcff165088d
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Implement RouteStylesChanged action
    
    This action looks at the actual route-style settings (i.e.,
    Settings.LineThickness), and gives these to the route style
    selector. The selector looks in its list and selects a style,
    if one matches. Otherwise, it does nothing.

diff --git a/src/hid/gtk/ghid-route-style-selector.c b/src/hid/gtk/ghid-route-style-selector.c
index b3b5cc1..ad8c26f 100644
--- a/src/hid/gtk/ghid-route-style-selector.c
+++ b/src/hid/gtk/ghid-route-style-selector.c
@@ -543,3 +543,43 @@ ghid_route_style_selector_get_accel_group (GHidRouteStyleSelector *rss)
   return rss->accel_group;
 }
 
+/*! \brief Sets a GHidRouteStyleSelector selection to given values
+ *  \par Function Description
+ *  Given the line thickness, via size and clearance values of a route
+ *  style, this function selects a route style with the given values.
+ *  If there is no such style registered with the selector, nothing
+ *  will happen. This function does not emit any signals.
+ *
+ *  \param [in] rss       The selector to be acted on
+ *  \param [in] Thick     Coord to match selection to
+ *  \param [in] Diameter  Coord to match selection to
+ *  \param [in] Hole      Coord to match selection to
+ *  \param [in] Keepaway  Coord to match selection to
+ */
+void
+ghid_route_style_selector_sync (GHidRouteStyleSelector *rss,
+                                Coord Thick, Coord Diameter,
+                                Coord Hole, Coord Keepaway)
+{
+  GtkTreeIter iter;
+  gtk_tree_model_get_iter_first (GTK_TREE_MODEL (rss->model), &iter);
+  do
+    {
+      struct _route_style *style;
+      gtk_tree_model_get (GTK_TREE_MODEL (rss->model),
+                          &iter, DATA_COL, &style, -1);
+      if (style->rst->Thick == Thick &&
+          style->rst->Diameter == Diameter &&
+          style->rst->Hole == Hole &&
+          style->rst->Keepaway == Keepaway)
+        {
+          g_signal_handler_block (G_OBJECT (style->action), style->sig_id);
+          gtk_toggle_action_set_active
+            (GTK_TOGGLE_ACTION (style->action), TRUE);
+          g_signal_handler_unblock (G_OBJECT (style->action), style->sig_id);
+          rss->active_style = style;
+        }
+    }
+  while (gtk_tree_model_iter_next (GTK_TREE_MODEL (rss->model), &iter));
+}
+
diff --git a/src/hid/gtk/ghid-route-style-selector.h b/src/hid/gtk/ghid-route-style-selector.h
index 48ae032..53c481f 100644
--- a/src/hid/gtk/ghid-route-style-selector.h
+++ b/src/hid/gtk/ghid-route-style-selector.h
@@ -33,5 +33,9 @@ void ghid_route_style_selector_edit_dialog (GHidRouteStyleSelector *rss);
 GtkAccelGroup *ghid_route_style_selector_get_accel_group
                  (GHidRouteStyleSelector *rss);
 
+void ghid_route_style_selector_sync (GHidRouteStyleSelector *rss,
+                                     Coord Thick, Coord Diameter,
+                                     Coord Hole, Coord Keepaway);
+
 G_END_DECLS  /* keep c++ happy */
 #endif
diff --git a/src/hid/gtk/gtkhid-main.c b/src/hid/gtk/gtkhid-main.c
index b1ea4ff..1eed303 100644
--- a/src/hid/gtk/gtkhid-main.c
+++ b/src/hid/gtk/gtkhid-main.c
@@ -1142,7 +1142,14 @@ static int PointCursor (int argc, char **argv, Coord x, Coord y)
 static int
 RouteStylesChanged (int argc, char **argv, Coord x, Coord y)
 {
-  /* TODO: handle this, somehow (asp) */
+  if (!ghidgui || !ghidgui->route_style_selector)
+    return 0;
+
+  ghid_route_style_selector_sync
+    (GHID_ROUTE_STYLE_SELECTOR (ghidgui->route_style_selector),
+     Settings.LineThickness, Settings.ViaThickness,
+     Settings.ViaDrillingHole, Settings.Keepaway);
+
   return 0;
 }
 

commit 06661490e4b112d277c14afe49d73460c2052baf
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Add Ctrl+F1,F2,F3,... accelerators to route style selector
    
    Since we now have three accelerator groups to worry about (those
    of the layer selector, route style selector and main menu), I
    have moved the hooking/unhooking code into two functions:
    
      ghid_install_accel_groups ()
      ghid_remove_accel_groups ()
    
    These should be used whenever accelerators need to be disabled,
    for example, when the user has the command box active.

diff --git a/src/hid/gtk/ghid-route-style-selector.c b/src/hid/gtk/ghid-route-style-selector.c
index 9178645..b3b5cc1 100644
--- a/src/hid/gtk/ghid-route-style-selector.c
+++ b/src/hid/gtk/ghid-route-style-selector.c
@@ -50,6 +50,9 @@ struct _GHidRouteStyleSelector
   GSList *action_radio_group;
   GtkWidget *edit_button;
 
+  GtkActionGroup *action_group;
+  GtkAccelGroup *accel_group;
+
   GtkListStore *model;
   struct _route_style *active_style;
 };
@@ -363,6 +366,9 @@ ghid_route_style_selector_new ()
   rss->button_radio_group = NULL;
   rss->model = gtk_list_store_new (N_COLS, G_TYPE_STRING, G_TYPE_POINTER);
 
+  rss->accel_group = gtk_accel_group_new ();
+  rss->action_group = gtk_action_group_new ("RouteStyleSelector");
+
   /* Create edit button */
   rss->edit_button = gtk_button_new_with_label (_("Route Styles"));
   g_signal_connect (G_OBJECT (rss->edit_button), "clicked",
@@ -409,6 +415,18 @@ ghid_route_style_selector_real_add_route_style (GHidRouteStyleSelector *rss,
                                                 path);
   gtk_tree_path_free (path);
 
+  /* Setup accelerator */
+  if (action_count < 12)
+    {
+      gchar *accel = g_strdup_printf ("<Ctrl>F%d", action_count + 1);
+      gtk_action_set_accel_group (GTK_ACTION (new_style->action),
+                                  rss->accel_group);
+      gtk_action_group_add_action_with_accel (rss->action_group,
+                                              GTK_ACTION (new_style->action),
+                                              accel);
+      g_free (accel);
+    }
+
   /* Hookup and install radio button */
   g_object_set_data (G_OBJECT (new_style->action), "route-style", new_style);
   new_style->sig_id = g_signal_connect (G_OBJECT (new_style->action),
@@ -512,3 +530,16 @@ ghid_route_style_selector_select_style (GHidRouteStyleSelector *rss,
   return FALSE;
 }
 
+/*! \brief Returns the GtkAccelGroup of a route style selector
+ *  \par Function Description
+ *
+ *  \param [in] rss            The selector to be acted on
+ *
+ *  \return the accel group of the selector
+ */
+GtkAccelGroup *
+ghid_route_style_selector_get_accel_group (GHidRouteStyleSelector *rss)
+{
+  return rss->accel_group;
+}
+
diff --git a/src/hid/gtk/ghid-route-style-selector.h b/src/hid/gtk/ghid-route-style-selector.h
index 4823d74..48ae032 100644
--- a/src/hid/gtk/ghid-route-style-selector.h
+++ b/src/hid/gtk/ghid-route-style-selector.h
@@ -30,5 +30,8 @@ gboolean ghid_route_style_selector_select_style (GHidRouteStyleSelector *rss,
                                                   RouteStyleType *rst);
 void ghid_route_style_selector_edit_dialog (GHidRouteStyleSelector *rss);
 
+GtkAccelGroup *ghid_route_style_selector_get_accel_group
+                 (GHidRouteStyleSelector *rss);
+
 G_END_DECLS  /* keep c++ happy */
 #endif
diff --git a/src/hid/gtk/gui-command-window.c b/src/hid/gtk/gui-command-window.c
index 3701853..310ace8 100644
--- a/src/hid/gtk/gui-command-window.c
+++ b/src/hid/gtk/gui-command-window.c
@@ -414,12 +414,7 @@ ghid_command_entry_get (gchar * prompt, gchar * command)
      |  insensitive so all the user can do is enter a command, grab focus
      |  and connect a handler to look for the escape key.
    */
-  gtk_window_remove_accel_group (GTK_WINDOW (out->top_window),
-                                 ghid_main_menu_get_accel_group
-                                   (GHID_MAIN_MENU (ghidgui->menu_bar)));
-  gtk_window_remove_accel_group (GTK_WINDOW (out->top_window),
-                                 ghid_layer_selector_get_accel_group
-                                   (GHID_LAYER_SELECTOR (ghidgui->layer_selector)));
+  ghid_remove_accel_groups (GTK_WINDOW (gport->top_window), ghidgui);
   ghid_interface_input_signals_disconnect ();
   ghid_interface_set_sensitive (FALSE);
   gtk_widget_grab_focus (GTK_WIDGET (ghidgui->command_entry));
@@ -440,12 +435,7 @@ ghid_command_entry_get (gchar * prompt, gchar * command)
   g_signal_handler_disconnect (ghidgui->command_entry, escape_sig_id);
   ghid_interface_input_signals_connect ();
   ghid_interface_set_sensitive (TRUE);
-  gtk_window_add_accel_group (GTK_WINDOW (out->top_window),
-                              ghid_main_menu_get_accel_group
-                                (GHID_MAIN_MENU (ghidgui->menu_bar)));
-  gtk_window_add_accel_group (GTK_WINDOW (out->top_window),
-                              ghid_layer_selector_get_accel_group
-                                (GHID_LAYER_SELECTOR (ghidgui->layer_selector)));
+  ghid_install_accel_groups (GTK_WINDOW (gport->top_window), ghidgui);
 
   /* Restore the status line label and give focus back to the drawing area
    */
diff --git a/src/hid/gtk/gui-top-window.c b/src/hid/gtk/gui-top-window.c
index 56c31f0..91572fb 100644
--- a/src/hid/gtk/gui-top-window.c
+++ b/src/hid/gtk/gui-top-window.c
@@ -424,15 +424,33 @@ layer_selector_toggle_callback (GHidLayerSelector *ls, int layer, gpointer d)
 }
 
 /*! \brief Install menu bar and accelerator groups */
-static void
-make_actions (GHidPort * port)
+void
+ghid_install_accel_groups (GtkWindow *window, GhidGui *gui)
+{
+  gtk_window_add_accel_group
+    (window, ghid_main_menu_get_accel_group
+               (GHID_MAIN_MENU (gui->menu_bar)));
+  gtk_window_add_accel_group
+    (window, ghid_layer_selector_get_accel_group
+               (GHID_LAYER_SELECTOR (gui->layer_selector)));
+  gtk_window_add_accel_group
+    (window, ghid_route_style_selector_get_accel_group
+               (GHID_ROUTE_STYLE_SELECTOR (gui->route_style_selector)));
+}
+
+/*! \brief Remove menu bar and accelerator groups */
+void
+ghid_remove_accel_groups (GtkWindow *window, GhidGui *gui)
 {
-  gtk_window_add_accel_group (GTK_WINDOW (gport->top_window),
-			      ghid_main_menu_get_accel_group
-                                (GHID_MAIN_MENU (ghidgui->menu_bar)));
-  gtk_window_add_accel_group (GTK_WINDOW (port->top_window),
-			      ghid_layer_selector_get_accel_group
-                                (GHID_LAYER_SELECTOR (ghidgui->layer_selector)));
+  gtk_window_remove_accel_group
+    (window, ghid_main_menu_get_accel_group
+               (GHID_MAIN_MENU (gui->menu_bar)));
+  gtk_window_remove_accel_group
+    (window, ghid_layer_selector_get_accel_group
+               (GHID_LAYER_SELECTOR (gui->layer_selector)));
+  gtk_window_remove_accel_group
+    (window, ghid_route_style_selector_get_accel_group
+               (GHID_ROUTE_STYLE_SELECTOR (gui->route_style_selector)));
 }
 
 static void
@@ -1163,7 +1181,6 @@ ghid_build_pcb_top_window (void)
                     NULL);
   /* Build main menu */
   ghidgui->menu_bar = ghid_load_menus ();
-  make_actions (port);
   gtk_box_pack_start (GTK_BOX (ghidgui->menubar_toolbar_vbox),
                       ghidgui->menu_bar, FALSE, FALSE, 0);
 
@@ -1436,6 +1453,7 @@ ghid_create_pcb_widgets (void)
     g_error_free(err);
     }
   ghid_build_pcb_top_window ();
+  ghid_install_accel_groups (GTK_WINDOW (port->top_window), ghidgui);
   ghid_update_toggle_flags ();
 
   ghid_init_icons (port);
diff --git a/src/hid/gtk/gui.h b/src/hid/gtk/gui.h
index e9dbf26..4fa67a7 100644
--- a/src/hid/gtk/gui.h
+++ b/src/hid/gtk/gui.h
@@ -338,6 +338,8 @@ int ghid_drc_window_throw_dialog (void);
 
 /* In gui-top-window.c  */
 void ghid_update_toggle_flags (void);
+void ghid_install_accel_groups (GtkWindow *window, GhidGui *gui);
+void ghid_remove_accel_groups (GtkWindow *window, GhidGui *gui);
 
 /* gui-utils.c
 */

commit ffe811f14d8db3aa4539b719b4212bb8f6bfd1d8
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Remove the last of ghidgui->toggle_holdoff

diff --git a/src/hid/gtk/gui-top-window.c b/src/hid/gtk/gui-top-window.c
index bed4ea6..56c31f0 100644
--- a/src/hid/gtk/gui-top-window.c
+++ b/src/hid/gtk/gui-top-window.c
@@ -49,9 +49,6 @@ I NEED TO DO THE STATUS LINE THING.  for example shift-alt-v to change the
 via size.  NOte the status line label does not get updated properly until
 a zoom in/out.
 
-- do not forget I can use
-  if (!ghidgui->toggle_holdoff)
-  
 #endif
 
 /* This file was originally written by Bill Wilson for the PCB Gtk
@@ -169,14 +166,8 @@ menu_toggle_update_cb (GtkAction *act, const char *tflag, const char *aflag)
 void
 ghid_update_toggle_flags ()
 {
-  /* mask the callbacks */
-  old_holdoff = ghidgui->toggle_holdoff;
-  ghidgui->toggle_holdoff = TRUE;
-
   ghid_main_menu_update_toggle_state (GHID_MAIN_MENU (ghidgui->menu_bar),
                                       menu_toggle_update_cb);
-
-  ghidgui->toggle_holdoff = old_holdoff;
 }
 
 static void
@@ -240,10 +231,6 @@ ghid_menu_cb (GtkAction *action, const Resource *node)
   if (action == NULL || node == NULL) 
     return;
 
-  /* Prevent recursion */
-  if (ghidgui->toggle_holdoff == TRUE) 
-    return;
-
   for (i = 1; i < node->c; i++)
     if (resource_type (node->v[i]) == 10)
       {
@@ -278,19 +265,6 @@ void ghid_hotkey_cb (int which)
 void
 ghid_sync_with_new_layout (void)
 {
-  gboolean old_holdoff;
-
-  /* Just want to update the state of the menus without calling the
-     |  action functions at this time because causing a toggle action can
-     |  undo the initial condition set we want here.
-   */
-  old_holdoff = ghidgui->toggle_holdoff;
-  ghidgui->toggle_holdoff = TRUE;
-
-  /* FIXME - need toggle_holdoff?  Need other calls to sync here? */
-
-  ghidgui->toggle_holdoff = old_holdoff;
-
   pcb_use_route_style (&PCB->RouteStyle[0]);
   ghid_route_style_selector_select_style
     (GHID_ROUTE_STYLE_SELECTOR (ghidgui->route_style_selector),
diff --git a/src/hid/gtk/gui.h b/src/hid/gtk/gui.h
index 316d409..e9dbf26 100644
--- a/src/hid/gtk/gui.h
+++ b/src/hid/gtk/gui.h
@@ -125,7 +125,6 @@ typedef struct
   gchar *name_label_string;
 
   gboolean adjustment_changed_holdoff,
-    toggle_holdoff,
     command_entry_status_line_active,
     auto_pan_on, in_popup;
 

commit a914d5ba58104d8559395b66798b35761afb991a
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Replace old route style selector with GHidRouteStyleSelector
    
    TODO: The RouteStylesChanged action is now very broken.
          Menu accelerators need to be installed

diff --git a/src/Makefile.am b/src/Makefile.am
index 2e01c31..7adb424 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -286,7 +286,6 @@ LIBGTK_SRCS = \
 	hid/gtk/gui-command-window.c \
 	hid/gtk/gui-config.c \
 	hid/gtk/gui-dialog-print.c \
-	hid/gtk/gui-dialog-size.c \
 	hid/gtk/gui-dialog.c \
 	hid/gtk/gui-drc-window.c \
 	hid/gtk/gui-drc-window.h \
diff --git a/src/hid/gtk/gtkhid-main.c b/src/hid/gtk/gtkhid-main.c
index 7a6b8a8..b1ea4ff 100644
--- a/src/hid/gtk/gtkhid-main.c
+++ b/src/hid/gtk/gtkhid-main.c
@@ -1142,11 +1142,7 @@ static int PointCursor (int argc, char **argv, Coord x, Coord y)
 static int
 RouteStylesChanged (int argc, char **argv, Coord x, Coord y)
 {
-  gint n;
-
-  if (PCB && PCB->RouteStyle[0].Name)
-    for (n = 0; n < NUM_STYLES; ++n)
-      ghid_route_style_set_button_label ((&PCB->RouteStyle[n])->Name, n);
+  /* TODO: handle this, somehow (asp) */
   return 0;
 }
 
diff --git a/src/hid/gtk/gui-dialog-size.c b/src/hid/gtk/gui-dialog-size.c
deleted file mode 100644
index e3047bb..0000000
--- a/src/hid/gtk/gui-dialog-size.c
+++ /dev/null
@@ -1,288 +0,0 @@
-/* $Id$ */
-
-/*
- *                            COPYRIGHT
- *
- *  PCB, interactive printed circuit board design
- *  Copyright (C) 1994,1995,1996 Thomas Nau
- *
- *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *  Contact addresses for paper mail and Email:
- *  Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany
- *  Thomas.Nau@xxxxxxxxxxxxx
- *
- */
-
-/* This file written by Bill Wilson for the PCB Gtk port. */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "global.h"
-
-#include "change.h"
-#include "crosshair.h"
-#include "data.h"
-#include "error.h"
-#include "misc.h"
-#include "set.h"
-#include "pcb-printf.h"
-
-#include "gui.h"
-
-#ifdef HAVE_LIBDMALLOC
-#include <dmalloc.h>
-#endif
-
-RCSID ("$Id$");
-
-typedef struct
-{
-  GtkWidget *name_entry,
-    *line_width_coord_entry,
-    *via_hole_coord_entry,
-    *via_size_coord_entry,
-    *clearance_coord_entry, *set_temp1_button, *set_temp2_button;
-}
-SizesDialog;
-
-static SizesDialog route_sizes;
-
-static void
-via_hole_cb (GHidCoordEntry * entry, gpointer data)
-{
-  SizesDialog * sd = (SizesDialog *)data;
-  gdouble via_hole_size, via_size;
-
-  via_hole_size = ghid_coord_entry_get_value (entry);
-  via_size = ghid_coord_entry_get_value
-               (GHID_COORD_ENTRY (sd->via_size_coord_entry));
-
-  if (via_size < via_hole_size + MIN_PINORVIACOPPER)
-    ghid_coord_entry_set_value (GHID_COORD_ENTRY (sd->via_size_coord_entry),
-			           via_hole_size + MIN_PINORVIACOPPER);
-}
-
-static void
-via_size_cb (GHidCoordEntry * entry, gpointer data)
-{
-  SizesDialog * sd = (SizesDialog *)data;
-  gdouble via_hole_size, via_size;
-
-  via_size = ghid_coord_entry_get_value (entry);
-  via_hole_size = ghid_coord_entry_get_value
-                    (GHID_COORD_ENTRY (sd->via_hole_coord_entry));
-
-  if (via_hole_size > via_size - MIN_PINORVIACOPPER)
-    ghid_coord_entry_set_value (GHID_COORD_ENTRY (sd->via_hole_coord_entry),
-			           via_size - MIN_PINORVIACOPPER);
-}
-
-static void
-use_temp_cb (GtkToggleButton * button, gpointer data)
-{
-  gint which = GPOINTER_TO_INT (data);
-  gboolean active;
-
-  active = gtk_toggle_button_get_active (button);
-  if (which == 1 && active)
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON
-				  (route_sizes.set_temp2_button), FALSE);
-  else if (which == 2 && active)
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON
-				  (route_sizes.set_temp1_button), FALSE);
-}
-
-
-  /* -----------------------------------------------------------------------
-     |  style sizes dialog
-   */
-void
-ghid_route_style_dialog (gint index, RouteStyleType * temp_rst)
-{
-  GtkWidget *dialog, *table, *vbox, *vbox1, *hbox, *label;
-  GtkWidget *set_default_button = NULL;
-  GHidPort *out = &ghid_port;
-  RouteStyleType *rst;
-  SizesDialog *sd;
-  gchar *s, buf[64];
-  gboolean set_temp1 = FALSE, set_temp2 = FALSE;
-  gboolean editing_temp, set_default = FALSE;
-
-  sd = &route_sizes;
-
-  editing_temp = (index >= NUM_STYLES);
-  rst = editing_temp ? temp_rst : &PCB->RouteStyle[index];
-
-  if (!rst)
-    return;
-
-  snprintf (buf, sizeof (buf), _("%s Sizes"), rst->Name);
-  dialog = gtk_dialog_new_with_buttons (buf,
-					GTK_WINDOW (out->top_window),
-					(GtkDialogFlags)(GTK_DIALOG_MODAL |
-							 GTK_DIALOG_DESTROY_WITH_PARENT),
-					GTK_STOCK_CANCEL, GTK_RESPONSE_NONE,
-					GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
-  gtk_window_set_wmclass (GTK_WINDOW (dialog), "Sizes_dialog", "PCB");
-
-  vbox = gtk_vbox_new (FALSE, 2);
-  gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
-  gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), vbox);
-
-  hbox = gtk_hbox_new (FALSE, 4);
-  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 4);
-  label = gtk_label_new (_("Route style name"));
-  gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
-  sd->name_entry = gtk_entry_new ();
-  gtk_box_pack_start (GTK_BOX (hbox), sd->name_entry, FALSE, FALSE, 0);
-
-  vbox1 = ghid_category_vbox (vbox, _("Sizes"), 4, 2, TRUE, TRUE);
-  table = gtk_table_new (4, 2, FALSE);
-  gtk_table_set_col_spacings (GTK_TABLE (table), 6);
-  gtk_table_set_row_spacings (GTK_TABLE (table), 3);
-
-  ghid_table_coord_entry (table, 0, 0, &sd->line_width_coord_entry,
-			  rst->Thick, MIN_LINESIZE, MAX_LINESIZE,
-			  CE_SMALL, 0, NULL, sd, TRUE,
-			  _("Line width"));
-  ghid_table_coord_entry (table, 1, 0, &sd->via_hole_coord_entry,
-			  rst->Hole, MIN_PINORVIAHOLE,
-			  MAX_PINORVIASIZE - MIN_PINORVIACOPPER,
-			  CE_SMALL, 0, via_hole_cb, sd, TRUE,
-			  _("Via hole"));
-  ghid_table_coord_entry (table, 2, 0, &sd->via_size_coord_entry,
-			  rst->Diameter, MIN_PINORVIAHOLE + MIN_PINORVIACOPPER,
-			  MAX_PINORVIASIZE,
-			  CE_SMALL, 0, via_size_cb, sd, TRUE,
-			  _("Via size"));
-  ghid_table_coord_entry (table, 3, 0, &sd->clearance_coord_entry,
-			  rst->Keepaway, MIN_LINESIZE, MAX_LINESIZE,
-			  CE_SMALL, 0, NULL, sd, true,
-			  _("Clearance"));
-  gtk_box_pack_start (GTK_BOX (vbox1), table, FALSE, FALSE, 0);
-
-  if (!editing_temp)
-    {
-      vbox1 = ghid_category_vbox (vbox, _("Temporary Styles"),
-				  4, 2, TRUE, TRUE);
-      label = gtk_label_new ("");
-      gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
-      s = g_strdup_printf (_("<small>"
-			     "Use values in a temporary route style instead of <b>%s</b>."
-			     "</small>"), rst->Name);
-      gtk_label_set_markup (GTK_LABEL (label), s);
-      g_free (s);
-      gtk_box_pack_start (GTK_BOX (vbox1), label, FALSE, FALSE, 0);
-
-      ghid_check_button_connected (vbox1, &sd->set_temp1_button, FALSE,
-				   TRUE, FALSE, FALSE, 0,
-				   use_temp_cb, GINT_TO_POINTER (1),
-				   _("Temp1"));
-      ghid_check_button_connected (vbox1, &sd->set_temp2_button, FALSE, TRUE,
-				   FALSE, FALSE, 0, use_temp_cb,
-				   GINT_TO_POINTER (2), _("Temp2"));
-
-      vbox1 = ghid_category_vbox (vbox, _("Default Style"), 4, 2, TRUE, TRUE);
-      label = gtk_label_new ("");
-      gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
-      s = g_strdup_printf (_("<small>"
-			     "Use values as the default route style for new layouts."
-			     "</small>"));
-      gtk_label_set_markup (GTK_LABEL (label), s);
-      g_free (s);
-      gtk_box_pack_start (GTK_BOX (vbox1), label, FALSE, FALSE, 0);
-      ghid_check_button_connected (vbox1, &set_default_button, FALSE,
-				   TRUE, FALSE, FALSE, 0,
-				   NULL, NULL, _("Set as default"));
-
-    }
-
-  gtk_entry_set_text (GTK_ENTRY (sd->name_entry), rst->Name);
-  if (editing_temp)
-    gtk_editable_set_editable (GTK_EDITABLE (sd->name_entry), FALSE);
-
-  gtk_widget_show_all (dialog);
-
-  if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
-    {
-      gchar *string;
-      RouteStyleType rst_buf;
-
-      if (!editing_temp)
-	{
-	  set_temp1 =
-	    gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
-					  (sd->set_temp1_button));
-	  set_temp2 =
-	    gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
-					  (sd->set_temp2_button));
-	  set_default =
-	    gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
-					  (set_default_button));
-	}
-      if (set_temp1 || set_temp2)
-	rst = &rst_buf;
-
-      rst->Thick =
-	ghid_coord_entry_get_value (GHID_COORD_ENTRY
-				        (sd->line_width_coord_entry));
-      rst->Hole =
-	ghid_coord_entry_get_value (GHID_COORD_ENTRY
-				        (sd->via_hole_coord_entry));
-      rst->Diameter =
-	ghid_coord_entry_get_value (GHID_COORD_ENTRY
-				        (sd->via_size_coord_entry));
-      rst->Keepaway =
-	ghid_coord_entry_get_value (GHID_COORD_ENTRY
-				        (sd->clearance_coord_entry));
-
-      if (index < NUM_STYLES && !set_temp1 && !set_temp2)
-	{
-	  string = ghid_entry_get_text (sd->name_entry);
-	  free (rst->Name);
-	  rst->Name = StripWhiteSpaceAndDup (string);
-	  pcb_use_route_style (rst);
-	  SetChangedFlag (true);
-	  ghid_route_style_set_button_label (rst->Name, index);
-	}
-      else
-	{
-	  pcb_use_route_style (rst);
-	  ghid_route_style_set_temp_style (rst, set_temp1 ? 0 :
-					   (set_temp2 ? 1 : index -
-					    NUM_STYLES));
-	}
-      if (set_default)
-	{
-	  gchar *s;
-
-	  Settings.RouteStyle[index] = *rst;
-	  ghidgui->config_modified = TRUE;
-	  s = make_route_string (Settings.RouteStyle, NUM_STYLES);
-	  g_free (Settings.Routes);
-	  Settings.Routes = s;
-	}
-    }
-
-  gtk_widget_destroy (dialog);
-  ghid_window_set_name_label (PCB->Name);
-  ghid_set_status_line_label ();
-}
diff --git a/src/hid/gtk/gui-top-window.c b/src/hid/gtk/gui-top-window.c
index 1352be0..bed4ea6 100644
--- a/src/hid/gtk/gui-top-window.c
+++ b/src/hid/gtk/gui-top-window.c
@@ -83,6 +83,7 @@ a zoom in/out.
 #endif
 
 #include "ghid-layer-selector.h"
+#include "ghid-route-style-selector.h"
 #include "gtkhid.h"
 #include "gui.h"
 #include "hid.h"
@@ -132,39 +133,10 @@ a zoom in/out.
 
 RCSID ("$Id$");
 
-/* ---------------------------------------------------------------------------
- * local types
- */
-
-/* Used by the route style buttons and menu */
-typedef struct
-{
-  GtkWidget *button;
-  RouteStyleType route_style;
-  gboolean shown;		/* For temp buttons */
-}
-RouteStyleButton;
-
-/* ---------------------------------------------------------------------------
- * local macros
- */
-
-/* ---------------------------------------------------------------------------
- * local prototypes
- */
-
-
-#define N_ROUTE_STYLES (NUM_STYLES + 3)
-
 static bool ignore_layer_update;
 
 static GtkWidget *ghid_load_menus (void);
 
-/* actions for the @routestyles menuitems */
-static GtkToggleActionEntry routestyle_toggle_entries[N_ROUTE_STYLES];
-static Resource *routestyle_resources[N_ROUTE_STYLES];
-#define ROUTESTYLE "RouteStyle"
-
 GhidGui _ghidgui, *ghidgui = NULL;
 
 GHidPort ghid_port, *gport;
@@ -177,22 +149,6 @@ static struct { GtkAction *action; const Resource *node; }
         (sizeof (ghid_hotkey_actions) / sizeof (ghid_hotkey_actions[0]))
 
 
-/* ------------------------------------------------------------------
- *  Route style buttons
- */
-
-/* Make 3 extra route style radio buttons.  2 for the extra Temp route
- * styles, and the 3rd is an always invisible button selected when the
- * route style settings in use don't match any defined route style (the
- * user can hit 'l', 'v', etc keys to change the settings without selecting
- * a new defined style.
- */
-
-static RouteStyleButton route_style_button[N_ROUTE_STYLES];
-static gint route_style_index;
-
-static GtkWidget *route_style_edit_button;
-
 /*! \brief callback for ghid_main_menu_update_toggle_state () */
 void
 menu_toggle_update_cb (GtkAction *act, const char *tflag, const char *aflag)
@@ -213,13 +169,6 @@ menu_toggle_update_cb (GtkAction *act, const char *tflag, const char *aflag)
 void
 ghid_update_toggle_flags ()
 {
-  int i;
-
-  GtkAction *a;
-  gboolean active;
-  gboolean old_holdoff;
-  char tmpnm[40];
-
   /* mask the callbacks */
   old_holdoff = ghidgui->toggle_holdoff;
   ghidgui->toggle_holdoff = TRUE;
@@ -227,24 +176,6 @@ ghid_update_toggle_flags ()
   ghid_main_menu_update_toggle_state (GHID_MAIN_MENU (ghidgui->menu_bar),
                                       menu_toggle_update_cb);
 
-  for (i = 0; i < N_ROUTE_STYLES; i++)
-    {
-      sprintf (tmpnm, "%s%d", ROUTESTYLE, i);
-      a = gtk_action_group_get_action (ghidgui->main_actions, tmpnm);
-      if (i >= NUM_STYLES)
-	{
-	  gtk_action_set_visible (a, FALSE);
-	}
-
-      /* Update the toggle states */
-      active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (route_style_button[i].button));
-#ifdef DEBUG_MENUS
-      printf ("ghid_update_toggle_flags():  route style %d, value is %d\n", i, active);
-#endif
-      gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (a), active);
-	
-    }
-
   ghidgui->toggle_holdoff = old_holdoff;
 }
 
@@ -304,7 +235,7 @@ top_window_configure_event_cb (GtkWidget * widget, GdkEventConfigure * ev,
 static void
 ghid_menu_cb (GtkAction *action, const Resource *node)
 {
-  const gchar *name = gtk_action_get_name (action);
+  int i;
 
   if (action == NULL || node == NULL) 
     return;
@@ -313,30 +244,14 @@ ghid_menu_cb (GtkAction *action, const Resource *node)
   if (ghidgui->toggle_holdoff == TRUE) 
     return;
 
+  for (i = 1; i < node->c; i++)
+    if (resource_type (node->v[i]) == 10)
+      {
 #ifdef DEBUG_MENUS
-  printf ("ghid_menu_cb():  name = \"%s\"\n", name);
+        printf ("    %s\n", node->v[i].value);
 #endif
-
-  /* Special-case route styles */
-  if (strncmp (name, ROUTESTYLE, strlen (ROUTESTYLE)) == 0)
-    {
-      int id = atoi (name + strlen (ROUTESTYLE));
-      if (ghidgui->toggle_holdoff != TRUE) 
-	ghid_route_style_button_set_active (id);
-      node = NULL;
-    }
-  else
-    {
-      int vi;
-      for (vi = 1; vi < node->c; vi++)
-	if (resource_type (node->v[vi]) == 10)
-	  {
-#ifdef DEBUG_MENUS
-	    printf ("    %s\n", node->v[vi].value);
-#endif
-	    hid_parse_actions (node->v[vi].value);
-	  }
-    }
+        hid_parse_actions (node->v[i].value);
+      }
 
   /* Sync gui widgets with pcb state */
   ghid_update_toggle_flags ();
@@ -377,8 +292,10 @@ ghid_sync_with_new_layout (void)
   ghidgui->toggle_holdoff = old_holdoff;
 
   pcb_use_route_style (&PCB->RouteStyle[0]);
+  ghid_route_style_selector_select_style
+    (GHID_ROUTE_STYLE_SELECTOR (ghidgui->route_style_selector),
+     &PCB->RouteStyle[0]);
 
-  ghid_route_style_button_set_active (0);
   ghid_config_handle_units_changed ();
 
   ghid_window_set_name_label (PCB->Name);
@@ -532,74 +449,11 @@ layer_selector_toggle_callback (GHidLayerSelector *ls, int layer, gpointer d)
     ghid_invalidate_all();
 }
 
-/*
- * The intial loading of all actions at startup.
- */
-static void
-ghid_make_programmed_menu_actions ()
-{
-  int i;
-  Resource *ar;
-  char av[64];
-
-  for (i = 0; i < N_ROUTE_STYLES; i++)
-    {
-      routestyle_toggle_entries[i].name = g_strdup_printf ("%s%d", ROUTESTYLE, i);
-      routestyle_toggle_entries[i].stock_id = NULL;
-      if (i < NUM_STYLES && PCB)
-	{
-	  routestyle_toggle_entries[i].label = g_strdup ( (PCB->RouteStyle)[i].Name);
-	}
-      else
-	{
-	  routestyle_toggle_entries[i].label = g_strdup (routestyle_toggle_entries[i].name);
-	}
-      routestyle_toggle_entries[i].accelerator = NULL;
-      routestyle_toggle_entries[i].tooltip = NULL;
-      routestyle_toggle_entries[i].callback = G_CALLBACK (ghid_menu_cb);
-      routestyle_toggle_entries[i].is_active = FALSE;
-
-      ar = resource_create (0);
-      sprintf (av, "RouteStyle(%d)", i + 1);
-      resource_add_val (ar, 0, strdup (av), 0);
-      resource_add_val (ar, 0, strdup (av), 0);
-      ar->flags |= FLAG_V;
-      routestyle_resources[i] = ar;
-
-      // FIXME
-      //sprintf (av, "current_style,%d", i + 1);
-      //note_toggle_flag (routestyle_toggle_entries[i].name, strdup (av));
-
-    }
-}
-
-static void
-make_menu_actions (GtkActionGroup * actions, GHidPort * port)
-{
-  ghid_make_programmed_menu_actions ();
-
-  gtk_action_group_add_toggle_actions (actions,
-				       routestyle_toggle_entries,
-				       N_ROUTE_STYLES, port);
-
-}
-
-
-/*
- * Load in actions for the menus and layer selector
- */
+/*! \brief Install menu bar and accelerator groups */
 static void
 make_actions (GHidPort * port)
 {
-  GtkActionGroup *actions;
-
-  actions = gtk_action_group_new ("Actions");
-  gtk_action_group_set_translation_domain (actions, NULL);
-  ghidgui->main_actions = actions;
-
-  make_menu_actions (actions, port);
- 
-  gtk_window_add_accel_group (GTK_WINDOW (port->top_window),
+  gtk_window_add_accel_group (GTK_WINDOW (gport->top_window),
 			      ghid_main_menu_get_accel_group
                                 (GHID_MAIN_MENU (ghidgui->menu_bar)));
   gtk_window_add_accel_group (GTK_WINDOW (port->top_window),
@@ -946,179 +800,45 @@ ghid_layer_buttons_update (void)
     (GHID_LAYER_SELECTOR (ghidgui->layer_selector), layer);
 }
 
-
-static void
-route_style_edit_cb (GtkWidget * widget, GHidPort * port)
-{
-  hid_action("AdjustStyle");
-}
-
+/*! \brief Called when user clicks OK on route style dialog */
 static void
-route_style_select_button_cb (GtkToggleButton * button, gpointer data)
+route_styles_edited_cb (GHidRouteStyleSelector *rss, gboolean save,
+                        gpointer data)
 {
-  RouteStyleType *rst;
-  gchar buf[16];
-  gint index = GPOINTER_TO_INT (data);
-
-  if (ghidgui->toggle_holdoff || index == NUM_STYLES + 2)
-    return;
-
-  if (route_style_index == index)
-    return;
-  route_style_index = index;
-
-  if (index < NUM_STYLES)
-    {
-      snprintf (buf, sizeof (buf), "%d", index + 1);
-      if (gtk_toggle_button_get_active (button))
-	hid_actionl ("RouteStyle", buf, NULL);
-    }
-  else if (index < NUM_STYLES + 2)
+  if (save)
     {
-      rst = &route_style_button[index].route_style;
-      SetLineSize (rst->Thick);
-      SetViaSize (rst->Diameter, TRUE);
-      SetViaDrillingHole (rst->Hole, TRUE);
-      SetKeepawayWidth (rst->Keepaway);
+      g_free (Settings.Routes);
+      Settings.Routes = make_route_string (PCB->RouteStyle, NUM_STYLES);
+      ghidgui->config_modified = TRUE;
+      ghid_config_files_write ();
     }
-  gtk_widget_set_sensitive (route_style_edit_button, TRUE);
-  ghid_set_status_line_label();
+  ghid_main_menu_install_route_style_selector
+      (GHID_MAIN_MENU (ghidgui->menu_bar),
+       GHID_ROUTE_STYLE_SELECTOR (ghidgui->route_style_selector));
 }
 
+/*! \brief Called when a route style is selected */
 static void
-ghid_route_style_temp_buttons_hide (void)
+route_style_changed_cb (GHidRouteStyleSelector *rss, RouteStyleType *rst,
+                        gpointer data)
 {
-  gtk_widget_hide (route_style_button[NUM_STYLES].button);
-  gtk_widget_hide (route_style_button[NUM_STYLES + 1].button);
-
-  /* This one never becomes visibile.
-   */
-  gtk_widget_hide (route_style_button[NUM_STYLES + 2].button);
+  pcb_use_route_style (rst);
+  ghid_set_status_line_label();
 }
 
-
+/*! \brief Configure the route style selector */
 static void
-make_route_style_buttons (GtkWidget * vbox, GHidPort * port)
-{
-  GtkWidget *button;
-  GSList *group = NULL;
-  RouteStyleButton *rbut;
-  gint i;
-
-  button = gtk_button_new_with_label (_("Route Style"));
-  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 2);
-  g_signal_connect (button, "clicked",
-		    G_CALLBACK (route_style_edit_cb), port);
-  route_style_edit_button = button;
-
-  for (i = 0; i < N_ROUTE_STYLES; ++i)
-    {
-      RouteStyleType *rst;
-      gchar buf[32];
-
-      rbut = &route_style_button[i];
-      if (i < NUM_STYLES)
-	{
-	  rst = &PCB->RouteStyle[i];
-	  button = gtk_radio_button_new_with_label (group, _(rst->Name));
-	}
-      else
-	{
-	  snprintf (buf, sizeof (buf), _("Temp%d"), i - NUM_STYLES + 1);
-	  button = gtk_radio_button_new_with_label (group, buf);
-	  if (!route_style_button[i].route_style.Name)
-	    route_style_button[i].route_style.Name = g_strdup (buf);
-	}
-      group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button));
-      gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
-      rbut->button = button;
-      if (i < NUM_STYLES + 2)
-	g_signal_connect (G_OBJECT (button), "toggled",
-			  G_CALLBACK (route_style_select_button_cb),
-			  GINT_TO_POINTER (i));
-    }
-}
-
-void
-ghid_route_style_button_set_active (gint n)
-{
-  if (n < 0 || n >= N_ROUTE_STYLES)
-    return;
-
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON
-				(route_style_button[n].button), TRUE);
-}
-
-  /* Upate the route style button selected to match current route settings.
-     |  If user has changed an in use route setting so they don't match any
-     |  defined route style, select the invisible dummy route style button.
-   */
-void
-ghid_route_style_buttons_update (void)
+make_route_style_buttons (GHidRouteStyleSelector *rss)
 {
-  RouteStyleType *rst;
-  gint i;
-
-  for (i = 0; i < NUM_STYLES + 2; ++i)
-    {
-      if (i < NUM_STYLES)
-	rst = &PCB->RouteStyle[i];
-      else
-	{
-	  if (!route_style_button[i].shown)	/* Temp button shown? */
-	    continue;
-	  rst = &route_style_button[i].route_style;
-	}
-      if (Settings.LineThickness == rst->Thick
-	  && Settings.ViaThickness == rst->Diameter
-	  && Settings.ViaDrillingHole == rst->Hole
-	  && Settings.Keepaway == rst->Keepaway)
-	break;
-    }
-  /* If i == NUM_STYLES + 2 at this point, we activate the invisible button.
-   */
-  ghidgui->toggle_holdoff = TRUE;
-  ghid_route_style_button_set_active (i);
-  route_style_index = i;
-  ghidgui->toggle_holdoff = FALSE;
-
-  gtk_widget_set_sensitive (route_style_edit_button,
-			    (i == NUM_STYLES + 2) ? FALSE : TRUE);
-}
-
-void
-ghid_route_style_set_button_label (gchar * name, gint index)
-{
-  if (index < 0 || index >= NUM_STYLES || !route_style_button[index].button)
-    return;
-  gtk_button_set_label (GTK_BUTTON (route_style_button[index].button),
-			_(name));
-}
-
-void
-ghid_route_style_set_temp_style (RouteStyleType * rst, gint which)
-{
-  RouteStyleButton *rsb;
-  gchar *tmp;
-  gint index = which + NUM_STYLES;
-
-  if (which < 0 || which > 1)
-    return;
-  rsb = &route_style_button[index];
-  gtk_widget_show (rsb->button);
-  rsb->shown = TRUE;
-  tmp = rsb->route_style.Name;
-  rsb->route_style = *rst;
-  rsb->route_style.Name = tmp;
-  if (route_style_index != index)
-    {
-      route_style_index = index;	/* Sets already done */
-      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rsb->button), TRUE);
-    }
+  int i;
+  for (i = 0; i < NUM_STYLES; ++i)
+    ghid_route_style_selector_add_route_style (rss, &PCB->RouteStyle[i]);
+  g_signal_connect (G_OBJECT (rss), "select_style",
+                    G_CALLBACK (route_style_changed_cb), NULL);
+  g_signal_connect (G_OBJECT (rss), "style_edited",
+                    G_CALLBACK (route_styles_edited_cb), NULL);
 }
 
-
-
 /*
  *  ---------------------------------------------------------------
  * Mode buttons
@@ -1516,9 +1236,11 @@ ghid_build_pcb_top_window (void)
   gtk_container_add(GTK_CONTAINER(frame), vbox);
   hbox = gtk_hbox_new(FALSE, 0);
   gtk_box_pack_start(GTK_BOX (vbox), hbox, FALSE, FALSE, 1);
-  vbox = gtk_vbox_new(FALSE, 0);
-  gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 4);
-  make_route_style_buttons(vbox, port);
+  ghidgui->route_style_selector = ghid_route_style_selector_new ();
+  make_route_style_buttons
+    (GHID_ROUTE_STYLE_SELECTOR (ghidgui->route_style_selector));
+  gtk_box_pack_start(GTK_BOX(hbox), ghidgui->route_style_selector,
+                     FALSE, FALSE, 4);
 
   ghidgui->vbox_middle = gtk_vbox_new (FALSE, 0);
   gtk_box_pack_start (GTK_BOX (hbox_middle),
@@ -1628,8 +1350,6 @@ ghid_build_pcb_top_window (void)
   gtk_widget_show_all (gport->top_window);
   ghid_pack_mode_buttons ();
   gdk_window_set_back_pixmap (gport->drawing_area->window, NULL, FALSE);
-
-  ghid_route_style_temp_buttons_hide ();
 }
 
 
@@ -1971,6 +1691,9 @@ ghid_do_export (HID_Attr_Val * options)
    * are properly initialized and synchronized with the current PCB.
    */
   ghid_layer_buttons_update ();
+  ghid_main_menu_install_route_style_selector
+      (GHID_MAIN_MENU (ghidgui->menu_bar),
+       GHID_ROUTE_STYLE_SELECTOR (ghidgui->route_style_selector));
 
   if (stdin_listen)
     ghid_create_listener ();
@@ -2337,15 +2060,11 @@ Opens the window which allows editing of the route styles.
 static int
 AdjustStyle(int argc, char **argv, Coord x, Coord y)
 {
-  RouteStyleType *rst = NULL;
-  
   if (argc > 1)
     AFAIL (adjuststyle);
 
-  if (route_style_index >= NUM_STYLES)
-    rst = &route_style_button[route_style_index].route_style;
-  ghid_route_style_dialog (route_style_index, rst);
-
+  ghid_route_style_selector_edit_dialog
+    (GHID_ROUTE_STYLE_SELECTOR (ghidgui->route_style_selector));
   return 0;
 }
 
diff --git a/src/hid/gtk/gui.h b/src/hid/gtk/gui.h
index 883e803..316d409 100644
--- a/src/hid/gtk/gui.h
+++ b/src/hid/gtk/gui.h
@@ -110,7 +110,7 @@ typedef struct
     *mode_buttons_frame;
   GtkWidget *left_toolbar;
   GtkWidget *grid_units_button;
-  GtkWidget *menu_bar, *layer_selector;
+  GtkWidget *menu_bar, *layer_selector, *route_style_selector;
   GtkWidget *mode_toolbar;
   GtkWidget *vbox_middle;
 
@@ -337,15 +337,7 @@ void ghid_drc_window_append_violation (DrcViolationType *violation);
 void ghid_drc_window_append_messagev (const char *fmt, va_list va);
 int ghid_drc_window_throw_dialog (void);
 
-/* gui-route-style function prototypes.
-*/
-  /* In gui-dialog-size.c */
-void ghid_route_style_dialog (gint index, RouteStyleType * rst);
-  /* In gui-top-window.c  */
-void ghid_route_style_set_button_label (gchar * name, gint index);
-void ghid_route_style_set_temp_style (RouteStyleType * rst, gint which);
-void ghid_route_style_button_set_active (gint number);
-void ghid_route_style_buttons_update (void);
+/* In gui-top-window.c  */
 void ghid_update_toggle_flags (void);
 
 /* gui-utils.c

commit 5ee21ef3feb0f40186617b8c7c5fd71d2902cc89
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Introduce functions for GHidRouteStyleSelector handling to menu

diff --git a/src/hid/gtk/ghid-main-menu.c b/src/hid/gtk/ghid-main-menu.c
index ed4e2e8..9ac0367 100644
--- a/src/hid/gtk/ghid-main-menu.c
+++ b/src/hid/gtk/ghid-main-menu.c
@@ -14,6 +14,7 @@
 
 #include "ghid-main-menu.h"
 #include "ghid-layer-selector.h"
+#include "ghid-route-style-selector.h"
 
 void Message (const char *, ...);
 
@@ -557,6 +558,31 @@ ghid_main_menu_install_layer_selector (GHidMainMenu *mm,
     }
 }
 
+/*! \brief Installs or updates route style selector items */
+void
+ghid_main_menu_install_route_style_selector (GHidMainMenu *mm,
+                                             GHidRouteStyleSelector *rss)
+{
+  GList *children;
+  /* @routestyles */
+  if (mm->route_style_shell)
+    {
+      /* Remove old children */
+      children = gtk_container_get_children
+                   (GTK_CONTAINER (mm->route_style_shell));
+      children = g_list_nth (children, mm->route_style_pos);
+      while (children && mm->n_route_styles--)
+        {
+          gtk_container_remove (GTK_CONTAINER (mm->route_style_shell),
+                                children->data);
+          children = g_list_next (children);
+        }
+      /* Install new ones */
+      mm->n_route_styles = ghid_route_style_selector_install_items
+                             (rss, mm->route_style_shell, mm->route_style_pos);
+    }
+}
+
 /*! \brief Returns the menu bar's accelerator group */
 GtkAccelGroup *
 ghid_main_menu_get_accel_group (GHidMainMenu *menu)
diff --git a/src/hid/gtk/ghid-main-menu.h b/src/hid/gtk/ghid-main-menu.h
index d667e34..da1fd9c 100644
--- a/src/hid/gtk/ghid-main-menu.h
+++ b/src/hid/gtk/ghid-main-menu.h
@@ -6,6 +6,7 @@
 #include <gtk/gtk.h>
 
 #include "ghid-layer-selector.h"
+#include "ghid-route-style-selector.h"
 #include "resource.h"
 
 G_BEGIN_DECLS  /* keep c++ happy */
@@ -37,6 +38,8 @@ GtkMenu *ghid_main_menu_get_popup (GHidMainMenu *menu, const char *name);
 
 void ghid_main_menu_install_layer_selector (GHidMainMenu *mm,
                                             GHidLayerSelector *ls);
+void ghid_main_menu_install_route_style_selector (GHidMainMenu *mm,
+                                                  GHidRouteStyleSelector *rss);
 
 G_END_DECLS  /* keep c++ happy */
 #endif

commit 705febbdfc68c7638739287b6feb50d625409dc6
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Introduce GHidRouteStyleSelector widget, don't use it yet

diff --git a/src/Makefile.am b/src/Makefile.am
index a9c51b2..2e01c31 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -278,6 +278,8 @@ LIBGTK_SRCS = \
 	hid/gtk/ghid-layer-selector.h \
 	hid/gtk/ghid-main-menu.c \
 	hid/gtk/ghid-main-menu.h \
+	hid/gtk/ghid-route-style-selector.c \
+	hid/gtk/ghid-route-style-selector.h \
 	hid/gtk/gtkhid-main.c \
 	hid/gtk/gtkhid.h \
 	hid/gtk/gui.h \
diff --git a/src/hid/gtk/ghid-route-style-selector.c b/src/hid/gtk/ghid-route-style-selector.c
new file mode 100644
index 0000000..9178645
--- /dev/null
+++ b/src/hid/gtk/ghid-route-style-selector.c
@@ -0,0 +1,514 @@
+/*! \file <gtk-pcb-route-style-selector.c>
+ *  \brief Implementation of GHidRouteStyleSelector widget
+ *  \par Description
+ *  Please write description here.
+ */
+
+/* TODO: write finalize function */
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
+
+#include "global.h"
+#include "gtkhid.h"
+#include "gui.h"
+#include "pcb-printf.h"
+
+#include "ghid-route-style-selector.h"
+
+/* Forward dec'ls */
+struct _route_style;
+struct _route_style *ghid_route_style_selector_real_add_route_style
+  (GHidRouteStyleSelector *, RouteStyleType *, gboolean temp);
+
+/*! \brief Global action creation counter */
+static gint action_count;
+
+/*! \brief Signals exposed by the widget */
+enum {
+  SELECT_STYLE_SIGNAL,
+  STYLE_EDITED_SIGNAL,
+  LAST_SIGNAL
+};
+
+/*! \brief Columns used for internal data store */
+enum {
+  TEXT_COL,
+  DATA_COL,
+  N_COLS
+};
+
+static guint ghid_route_style_selector_signals[LAST_SIGNAL] = { 0 };
+
+struct _GHidRouteStyleSelector
+{
+  GtkVBox parent;
+
+  GSList *button_radio_group;
+  GSList *action_radio_group;
+  GtkWidget *edit_button;
+
+  GtkListStore *model;
+  struct _route_style *active_style;
+};
+
+struct _GHidRouteStyleSelectorClass
+{
+  GtkVBoxClass parent_class;
+
+  void (* select_style) (GHidRouteStyleSelector *, RouteStyleType *);
+  void (* style_edited) (GHidRouteStyleSelector *, gboolean);
+};
+
+struct _route_style
+{
+  gboolean temporary;   /* TODO: actually use this for something */
+  GtkRadioAction *action;
+  GtkWidget *button;
+  GtkWidget *menu_item;
+  GtkTreeRowReference *rref;
+  RouteStyleType *rst;
+  gulong sig_id;
+};
+
+/* SIGNAL HANDLERS */
+/*! \brief Callback for user selection of a route style */
+static void
+radio_select_cb (GtkToggleAction *action, GHidRouteStyleSelector *rss)
+{
+  rss->active_style = g_object_get_data (G_OBJECT (action), "route-style");
+  if (gtk_toggle_action_get_active (action))
+    g_signal_emit (rss, ghid_route_style_selector_signals[SELECT_STYLE_SIGNAL],
+                   0, rss->active_style->rst);
+}
+
+/* EDIT DIALOG */
+struct _dialog
+{
+  GHidRouteStyleSelector *rss;
+  GtkWidget *name_entry;
+  GtkWidget *line_entry;
+  GtkWidget *via_hole_entry;
+  GtkWidget *via_size_entry;
+  GtkWidget *clearance_entry;
+};
+
+/*! \brief Callback for dialog box's combobox being changed
+ *  \par Function Description
+ *  When a different layer is selected, this function loads
+ *  that layer's data into the dialog. Alternately, if the
+ *  "New layer" option is selected, this loads a new name
+ *  but no other data.
+ *
+ *  \param [in] combo   The combobox
+ *  \param [in] dialog  The rest of the widgets to be updated
+ */
+static void
+dialog_style_changed_cb (GtkComboBox *combo, struct _dialog *dialog)
+{
+  struct _route_style *style;
+  GtkTreeIter iter;
+  gtk_combo_box_get_active_iter (combo, &iter);
+  gtk_tree_model_get (GTK_TREE_MODEL (dialog->rss->model),
+                      &iter, DATA_COL, &style, -1);
+
+  if (style == NULL)
+    {
+      gtk_entry_set_text (GTK_ENTRY (dialog->name_entry),
+                          _("New Style"));
+      return;
+    }
+
+  gtk_entry_set_text (GTK_ENTRY (dialog->name_entry), style->rst->Name);
+  ghid_coord_entry_set_value (GHID_COORD_ENTRY (dialog->line_entry),
+                              style->rst->Thick);
+  ghid_coord_entry_set_value (GHID_COORD_ENTRY (dialog->via_size_entry),
+                              style->rst->Diameter);
+  ghid_coord_entry_set_value (GHID_COORD_ENTRY (dialog->via_hole_entry),
+                              style->rst->Hole);
+  ghid_coord_entry_set_value (GHID_COORD_ENTRY (dialog->clearance_entry),
+                              style->rst->Keepaway);
+
+}
+
+/* \brief Helper for edit_button_cb */
+static void
+_table_attach (GtkWidget *table, gint row, const gchar *label,
+               GtkWidget **entry, Coord min, Coord max)
+{
+  GtkWidget *label_w = gtk_label_new (label);
+  gtk_misc_set_alignment (GTK_MISC (label_w), 1.0, 0.5);
+
+  *entry = ghid_coord_entry_new (min, max, 0, Settings.grid_unit, CE_SMALL);
+  gtk_table_attach (GTK_TABLE (table), label_w, 0, 1, row, row + 1,
+                    GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 2, 2);
+  gtk_table_attach (GTK_TABLE (table), *entry, 1, 2, row, row + 1,
+                    GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 2, 2);
+}
+
+/* \brief Builds and runs the "edit route styles" dialog */
+void
+ghid_route_style_selector_edit_dialog (GHidRouteStyleSelector *rss)
+{
+  GtkTreePath *path;
+  GtkTreeIter iter, tmp_iter;
+  struct _dialog dialog_data;
+  GtkCellRenderer *renderer = gtk_cell_renderer_text_new ();
+  GtkWidget *window = gtk_widget_get_toplevel (GTK_WIDGET (rss));
+  GtkWidget *dialog, *vbox, *hbox, *sub_vbox, *table;
+  GtkWidget *label, *select_box, *check_box;
+
+  /* Build dialog */
+  dialog = gtk_dialog_new_with_buttons (_("Edit Route Styles"),
+                                        GTK_WINDOW (window),
+                                        GTK_DIALOG_DESTROY_WITH_PARENT,
+                                        GTK_STOCK_CANCEL, GTK_RESPONSE_NONE,
+                                        GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
+
+  label = gtk_label_new (_("Edit Style:"));
+  gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
+
+  select_box = gtk_combo_box_new_with_model (GTK_TREE_MODEL (rss->model));
+  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (select_box), renderer, TRUE);
+  gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT(select_box), renderer,
+                                  "text", TEXT_COL, NULL);
+
+  vbox = GTK_DIALOG (dialog)->vbox;
+
+  hbox = gtk_hbox_new (FALSE, 4);
+  gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 4);
+  vbox = gtk_vbox_new (FALSE, 4);
+  gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 4);
+
+  hbox = gtk_hbox_new (FALSE, 4);
+  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 4);
+  gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
+  gtk_box_pack_start (GTK_BOX (hbox), select_box, TRUE, TRUE, 0);
+
+  sub_vbox = ghid_category_vbox (vbox, _("Route Style Data"),
+                                 4, 2, TRUE, TRUE);
+  table = gtk_table_new (5, 2, FALSE);
+  gtk_box_pack_start (GTK_BOX (sub_vbox), table, TRUE, TRUE, 4);
+  label = gtk_label_new (_("Name:"));
+  gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
+  dialog_data.name_entry = gtk_entry_new ();
+  gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
+                    GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 2, 2);
+  gtk_table_attach (GTK_TABLE (table), dialog_data.name_entry, 1, 2, 0, 1,
+                    GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 2, 2);
+
+  _table_attach (table, 1, _("Line width:"),
+                 &dialog_data.line_entry,
+                 MIN_LINESIZE, MAX_LINESIZE);
+  _table_attach (table, 2, _("Via hole size:"),
+                 &dialog_data.via_hole_entry,
+                 MIN_PINORVIAHOLE, MAX_PINORVIASIZE - MIN_PINORVIACOPPER);
+  _table_attach (table, 3, _("Via ring size:"),
+                 &dialog_data.via_size_entry,
+                 MIN_PINORVIAHOLE + MIN_PINORVIACOPPER, MAX_PINORVIASIZE);
+  _table_attach (table, 4, _("Clearance:"),
+                 &dialog_data.clearance_entry,
+                 MIN_LINESIZE, MAX_LINESIZE);
+
+  sub_vbox = ghid_category_vbox (vbox, _("Set as Default"),
+                                 4, 2, TRUE, TRUE);
+  check_box = gtk_check_button_new_with_label
+                (_("Save route style settings as default"));
+  gtk_box_pack_start (GTK_BOX (sub_vbox), check_box, TRUE, TRUE, 0);
+
+  /* Add "new style" option to list */
+  gtk_list_store_append (rss->model, &tmp_iter);
+  gtk_list_store_set (rss->model, &tmp_iter, TEXT_COL,
+                      _("New (this session only)"), DATA_COL, NULL, -1);
+
+  /* Display dialog */
+  dialog_data.rss = rss;
+  path = gtk_tree_row_reference_get_path (rss->active_style->rref);
+  gtk_tree_model_get_iter (GTK_TREE_MODEL (rss->model), &iter, path);
+  g_signal_connect (G_OBJECT (select_box), "changed",
+                    G_CALLBACK (dialog_style_changed_cb), &dialog_data);
+  gtk_combo_box_set_active_iter (GTK_COMBO_BOX (select_box), &iter);
+  gtk_widget_show_all (dialog);
+  if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
+    {
+      RouteStyleType *rst;
+      struct _route_style *style;
+      gboolean save;
+      gtk_combo_box_get_active_iter (GTK_COMBO_BOX (select_box), &iter);
+      gtk_tree_model_get (GTK_TREE_MODEL (rss->model),
+                          &iter, DATA_COL, &style, -1);
+      if (style == NULL)
+        rst = g_malloc (sizeof *rst);
+      else
+        {
+          rst = style->rst;
+          free (rst->Name);
+        }
+
+      rst->Name = StripWhiteSpaceAndDup
+                    (gtk_entry_get_text (GTK_ENTRY (dialog_data.name_entry)));
+      rst->Thick = ghid_coord_entry_get_value
+                     (GHID_COORD_ENTRY (dialog_data.line_entry));
+      rst->Diameter = ghid_coord_entry_get_value
+                        (GHID_COORD_ENTRY (dialog_data.via_hole_entry));
+      rst->Hole = ghid_coord_entry_get_value
+                    (GHID_COORD_ENTRY (dialog_data.via_size_entry));
+      rst->Keepaway = ghid_coord_entry_get_value
+                        (GHID_COORD_ENTRY (dialog_data.clearance_entry));
+      save = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check_box));
+
+      if (style == NULL)
+        style = ghid_route_style_selector_real_add_route_style
+                  (rss, rst, TRUE);
+      else
+        {
+          gtk_action_set_label (GTK_ACTION (style->action), rst->Name); 
+          gtk_list_store_set (rss->model, &iter, TEXT_COL, rst->Name, -1);
+        }
+
+      /* Cleanup */
+      gtk_widget_destroy (dialog);
+      gtk_list_store_remove (rss->model, &tmp_iter);
+      /* Emit change signals */
+      ghid_route_style_selector_select_style (rss, rst);
+      g_signal_emit
+        (rss, ghid_route_style_selector_signals[STYLE_EDITED_SIGNAL],
+         0, save);
+    }
+  else
+    {
+      gtk_widget_destroy (dialog);
+      gtk_list_store_remove (rss->model, &tmp_iter);
+    }
+}
+/* end EDIT DIALOG */
+
+static void
+edit_button_cb (GtkButton *btn, GHidRouteStyleSelector *rss)
+{
+  ghid_route_style_selector_edit_dialog (rss);
+}
+
+/* CONSTRUCTOR */
+static void
+ghid_route_style_selector_init (GHidRouteStyleSelector *rss)
+{
+}
+
+static void
+ghid_route_style_selector_class_init (GHidRouteStyleSelectorClass *klass)
+{
+  ghid_route_style_selector_signals[SELECT_STYLE_SIGNAL] =
+    g_signal_new ("select-style",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+                  G_STRUCT_OFFSET (GHidRouteStyleSelectorClass, select_style),
+                  NULL, NULL,
+                  g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE,
+                  1, G_TYPE_POINTER);
+  ghid_route_style_selector_signals[STYLE_EDITED_SIGNAL] =
+    g_signal_new ("style-edited",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+                  G_STRUCT_OFFSET (GHidRouteStyleSelectorClass, style_edited),
+                  NULL, NULL,
+                  g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE,
+                  1, G_TYPE_BOOLEAN);
+}
+
+/* PUBLIC FUNCTIONS */
+GType
+ghid_route_style_selector_get_type (void)
+{
+  static GType rss_type = 0;
+
+  if (!rss_type)
+    {
+      const GTypeInfo rss_info =
+      {
+	sizeof (GHidRouteStyleSelectorClass),
+	NULL, /* base_init */
+	NULL, /* base_finalize */
+	(GClassInitFunc) ghid_route_style_selector_class_init,
+	NULL, /* class_finalize */
+	NULL, /* class_data */
+	sizeof (GHidRouteStyleSelector),
+	0,    /* n_preallocs */
+	(GInstanceInitFunc) ghid_route_style_selector_init,
+      };
+
+      rss_type = g_type_register_static (GTK_TYPE_VBOX,
+                                         "GHidRouteStyleSelector",
+                                         &rss_info,
+                                         0);
+    }
+
+  return rss_type;
+}
+
+/*! \brief Create a new GHidRouteStyleSelector
+ *
+ *  \return a freshly-allocated GHidRouteStyleSelector.
+ */
+GtkWidget *
+ghid_route_style_selector_new ()
+{
+  GHidRouteStyleSelector *rss =
+    g_object_new (GHID_ROUTE_STYLE_SELECTOR_TYPE, NULL);
+
+  rss->active_style = NULL;
+  rss->action_radio_group = NULL;
+  rss->button_radio_group = NULL;
+  rss->model = gtk_list_store_new (N_COLS, G_TYPE_STRING, G_TYPE_POINTER);
+
+  /* Create edit button */
+  rss->edit_button = gtk_button_new_with_label (_("Route Styles"));
+  g_signal_connect (G_OBJECT (rss->edit_button), "clicked",
+                    G_CALLBACK (edit_button_cb), rss);
+  gtk_box_pack_start (GTK_BOX (rss), rss->edit_button, FALSE, FALSE, 0);
+
+  return GTK_WIDGET (rss);
+}
+
+/*! \brief Create a new GHidRouteStyleSelector 
+ *
+ *  \param [in] rss     The selector to be acted on
+ *  \param [in] data    PCB's route style object that will be edited
+ *  \param [in] temp    Whether the style is "real" or session-only
+ */
+struct _route_style *
+ghid_route_style_selector_real_add_route_style (GHidRouteStyleSelector *rss,
+                                                RouteStyleType *data,
+                                                gboolean temp)
+{
+  GtkTreeIter iter;
+  GtkTreePath *path;
+  gchar *action_name = g_strdup_printf ("RouteStyle%d", action_count);
+  struct _route_style *new_style = g_malloc (sizeof (*new_style));
+
+  /* Key the route style data with the RouteStyleType it controls */
+  new_style->rst = data;
+  new_style->temporary = temp;
+  new_style->action = gtk_radio_action_new (action_name, data->Name,
+                                            NULL, NULL, action_count);
+  gtk_radio_action_set_group (new_style->action, rss->action_radio_group);
+  rss->action_radio_group = gtk_radio_action_get_group (new_style->action);
+  new_style->button = gtk_radio_button_new (rss->button_radio_group);
+  rss->button_radio_group = gtk_radio_button_get_group
+                              (GTK_RADIO_BUTTON (new_style->button));
+  gtk_activatable_set_related_action (GTK_ACTIVATABLE (new_style->button),
+                                      GTK_ACTION (new_style->action));
+
+  gtk_list_store_append (rss->model, &iter);
+  gtk_list_store_set (rss->model, &iter, TEXT_COL, data->Name,
+                      DATA_COL, new_style, -1);
+  path = gtk_tree_model_get_path (GTK_TREE_MODEL (rss->model), &iter);
+  new_style->rref = gtk_tree_row_reference_new (GTK_TREE_MODEL (rss->model),
+                                                path);
+  gtk_tree_path_free (path);
+
+  /* Hookup and install radio button */
+  g_object_set_data (G_OBJECT (new_style->action), "route-style", new_style);
+  new_style->sig_id = g_signal_connect (G_OBJECT (new_style->action),
+                                        "activate",
+                                        G_CALLBACK (radio_select_cb), rss);
+  gtk_box_pack_start (GTK_BOX (rss), new_style->button, FALSE, FALSE, 0);
+
+  g_free (action_name);
+  ++action_count;
+  return new_style;
+}
+
+/*! \brief Adds a route style to a GHidRouteStyleSelector
+ *  \par Function Description
+ *  Adds a new route style to be managed by this selector. Note
+ *  that the route style object passed to this function will be
+ *  updated directly.
+ *
+ *  \param [in] rss     The selector to be acted on
+ *  \param [in] data    PCB's route style object describing the style
+ */
+void
+ghid_route_style_selector_add_route_style (GHidRouteStyleSelector *rss,
+                                           RouteStyleType *data)
+{
+  ghid_route_style_selector_real_add_route_style (rss, data, FALSE);
+}
+
+
+/*! \brief Install the "Route Style" menu items
+ *  \par Function Description
+ *  Takes a menu shell and installs menu items for route style selection in
+ *  the shell, at the given position. Note that we aren't really guaranteed
+ *  the ordering of these items, since our internal data structure is a hash
+ *  table. This shouldn't be a problem.
+ *
+ *  \param [in] rss     The selector to be acted on
+ *  \param [in] shell   The menu to install the items in
+ *  \param [in] pos     The position in the menu to install items
+ *
+ *  \return the number of items installed
+ */
+gint
+ghid_route_style_selector_install_items (GHidRouteStyleSelector *rss,
+                                         GtkMenuShell *shell, gint pos)
+{
+  gint n = 0;
+  GtkTreeIter iter;
+
+  gtk_tree_model_get_iter_first (GTK_TREE_MODEL (rss->model), &iter);
+  do
+    {
+      GtkAction *action;
+      struct _route_style *style;
+
+      gtk_tree_model_get (GTK_TREE_MODEL (rss->model),
+                          &iter, DATA_COL, &style, -1);
+      action = GTK_ACTION (style->action);
+      style->menu_item = gtk_action_create_menu_item (action);
+      gtk_menu_shell_insert (shell, style->menu_item, pos + n);
+      ++n;
+    }
+  while (gtk_tree_model_iter_next (GTK_TREE_MODEL (rss->model), &iter));
+
+  return n;
+}
+
+/*! \brief Selects a route style and emits a select-style signal
+ *
+ *  \param [in] rss  The selector to be acted on
+ *  \param [in] rst  The style to select
+ *
+ *  \return TRUE if a style was selected, FALSE otherwise
+ */
+gboolean
+ghid_route_style_selector_select_style (GHidRouteStyleSelector *rss,
+                                        RouteStyleType *rst)
+{
+  GtkTreeIter iter;
+  gtk_tree_model_get_iter_first (GTK_TREE_MODEL (rss->model), &iter);
+  do
+    {
+      struct _route_style *style;
+      gtk_tree_model_get (GTK_TREE_MODEL (rss->model),
+                          &iter, DATA_COL, &style, -1);
+      if (style->rst == rst)
+        {
+          g_signal_handler_block (G_OBJECT (style->action), style->sig_id);
+          gtk_toggle_action_set_active
+            (GTK_TOGGLE_ACTION (style->action), TRUE);
+          g_signal_handler_unblock (G_OBJECT (style->action), style->sig_id);
+          rss->active_style = style;
+          g_signal_emit
+            (rss, ghid_route_style_selector_signals[SELECT_STYLE_SIGNAL],
+             0, rss->active_style->rst);
+          return TRUE;
+        }
+    }
+  while (gtk_tree_model_iter_next (GTK_TREE_MODEL (rss->model), &iter));
+
+  return FALSE;
+}
+
diff --git a/src/hid/gtk/ghid-route-style-selector.h b/src/hid/gtk/ghid-route-style-selector.h
new file mode 100644
index 0000000..4823d74
--- /dev/null
+++ b/src/hid/gtk/ghid-route-style-selector.h
@@ -0,0 +1,34 @@
+#ifndef GHID_ROUTE_STYLE_SELECTOR_H__
+#define GHID_ROUTE_STYLE_SELECTOR_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+#include "global.h"
+
+G_BEGIN_DECLS  /* keep c++ happy */
+
+#define GHID_ROUTE_STYLE_SELECTOR_TYPE            (ghid_route_style_selector_get_type ())
+#define GHID_ROUTE_STYLE_SELECTOR(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GHID_ROUTE_STYLE_SELECTOR_TYPE, GHidRouteStyleSelector))
+#define GHID_ROUTE_STYLE_SELECTOR_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GHID_ROUTE_STYLE_SELECTOR_TYPE, GHidRouteStyleSelectorClass))
+#define IS_GHID_ROUTE_STYLE_SELECTOR(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GHID_ROUTE_STYLE_SELECTOR_TYPE))
+#define IS_GHID_ROUTE_STYLE_SELECTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GHID_ROUTE_STYLE_SELECTOR_TYPE))
+
+typedef struct _GHidRouteStyleSelector       GHidRouteStyleSelector;
+typedef struct _GHidRouteStyleSelectorClass  GHidRouteStyleSelectorClass;
+
+GType ghid_route_style_selector_get_type (void);
+GtkWidget* ghid_route_style_selector_new (void);
+
+gint ghid_route_style_selector_install_items (GHidRouteStyleSelector *rss,
+                                              GtkMenuShell *shell, gint pos);
+
+void ghid_route_style_selector_add_route_style (GHidRouteStyleSelector *rss,
+                                                RouteStyleType *data);
+gboolean ghid_route_style_selector_select_style (GHidRouteStyleSelector *rss,
+                                                  RouteStyleType *rst);
+void ghid_route_style_selector_edit_dialog (GHidRouteStyleSelector *rss);
+
+G_END_DECLS  /* keep c++ happy */
+#endif




_______________________________________________
geda-cvs mailing list
geda-cvs@xxxxxxxxxxxxxx
http://www.seul.org/cgi-bin/mailman/listinfo/geda-cvs