[gnumeric] Sheet Objects: simplify radio buttons.
- From: Morten Welinder <mortenw src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnumeric] Sheet Objects: simplify radio buttons.
- Date: Sun, 27 Sep 2009 15:14:30 +0000 (UTC)
commit 2388363327bbef8d558240e90b9e70c5e762e0e2
Author: Morten Welinder <terra gnome org>
Date: Sun Sep 27 11:13:53 2009 -0400
Sheet Objects: simplify radio buttons.
ChangeLog | 4 +
src/sheet-object-widget.c | 233 +++++++----------------------------------
src/widgets/ChangeLog | 4 +
src/widgets/Makefile.am | 2 +
src/widgets/gnm-radiobutton.c | 41 +++++++
src/widgets/gnm-radiobutton.h | 34 ++++++
6 files changed, 121 insertions(+), 197 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 83317cd..f3f1781 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2009-09-27 Morten Welinder <terra gnome org>
+
+ * src/sheet-object-widget.c: Simplify radio button stuff.
+
2009-09-27 Andreas J. Guelzow <aguelzow pyrshep ca>
* src/wbc-gtk-actions.c (cb_view_freeze_panes): special handling if the
diff --git a/src/sheet-object-widget.c b/src/sheet-object-widget.c
index 2723478..97e193f 100644
--- a/src/sheet-object-widget.c
+++ b/src/sheet-object-widget.c
@@ -24,7 +24,7 @@
#include <glib/gi18n-lib.h>
#include "gnumeric.h"
#include "sheet-object-widget-impl.h"
-
+#include "widgets/gnm-radiobutton.h"
#include "gnm-pane.h"
#include "gnumeric-simple-canvas.h"
#include "gui-util.h"
@@ -2204,119 +2204,13 @@ GSF_CLASS (SheetWidgetToggleButton, sheet_widget_toggle_button,
#define SHEET_WIDGET_RADIO_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SHEET_WIDGET_RADIO_BUTTON_TYPE, SheetWidgetRadioButton))
#define DEP_TO_RADIO_BUTTON(d_ptr) (SheetWidgetRadioButton *)(((char *)d_ptr) - G_STRUCT_OFFSET(SheetWidgetRadioButton, dep))
-#include "expr-impl.h"
-
-/* Keep track of GnmDepenmdent -> radio button group mapping. We have to go to
- some lengths here because the cell reference expressions in the dependents
- are not forced to have explicit sheet references. Thus, when hashing or
- comparing the dependents, we check for cell references with a NULL sheet in
- which case we assume the sheet of the dependent instead. */
-
-static GHashTable *groups = NULL;
-
-static guint
-dep_cellref_hash(GnmDependent const *k)
-{
- const GnmCellRef *ref = &k->texpr->expr->cellref.ref;
- GnmCellRef r;
- if (!ref->sheet) {
- r = *ref;
- r.sheet = k->sheet;
- ref = &r;
- }
- return gnm_cellref_hash(ref);
-}
-
-static guint
-dep_hash(GnmDependent const *k)
-{
- if (!k || !k->texpr)
- return 0;
- else if (GNM_EXPR_GET_OPER (k->texpr->expr) == GNM_EXPR_OP_CELLREF)
- return dep_cellref_hash(k);
- else
- /* shouldn't happen */
- return gnm_expr_top_hash(k->texpr);
-}
-
-static gint
-dep_cellref_equal(GnmDependent const *k1, GnmDependent const *k2)
-{
- const GnmCellRef *ref1 = &k1->texpr->expr->cellref.ref;
- const GnmCellRef *ref2 = &k2->texpr->expr->cellref.ref;
- GnmCellRef r1, r2;
- if (!ref1->sheet) {
- r1 = *ref1;
- r1.sheet = k1->sheet;
- ref1 = &r1;
- }
- if (!ref2->sheet) {
- r2 = *ref2;
- r2.sheet = k2->sheet;
- ref2 = &r2;
- }
- return gnm_cellref_equal(ref1, ref2);
-}
-
-static gint
-dep_equal(GnmDependent const *k1, GnmDependent const *k2)
-{
- if (k1 && k2)
- if (k1->texpr == k2->texpr)
- return 1;
- else if (!k1->texpr || !k2->texpr)
- return 0;
- else if (GNM_EXPR_GET_OPER (k1->texpr->expr) == GNM_EXPR_OP_CELLREF &&
- GNM_EXPR_GET_OPER (k2->texpr->expr) == GNM_EXPR_OP_CELLREF)
- return dep_cellref_equal(k1, k2);
- else
- /* shouldn't happen */
- return gnm_expr_top_equal(k1->texpr, k2->texpr);
- else
- return k1==k2;
-}
-
-static void
-dep_destroy(GnmDependent *k)
-{
- if (k) {
- if (k->texpr) gnm_expr_top_unref(k->texpr);
- g_free(k);
- }
-}
-
-static GSList *get_group(const GnmDependent *dep)
-{
- if (!groups)
- groups = g_hash_table_new_full ((GHashFunc)dep_hash,
- (GEqualFunc)dep_equal,
- (GDestroyNotify)dep_destroy,
- NULL);
- return g_hash_table_lookup (groups, dep);
-}
-
-static void set_group(const GnmDependent *d, GSList *g)
-{
- if (g) {
- GnmDependent *dep;
- g_return_if_fail (groups != NULL);
- if (d) {
- dep = g_new(GnmDependent, 1);
- *dep = *d;
- if (dep->texpr) gnm_expr_top_ref(dep->texpr);
- } else
- dep = NULL;
- g_hash_table_insert (groups, dep, g);
- } else
- g_hash_table_remove (groups, d);
-}
-
/* Radiobutton values are stored internally as simple strings and are parsed
on the fly when needed. At present we recognize booleans, numbers and
strings. A string value looking like a boolean or a number may be escaped
with a leading single quote. */
-static GnmValue *parse_value(const char *val)
+static GnmValue *
+parse_value(const char *val)
{
g_return_val_if_fail (val != NULL, NULL);
if (*val == '\'')
@@ -2330,7 +2224,8 @@ static GnmValue *parse_value(const char *val)
return value_new_string (val);
}
-static gboolean match_value(const char *val, const GnmValue *res)
+static gboolean
+match_value(const char *val, const GnmValue *res)
{
GnmValue *v = parse_value(val);
gboolean ret = value_equal(v, res);
@@ -2339,7 +2234,7 @@ static gboolean match_value(const char *val, const GnmValue *res)
}
typedef struct {
- SheetObjectWidget sow;
+ SheetObjectWidget sow;
gboolean being_updated;
char *label, *value;
@@ -2356,7 +2251,7 @@ enum {
static void
sheet_widget_radio_button_get_property (GObject *obj, guint param_id,
- GValue *value, GParamSpec *pspec)
+ GValue *value, GParamSpec *pspec)
{
SheetWidgetRadioButton *swrb = SHEET_WIDGET_RADIO_BUTTON (obj);
@@ -2411,11 +2306,14 @@ sheet_widget_radio_button_set_value (SheetObject *so, char const *str)
}
static void
-sheet_widget_radio_button_set_active (SheetWidgetRadioButton *swrb)
+sheet_widget_radio_button_set_active (SheetWidgetRadioButton *swrb,
+ gboolean active)
{
GList *ptr;
- if (!swrb->active) return;
+ if (swrb->active == active)
+ return;
+ swrb->active = active;
swrb->being_updated = TRUE;
@@ -2423,37 +2321,7 @@ sheet_widget_radio_button_set_active (SheetWidgetRadioButton *swrb)
SheetObjectView *view = ptr->data;
GocWidget *item = get_goc_widget (view);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item->widget),
- TRUE);
- }
-
- swrb->being_updated = FALSE;
-}
-
-static void
-sheet_widget_radio_button_set_group (SheetWidgetRadioButton *swrb, GSList *grp)
-{
- GList *ptr;
-
- swrb->being_updated = TRUE;
- swrb->active = FALSE;
-
- for (ptr = swrb->sow.realized_list; ptr != NULL ; ptr = ptr->next) {
- SheetObjectView *view = ptr->data;
- GocWidget *item = get_goc_widget (view);
- GtkRadioButton *w = GTK_RADIO_BUTTON(item->widget);
- GSList *old_grp = gtk_radio_button_get_group (w);
- /* Move widget from old_grp to new_grp. */
- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w))) {
- /* Activate some other widget in the same group. */
- for (; old_grp; old_grp = old_grp->next) {
- GtkRadioButton *v = GTK_RADIO_BUTTON(old_grp->data);
- if (v != w) {
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (v), TRUE);
- break;
- }
- }
- }
- gtk_radio_button_set_group (w, grp);
+ active);
}
swrb->being_updated = FALSE;
@@ -2469,8 +2337,8 @@ radio_button_eval (GnmDependent *dep)
GNM_EXPR_EVAL_SCALAR_NON_EMPTY);
if (v) {
SheetWidgetRadioButton *swrb = DEP_TO_RADIO_BUTTON(dep);
- swrb->active = match_value (swrb->value, v);
- sheet_widget_radio_button_set_active (swrb);
+ gboolean active = match_value (swrb->value, v);
+ sheet_widget_radio_button_set_active (swrb, active);
}
value_release (v);
}
@@ -2498,9 +2366,8 @@ sheet_widget_radio_button_init_full (SheetObjectWidget *sow,
swrb->being_updated = FALSE;
swrb->label = g_strdup (label?label:_("RadioButton"));
swrb->value = g_strdup (value?value:"");
- swrb->active = FALSE;
+ swrb->active = TRUE;
- swrb->being_updated = FALSE;
swrb->dep.sheet = NULL;
swrb->dep.flags = radio_button_get_dep_type ();
swrb->dep.texpr = (ref != NULL)
@@ -2519,7 +2386,6 @@ static void
sheet_widget_radio_button_finalize (GObject *obj)
{
SheetWidgetRadioButton *swrb = SHEET_WIDGET_RADIO_BUTTON (obj);
- GSList *grp;
g_return_if_fail (swrb != NULL);
@@ -2528,16 +2394,9 @@ sheet_widget_radio_button_finalize (GObject *obj)
g_free (swrb->value);
swrb->value = NULL;
- if ((grp = get_group(&swrb->dep)) && grp->next == NULL)
- /* Removing the last button from the group. */
- set_group(&swrb->dep, NULL);
dependent_set_expr (&swrb->dep, NULL);
- (*sheet_object_widget_class->finalize) (obj);
- if (--rb_counter == 0) {
- g_hash_table_destroy(groups);
- groups = NULL;
- }
+ sheet_object_widget_class->finalize (obj);
}
static void
@@ -2545,10 +2404,9 @@ sheet_widget_radio_button_toggled (GtkToggleButton *button,
SheetWidgetRadioButton *swrb)
{
GnmCellRef ref;
- if (swrb->being_updated || !gtk_toggle_button_get_active (button))
+
+ if (swrb->being_updated)
return;
- swrb->active = TRUE;
- sheet_widget_radio_button_set_active (swrb);
if (so_get_ref (SHEET_OBJECT (swrb), &ref, TRUE) != NULL) {
cmd_so_set_value (widget_wbc (GTK_WIDGET (button)),
@@ -2559,35 +2417,21 @@ sheet_widget_radio_button_toggled (GtkToggleButton *button,
}
}
-static void
-sheet_widget_radio_button_changed (GtkRadioButton *button,
- SheetWidgetRadioButton *swrb)
-{
- GSList *old_grp = get_group (&swrb->dep),
- *new_grp = gtk_radio_button_get_group (button);
- if (old_grp != new_grp)
- set_group(&swrb->dep, new_grp);
-}
-
static GtkWidget *
sheet_widget_radio_button_create_widget (SheetObjectWidget *sow)
{
SheetWidgetRadioButton *swrb = SHEET_WIDGET_RADIO_BUTTON (sow);
- GSList* grp = get_group(&swrb->dep);
- GtkWidget *w = gtk_radio_button_new_with_label (grp, swrb->label);
- if (!grp) {
- grp = gtk_radio_button_get_group (GTK_RADIO_BUTTON(w));
- set_group (&swrb->dep, grp);
- }
+ GtkWidget *w = g_object_new (GNM_TYPE_RADIO_BUTTON,
+ "label", swrb->label,
+ NULL) ;
+
GTK_WIDGET_UNSET_FLAGS (w, GTK_CAN_FOCUS);
- if (swrb->active)
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), TRUE);
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), swrb->active);
+
g_signal_connect (G_OBJECT (w),
"toggled",
G_CALLBACK (sheet_widget_radio_button_toggled), sow);
- g_signal_connect (G_OBJECT (w),
- "group-changed",
- G_CALLBACK (sheet_widget_radio_button_changed), sow);
return w;
}
@@ -2597,10 +2441,12 @@ sheet_widget_radio_button_copy (SheetObject *dst, SheetObject const *src)
SheetWidgetRadioButton const *src_swrb = SHEET_WIDGET_RADIO_BUTTON (src);
SheetWidgetRadioButton *dst_swrb = SHEET_WIDGET_RADIO_BUTTON (dst);
GnmCellRef ref;
+
sheet_widget_radio_button_init_full (SHEET_OBJECT (dst_swrb),
so_get_ref (src, &ref, FALSE),
src_swrb->label,
src_swrb->value);
+ sheet_widget_radio_button_set_active (dst_swrb, dst_swrb->active);
}
static gboolean
@@ -2609,7 +2455,6 @@ sheet_widget_radio_button_set_sheet (SheetObject *so, Sheet *sheet)
SheetWidgetRadioButton *swrb = SHEET_WIDGET_RADIO_BUTTON (so);
dependent_set_sheet (&swrb->dep, sheet);
- sheet_widget_radio_button_set_active (swrb);
return FALSE;
}
@@ -2624,8 +2469,9 @@ sheet_widget_radio_button_foreach_dep (SheetObject *so,
}
static void
-sheet_widget_radio_button_write_xml_sax (SheetObject const *so, GsfXMLOut *output,
- GnmConventions const *convs)
+sheet_widget_radio_button_write_xml_sax (SheetObject const *so,
+ GsfXMLOut *output,
+ GnmConventions const *convs)
{
SheetWidgetRadioButton const *swrb = SHEET_WIDGET_RADIO_BUTTON (so);
@@ -2637,8 +2483,8 @@ sheet_widget_radio_button_write_xml_sax (SheetObject const *so, GsfXMLOut *outpu
static void
sheet_widget_radio_button_prep_sax_parser (SheetObject *so, GsfXMLIn *xin,
- xmlChar const **attrs,
- GnmConventions const *convs)
+ xmlChar const **attrs,
+ GnmConventions const *convs)
{
SheetWidgetRadioButton *swrb = SHEET_WIDGET_RADIO_BUTTON (so);
@@ -2649,8 +2495,8 @@ sheet_widget_radio_button_prep_sax_parser (SheetObject *so, GsfXMLIn *xin,
} else if (attr_eq (attrs[0], "Value")) {
g_free (swrb->value);
swrb->value = g_strdup (CXML2C (attrs[1]));
- } else if (gnm_xml_attr_int (attrs, "Active", &swrb->active))
- ; /* ??? */
+ } else if (gnm_xml_attr_bool (attrs, "Active", &swrb->active))
+ ; /* Nothing */
else if (sax_read_dep (attrs, "Input", &swrb->dep, xin, convs))
; /* ??? */
}
@@ -2659,20 +2505,13 @@ void
sheet_widget_radio_button_set_link (SheetObject *so, GnmExprTop const *texpr)
{
SheetWidgetRadioButton *swrb = SHEET_WIDGET_RADIO_BUTTON (so);
- GSList *old_grp = get_group(&swrb->dep), *new_grp;
- if (old_grp && old_grp->next == NULL)
- /* Removing the last button from the group. */
- set_group(&swrb->dep, NULL);
dependent_set_expr (&swrb->dep, texpr);
if (NULL != texpr)
dependent_link (&swrb->dep);
- new_grp = get_group(&swrb->dep);
- if (old_grp != new_grp)
- sheet_widget_radio_button_set_group(swrb, new_grp);
}
GnmExprTop const *
-sheet_widget_radio_button_get_link (SheetObject *so)
+sheet_widget_radio_button_get_link (SheetObject *so)
{
SheetWidgetRadioButton *swrb = SHEET_WIDGET_RADIO_BUTTON (so);
GnmExprTop const *texpr = swrb->dep.texpr;
diff --git a/src/widgets/ChangeLog b/src/widgets/ChangeLog
index 846d579..4cd4bab 100644
--- a/src/widgets/ChangeLog
+++ b/src/widgets/ChangeLog
@@ -1,3 +1,7 @@
+2009-09-27 Morten Welinder <terra gnome org>
+
+ * gnm-radiobutton.[ch]: New files.
+
2009-09-20 Morten Welinder <terra gnome org>
* Release 1.9.13
diff --git a/src/widgets/Makefile.am b/src/widgets/Makefile.am
index 0343bb1..d0cc86e 100644
--- a/src/widgets/Makefile.am
+++ b/src/widgets/Makefile.am
@@ -15,6 +15,8 @@ libwidgets_la_SOURCES = \
gnm-format-sel.h \
gnm-notebook.c \
gnm-notebook.h \
+ gnm-radiobutton.c \
+ gnm-radiobutton.h \
widget-editable-label.c \
widget-editable-label.h \
widget-font-selector.c \
diff --git a/src/widgets/gnm-radiobutton.c b/src/widgets/gnm-radiobutton.c
new file mode 100644
index 0000000..0d8a10c
--- /dev/null
+++ b/src/widgets/gnm-radiobutton.c
@@ -0,0 +1,41 @@
+/**
+ * gnm-radiobutton.c: Implements a special radiobutton
+ *
+ * Copyright (c) 2009 Morten Welinder <terra gnome org>
+ *
+ * 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.
+ **/
+
+#include <gnumeric-config.h>
+#include "gnm-radiobutton.h"
+#include <gsf/gsf-impl-utils.h>
+
+typedef GtkRadioButtonClass GnmRadioButtonClass;
+
+static void
+gnm_radiobutton_class_init (GnmRadioButtonClass *class)
+{
+ GtkButtonClass *button_class = GTK_BUTTON_CLASS (class);
+ GtkWidget *tb = gtk_toggle_button_new ();
+
+ button_class->clicked = GTK_BUTTON_GET_CLASS(tb)->clicked;
+
+ g_object_ref_sink (tb);
+ gtk_widget_destroy (tb);
+ g_object_unref (tb);
+}
+
+GSF_CLASS (GnmRadioButton, gnm_radiobutton,
+ gnm_radiobutton_class_init, NULL, GTK_TYPE_RADIO_BUTTON)
diff --git a/src/widgets/gnm-radiobutton.h b/src/widgets/gnm-radiobutton.h
new file mode 100644
index 0000000..a23fb30
--- /dev/null
+++ b/src/widgets/gnm-radiobutton.h
@@ -0,0 +1,34 @@
+/**
+ * gnm-radiobutton.h: Implements a special radiobutton.
+ *
+ * Copyright (c) 2009 Morten Welinder <terra gnome org>
+ *
+ * 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.
+ **/
+
+#ifndef __GNM_RADIO_BUTTON_H__
+#define __GNM_RADIO_BUTTON_H__
+
+#include <gtk/gtk.h>
+
+#define GNM_TYPE_RADIO_BUTTON (gnm_radiobutton_get_type ())
+#define GNM_RADIO_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNM_RADIO_BUTTON_TYPE, GnmRadioButton))
+#define GNM_IS_RADIO_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNM_RADIO_BUTTON_TYPE))
+
+typedef GtkRadioButton GnmRadioButton;
+
+GType gnm_radiobutton_get_type (void);
+
+#endif /*__GNM_RADIO_BUTTON_H__*/
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]