Index: trunk/scconfig/Rev.h
===================================================================
--- trunk/scconfig/Rev.h (revision 6712)
+++ trunk/scconfig/Rev.h (revision 6713)
@@ -1 +1 @@
-static const int myrev = 6710;
+static const int myrev = 6713;
Index: trunk/scconfig/Rev.tab
===================================================================
--- trunk/scconfig/Rev.tab (revision 6712)
+++ trunk/scconfig/Rev.tab (revision 6713)
@@ -1,4 +1,4 @@
-6710 configure gtk splitup
+6713 configure gtk splitup
6392 configure draw cross section plugin (gtk and lesstif depend on it)
6365 configure gtk splitup
6111 configure layer vs. layer group code split
Index: trunk/src_plugins/hid_gtk/gui.h
===================================================================
--- trunk/src_plugins/hid_gtk/gui.h (revision 6712)
+++ trunk/src_plugins/hid_gtk/gui.h (revision 6713)
@@ -51,7 +51,7 @@
#include "../src_plugins/lib_gtk_common/bu_spin_button.h"
#include "../src_plugins/lib_gtk_common/bu_status_line.h"
#include "../src_plugins/lib_gtk_common/wt_coord_entry.h"
-#include "../src_plugins/lib_gtk_common/wt_route_style.h"
+#include "../src_plugins/lib_gtk_common/dlg_route_style.h"
#include "../src_plugins/lib_gtk_common/dlg_propedit.h"
/* needed for a type in GhidGui */
Index: trunk/src_plugins/lib_gtk_common/Plug.tmpasm
===================================================================
--- trunk/src_plugins/lib_gtk_common/Plug.tmpasm (revision 6712)
+++ trunk/src_plugins/lib_gtk_common/Plug.tmpasm (revision 6713)
@@ -26,6 +26,7 @@
$(PLUGDIR)/lib_gtk_common/dlg_progress.o
$(PLUGDIR)/lib_gtk_common/dlg_propedit.o
$(PLUGDIR)/lib_gtk_common/dlg_report.o
+ $(PLUGDIR)/lib_gtk_common/dlg_route_style.o
$(PLUGDIR)/lib_gtk_common/dlg_search.o
$(PLUGDIR)/lib_gtk_common/in_keyboard.o
$(PLUGDIR)/lib_gtk_common/in_mouse.o
Index: trunk/src_plugins/lib_gtk_common/dlg_route_style.c
===================================================================
--- trunk/src_plugins/lib_gtk_common/dlg_route_style.c (nonexistent)
+++ trunk/src_plugins/lib_gtk_common/dlg_route_style.c (revision 6713)
@@ -0,0 +1,460 @@
+/*
+ * COPYRIGHT
+ *
+ * pcb-rnd, interactive printed circuit board design
+ * Copyright (C) 2017 Alain Vigne
+ *
+ * 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, see .
+ *
+ */
+
+/* route style edit dialog */
+
+#include
+#include
+#include "config.h"
+
+#include "compat_misc.h"
+#include "compat_nls.h"
+#include "polygon.h"
+#include "obj_all.h"
+
+#include "bu_box.h"
+#include "compat.h"
+
+/* FIXME: Get rid of that ... means get rid of global ghidgui */
+#include "../hid_gtk/gui.h"
+
+/* and replace by this one, at least
+#include "dlg_route_style.h"
+*/
+
+/* SIGNAL HANDLERS */
+
+/* Rebuild the gtk table for attribute list from style */
+static void update_attrib(pcb_gtk_dlg_route_style_t * dialog, pcb_gtk_obj_route_style_t * style)
+{
+ GtkTreeIter iter;
+ int i;
+
+ gtk_list_store_clear(dialog->attr_model);
+
+ for (i = 0; i < style->rst->attr.Number; i++) {
+ gtk_list_store_append(dialog->attr_model, &iter);
+ gtk_list_store_set(dialog->attr_model, &iter, 0, style->rst->attr.List[i].name, -1);
+ gtk_list_store_set(dialog->attr_model, &iter, 1, style->rst->attr.List[i].value, -1);
+ }
+
+ gtk_list_store_append(dialog->attr_model, &iter);
+ gtk_list_store_set(dialog->attr_model, &iter, 0, "", -1);
+ gtk_list_store_set(dialog->attr_model, &iter, 1, "", -1);
+}
+
+/** attr table ? */
+static int get_sel(pcb_gtk_dlg_route_style_t * dlg)
+{
+ GtkTreeIter iter;
+ GtkTreeSelection *tsel;
+ GtkTreeModel *tm;
+ GtkTreePath *path;
+ int *i;
+
+ tsel = gtk_tree_view_get_selection(GTK_TREE_VIEW(dlg->attr_table));
+ if (tsel == NULL)
+ return -1;
+
+ gtk_tree_selection_get_selected(tsel, &tm, &iter);
+ if (iter.stamp == 0)
+ return -1;
+
+ path = gtk_tree_model_get_path(tm, &iter);
+ if (path != NULL) {
+ i = gtk_tree_path_get_indices(path);
+ if (i != NULL) {
+/* gtk_tree_model_get(GTK_TREE_MODEL(dlg->attr_model), &iter, 0, nkey, 1, nval, -1);*/
+ return i[0];
+ }
+ }
+ return -1;
+}
+
+/** 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, pcb_gtk_dlg_route_style_t * dialog)
+{
+ pcb_gtk_route_style_t *rss;
+ pcb_gtk_obj_route_style_t *style;
+ GtkTreeIter iter;
+ GtkTreeModel *tree_model;
+
+ if (dialog->inhibit_style_change)
+ return;
+
+ rss = dialog->rss;
+ tree_model = GTK_TREE_MODEL(rss->model);
+ gtk_combo_box_get_active_iter(combo, &iter);
+ gtk_tree_model_get(tree_model, &iter, STYLE_DATA_COL, &style, -1);
+
+ if (style == NULL) {
+ gtk_entry_set_text(GTK_ENTRY(dialog->name_entry), _("New Style"));
+ rss->selected = -1;
+ return;
+ }
+
+ gtk_entry_set_text(GTK_ENTRY(dialog->name_entry), style->rst->name);
+ pcb_gtk_coord_entry_set_value(GHID_COORD_ENTRY(dialog->line_entry), style->rst->Thick);
+ pcb_gtk_coord_entry_set_value(GHID_COORD_ENTRY(dialog->via_hole_entry), style->rst->Hole);
+ pcb_gtk_coord_entry_set_value(GHID_COORD_ENTRY(dialog->via_size_entry), style->rst->Diameter);
+ pcb_gtk_coord_entry_set_value(GHID_COORD_ENTRY(dialog->clearance_entry), style->rst->Clearance);
+
+ if (style->hidden)
+ rss->selected = -1;
+ else
+ rss->selected = style->rst - PCB->RouteStyle.array;
+
+ update_attrib(dialog, style);
+}
+
+static void attr_edited(int col, GtkCellRendererText * cell, gchar * path, gchar * new_text, pcb_gtk_dlg_route_style_t * dlg)
+{
+ GtkTreeIter iter;
+ pcb_gtk_obj_route_style_t *style;
+ int idx = get_sel(dlg);
+
+ dlg->attr_editing = 0;
+
+ gtk_combo_box_get_active_iter(GTK_COMBO_BOX(dlg->select_box), &iter);
+ gtk_tree_model_get(GTK_TREE_MODEL(dlg->rss->model), &iter, STYLE_DATA_COL, &style, -1);
+
+ if (style == NULL)
+ return;
+
+ if (idx >= style->rst->attr.Number) { /* add new */
+ if (col == 0)
+ pcb_attribute_put(&style->rst->attr, new_text, "n/a", 0);
+ else
+ pcb_attribute_put(&style->rst->attr, "n/a", new_text, 0);
+ }
+ else { /* overwrite existing */
+ char **dest;
+ if (col == 0)
+ dest = &style->rst->attr.List[idx].name;
+ else
+ dest = &style->rst->attr.List[idx].value;
+ if (*dest != NULL)
+ free(*dest);
+ *dest = pcb_strdup(new_text);
+ }
+
+ /* rebuild the table to keep it in sync - expensive, but it happens rarely */
+ update_attrib(dlg, style);
+}
+
+static void attr_edited_key_cb(GtkCellRendererText * cell, gchar * path, gchar * new_text, pcb_gtk_dlg_route_style_t * dlg)
+{
+ attr_edited(0, cell, path, new_text, dlg);
+}
+
+static void attr_edited_val_cb(GtkCellRendererText * cell, gchar * path, gchar * new_text, pcb_gtk_dlg_route_style_t * dlg)
+{
+ attr_edited(1, cell, path, new_text, dlg);
+}
+
+static void attr_edit_started_cb(GtkCellRendererText * cell, GtkCellEditable * e, gchar * path, pcb_gtk_dlg_route_style_t * dlg)
+{
+ dlg->attr_editing = 1;
+}
+
+static void attr_edit_canceled_cb(GtkCellRendererText * cell, pcb_gtk_dlg_route_style_t * dlg)
+{
+ dlg->attr_editing = 0;
+}
+
+static gboolean attr_key_release_cb(GtkWidget * widget, GdkEventKey * event, pcb_gtk_dlg_route_style_t * dlg)
+{
+ unsigned short int kv = event->keyval;
+
+ if (dlg->attr_editing)
+ return FALSE;
+
+ switch (kv) {
+#ifdef GDK_KEY_KP_Delete
+ case GDK_KEY_KP_Delete:
+#endif
+#ifdef GDK_KEY_Delete
+ case GDK_KEY_Delete:
+#endif
+ case 'd':
+ {
+ int idx = get_sel(dlg);
+ GtkTreeIter iter;
+ pcb_gtk_obj_route_style_t *style;
+ gtk_combo_box_get_active_iter(GTK_COMBO_BOX(dlg->select_box), &iter);
+ gtk_tree_model_get(GTK_TREE_MODEL(dlg->rss->model), &iter, STYLE_DATA_COL, &style, -1);
+ if (style == NULL)
+ return FALSE;
+ if ((idx >= 0) && (idx < style->rst->attr.Number)) {
+ pcb_attribute_remove_idx(&style->rst->attr, idx);
+ update_attrib(dlg, style);
+ }
+ }
+ break;
+ }
+ return FALSE;
+}
+
+static void add_new_iter(pcb_gtk_route_style_t * rss)
+{
+ /* Add "new style" option to list */
+ gtk_list_store_append(rss->model, &rss->new_iter);
+ gtk_list_store_set(rss->model, &rss->new_iter, STYLE_TEXT_COL, _(""), STYLE_DATA_COL, NULL, -1);
+}
+
+/* Callback for Delete route style button */
+static void delete_button_cb(GtkButton * button, pcb_gtk_dlg_route_style_t * dialog)
+{
+ if (dialog->rss->selected < 0)
+ return;
+
+ dialog->inhibit_style_change = 1;
+ pcb_gtk_route_style_empty(GHID_ROUTE_STYLE(ghidgui->route_style_selector));
+
+#warning TODO: some of these should be in core
+ pcb_gtk_route_style_copy(dialog->rss->selected);
+
+ vtroutestyle_remove(&PCB->RouteStyle, dialog->rss->selected, 1);
+ dialog->rss->active_style = NULL;
+ make_route_style_buttons(GHID_ROUTE_STYLE(ghidgui->route_style_selector));
+ pcb_trace("Style: %d deleted\n", dialog->rss->selected);
+ pcb_board_set_changed_flag(pcb_true);
+ ghid_window_set_name_label(PCB->Name);
+ add_new_iter(dialog->rss);
+ dialog->inhibit_style_change = 0;
+ pcb_gtk_route_style_select_style(dialog->rss, &pcb_custom_route_style);
+ gtk_combo_box_set_active(GTK_COMBO_BOX(dialog->select_box), 0);
+}
+
+/** Helper for edit_button_cb */
+static void _table_attach_(GtkWidget * table, gint row, const gchar * label, GtkWidget * entry)
+{
+ GtkWidget *label_w = gtk_label_new(label);
+ gtk_misc_set_alignment(GTK_MISC(label_w), 1.0, 0.5);
+ 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);
+}
+
+/** Helper for edit_button_cb */
+static void _table_attach(GtkWidget * table, gint row, const gchar * label, GtkWidget ** entry, pcb_coord_t min,
+ pcb_coord_t max)
+{
+ *entry = pcb_gtk_coord_entry_new(min, max, 0, conf_core.editor.grid_unit, CE_SMALL);
+ _table_attach_(table, row, label, *entry);
+}
+
+void pcb_gtk_route_style_edit_dialog(pcb_gtk_route_style_t * rss)
+{
+ GtkTreePath *path;
+ GtkTreeIter iter;
+ pcb_gtk_dlg_route_style_t dialog_data;
+ GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
+ GtkWidget *window = gtk_widget_get_toplevel(GTK_WIDGET(rss));
+ GtkWidget *dialog;
+ GtkWidget *content_area;
+ GtkWidget *vbox, *hbox, *sub_vbox, *table;
+ GtkWidget *label, *select_box, *check_box;
+ GtkWidget *button;
+ const char *new_name;
+
+ memset(&dialog_data, 0, sizeof(dialog_data)); /* make sure all flags are cleared */
+
+ /* 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", STYLE_TEXT_COL, NULL);
+
+ content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+
+ hbox = gtkc_hbox_new(FALSE, 4);
+ gtk_box_pack_start(GTK_BOX(content_area), hbox, TRUE, TRUE, 4);
+ vbox = gtkc_vbox_new(FALSE, 4);
+ gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 4);
+
+ hbox = gtkc_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, PCB_MIN_LINESIZE, PCB_MAX_LINESIZE);
+ _table_attach(table, 2, _("Via hole size:"),
+ &dialog_data.via_hole_entry, PCB_MIN_PINORVIAHOLE, PCB_MAX_PINORVIASIZE - PCB_MIN_PINORVIACOPPER);
+ _table_attach(table, 3, _("Via ring size:"),
+ &dialog_data.via_size_entry, PCB_MIN_PINORVIAHOLE + PCB_MIN_PINORVIACOPPER, PCB_MAX_PINORVIASIZE);
+ _table_attach(table, 4, _("Clearance:"), &dialog_data.clearance_entry, PCB_MIN_LINESIZE, PCB_MAX_LINESIZE);
+
+ _table_attach_(table, 5, "", gtk_label_new(""));
+
+ /* create attrib table */
+ {
+ GType *ty;
+ GtkCellRenderer *renderer;
+
+ dialog_data.attr_table = gtk_tree_view_new();
+
+ ty = malloc(sizeof(GType) * 2);
+ ty[0] = G_TYPE_STRING;
+ ty[1] = G_TYPE_STRING;
+ dialog_data.attr_model = gtk_list_store_newv(2, ty);
+ free(ty);
+
+ renderer = gtk_cell_renderer_text_new();
+ g_object_set(renderer, "editable", TRUE, NULL);
+ g_signal_connect(renderer, "edited", G_CALLBACK(attr_edited_key_cb), &dialog_data);
+ g_signal_connect(renderer, "editing-started", G_CALLBACK(attr_edit_started_cb), &dialog_data);
+ g_signal_connect(renderer, "editing-canceled", G_CALLBACK(attr_edit_canceled_cb), &dialog_data);
+ gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(dialog_data.attr_table), -1, "key", renderer, "text", 0, NULL);
+
+
+ renderer = gtk_cell_renderer_text_new();
+ g_object_set(renderer, "editable", TRUE, NULL);
+ g_signal_connect(renderer, "edited", G_CALLBACK(attr_edited_val_cb), &dialog_data);
+ g_signal_connect(renderer, "editing-started", G_CALLBACK(attr_edit_started_cb), &dialog_data);
+ g_signal_connect(renderer, "editing-canceled", G_CALLBACK(attr_edit_canceled_cb), &dialog_data);
+ gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(dialog_data.attr_table), -1, "value", renderer, "text", 1, NULL);
+
+ gtk_tree_view_set_model(GTK_TREE_VIEW(dialog_data.attr_table), GTK_TREE_MODEL(dialog_data.attr_model));
+ g_signal_connect(G_OBJECT(dialog_data.attr_table), "key-release-event", G_CALLBACK(attr_key_release_cb), &dialog_data);
+
+ }
+ _table_attach_(table, 6, _("Attributes:"), dialog_data.attr_table);
+
+
+ /* create delete button */
+ button = gtk_button_new_with_label(_("Delete Style"));
+ g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(delete_button_cb), &dialog_data);
+ gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, FALSE, 0);
+
+ 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_iter(rss);
+
+ /* Display dialog */
+ dialog_data.rss = rss;
+ dialog_data.select_box = select_box;
+ if (rss->active_style != NULL) {
+ 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) {
+ int changed = 0;
+ pcb_route_style_t *rst;
+ pcb_gtk_obj_route_style_t *style;
+ gboolean save;
+
+ if (!gtk_combo_box_get_active_iter(GTK_COMBO_BOX(select_box), &iter))
+ goto cancel;
+ gtk_tree_model_get(GTK_TREE_MODEL(rss->model), &iter, STYLE_DATA_COL, &style, -1);
+ if (style == NULL) {
+ int n = vtroutestyle_len(&PCB->RouteStyle);
+ rst = vtroutestyle_get(&PCB->RouteStyle, n, 1);
+ }
+ else {
+ rst = style->rst;
+ *rst->name = '\0';
+ }
+
+ new_name = gtk_entry_get_text(GTK_ENTRY(dialog_data.name_entry));
+
+ while (isspace(*new_name))
+ new_name++;
+ if (strcmp(rst->name, new_name) != 0) {
+ strncpy(rst->name, new_name, sizeof(rst->name) - 1);
+ rst->name[sizeof(rst->name) - 1] = '0';
+ changed = 1;
+ }
+
+/* Modify the route style only if there's significant difference (beyond rouding errors) */
+#define rst_modify(changed, dst, src) \
+ do { \
+ pcb_coord_t __tmp__ = src; \
+ if (abs(dst - __tmp__) > 10) { \
+ changed = 1; \
+ dst = __tmp__; \
+ } \
+ } while(0)
+ rst_modify(changed, rst->Thick, pcb_gtk_coord_entry_get_value(GHID_COORD_ENTRY(dialog_data.line_entry)));
+ rst_modify(changed, rst->Hole, pcb_gtk_coord_entry_get_value(GHID_COORD_ENTRY(dialog_data.via_hole_entry)));
+ rst_modify(changed, rst->Diameter, pcb_gtk_coord_entry_get_value(GHID_COORD_ENTRY(dialog_data.via_size_entry)));
+ rst_modify(changed, rst->Clearance, pcb_gtk_coord_entry_get_value(GHID_COORD_ENTRY(dialog_data.clearance_entry)));
+#undef rst_modify
+ save = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check_box));
+ if (style == NULL)
+ /*style = ghid_route_style_real_add_route_style(rss, rst, 0); */
+ /* FIXME !!! static. function :(
+ style = ghid_route_style_real_add_route_style(rss, rst, 0);
+ */
+ ;
+ else {
+ gtk_action_set_label(GTK_ACTION(style->action), rst->name);
+ gtk_list_store_set(rss->model, &iter, STYLE_TEXT_COL, rst->name, -1);
+ }
+
+ /* Cleanup */
+ gtk_widget_destroy(dialog);
+ gtk_list_store_remove(rss->model, &rss->new_iter);
+ /* Emit change signals */
+ pcb_gtk_route_style_select_style(rss, rst);
+ /*g_signal_emit(rss, ghid_route_style_signals[STYLE_EDITED_SIGNAL], 0, save); */
+ g_signal_emit_by_name(rss, "style-edited", 0, save);
+
+ if (changed) {
+ pcb_board_set_changed_flag(pcb_true);
+ ghid_window_set_name_label(PCB->Name);
+ }
+ }
+ else {
+ cancel:;
+ gtk_widget_destroy(dialog);
+ gtk_list_store_remove(rss->model, &rss->new_iter);
+ }
+}
Index: trunk/src_plugins/lib_gtk_common/dlg_route_style.h
===================================================================
--- trunk/src_plugins/lib_gtk_common/dlg_route_style.h (nonexistent)
+++ trunk/src_plugins/lib_gtk_common/dlg_route_style.h (revision 6713)
@@ -0,0 +1,22 @@
+/* Very linked to the widget ! */
+#include "wt_route_style.h"
+
+struct pcb_gtk_dlg_route_style_s {
+ pcb_gtk_route_style_t *rss;
+ GtkWidget *name_entry;
+ GtkWidget *line_entry;
+ GtkWidget *via_hole_entry;
+ GtkWidget *via_size_entry;
+ GtkWidget *clearance_entry;
+
+ GtkWidget *select_box;
+
+ GtkWidget *attr_table; /* Attributes gtk_tree_view */
+ GtkListStore *attr_model; /* Attributes gtk_tree_model */
+
+ int inhibit_style_change; /* when 1, do not do anything when style changes */
+ int attr_editing; /* set to 1 when an attribute key or value text is being edited */
+};
+
+/** Builds and runs the "edit route style" dialog */
+void pcb_gtk_route_style_edit_dialog(pcb_gtk_route_style_t * rss);
Index: trunk/src_plugins/lib_gtk_common/wt_route_style.c
===================================================================
--- trunk/src_plugins/lib_gtk_common/wt_route_style.c (revision 6712)
+++ trunk/src_plugins/lib_gtk_common/wt_route_style.c (revision 6713)
@@ -1,174 +1,51 @@
-/*! \file
- * \brief Implementation of pcb_gtk_route_style_t widget
- * \par Description
- * Please write description here.
+/*
+ * COPYRIGHT
+ *
+ * pcb-rnd, interactive printed circuit board design
+ * Copyright (C) 2017 Alain Vigne
+ *
+ * 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, see .
+ *
*/
+/** Implementation of pcb_gtk_route_style_t widget.
+ This widget is calling another Dialog, upon "Edit" clicked button */
+
#include "config.h"
#include "conf_core.h"
-#include "wt_route_style.h"
-//#include "gtkhid.h"
+/*FIXME: Remove... */
#include "../hid_gtk/gui.h"
+/* and replace with, at least
+#include "dlg_route_style.h"
+*/
#include "pcb-printf.h"
-#include "route_style.h"
#include "compat_nls.h"
#include
-/* Forward dec'ls */
-struct _route_style;
-struct _route_style *ghid_route_style_real_add_route_style(pcb_gtk_route_style_t *, pcb_route_style_t *, int);
-static void ghid_route_style_finalize(GObject * object);
-static void add_new_iter(pcb_gtk_route_style_t * rss);
/** Global action creation counter */
static gint action_count;
-/** Signals exposed by the widget */
-enum {
- SELECT_STYLE_SIGNAL,
- STYLE_EDITED_SIGNAL,
- LAST_SIGNAL
-};
-
-/** Columns used for internal data store */
-enum {
- TEXT_COL,
- DATA_COL,
- N_COLS
-};
-
static GtkVBox *pcb_gtk_route_style_parent_class;
-static guint ghid_route_style_signals[LAST_SIGNAL] = { 0 };
+static guint ghid_route_style_signals[STYLE_LAST_SIGNAL] = { 0 };
-struct pcb_gtk_route_style_s {
- GtkVBox parent;
- GSList *button_radio_group;
- GSList *action_radio_group;
- GtkWidget *edit_button;
-
- GtkActionGroup *action_group;
- GtkAccelGroup *accel_group;
-
- int hidden_button; /* whether the hidden button is created */
- int selected; /* index of the currently selected route style */
-
- GtkListStore *model;
- struct _route_style *active_style;
-
- GtkTreeIter new_iter; /* iter for the item */
-
-};
-
-struct pcb_gtk_route_style_class_s {
- GtkVBoxClass parent_class;
-
- void (*select_style) (pcb_gtk_route_style_t *, pcb_route_style_t *);
- void (*style_edited) (pcb_gtk_route_style_t *, gboolean);
-};
-
-struct _route_style {
- GtkRadioAction *action;
- GtkWidget *button;
- GtkWidget *menu_item;
- GtkTreeRowReference *rref;
- pcb_route_style_t *rst;
- gulong sig_id;
- int hidden;
-};
-
-/* SIGNAL HANDLERS */
-/** Callback for user selection of a route style */
-static void radio_select_cb(GtkToggleAction * action, pcb_gtk_route_style_t * 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_signals[SELECT_STYLE_SIGNAL], 0, rss->active_style->rst);
-}
-
-/* EDIT DIALOG */
-struct _dialog {
- pcb_gtk_route_style_t *rss;
- GtkWidget *name_entry;
- GtkWidget *line_entry;
- GtkWidget *via_hole_entry;
- GtkWidget *via_size_entry;
- GtkWidget *clearance_entry;
-
- GtkWidget *select_box;
-
- GtkWidget *attr_table;
- GtkListStore *attr_model;
-
- int inhibit_style_change; /* when 1, do not do anything when style changes */
- int attr_editing; /* set to 1 when an attribute key or value text is being edited */
-};
-
-/* Rebuild the gtk table for attribute list from style */
-static void update_attrib(struct _dialog *dialog, struct _route_style *style)
-{
- GtkTreeIter iter;
- int i;
-
- gtk_list_store_clear(dialog->attr_model);
-
- for (i = 0; i < style->rst->attr.Number; i++) {
- gtk_list_store_append(dialog->attr_model, &iter);
- gtk_list_store_set(dialog->attr_model, &iter, 0, style->rst->attr.List[i].name, -1);
- gtk_list_store_set(dialog->attr_model, &iter, 1, style->rst->attr.List[i].value, -1);
- }
-
- gtk_list_store_append(dialog->attr_model, &iter);
- gtk_list_store_set(dialog->attr_model, &iter, 0, "", -1);
- gtk_list_store_set(dialog->attr_model, &iter, 1, "", -1);
-}
-
-/** 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;
-
- if (dialog->inhibit_style_change)
- return;
-
- 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"));
- dialog->rss->selected = -1;
- return;
- }
-
- gtk_entry_set_text(GTK_ENTRY(dialog->name_entry), style->rst->name);
- pcb_gtk_coord_entry_set_value(GHID_COORD_ENTRY(dialog->line_entry), style->rst->Thick);
- pcb_gtk_coord_entry_set_value(GHID_COORD_ENTRY(dialog->via_hole_entry), style->rst->Hole);
- pcb_gtk_coord_entry_set_value(GHID_COORD_ENTRY(dialog->via_size_entry), style->rst->Diameter);
- pcb_gtk_coord_entry_set_value(GHID_COORD_ENTRY(dialog->clearance_entry), style->rst->Clearance);
-
- if (style->hidden)
- dialog->rss->selected = -1;
- else
- dialog->rss->selected = style->rst - PCB->RouteStyle.array;
-
- update_attrib(dialog, style);
-}
-
#warning TODO: this should be in core
-static void copy_route_style(int idx)
+void pcb_gtk_route_style_copy(int idx)
{
pcb_route_style_t *drst;
@@ -181,367 +58,38 @@
pcb_custom_route_style.Hole = drst->Hole;
}
-/* Callback for Delete route style button */
-static void delete_button_cb(GtkButton * button, struct _dialog *dialog)
+/** Launches the Edit dialog */
+static void edit_button_cb(GtkButton * btn, pcb_gtk_route_style_t * rss)
{
- if (dialog->rss->selected < 0)
- return;
-
- dialog->inhibit_style_change = 1;
- pcb_gtk_route_style_empty(GHID_ROUTE_STYLE(ghidgui->route_style_selector));
-
-#warning TODO: some of these should be in core
- copy_route_style(dialog->rss->selected);
-
- vtroutestyle_remove(&PCB->RouteStyle, dialog->rss->selected, 1);
- dialog->rss->active_style = NULL;
- make_route_style_buttons(GHID_ROUTE_STYLE(ghidgui->route_style_selector));
- pcb_trace("Style: %d deleted\n", dialog->rss->selected);
- pcb_board_set_changed_flag(pcb_true);
- ghid_window_set_name_label(PCB->Name);
- add_new_iter(dialog->rss);
- dialog->inhibit_style_change = 0;
- pcb_gtk_route_style_select_style(dialog->rss, &pcb_custom_route_style);
- gtk_combo_box_set_active(GTK_COMBO_BOX(dialog->select_box), 0);
+ pcb_gtk_route_style_edit_dialog(rss);
}
-/***** attr table *****/
-static int get_sel(struct _dialog *dlg)
+/** Callback for user selection of a route style */
+static void radio_select_cb(GtkToggleAction * action, pcb_gtk_route_style_t * rss)
{
- GtkTreeIter iter;
- GtkTreeSelection *tsel;
- GtkTreeModel *tm;
- GtkTreePath *path;
- int *i;
-
- tsel = gtk_tree_view_get_selection(GTK_TREE_VIEW(dlg->attr_table));
- if (tsel == NULL)
- return -1;
-
- gtk_tree_selection_get_selected(tsel, &tm, &iter);
- if (iter.stamp == 0)
- return -1;
-
- path = gtk_tree_model_get_path(tm, &iter);
- if (path != NULL) {
- i = gtk_tree_path_get_indices(path);
- if (i != NULL) {
-/* gtk_tree_model_get(GTK_TREE_MODEL(dlg->attr_model), &iter, 0, nkey, 1, nval, -1);*/
- return i[0];
- }
- }
- return -1;
+ 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_signals[SELECT_STYLE_SIGNAL], 0, rss->active_style->rst);
}
-static void attr_edited(int col, GtkCellRendererText * cell, gchar * path, gchar * new_text, struct _dialog *dlg)
+/* CONSTRUCTOR */
+static void ghid_route_style_init(pcb_gtk_route_style_t * rss)
{
- GtkTreeIter iter;
- struct _route_style *style;
- int idx = get_sel(dlg);
-
- dlg->attr_editing = 0;
-
- gtk_combo_box_get_active_iter(GTK_COMBO_BOX(dlg->select_box), &iter);
- gtk_tree_model_get(GTK_TREE_MODEL(dlg->rss->model), &iter, DATA_COL, &style, -1);
-
- if (style == NULL)
- return;
-
- if (idx >= style->rst->attr.Number) { /* add new */
- if (col == 0)
- pcb_attribute_put(&style->rst->attr, new_text, "n/a", 0);
- else
- pcb_attribute_put(&style->rst->attr, "n/a", new_text, 0);
- }
- else { /* overwrite existing */
- char **dest;
- if (col == 0)
- dest = &style->rst->attr.List[idx].name;
- else
- dest = &style->rst->attr.List[idx].value;
- if (*dest != NULL)
- free(*dest);
- *dest = pcb_strdup(new_text);
- }
-
- /* rebuild the table to keep it in sync - expensive, but it happens rarely */
- update_attrib(dlg, style);
}
-static void attr_edited_key_cb(GtkCellRendererText * cell, gchar * path, gchar * new_text, struct _dialog *dlg)
+/** Clean up object before garbage collection */
+static void ghid_route_style_finalize(GObject * object)
{
- attr_edited(0, cell, path, new_text, dlg);
-}
+ pcb_gtk_route_style_t *rss = (pcb_gtk_route_style_t *) object;
-static void attr_edited_val_cb(GtkCellRendererText * cell, gchar * path, gchar * new_text, struct _dialog *dlg)
-{
- attr_edited(1, cell, path, new_text, dlg);
-}
+ pcb_gtk_route_style_empty(rss);
-static void attr_edit_started_cb(GtkCellRendererText * cell, GtkCellEditable * e, gchar * path, struct _dialog *dlg)
-{
- dlg->attr_editing = 1;
-}
+ g_object_unref(rss->accel_group);
+ g_object_unref(rss->action_group);
-static void attr_edit_canceled_cb(GtkCellRendererText * cell, struct _dialog *dlg)
-{
- dlg->attr_editing = 0;
+ G_OBJECT_CLASS(pcb_gtk_route_style_parent_class)->finalize(object);
}
-static gboolean attr_key_release_cb(GtkWidget * widget, GdkEventKey * event, struct _dialog *dlg)
-{
- unsigned short int kv = event->keyval;
-
- if (dlg->attr_editing)
- return FALSE;
-
- switch (kv) {
-#ifdef GDK_KEY_KP_Delete
- case GDK_KEY_KP_Delete:
-#endif
-#ifdef GDK_KEY_Delete
- case GDK_KEY_Delete:
-#endif
- case 'd':
- {
- int idx = get_sel(dlg);
- GtkTreeIter iter;
- struct _route_style *style;
- gtk_combo_box_get_active_iter(GTK_COMBO_BOX(dlg->select_box), &iter);
- gtk_tree_model_get(GTK_TREE_MODEL(dlg->rss->model), &iter, DATA_COL, &style, -1);
- if (style == NULL)
- return FALSE;
- if ((idx >= 0) && (idx < style->rst->attr.Number)) {
- pcb_attribute_remove_idx(&style->rst->attr, idx);
- update_attrib(dlg, style);
- }
- }
- break;
- }
- return FALSE;
-}
-
-/**** dialog creation ****/
-
-/** Helper for edit_button_cb */
-static void _table_attach_(GtkWidget * table, gint row, const gchar * label, GtkWidget * entry)
-{
- GtkWidget *label_w = gtk_label_new(label);
- gtk_misc_set_alignment(GTK_MISC(label_w), 1.0, 0.5);
- 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);
-}
-
-/** Helper for edit_button_cb */
-static void _table_attach(GtkWidget * table, gint row, const gchar * label, GtkWidget ** entry, pcb_coord_t min,
- pcb_coord_t max)
-{
- *entry = pcb_gtk_coord_entry_new(min, max, 0, conf_core.editor.grid_unit, CE_SMALL);
- _table_attach_(table, row, label, *entry);
-}
-
-static void add_new_iter(pcb_gtk_route_style_t * rss)
-{
- /* Add "new style" option to list */
- gtk_list_store_append(rss->model, &rss->new_iter);
- gtk_list_store_set(rss->model, &rss->new_iter, TEXT_COL, _(""), DATA_COL, NULL, -1);
-}
-
-void pcb_gtk_route_style_edit_dialog(pcb_gtk_route_style_t * rss)
-{
- GtkTreePath *path;
- GtkTreeIter iter;
- struct _dialog dialog_data;
- GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
- GtkWidget *window = gtk_widget_get_toplevel(GTK_WIDGET(rss));
- GtkWidget *dialog;
- GtkWidget *content_area;
- GtkWidget *vbox, *hbox, *sub_vbox, *table;
- GtkWidget *label, *select_box, *check_box;
- GtkWidget *button;
- const char *new_name;
-
- memset(&dialog_data, 0, sizeof(dialog_data)); /* make sure all flags are cleared */
-
- /* 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);
-
- content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
-
- hbox = gtk_hbox_new(FALSE, 4);
- gtk_box_pack_start(GTK_BOX(content_area), 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, PCB_MIN_LINESIZE, PCB_MAX_LINESIZE);
- _table_attach(table, 2, _("Via hole size:"),
- &dialog_data.via_hole_entry, PCB_MIN_PINORVIAHOLE, PCB_MAX_PINORVIASIZE - PCB_MIN_PINORVIACOPPER);
- _table_attach(table, 3, _("Via ring size:"),
- &dialog_data.via_size_entry, PCB_MIN_PINORVIAHOLE + PCB_MIN_PINORVIACOPPER, PCB_MAX_PINORVIASIZE);
- _table_attach(table, 4, _("Clearance:"), &dialog_data.clearance_entry, PCB_MIN_LINESIZE, PCB_MAX_LINESIZE);
-
- _table_attach_(table, 5, "", gtk_label_new(""));
-
- /* create attrib table */
- {
- GType *ty;
- GtkCellRenderer *renderer;
-
- dialog_data.attr_table = gtk_tree_view_new();
-
- ty = malloc(sizeof(GType) * 2);
- ty[0] = G_TYPE_STRING;
- ty[1] = G_TYPE_STRING;
- dialog_data.attr_model = gtk_list_store_newv(2, ty);
- free(ty);
-
- renderer = gtk_cell_renderer_text_new();
- g_object_set(renderer, "editable", TRUE, NULL);
- g_signal_connect(renderer, "edited", G_CALLBACK(attr_edited_key_cb), &dialog_data);
- g_signal_connect(renderer, "editing-started", G_CALLBACK(attr_edit_started_cb), &dialog_data);
- g_signal_connect(renderer, "editing-canceled", G_CALLBACK(attr_edit_canceled_cb), &dialog_data);
- gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(dialog_data.attr_table), -1, "key", renderer, "text", 0, NULL);
-
-
- renderer = gtk_cell_renderer_text_new();
- g_object_set(renderer, "editable", TRUE, NULL);
- g_signal_connect(renderer, "edited", G_CALLBACK(attr_edited_val_cb), &dialog_data);
- g_signal_connect(renderer, "editing-started", G_CALLBACK(attr_edit_started_cb), &dialog_data);
- g_signal_connect(renderer, "editing-canceled", G_CALLBACK(attr_edit_canceled_cb), &dialog_data);
- gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(dialog_data.attr_table), -1, "value", renderer, "text", 1, NULL);
-
- gtk_tree_view_set_model(GTK_TREE_VIEW(dialog_data.attr_table), GTK_TREE_MODEL(dialog_data.attr_model));
- g_signal_connect(G_OBJECT(dialog_data.attr_table), "key-release-event", G_CALLBACK(attr_key_release_cb), &dialog_data);
-
- }
- _table_attach_(table, 6, _("Attributes:"), dialog_data.attr_table);
-
-
- /* create delete button */
- button = gtk_button_new_with_label(_("Delete Style"));
- g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(delete_button_cb), &dialog_data);
- gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, FALSE, 0);
-
- 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_iter(rss);
-
- /* Display dialog */
- dialog_data.rss = rss;
- dialog_data.select_box = select_box;
- if (rss->active_style != NULL) {
- 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) {
- int changed = 0;
- pcb_route_style_t *rst;
- struct _route_style *style;
- gboolean save;
- if (!gtk_combo_box_get_active_iter(GTK_COMBO_BOX(select_box), &iter))
- goto cancel;
- gtk_tree_model_get(GTK_TREE_MODEL(rss->model), &iter, DATA_COL, &style, -1);
- if (style == NULL) {
- int n = vtroutestyle_len(&PCB->RouteStyle);
- rst = vtroutestyle_get(&PCB->RouteStyle, n, 1);
- }
- else {
- rst = style->rst;
- *rst->name = '\0';
- }
-
- new_name = gtk_entry_get_text(GTK_ENTRY(dialog_data.name_entry));
-
- while (isspace(*new_name))
- new_name++;
- if (strcmp(rst->name, new_name) != 0) {
- strncpy(rst->name, new_name, sizeof(rst->name) - 1);
- rst->name[sizeof(rst->name) - 1] = '0';
- changed = 1;
- }
-
-/* Modify the route style only if there's significant difference (beyond rouding errors) */
-#define rst_modify(changed, dst, src) \
- do { \
- pcb_coord_t __tmp__ = src; \
- if (abs(dst - __tmp__) > 10) { \
- changed = 1; \
- dst = __tmp__; \
- } \
- } while(0)
- rst_modify(changed, rst->Thick, pcb_gtk_coord_entry_get_value(GHID_COORD_ENTRY(dialog_data.line_entry)));
- rst_modify(changed, rst->Hole, pcb_gtk_coord_entry_get_value(GHID_COORD_ENTRY(dialog_data.via_hole_entry)));
- rst_modify(changed, rst->Diameter, pcb_gtk_coord_entry_get_value(GHID_COORD_ENTRY(dialog_data.via_size_entry)));
- rst_modify(changed, rst->Clearance, pcb_gtk_coord_entry_get_value(GHID_COORD_ENTRY(dialog_data.clearance_entry)));
-#undef rst_modify
- save = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check_box));
- if (style == NULL)
- style = ghid_route_style_real_add_route_style(rss, rst, 0);
- 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, &rss->new_iter);
- /* Emit change signals */
- pcb_gtk_route_style_select_style(rss, rst);
- g_signal_emit(rss, ghid_route_style_signals[STYLE_EDITED_SIGNAL], 0, save);
-
- if (changed) {
- pcb_board_set_changed_flag(pcb_true);
- ghid_window_set_name_label(PCB->Name);
- }
- }
- else {
- cancel:;
- gtk_widget_destroy(dialog);
- gtk_list_store_remove(rss->model, &rss->new_iter);
- }
-}
-
-/* end EDIT DIALOG */
-
-static void edit_button_cb(GtkButton * btn, pcb_gtk_route_style_t * rss)
-{
- pcb_gtk_route_style_edit_dialog(rss);
-}
-
-/* CONSTRUCTOR */
-static void ghid_route_style_init(pcb_gtk_route_style_t * rss)
-{
-}
-
static void ghid_route_style_class_init(pcb_gtk_route_style_class_t * klass)
{
GObjectClass *object_class = (GObjectClass *) klass;
@@ -564,20 +112,7 @@
object_class->finalize = ghid_route_style_finalize;
}
-/** Clean up object before garbage collection
- */
-static void ghid_route_style_finalize(GObject * object)
-{
- pcb_gtk_route_style_t *rss = (pcb_gtk_route_style_t *) object;
- pcb_gtk_route_style_empty(rss);
-
- g_object_unref(rss->accel_group);
- g_object_unref(rss->action_group);
-
- G_OBJECT_CLASS(pcb_gtk_route_style_parent_class)->finalize(object);
-}
-
/* PUBLIC FUNCTIONS */
GType pcb_gtk_route_style_get_type(void)
{
@@ -609,7 +144,7 @@
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);
+ rss->model = gtk_list_store_new(STYLE_N_COLS, G_TYPE_STRING, G_TYPE_POINTER);
rss->accel_group = gtk_accel_group_new();
rss->action_group = gtk_action_group_new("RouteStyleSelector");
@@ -622,17 +157,18 @@
return GTK_WIDGET(rss);
}
-/** Create a new pcb_gtk_route_style_t
- *
- * \param [in] rss The selector to be acted on
- * \param [in] data PCB's route style object that will be edited
+/** FIXME: Remove comments ? Create a new pcb_gtk_route_style_t
+
+ \param [in] rss The selector to be acted on
+ \param [in] data PCB's route style object that will be edited
*/
-struct _route_style *ghid_route_style_real_add_route_style(pcb_gtk_route_style_t * rss, pcb_route_style_t * data, int hide)
+static pcb_gtk_dlg_route_style_t *ghid_route_style_real_add_route_style(pcb_gtk_route_style_t * rss,
+ pcb_route_style_t * data, int hide)
{
GtkTreeIter iter;
GtkTreePath *path;
gchar *action_name = g_strdup_printf("RouteStyle%d", action_count);
- struct _route_style *new_style = g_malloc(sizeof(*new_style));
+ pcb_gtk_obj_route_style_t *new_style = g_malloc(sizeof(*new_style));
/* Key the route style data with the pcb_route_style_t it controls */
new_style->hidden = hide;
@@ -645,7 +181,7 @@
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);
+ gtk_list_store_set(rss->model, &iter, STYLE_TEXT_COL, data->name, STYLE_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);
@@ -678,7 +214,7 @@
if (*pcb_custom_route_style.name == '\0') {
memset(&pcb_custom_route_style, 0, sizeof(pcb_custom_route_style));
strcpy(pcb_custom_route_style.name, "");
- copy_route_style(0);
+ pcb_gtk_route_style_copy(0);
}
ghid_route_style_real_add_route_style(rss, &pcb_custom_route_style, 1);
rss->hidden_button = 1;
@@ -696,9 +232,9 @@
return 0;
do {
GtkAction *action;
- struct _route_style *style;
+ pcb_gtk_obj_route_style_t *style;
- gtk_tree_model_get(GTK_TREE_MODEL(rss->model), &iter, DATA_COL, &style, -1);
+ gtk_tree_model_get(GTK_TREE_MODEL(rss->model), &iter, STYLE_DATA_COL, &style, -1);
if (style->hidden)
continue;
action = GTK_ACTION(style->action);
@@ -717,8 +253,9 @@
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);
+ pcb_gtk_obj_route_style_t *style;
+
+ gtk_tree_model_get(GTK_TREE_MODEL(rss->model), &iter, STYLE_DATA_COL, &style, -1);
if ((style != NULL) && (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);
@@ -738,8 +275,8 @@
return rss->accel_group;
}
-void pcb_gtk_route_style_sync(pcb_gtk_route_style_t * rss, pcb_coord_t Thick, pcb_coord_t Hole, pcb_coord_t Diameter,
- pcb_coord_t Clearance)
+void pcb_gtk_route_style_sync(pcb_gtk_route_style_t * rss,
+ pcb_coord_t Thick, pcb_coord_t Hole, pcb_coord_t Diameter, pcb_coord_t Clearance)
{
GtkTreeIter iter;
int target, n;
@@ -752,13 +289,13 @@
target = pcb_route_style_lookup(&PCB->RouteStyle, Thick, Diameter, Hole, Clearance, NULL);
if (target == -1) {
- struct _route_style *style;
+ pcb_gtk_obj_route_style_t *style;
/* None of the styles matched: select the hidden custom button */
if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(rss->model), &iter))
return;
- gtk_tree_model_get(GTK_TREE_MODEL(rss->model), &iter, DATA_COL, &style, -1);
+ gtk_tree_model_get(GTK_TREE_MODEL(rss->model), &iter, STYLE_DATA_COL, &style, -1);
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);
@@ -770,8 +307,8 @@
/* need to select the style with index stored in target */
n = -1;
do {
- struct _route_style *style;
- gtk_tree_model_get(GTK_TREE_MODEL(rss->model), &iter, DATA_COL, &style, -1);
+ pcb_gtk_obj_route_style_t *style;
+ gtk_tree_model_get(GTK_TREE_MODEL(rss->model), &iter, STYLE_DATA_COL, &style, -1);
if (n == target) {
g_signal_handler_block(G_OBJECT(style->action), style->sig_id);
gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(style->action), TRUE);
@@ -788,8 +325,8 @@
GtkTreeIter iter;
if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(rss->model), &iter)) {
do {
- struct _route_style *rsdata;
- gtk_tree_model_get(GTK_TREE_MODEL(rss->model), &iter, DATA_COL, &rsdata, -1);
+ pcb_gtk_obj_route_style_t *rsdata;
+ gtk_tree_model_get(GTK_TREE_MODEL(rss->model), &iter, STYLE_DATA_COL, &rsdata, -1);
if (rsdata != NULL) {
if (rsdata->action) {
gtk_action_disconnect_accelerator(GTK_ACTION(rsdata->action));
Index: trunk/src_plugins/lib_gtk_common/wt_route_style.h
===================================================================
--- trunk/src_plugins/lib_gtk_common/wt_route_style.h (revision 6712)
+++ trunk/src_plugins/lib_gtk_common/wt_route_style.h (revision 6713)
@@ -8,15 +8,74 @@
G_BEGIN_DECLS /* keep c++ happy */
#define GHID_ROUTE_STYLE_TYPE (pcb_gtk_route_style_get_type ())
-#define GHID_ROUTE_STYLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GHID_ROUTE_STYLE_TYPE, pcb_gtk_route_style_t))
-#define GHID_ROUTE_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GHID_ROUTE_STYLE_TYPE, pcb_gtk_route_style_class_t))
-#define IS_GHID_ROUTE_STYLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GHID_ROUTE_STYLE_TYPE))
-#define IS_GHID_ROUTE_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GHID_ROUTE_STYLE_TYPE))
-//typedef struct _GHidRouteStyleSelector GHidRouteStyleSelector;
-//typedef struct _GHidRouteStyleSelectorClass GHidRouteStyleSelectorClass;
+#define GHID_ROUTE_STYLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GHID_ROUTE_STYLE_TYPE, pcb_gtk_route_style_t))
+#define GHID_ROUTE_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GHID_ROUTE_STYLE_TYPE, pcb_gtk_route_style_class_t))
+#define IS_GHID_ROUTE_STYLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GHID_ROUTE_STYLE_TYPE))
+#define IS_GHID_ROUTE_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GHID_ROUTE_STYLE_TYPE))
+/** The widget Object */
+ struct pcb_gtk_route_style_s {
+ GtkVBox parent;
+
+ GSList *button_radio_group;
+ GSList *action_radio_group;
+ GtkWidget *edit_button;
+
+ GtkActionGroup *action_group;
+ GtkAccelGroup *accel_group;
+
+ int hidden_button; /* whether the hidden button is created */
+ int selected; /* index of the currently selected route style */
+
+ GtkListStore *model; /* All the route styles */
+ struct pcb_gtk_obj_route_style_s *active_style; /* The current route style */
+
+ GtkTreeIter new_iter; /* iter for the item */
+};
+
typedef struct pcb_gtk_route_style_s pcb_gtk_route_style_t;
+
+/** The widget Class */
+struct pcb_gtk_route_style_class_s {
+ GtkVBoxClass parent_class;
+
+ void (*select_style) (pcb_gtk_route_style_t *, pcb_route_style_t *);
+ void (*style_edited) (pcb_gtk_route_style_t *, gboolean);
+};
+
typedef struct pcb_gtk_route_style_class_s pcb_gtk_route_style_class_t;
+/** Signals exposed by the widget */
+enum {
+ SELECT_STYLE_SIGNAL,
+ STYLE_EDITED_SIGNAL,
+ STYLE_LAST_SIGNAL
+};
+
+/** Columns used for internal data store */
+enum {
+ STYLE_TEXT_COL,
+ STYLE_DATA_COL,
+ STYLE_N_COLS
+};
+
+/** Structure for a single Route Style object */
+struct pcb_gtk_obj_route_style_s {
+ GtkRadioAction *action;
+ GtkWidget *button;
+ GtkWidget *menu_item;
+ GtkTreeRowReference *rref;
+ pcb_route_style_t *rst;
+ gulong sig_id;
+ int hidden;
+};
+typedef struct pcb_gtk_obj_route_style_s pcb_gtk_obj_route_style_t;
+
+/** Structure for "Edit Route Style" Dialog */
+typedef struct pcb_gtk_dlg_route_style_s pcb_gtk_dlg_route_style_t;
+
+/* API */
+
+/** GObject type for this widget */
GType pcb_gtk_route_style_get_type(void);
/** Creates and returns a new freshly-allocated pcb_gtk_route_style_t object */
@@ -53,9 +112,6 @@
*/
gboolean pcb_gtk_route_style_select_style(pcb_gtk_route_style_t * rss, pcb_route_style_t * rst);
-/** Builds and runs the "edit route styles" dialog */
-void pcb_gtk_route_style_edit_dialog(pcb_gtk_route_style_t * rss);
-
/** Returns the GtkAccelGroup of a route style selector
\param [in] rss The selector to be acted on
@@ -79,6 +135,9 @@
void pcb_gtk_route_style_sync(pcb_gtk_route_style_t * rss, pcb_coord_t Thick, pcb_coord_t Hole, pcb_coord_t Diameter,
pcb_coord_t Clearance);
+void pcb_gtk_route_style_copy(int idx);
+
+
/** Removes all styles from a route style selector */
void pcb_gtk_route_style_empty(pcb_gtk_route_style_t * rss);