~ubuntu-branches/ubuntu/quantal/gnumeric/quantal

« back to all changes in this revision

Viewing changes to src/sheet-object-widget.c

  • Committer: Bazaar Package Importer
  • Author(s): Gauvain Pocentek
  • Date: 2009-06-07 11:10:47 UTC
  • mfrom: (1.1.19 upstream) (2.1.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090607111047-l3rtbzfjxvmi1kx0
Tags: 1.9.8-1ubuntu1
* Merge from debian unstable, remaining changes:
  - Promoted gnumeric-doc to Recommends in gnumeric package for help to be
    installed automatically
  - gnumeric-gtk is a transitional package
  - gnumeric conflicts with gnumeric-gtk << 1.8.3-3ubuntu1
  - call initltool-update in po*
  - remove psiconv support (psiconv is in universe):
    o debian/control: remove B-D on libpsiconv-dev
    o debian/rules: don't pass --with-psiconv to ./configure

Show diffs side-by-side

added added

removed removed

Lines of Context:
61
61
#include <string.h>
62
62
 
63
63
#define CXML2C(s) ((char const *)(s))
 
64
#define CC2XML(s) ((xmlChar const *)(s))
64
65
 
65
66
static inline gboolean
66
67
attr_eq (const xmlChar *a, const char *s)
71
72
/****************************************************************************/
72
73
 
73
74
static void
 
75
cb_so_get_ref (GnmDependent *dep, SheetObject *so, gpointer user)
 
76
{
 
77
        GnmDependent **pdep = user;
 
78
        *pdep = dep;
 
79
}
 
80
 
 
81
static GnmCellRef *
 
82
so_get_ref (SheetObject const *so, GnmCellRef *res, gboolean force_sheet)
 
83
{
 
84
        GnmValue *target;
 
85
        GnmDependent *dep = NULL;
 
86
 
 
87
        g_return_val_if_fail (so != NULL, NULL);
 
88
 
 
89
        /* Let's hope there's just one.  */
 
90
        sheet_object_foreach_dep ((SheetObject*)so, cb_so_get_ref, &dep);
 
91
        g_return_val_if_fail (dep, NULL);
 
92
 
 
93
        if (dep->texpr == NULL)
 
94
                return NULL;
 
95
 
 
96
        target = gnm_expr_top_get_range (dep->texpr);
 
97
        if (target == NULL)
 
98
                return NULL;
 
99
 
 
100
        *res = target->v_range.cell.a;
 
101
        value_release (target);
 
102
 
 
103
        if (force_sheet && res->sheet == NULL)
 
104
                res->sheet = sheet_object_get_sheet (so);
 
105
        return res;
 
106
}
 
107
 
 
108
static void
 
109
cb_so_clear_sheet (GnmDependent *dep, SheetObject *so, gpointer user)
 
110
{
 
111
        if (dependent_is_linked (dep))
 
112
                dependent_unlink (dep);
 
113
        dep->sheet = NULL;
 
114
}
 
115
 
 
116
static gboolean
 
117
so_clear_sheet (SheetObject *so)
 
118
{
 
119
        /* Note: This implements sheet_object_clear_sheet.  */
 
120
        sheet_object_foreach_dep (so, cb_so_clear_sheet, NULL);
 
121
        return FALSE;
 
122
}
 
123
 
 
124
 
 
125
static void
74
126
so_widget_view_destroy (SheetObjectView *sov)
75
127
{
76
128
        gtk_object_destroy (GTK_OBJECT (sov));
79
131
so_widget_view_set_bounds (SheetObjectView *sov, double const *coords, gboolean visible)
80
132
{
81
133
        FooCanvasItem *view = FOO_CANVAS_ITEM (sov);
 
134
        double left = MIN (coords [0], coords [2]);
 
135
        double top = MIN (coords [1], coords [3]);
 
136
        double width = fabs (coords [2] - coords [0]) + 1.;
 
137
        double height = fabs (coords [3] - coords [1]) + 1.;
 
138
 
 
139
        /* We only need the next check for frames, but it doesn't hurt otherwise. */
 
140
        if (width < 8.)
 
141
                width = 8.;
 
142
 
82
143
        if (visible) {
83
144
                /* NOTE : far point is EXCLUDED so we add 1 */
84
145
                foo_canvas_item_set (view,
85
 
                        "x",      MIN (coords [0], coords [2]),
86
 
                        "y",      MIN (coords [1], coords [3]),
87
 
                        "width",  fabs (coords [2] - coords [0]) + 1.,
88
 
                        "height", fabs (coords [3] - coords [1]) + 1.,
 
146
                        "x",      left,
 
147
                        "y",      top,
 
148
                        "width",  width,
 
149
                        "height", height,
89
150
                        NULL);
90
151
                foo_canvas_item_show (view);
91
152
        } else
142
203
GSF_CLASS (SheetWidget ## n2, sheet_widget_ ## n1,                                      \
143
204
           &sheet_widget_ ## n1 ## _class_init,                                         \
144
205
           &sheet_widget_ ## n1 ## _init,                                               \
145
 
           SHEET_OBJECT_WIDGET_TYPE);
 
206
           SHEET_OBJECT_WIDGET_TYPE)
146
207
 
147
208
typedef SheetObject SheetObjectWidget;
148
209
typedef struct {
156
217
static GType sheet_object_widget_get_type       (void);
157
218
 
158
219
static void
159
 
sax_write_dep (GsfXMLOut *output, GnmDependent const *dep, char const *id)
 
220
sax_write_dep (GsfXMLOut *output, GnmDependent const *dep, char const *id,
 
221
               GnmConventions const *convs)
160
222
{
161
223
        if (dep->texpr != NULL) {
162
224
                GnmParsePos pos;
163
 
                char *val = gnm_expr_top_as_string (dep->texpr,
164
 
                        parse_pos_init_sheet (&pos, dep->sheet),
165
 
                        gnm_conventions_default);
 
225
                char *val = gnm_expr_top_as_string
 
226
                        (dep->texpr,
 
227
                         parse_pos_init_sheet (&pos, dep->sheet),
 
228
                         convs);
166
229
                gsf_xml_out_add_cstr (output, id, val);
167
230
                g_free (val);
168
231
        }
170
233
 
171
234
static gboolean
172
235
sax_read_dep (xmlChar const * const *attrs, char const *name,
173
 
              GnmDependent *dep, GsfXMLIn *xin)
 
236
              GnmDependent *dep, GsfXMLIn *xin, GnmConventions const *convs)
174
237
{
175
238
        g_return_val_if_fail (attrs != NULL, FALSE);
176
239
        g_return_val_if_fail (attrs[0] != NULL, FALSE);
182
245
        dep->sheet = NULL;
183
246
        if (attrs[1] != NULL && *attrs[1] != '\0') {
184
247
                GnmParsePos pp;
185
 
                dep->texpr = gnm_expr_parse_str_simple (CXML2C (attrs[1]),
186
 
                        parse_pos_init_sheet (&pp, gnm_xml_in_cur_sheet (xin)));
 
248
 
 
249
                parse_pos_init_sheet (&pp, gnm_xml_in_cur_sheet (xin));
 
250
                dep->texpr = gnm_expr_parse_str (CXML2C (attrs[1]), &pp,
 
251
                                                 GNM_EXPR_PARSE_DEFAULT,
 
252
                                                 convs, NULL);
187
253
        } else
188
254
                dep->texpr = NULL;
189
255
 
194
260
read_dep (GnmDependent *dep, char const *name,
195
261
          xmlNodePtr tree, XmlParseContext const *context)
196
262
{
197
 
        char *txt = (gchar *)xmlGetProp (tree, (xmlChar *)name);
 
263
        xmlChar *txt = xmlGetProp (tree, CC2XML (name));
198
264
 
199
265
        dep->sheet = NULL;
200
266
        dep->texpr = NULL;
201
267
        if (txt != NULL && *txt != '\0') {
202
268
                GnmParsePos pos;
203
 
                dep->texpr = gnm_expr_parse_str_simple (txt,
204
 
                        parse_pos_init_sheet (&pos, context->sheet));
 
269
 
 
270
                parse_pos_init_sheet (&pos, context->sheet);
 
271
                dep->texpr = gnm_expr_parse_str
 
272
                        (CC2XML (txt), &pos, GNM_EXPR_PARSE_DEFAULT,
 
273
                         sheet_get_conventions (pos.sheet), NULL);
205
274
                xmlFree (txt);
206
275
        }
207
276
}
217
286
                "widget", view_widget,
218
287
                "size_pixels", FALSE,
219
288
                NULL);
220
 
        /* g_warning ("%p is widget for so %p", view_widget, so);*/
 
289
        /* g_warning ("%p is widget for so %p", (void *)view_widget, (void *)so);*/
221
290
        gtk_widget_show_all (view_widget);
222
291
        foo_canvas_item_hide (view_item);
223
292
        gnm_pane_widget_register (so, view_widget, view_item);
250
319
static GSF_CLASS (SheetObjectWidget, sheet_object_widget,
251
320
                  sheet_object_widget_class_init,
252
321
                  sheet_object_widget_init,
253
 
                  SHEET_OBJECT_TYPE);
 
322
                  SHEET_OBJECT_TYPE)
254
323
 
255
324
static WorkbookControl *
256
325
widget_wbc (GtkWidget *widget)
305
374
}
306
375
 
307
376
static void
308
 
sheet_widget_frame_write_xml_sax (SheetObject const *so, GsfXMLOut *output)
 
377
sheet_widget_frame_write_xml_sax (SheetObject const *so, GsfXMLOut *output,
 
378
                                  GnmConventions const *convs)
309
379
{
310
380
        SheetWidgetFrame const *swf = SHEET_WIDGET_FRAME (so);
311
381
        gsf_xml_out_add_cstr (output, "Label", swf->label);
312
382
}
313
383
 
314
384
static void
315
 
sheet_widget_frame_prep_sax_parser (SheetObject *so, GsfXMLIn *xin, xmlChar const **attrs)
 
385
sheet_widget_frame_prep_sax_parser (SheetObject *so, GsfXMLIn *xin,
 
386
                                    xmlChar const **attrs,
 
387
                                    GnmConventions const *convs)
316
388
{
317
389
        SheetWidgetFrame *swf = SHEET_WIDGET_FRAME (so);
318
390
        for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
328
400
                                 xmlNodePtr tree)
329
401
{
330
402
        SheetWidgetFrame *swf = SHEET_WIDGET_FRAME (so);
331
 
        gchar *label = (gchar *)xmlGetProp (tree, (xmlChar *)"Label");
 
403
        xmlChar *label = xmlGetProp (tree, CC2XML ("Label"));
332
404
 
333
405
        if (!label) {
334
406
                g_warning ("Could not read a SheetWidgetFrame because it lacks a label property.");
336
408
        }
337
409
 
338
410
        g_free (swf->label);
339
 
        swf->label = g_strdup (label);
 
411
        swf->label = g_strdup (CC2XML (label));
340
412
        xmlFree (label);
341
413
 
342
414
        return FALSE;
374
446
static void
375
447
cb_frame_config_ok_clicked (GtkWidget *button, FrameConfigState *state)
376
448
{
 
449
        gchar const *text = gtk_entry_get_text(GTK_ENTRY(state->label));
 
450
 
 
451
        cmd_so_set_frame_label (WORKBOOK_CONTROL (state->wbcg),
 
452
                                SHEET_OBJECT (state->swf),
 
453
                                g_strdup (state->old_label), g_strdup (text));
377
454
        gtk_widget_destroy (state->dialog);
378
455
}
379
456
 
 
457
void
 
458
sheet_widget_frame_set_label (SheetObject *so, char const* str)
 
459
{
 
460
        SheetWidgetFrame *swf = SHEET_WIDGET_FRAME (so);
 
461
        GList *ptr;
 
462
 
 
463
        str = str ? str : "";
 
464
 
 
465
        if (go_str_compare (str, swf->label) == 0)
 
466
                return;
 
467
 
 
468
        g_free (swf->label);
 
469
        swf->label = g_strdup (str);
 
470
 
 
471
        for (ptr = swf->sow.realized_list; ptr != NULL; ptr = ptr->next) {
 
472
                FooCanvasWidget *item = FOO_CANVAS_WIDGET (ptr->data);
 
473
                gtk_frame_set_label (GTK_FRAME (item->widget), str);
 
474
        }
 
475
}
 
476
 
380
477
static void
381
478
cb_frame_config_cancel_clicked (GtkWidget *button, FrameConfigState *state)
382
479
{
383
 
        GList *ptr;
384
 
        SheetWidgetFrame *swf = state->swf;
385
 
 
386
 
        g_free (swf->label);
387
 
 
388
 
        swf->label = g_strdup (state->old_label);
389
 
        for (ptr = swf->sow.realized_list; ptr != NULL ; ptr = ptr->next)
390
 
                gtk_frame_set_label
391
 
                        (GTK_FRAME (FOO_CANVAS_WIDGET (ptr->data)->widget),
392
 
                         state->old_label);
 
480
        sheet_widget_frame_set_label (SHEET_OBJECT (state->swf), state->old_label);
393
481
 
394
482
        gtk_widget_destroy (state->dialog);
395
483
}
396
484
 
 
485
 
397
486
static void
398
487
cb_frame_label_changed (GtkWidget *entry, FrameConfigState *state)
399
488
{
400
 
        GList *ptr;
401
 
        SheetWidgetFrame *swf;
402
489
        gchar const *text;
403
490
 
404
491
        text = gtk_entry_get_text(GTK_ENTRY(entry));
405
 
        swf = state->swf;
406
 
 
407
 
        g_free (swf->label);
408
 
        swf->label = g_strdup (text);
409
 
 
410
 
        for (ptr = swf->sow.realized_list; ptr != NULL; ptr = ptr->next) {
411
 
                gtk_frame_set_label
412
 
                        (GTK_FRAME (FOO_CANVAS_WIDGET (ptr->data)->widget),
413
 
                         text);
414
 
        }
 
492
        sheet_widget_frame_set_label (SHEET_OBJECT (state->swf), text);
415
493
}
416
494
 
417
495
static void
547
625
}
548
626
 
549
627
static void
550
 
sheet_widget_button_write_xml_sax (SheetObject const *so, GsfXMLOut *output)
 
628
sheet_widget_button_write_xml_sax (SheetObject const *so, GsfXMLOut *output,
 
629
                                   GnmConventions const *convs)
551
630
{
552
 
        // FIXME: markup
 
631
        /* FIXME: markup */
553
632
        SheetWidgetButton *swb = SHEET_WIDGET_BUTTON (so);
554
633
        gsf_xml_out_add_cstr (output, "Label", swb->label);
555
634
}
556
635
 
557
636
static void
558
 
sheet_widget_button_prep_sax_parser (SheetObject *so, GsfXMLIn *xin, xmlChar const **attrs)
 
637
sheet_widget_button_prep_sax_parser (SheetObject *so, GsfXMLIn *xin,
 
638
                                     xmlChar const **attrs,
 
639
                                     GnmConventions const *convs)
559
640
{
560
641
        SheetWidgetButton *swb = SHEET_WIDGET_BUTTON (so);
561
642
        for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
568
649
                                  XmlParseContext const *context,
569
650
                                  xmlNodePtr tree)
570
651
{
571
 
        // FIXME: markup
 
652
        /* FIXME: markup */
572
653
        SheetWidgetButton *swb = SHEET_WIDGET_BUTTON (so);
573
 
        gchar *label = (gchar *)xmlGetProp (tree, (xmlChar *)"Label");
 
654
        xmlChar *label = xmlGetProp (tree, CC2XML ("Label"));
574
655
 
575
656
        if (!label) {
576
657
                g_warning ("Could not read a SheetWidgetButton because it lacks a label property.");
577
658
                return TRUE;
578
659
        }
579
660
 
580
 
        swb->label = g_strdup (label);
 
661
        swb->label = g_strdup (CC2XML (label));
581
662
        xmlFree (label);
582
663
 
583
664
        return FALSE;
695
776
#define SHEET_WIDGET_ADJUSTMENT_TYPE    (sheet_widget_adjustment_get_type())
696
777
#define SHEET_WIDGET_ADJUSTMENT(obj)    (G_TYPE_CHECK_INSTANCE_CAST ((obj), SHEET_WIDGET_ADJUSTMENT_TYPE, SheetWidgetAdjustment))
697
778
#define DEP_TO_ADJUSTMENT(d_ptr)        (SheetWidgetAdjustment *)(((char *)d_ptr) - G_STRUCT_OFFSET(SheetWidgetAdjustment, dep))
 
779
#define SHEET_WIDGET_ADJUSTMENT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), SHEET_WIDGET_ADJUSTMENT_TYPE, SheetWidgetAdjustmentClass))
 
780
#define SWA_CLASS(so)                (SHEET_WIDGET_ADJUSTMENT_CLASS (G_OBJECT_GET_CLASS(so)))
698
781
 
699
782
typedef struct {
700
783
        SheetObjectWidget       sow;
702
785
        gboolean  being_updated;
703
786
        GnmDependent dep;
704
787
        GtkAdjustment *adjustment;
 
788
 
 
789
        gboolean horizontal;
705
790
} SheetWidgetAdjustment;
706
 
typedef SheetObjectWidgetClass SheetWidgetAdjustmentClass;
 
791
 
 
792
typedef struct {
 
793
        SheetObjectWidgetClass parent_class;
 
794
        GType htype, vtype;
 
795
} SheetWidgetAdjustmentClass;
 
796
 
 
797
enum {
 
798
        SWA_PROP_0 = 0,
 
799
        SWA_PROP_HORIZONTAL
 
800
};
707
801
 
708
802
static GType sheet_widget_adjustment_get_type (void);
709
803
 
719
813
        swa->being_updated = FALSE;
720
814
}
721
815
 
 
816
GtkAdjustment *
 
817
sheet_widget_adjustment_get_adjustment (SheetObject *so)
 
818
{
 
819
        return (SHEET_WIDGET_ADJUSTMENT (so)->adjustment);
 
820
}
 
821
 
 
822
void
 
823
sheet_widget_adjustment_set_link (SheetObject *so, GnmExprTop const *texpr)
 
824
{
 
825
        SheetWidgetAdjustment *swa = SHEET_WIDGET_ADJUSTMENT (so);
 
826
        dependent_set_expr (&swa->dep, texpr);
 
827
        if (NULL != texpr)
 
828
                dependent_link (&swa->dep);
 
829
}
 
830
 
 
831
GnmExprTop const *
 
832
sheet_widget_adjustment_get_link (SheetObject *so)
 
833
{
 
834
        SheetWidgetAdjustment *swa = SHEET_WIDGET_ADJUSTMENT (so);
 
835
        GnmExprTop const *texpr = swa->dep.texpr;
 
836
 
 
837
        if (texpr)
 
838
                gnm_expr_top_ref (texpr);
 
839
 
 
840
        return texpr;
 
841
}
 
842
 
 
843
 
722
844
static void
723
845
adjustment_eval (GnmDependent *dep)
724
846
{
735
857
static void
736
858
adjustment_debug_name (GnmDependent const *dep, GString *target)
737
859
{
738
 
        g_string_append_printf (target, "Adjustment%p", dep);
 
860
        g_string_append_printf (target, "Adjustment%p", (void *)dep);
739
861
}
740
862
 
741
863
static DEPENDENT_MAKE_TYPE (adjustment, NULL)
742
864
 
743
 
static GnmCellRef *
744
 
sheet_widget_adjustment_get_ref (SheetWidgetAdjustment const *swa,
745
 
                                GnmCellRef *res, gboolean force_sheet)
746
 
{
747
 
        GnmValue *target;
748
 
        g_return_val_if_fail (swa != NULL, NULL);
749
 
 
750
 
        if (swa->dep.texpr == NULL)
751
 
                return NULL;
752
 
 
753
 
        target = gnm_expr_top_get_range (swa->dep.texpr);
754
 
        if (target == NULL)
755
 
                return NULL;
756
 
 
757
 
        *res = target->v_range.cell.a;
758
 
        value_release (target);
759
 
 
760
 
        if (force_sheet && res->sheet == NULL)
761
 
                res->sheet = sheet_object_get_sheet (SHEET_OBJECT (swa));
762
 
        return res;
763
 
}
764
 
 
765
865
static void
766
866
cb_adjustment_widget_value_changed (GtkWidget *widget,
767
867
                                    SheetWidgetAdjustment *swa)
771
871
        if (swa->being_updated)
772
872
                return;
773
873
 
774
 
        if (sheet_widget_adjustment_get_ref (swa, &ref, TRUE) != NULL) {
 
874
        if (so_get_ref (SHEET_OBJECT (swa), &ref, TRUE) != NULL) {
775
875
                GnmCell *cell = sheet_cell_fetch (ref.sheet, ref.col, ref.row);
776
876
                /* TODO : add more control for precision, XL is stupid */
777
877
                int new_val = gnm_fake_round (swa->adjustment->value);
784
884
                cmd_so_set_value (widget_wbc (widget),
785
885
                                  /* FIXME: This text sucks:  */
786
886
                                  _("Change widget"),
787
 
                                  &ref, value_new_int (new_val));
 
887
                                  &ref, value_new_int (new_val),
 
888
                                  sheet_object_get_sheet (SHEET_OBJECT (swa)));
788
889
                swa->being_updated = FALSE;
789
890
        }
790
891
}
791
892
 
792
893
static void
793
 
sheet_widget_adjustment_init_full (SheetWidgetAdjustment *swa, GnmCellRef const *ref)
 
894
sheet_widget_adjustment_set_horizontal (SheetWidgetAdjustment *swa,
 
895
                                        gboolean horizontal)
 
896
{
 
897
        GList *ptr;
 
898
 
 
899
        horizontal = !!horizontal;
 
900
        if (horizontal == swa->horizontal)
 
901
                return;
 
902
        swa->horizontal = horizontal;
 
903
 
 
904
        /* Change direction for all realized widgets.  */
 
905
        for (ptr = swa->sow.realized_list; ptr != NULL; ptr = ptr->next) {
 
906
                FooCanvasItem *item = FOO_CANVAS_ITEM (ptr->data);
 
907
                GtkWidget *neww =
 
908
                        SOW_CLASS (swa)->create_widget (SHEET_OBJECT (swa));
 
909
                gtk_widget_show (neww);
 
910
                foo_canvas_item_set (item, "widget", neww, NULL);
 
911
        }
 
912
}
 
913
 
 
914
 
 
915
static void
 
916
sheet_widget_adjustment_get_property (GObject *obj, guint param_id,
 
917
                                      GValue  *value, GParamSpec *pspec)
 
918
{
 
919
        SheetWidgetAdjustment *swa = SHEET_WIDGET_ADJUSTMENT (obj);
 
920
 
 
921
        switch (param_id) {
 
922
        case SWA_PROP_HORIZONTAL:
 
923
                g_value_set_boolean (value, swa->horizontal);
 
924
                break;
 
925
        default :
 
926
                G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec);
 
927
                break;
 
928
        }
 
929
}
 
930
 
 
931
static void
 
932
sheet_widget_adjustment_set_property (GObject *obj, guint param_id,
 
933
                                      GValue const *value, GParamSpec *pspec)
 
934
{
 
935
        SheetWidgetAdjustment *swa = SHEET_WIDGET_ADJUSTMENT (obj);
 
936
 
 
937
        switch (param_id) {
 
938
        case SWA_PROP_HORIZONTAL:
 
939
                sheet_widget_adjustment_set_horizontal (swa, g_value_get_boolean (value));
 
940
                /* FIXME */
 
941
                break;
 
942
        default:
 
943
                G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec);
 
944
                return;
 
945
        }
 
946
}
 
947
 
 
948
static void
 
949
sheet_widget_adjustment_init_full (SheetWidgetAdjustment *swa,
 
950
                                   GnmCellRef const *ref,
 
951
                                   gboolean horizontal)
794
952
{
795
953
        g_return_if_fail (swa != NULL);
796
954
 
797
955
        swa->adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (0., 0., 100., 1., 10., 0.));
798
 
#if GLIB_CHECK_VERSION(2,10,0) && GTK_CHECK_VERSION(2,8,14)
799
956
        g_object_ref_sink (swa->adjustment);
800
 
#else
801
 
        g_object_ref (swa->adjustment);
802
 
        gtk_object_sink (GTK_OBJECT (swa->adjustment));
803
 
#endif
804
957
 
 
958
        swa->horizontal = horizontal;
805
959
        swa->being_updated = FALSE;
806
960
        swa->dep.sheet = NULL;
807
961
        swa->dep.flags = adjustment_get_dep_type ();
813
967
static void
814
968
sheet_widget_adjustment_init (SheetWidgetAdjustment *swa)
815
969
{
816
 
        sheet_widget_adjustment_init_full (swa, NULL);
 
970
        SheetWidgetAdjustmentClass *klass = SWA_CLASS (swa);
 
971
        gboolean horizontal = (klass->vtype == G_TYPE_NONE);
 
972
        sheet_widget_adjustment_init_full (swa, NULL, horizontal);
817
973
}
818
974
 
819
975
static void
841
997
        GnmCellRef ref;
842
998
 
843
999
        sheet_widget_adjustment_init_full (dst_swa,
844
 
                sheet_widget_adjustment_get_ref (src_swa, &ref, FALSE));
 
1000
                                           so_get_ref (src, &ref, FALSE),
 
1001
                                           src_swa->horizontal);
845
1002
        dst_adjust = dst_swa->adjustment;
846
1003
        src_adjust = src_swa->adjustment;
847
1004
 
855
1012
typedef struct {
856
1013
        GladeXML           *gui;
857
1014
        GtkWidget          *dialog;
858
 
        GnmExprEntry  *expression;
 
1015
        GnmExprEntry       *expression;
859
1016
        GtkWidget          *min;
860
1017
        GtkWidget          *max;
861
1018
        GtkWidget          *inc;
862
1019
        GtkWidget          *page;
 
1020
        GtkWidget          *direction_h;
 
1021
        GtkWidget          *direction_v;
863
1022
 
 
1023
        char               *undo_label;
864
1024
        GtkWidget          *old_focus;
865
1025
 
866
1026
        WBCGtk *wbcg;
899
1059
                g_object_unref (G_OBJECT (state->gui));
900
1060
                state->gui = NULL;
901
1061
        }
 
1062
        g_free (state->undo_label);
902
1063
 
903
1064
        state->dialog = NULL;
904
1065
        g_free (state);
908
1069
cb_adjustment_config_ok_clicked (GtkWidget *button, AdjustmentConfigState *state)
909
1070
{
910
1071
        SheetObject *so = SHEET_OBJECT (state->swa);
911
 
        GnmParsePos  pp;
 
1072
        GnmParsePos pp;
912
1073
        GnmExprTop const *texpr = gnm_expr_entry_parse (state->expression,
913
1074
                parse_pos_init_sheet (&pp, so->sheet),
914
1075
                NULL, FALSE, GNM_EXPR_PARSE_DEFAULT);
915
 
        if (texpr != NULL) {
916
 
                dependent_set_expr (&state->swa->dep, texpr);
917
 
                dependent_link (&state->swa->dep);
918
 
                gnm_expr_top_unref (texpr);
919
 
        }
920
 
 
921
 
        state->swa->adjustment->lower = gtk_spin_button_get_value_as_int (
922
 
                GTK_SPIN_BUTTON (state->min));
923
 
        state->swa->adjustment->upper = gtk_spin_button_get_value_as_int (
924
 
                GTK_SPIN_BUTTON (state->max));
925
 
        state->swa->adjustment->step_increment = gtk_spin_button_get_value_as_int (
926
 
                GTK_SPIN_BUTTON (state->inc));
927
 
        state->swa->adjustment->page_increment = gtk_spin_button_get_value_as_int (
928
 
                GTK_SPIN_BUTTON (state->page));
929
 
 
930
 
        gtk_adjustment_changed  (state->swa->adjustment);
 
1076
        gboolean horizontal;
 
1077
 
 
1078
        horizontal = state->direction_h
 
1079
                ? gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (state->direction_h))
 
1080
                : state->swa->horizontal;
 
1081
 
 
1082
        cmd_so_set_adjustment (WORKBOOK_CONTROL (state->wbcg), so,
 
1083
                               texpr,
 
1084
                               horizontal,
 
1085
                               gtk_spin_button_get_value_as_int (
 
1086
                                       GTK_SPIN_BUTTON (state->min)),
 
1087
                               gtk_spin_button_get_value_as_int (
 
1088
                                       GTK_SPIN_BUTTON (state->max)),
 
1089
                               gtk_spin_button_get_value_as_int (
 
1090
                                       GTK_SPIN_BUTTON (state->inc)),
 
1091
                               gtk_spin_button_get_value_as_int (
 
1092
                                       GTK_SPIN_BUTTON (state->page)),
 
1093
                               state->undo_label);
931
1094
 
932
1095
        gtk_widget_destroy (state->dialog);
933
1096
}
939
1102
}
940
1103
 
941
1104
static void
942
 
sheet_widget_adjustment_user_config (SheetObject *so, SheetControl *sc)
 
1105
sheet_widget_adjustment_user_config_impl (SheetObject *so, SheetControl *sc, char const *undo_label, char const *dialog_label)
943
1106
{
944
1107
        SheetWidgetAdjustment *swa = SHEET_WIDGET_ADJUSTMENT (so);
945
 
        WBCGtk   *wbcg = scg_wbcg (SHEET_CONTROL_GUI (sc));
 
1108
        SheetWidgetAdjustmentClass *swa_class = SWA_CLASS (swa);
 
1109
        WBCGtk *wbcg = scg_wbcg (SHEET_CONTROL_GUI (sc));
946
1110
        AdjustmentConfigState *state;
947
1111
        GtkWidget *table;
948
 
 
949
 
        g_return_if_fail (swa != NULL);
 
1112
        gboolean has_directions = (swa_class->htype != G_TYPE_NONE &&
 
1113
                                   swa_class->vtype != G_TYPE_NONE);
950
1114
 
951
1115
        /* Only pop up one copy per workbook */
952
1116
        if (gnumeric_dialog_raise_if_exists (wbcg, SHEET_OBJECT_CONFIG_KEY))
957
1121
        state->wbcg = wbcg;
958
1122
        state->sheet = sc_sheet (sc);
959
1123
        state->old_focus = NULL;
 
1124
        state->undo_label = (undo_label == NULL) ? NULL : g_strdup (undo_label);
960
1125
        state->gui = gnm_glade_xml_new (GO_CMD_CONTEXT (wbcg),
961
1126
                "so-scrollbar.glade", NULL, NULL);
962
1127
        state->dialog = glade_xml_get_widget (state->gui, "SO-Scrollbar");
963
1128
 
 
1129
        if (dialog_label != NULL)
 
1130
                gtk_window_set_title (GTK_WINDOW (state->dialog), dialog_label);
 
1131
 
964
1132
        table = glade_xml_get_widget (state->gui, "table");
965
1133
 
966
1134
        state->expression = gnm_expr_entry_new (wbcg, TRUE);
976
1144
                          0, 0);
977
1145
        gtk_widget_show (GTK_WIDGET (state->expression));
978
1146
 
 
1147
        if (has_directions) {
 
1148
                state->direction_h = glade_xml_get_widget (state->gui, "direction_h");
 
1149
                state->direction_v = glade_xml_get_widget (state->gui, "direction_v");
 
1150
                gtk_toggle_button_set_active
 
1151
                        (GTK_TOGGLE_BUTTON (swa->horizontal
 
1152
                                            ? state->direction_h
 
1153
                                            : state->direction_v),
 
1154
                         TRUE);
 
1155
        } else {
 
1156
                state->direction_h = NULL;
 
1157
                state->direction_v = NULL;
 
1158
                gtk_widget_destroy (glade_xml_get_widget (state->gui, "direction_label"));
 
1159
                gtk_widget_destroy (glade_xml_get_widget (state->gui, "direction_box"));
 
1160
        }
 
1161
 
979
1162
        /* TODO : This is silly, no need to be similar to XL here. */
980
1163
        state->min = glade_xml_get_widget (state->gui, "spin_min");
981
1164
        gtk_spin_button_set_value (GTK_SPIN_BUTTON (state->min), swa->adjustment->lower);
1022
1205
        gtk_widget_show (state->dialog);
1023
1206
}
1024
1207
 
 
1208
static void
 
1209
sheet_widget_adjustment_user_config (SheetObject *so, SheetControl *sc)
 
1210
{
 
1211
        sheet_widget_adjustment_user_config_impl (so, sc, N_("Configure Adjustment"),
 
1212
                                                  N_("Adjustment Properties"));
 
1213
}
 
1214
 
1025
1215
static gboolean
1026
1216
sheet_widget_adjustment_set_sheet (SheetObject *so, Sheet *sheet)
1027
1217
{
1032
1222
        return FALSE;
1033
1223
}
1034
1224
 
1035
 
static gboolean
1036
 
sheet_widget_adjustment_clear_sheet (SheetObject *so)
1037
 
{
1038
 
        SheetWidgetAdjustment *swa = SHEET_WIDGET_ADJUSTMENT (so);
1039
 
 
1040
 
        if (dependent_is_linked (&swa->dep))
1041
 
                dependent_unlink (&swa->dep);
1042
 
        swa->dep.sheet = NULL;
1043
 
        return FALSE;
1044
 
}
1045
 
 
1046
1225
static void
1047
1226
sheet_widget_adjustment_foreach_dep (SheetObject *so,
1048
1227
                                     SheetObjectForeachDepFunc func,
1053
1232
}
1054
1233
 
1055
1234
static void
1056
 
sheet_widget_adjustment_write_xml_sax (SheetObject const *so, GsfXMLOut *output)
 
1235
sheet_widget_adjustment_write_xml_sax (SheetObject const *so, GsfXMLOut *output,
 
1236
                                       GnmConventions const *convs)
1057
1237
{
1058
1238
        SheetWidgetAdjustment const *swa = SHEET_WIDGET_ADJUSTMENT (so);
 
1239
        SheetWidgetAdjustmentClass *swa_class = SWA_CLASS (so);
 
1240
 
1059
1241
        gsf_xml_out_add_float (output, "Min",   swa->adjustment->lower, 2);
1060
1242
        gsf_xml_out_add_float (output, "Max",   swa->adjustment->upper, 2); /* allow scrolling to max */
1061
1243
        gsf_xml_out_add_float (output, "Inc",   swa->adjustment->step_increment, 2);
1062
1244
        gsf_xml_out_add_float (output, "Page",  swa->adjustment->page_increment, 2);
1063
1245
        gsf_xml_out_add_float (output, "Value", swa->adjustment->value, 2);
1064
 
        sax_write_dep (output, &swa->dep, "Input");
 
1246
 
 
1247
        if (swa_class->htype != G_TYPE_NONE && swa_class->vtype != G_TYPE_NONE)
 
1248
                gsf_xml_out_add_bool (output, "Horizontal", swa->horizontal);
 
1249
 
 
1250
        sax_write_dep (output, &swa->dep, "Input", convs);
1065
1251
}
1066
1252
 
1067
1253
static void
1068
 
sheet_widget_adjustment_prep_sax_parser (SheetObject *so, GsfXMLIn *xin, xmlChar const **attrs)
 
1254
sheet_widget_adjustment_prep_sax_parser (SheetObject *so, GsfXMLIn *xin,
 
1255
                                         xmlChar const **attrs,
 
1256
                                         GnmConventions const *convs)
1069
1257
{
1070
1258
        SheetWidgetAdjustment *swa = SHEET_WIDGET_ADJUSTMENT (so);
1071
 
        double tmp;
1072
 
 
1073
 
        for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
 
1259
        SheetWidgetAdjustmentClass *swa_class = SWA_CLASS (so);
 
1260
        swa->horizontal = (swa_class->vtype == G_TYPE_NONE);
 
1261
 
 
1262
        for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2) {
 
1263
                double tmp;
 
1264
                gboolean b;
 
1265
 
1074
1266
                if (gnm_xml_attr_double (attrs, "Min", &tmp))
1075
1267
                        swa->adjustment->lower = tmp;
1076
1268
                else if (gnm_xml_attr_double (attrs, "Max", &tmp))
1081
1273
                        swa->adjustment->page_increment = tmp;
1082
1274
                else if (gnm_xml_attr_double (attrs, "Value", &tmp))
1083
1275
                        swa->adjustment->value = tmp;
1084
 
                else if (sax_read_dep (attrs, "Input", &swa->dep, xin))
 
1276
                else if (sax_read_dep (attrs, "Input", &swa->dep, xin, convs))
1085
1277
                        ;
 
1278
                else if (swa_class->htype != G_TYPE_NONE &&
 
1279
                         swa_class->vtype != G_TYPE_NONE &&
 
1280
                         gnm_xml_attr_bool (attrs, "Horizontal", &b))
 
1281
                        swa->horizontal = b;
 
1282
        }
1086
1283
 
1087
1284
        swa->dep.flags = adjustment_get_dep_type ();
1088
1285
        gtk_adjustment_changed  (swa->adjustment);
1094
1291
                                      xmlNodePtr tree)
1095
1292
{
1096
1293
        SheetWidgetAdjustment *swa = SHEET_WIDGET_ADJUSTMENT (so);
 
1294
        SheetWidgetAdjustmentClass *swa_class = SWA_CLASS (so);
1097
1295
        double tmp;
 
1296
        gboolean b;
 
1297
 
 
1298
        swa->horizontal = (swa_class->vtype == G_TYPE_NONE);
1098
1299
 
1099
1300
        read_dep (&swa->dep, "Input", tree, context);
1100
1301
        swa->dep.flags = adjustment_get_dep_type ();
1109
1310
                swa->adjustment->page_increment = tmp;
1110
1311
        if (xml_node_get_double  (tree, "Value", &tmp))
1111
1312
                swa->adjustment->value = tmp;
 
1313
        if (swa_class->htype != G_TYPE_NONE &&
 
1314
            swa_class->vtype != G_TYPE_NONE &&
 
1315
            xml_node_get_bool (tree, "Horizontal", &b))
 
1316
                swa->horizontal = b;
 
1317
 
1112
1318
        gtk_adjustment_changed  (swa->adjustment);
1113
1319
 
1114
1320
        return FALSE;
1143
1349
SOW_MAKE_TYPE (adjustment, Adjustment,
1144
1350
               sheet_widget_adjustment_user_config,
1145
1351
               sheet_widget_adjustment_set_sheet,
1146
 
               sheet_widget_adjustment_clear_sheet,
 
1352
               so_clear_sheet,
1147
1353
               sheet_widget_adjustment_foreach_dep,
1148
1354
               sheet_widget_adjustment_copy,
1149
1355
               sheet_widget_adjustment_read_xml_dom,
1150
1356
               sheet_widget_adjustment_write_xml_sax,
1151
1357
               sheet_widget_adjustment_prep_sax_parser,
1152
 
               NULL,
1153
 
               NULL,
1154
 
               {})
 
1358
               sheet_widget_adjustment_get_property,
 
1359
               sheet_widget_adjustment_set_property,
 
1360
               {
 
1361
                       g_object_class_install_property
 
1362
                               (object_class, SWA_PROP_HORIZONTAL,
 
1363
                                g_param_spec_boolean ("horizontal", NULL, NULL,
 
1364
                                                      FALSE,
 
1365
                                                      GSF_PARAM_STATIC | G_PARAM_READWRITE));
 
1366
               })
1155
1367
 
1156
1368
/****************************************************************************/
1157
1369
#define SHEET_WIDGET_SCROLLBAR_TYPE     (sheet_widget_scrollbar_get_type ())
1158
1370
#define SHEET_WIDGET_SCROLLBAR(obj)     (G_TYPE_CHECK_INSTANCE_CAST((obj), SHEET_WIDGET_SCROLLBAR_TYPE, SheetWidgetScrollbar))
1159
1371
#define DEP_TO_SCROLLBAR(d_ptr)         (SheetWidgetScrollbar *)(((char *)d_ptr) - G_STRUCT_OFFSET(SheetWidgetScrollbar, dep))
1160
1372
 
1161
 
typedef SheetWidgetAdjustment           SheetWidgetScrollbar;
1162
 
typedef SheetWidgetAdjustmentClass      SheetWidgetScrollbarClass;
 
1373
typedef SheetWidgetAdjustment  SheetWidgetScrollbar;
 
1374
typedef SheetWidgetAdjustmentClass SheetWidgetScrollbarClass;
1163
1375
 
1164
1376
static GtkWidget *
1165
1377
sheet_widget_scrollbar_create_widget (SheetObjectWidget *sow)
1166
1378
{
1167
 
        SheetObject *so = SHEET_OBJECT (sow);
1168
1379
        SheetWidgetAdjustment *swa = SHEET_WIDGET_ADJUSTMENT (sow);
1169
1380
        GtkWidget *bar;
1170
1381
 
1171
 
        /* TODO : this is not exactly accurate, but should catch the worst of it
1172
 
         * However we do not have a way to handle resizes.
1173
 
         */
1174
 
        gboolean is_horizontal = range_width (&so->anchor.cell_bound) > range_height (&so->anchor.cell_bound);
1175
 
 
1176
1382
        swa->being_updated = TRUE;
1177
 
        bar = is_horizontal
 
1383
        bar = swa->horizontal
1178
1384
                ? gtk_hscrollbar_new (swa->adjustment)
1179
1385
                : gtk_vscrollbar_new (swa->adjustment);
1180
1386
        GTK_WIDGET_UNSET_FLAGS (bar, GTK_CAN_FOCUS);
1187
1393
}
1188
1394
 
1189
1395
static void
 
1396
sheet_widget_scrollbar_user_config (SheetObject *so, SheetControl *sc)
 
1397
{
 
1398
        sheet_widget_adjustment_user_config_impl (so, sc, N_("Configure Scrollbar"),
 
1399
                                                  N_("Scrollbar Properties"));
 
1400
}
 
1401
 
 
1402
static void
1190
1403
sheet_widget_scrollbar_class_init (SheetObjectWidgetClass *sow_class)
1191
1404
{
 
1405
        SheetWidgetAdjustmentClass *swa_class = (SheetWidgetAdjustmentClass *)sow_class;
 
1406
 
1192
1407
        sow_class->create_widget = &sheet_widget_scrollbar_create_widget;
 
1408
        SHEET_OBJECT_CLASS (sow_class)->user_config = &sheet_widget_scrollbar_user_config;
 
1409
        swa_class->htype = GTK_TYPE_HSCROLLBAR;
 
1410
        swa_class->vtype = GTK_TYPE_VSCROLLBAR;
1193
1411
}
1194
1412
 
1195
1413
GSF_CLASS (SheetWidgetScrollbar, sheet_widget_scrollbar,
1196
1414
           &sheet_widget_scrollbar_class_init, NULL,
1197
 
           SHEET_WIDGET_ADJUSTMENT_TYPE);
 
1415
           SHEET_WIDGET_ADJUSTMENT_TYPE)
1198
1416
 
1199
1417
/****************************************************************************/
1200
1418
#define SHEET_WIDGET_SPINBUTTON_TYPE    (sheet_widget_spinbutton_get_type ())
1222
1440
}
1223
1441
 
1224
1442
static void
 
1443
sheet_widget_spinbutton_user_config (SheetObject *so, SheetControl *sc)
 
1444
{
 
1445
           sheet_widget_adjustment_user_config_impl (so, sc, N_("Configure Spinbutton"),
 
1446
                                                     N_("Spinbutton Properties"));
 
1447
}
 
1448
 
 
1449
static void
1225
1450
sheet_widget_spinbutton_class_init (SheetObjectWidgetClass *sow_class)
1226
1451
{
 
1452
        SheetWidgetAdjustmentClass *swa_class = (SheetWidgetAdjustmentClass *)sow_class;
 
1453
 
1227
1454
        sow_class->create_widget = &sheet_widget_spinbutton_create_widget;
 
1455
        SHEET_OBJECT_CLASS (sow_class)->user_config = &sheet_widget_spinbutton_user_config;
 
1456
 
 
1457
        swa_class->htype = GTK_TYPE_SPIN_BUTTON;
 
1458
        swa_class->vtype = G_TYPE_NONE;
1228
1459
}
1229
1460
 
1230
1461
GSF_CLASS (SheetWidgetSpinbutton, sheet_widget_spinbutton,
1231
1462
           &sheet_widget_spinbutton_class_init, NULL,
1232
 
           SHEET_WIDGET_ADJUSTMENT_TYPE);
 
1463
           SHEET_WIDGET_ADJUSTMENT_TYPE)
1233
1464
 
1234
1465
/****************************************************************************/
1235
1466
#define SHEET_WIDGET_SLIDER_TYPE        (sheet_widget_slider_get_type ())
1242
1473
static GtkWidget *
1243
1474
sheet_widget_slider_create_widget (SheetObjectWidget *sow)
1244
1475
{
1245
 
        SheetObject *so = SHEET_OBJECT (sow);
1246
1476
        SheetWidgetAdjustment *swa = SHEET_WIDGET_ADJUSTMENT (sow);
1247
1477
        GtkWidget *slider;
1248
 
        /* TODO : this is not exactly accurate, but should catch the worst of it
1249
 
         * However we do not have a way to handle resizes.
1250
 
         */
1251
 
        gboolean is_horizontal = range_width (&so->anchor.cell_bound) > range_height (&so->anchor.cell_bound);
1252
1478
 
1253
1479
        swa->being_updated = TRUE;
1254
 
        slider = is_horizontal
 
1480
        slider = swa->horizontal
1255
1481
                ? gtk_hscale_new (swa->adjustment)
1256
1482
                : gtk_vscale_new (swa->adjustment);
1257
1483
        gtk_scale_set_draw_value (GTK_SCALE (slider), FALSE);
1265
1491
}
1266
1492
 
1267
1493
static void
 
1494
sheet_widget_slider_user_config (SheetObject *so, SheetControl *sc)
 
1495
{
 
1496
           sheet_widget_adjustment_user_config_impl (so, sc, N_("Configure Slider"),
 
1497
                           N_("Slider Properties"));
 
1498
}
 
1499
 
 
1500
static void
1268
1501
sheet_widget_slider_class_init (SheetObjectWidgetClass *sow_class)
1269
1502
{
 
1503
        SheetWidgetAdjustmentClass *swa_class = (SheetWidgetAdjustmentClass *)sow_class;
 
1504
 
1270
1505
        sow_class->create_widget = &sheet_widget_slider_create_widget;
 
1506
        SHEET_OBJECT_CLASS (sow_class)->user_config = &sheet_widget_slider_user_config;
 
1507
 
 
1508
        swa_class->htype = GTK_TYPE_HSCALE;
 
1509
        swa_class->vtype = GTK_TYPE_VSCALE;
1271
1510
}
1272
1511
 
1273
1512
GSF_CLASS (SheetWidgetSlider, sheet_widget_slider,
1274
1513
           &sheet_widget_slider_class_init, NULL,
1275
 
           SHEET_WIDGET_ADJUSTMENT_TYPE);
 
1514
           SHEET_WIDGET_ADJUSTMENT_TYPE)
1276
1515
 
1277
1516
/****************************************************************************/
1278
1517
#define SHEET_WIDGET_CHECKBOX_TYPE      (sheet_widget_checkbox_get_type ())
1323
1562
        switch (param_id) {
1324
1563
        case SOC_PROP_TEXT:
1325
1564
                sheet_widget_checkbox_set_label (SHEET_OBJECT (swc),
1326
 
                                               g_value_get_string (value));
 
1565
                                                 g_value_get_string (value));
1327
1566
                break;
1328
1567
        case SOC_PROP_MARKUP:
1329
1568
#if 0
1376
1615
static void
1377
1616
checkbox_debug_name (GnmDependent const *dep, GString *target)
1378
1617
{
1379
 
        g_string_append_printf (target, "Checkbox%p", dep);
 
1618
        g_string_append_printf (target, "Checkbox%p", (void *)dep);
1380
1619
}
1381
1620
 
1382
1621
static DEPENDENT_MAKE_TYPE (checkbox, NULL)
1420
1659
        sheet_object_widget_class->finalize (obj);
1421
1660
}
1422
1661
 
1423
 
static GnmCellRef *
1424
 
sheet_widget_checkbox_get_ref (SheetWidgetCheckbox const *swc,
1425
 
                               GnmCellRef *res, gboolean force_sheet)
1426
 
{
1427
 
        GnmValue *target;
1428
 
        g_return_val_if_fail (swc != NULL, NULL);
1429
 
 
1430
 
        if (swc->dep.texpr == NULL)
1431
 
                return NULL;
1432
 
 
1433
 
        target = gnm_expr_top_get_range (swc->dep.texpr);
1434
 
        if (target == NULL)
1435
 
                return NULL;
1436
 
 
1437
 
        *res = target->v_range.cell.a;
1438
 
        value_release (target);
1439
 
 
1440
 
        if (force_sheet && res->sheet == NULL)
1441
 
                res->sheet = sheet_object_get_sheet (SHEET_OBJECT (swc));
1442
 
        return res;
1443
 
}
1444
 
 
1445
1662
static void
1446
1663
cb_checkbox_toggled (GtkToggleButton *button, SheetWidgetCheckbox *swc)
1447
1664
{
1452
1669
        swc->value = gtk_toggle_button_get_active (button);
1453
1670
        sheet_widget_checkbox_set_active (swc);
1454
1671
 
1455
 
        if (sheet_widget_checkbox_get_ref (swc, &ref, TRUE) != NULL) {
 
1672
        if (so_get_ref (SHEET_OBJECT (swc), &ref, TRUE) != NULL) {
1456
1673
                gboolean new_val = gtk_toggle_button_get_active (button);
1457
1674
                cmd_so_set_value (widget_wbc (GTK_WIDGET (button)),
1458
1675
                                  /* FIXME: This text sucks:  */
1459
1676
                                  _("Clicking checkbox"),
1460
 
                                  &ref, value_new_bool (new_val));
 
1677
                                  &ref, value_new_bool (new_val),
 
1678
                                  sheet_object_get_sheet (SHEET_OBJECT (swc)));
1461
1679
        }
1462
1680
}
1463
1681
 
1473
1691
        GTK_WIDGET_UNSET_FLAGS (button, GTK_CAN_FOCUS);
1474
1692
        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), swc->value);
1475
1693
        g_signal_connect (G_OBJECT (button),
1476
 
                "toggled",
1477
 
                G_CALLBACK (cb_checkbox_toggled), swc);
 
1694
                          "toggled",
 
1695
                          G_CALLBACK (cb_checkbox_toggled), swc);
1478
1696
 
1479
1697
        return button;
1480
1698
}
1486
1704
        SheetWidgetCheckbox       *dst_swc = SHEET_WIDGET_CHECKBOX (dst);
1487
1705
        GnmCellRef ref;
1488
1706
        sheet_widget_checkbox_init_full (dst_swc,
1489
 
                sheet_widget_checkbox_get_ref (src_swc, &ref, FALSE),
1490
 
                src_swc->label);
 
1707
                                         so_get_ref (src, &ref, FALSE),
 
1708
                                         src_swc->label);
1491
1709
        dst_swc->value = src_swc->value;
1492
1710
}
1493
1711
 
1551
1769
        GnmExprTop const *texpr = gnm_expr_entry_parse (state->expression,
1552
1770
                parse_pos_init_sheet (&pp, so->sheet),
1553
1771
                NULL, FALSE, GNM_EXPR_PARSE_DEFAULT);
1554
 
        if (texpr != NULL) {
1555
 
                dependent_set_expr (&state->swc->dep, texpr);
1556
 
                dependent_link (&state->swc->dep);
1557
 
                gnm_expr_top_unref (texpr);
1558
 
        }
 
1772
        gchar const *text = gtk_entry_get_text(GTK_ENTRY(state->label));
 
1773
 
 
1774
        cmd_so_set_checkbox (WORKBOOK_CONTROL (state->wbcg), so,
 
1775
                             texpr, g_strdup (state->old_label), g_strdup (text));
1559
1776
 
1560
1777
        gtk_widget_destroy (state->dialog);
1561
1778
}
1662
1879
        return FALSE;
1663
1880
}
1664
1881
 
1665
 
static gboolean
1666
 
sheet_widget_checkbox_clear_sheet (SheetObject *so)
1667
 
{
1668
 
        SheetWidgetCheckbox *swc = SHEET_WIDGET_CHECKBOX (so);
1669
 
 
1670
 
        if (dependent_is_linked (&swc->dep))
1671
 
                dependent_unlink (&swc->dep);
1672
 
        swc->dep.sheet = NULL;
1673
 
        return FALSE;
1674
 
}
1675
 
 
1676
1882
static void
1677
1883
sheet_widget_checkbox_foreach_dep (SheetObject *so,
1678
1884
                                   SheetObjectForeachDepFunc func,
1683
1889
}
1684
1890
 
1685
1891
static void
1686
 
sheet_widget_checkbox_write_xml_sax (SheetObject const *so, GsfXMLOut *output)
 
1892
sheet_widget_checkbox_write_xml_sax (SheetObject const *so, GsfXMLOut *output,
 
1893
                                     GnmConventions const *convs)
1687
1894
{
1688
1895
        SheetWidgetCheckbox const *swc = SHEET_WIDGET_CHECKBOX (so);
1689
1896
 
1690
1897
        gsf_xml_out_add_cstr (output, "Label", swc->label);
1691
1898
        gsf_xml_out_add_int (output, "Value", swc->value);
1692
 
        sax_write_dep (output, &swc->dep, "Input");
 
1899
        sax_write_dep (output, &swc->dep, "Input", convs);
1693
1900
}
1694
1901
 
1695
1902
static void
1696
 
sheet_widget_checkbox_prep_sax_parser (SheetObject *so, GsfXMLIn *xin, xmlChar const **attrs)
 
1903
sheet_widget_checkbox_prep_sax_parser (SheetObject *so, GsfXMLIn *xin,
 
1904
                                       xmlChar const **attrs,
 
1905
                                       GnmConventions const *convs)
1697
1906
{
1698
1907
        SheetWidgetCheckbox *swc = SHEET_WIDGET_CHECKBOX (so);
1699
1908
 
1703
1912
                        swc->label = g_strdup (CXML2C (attrs[1]));
1704
1913
                } else if (gnm_xml_attr_int (attrs, "Value", &swc->value))
1705
1914
                        ; /* ??? */
1706
 
                else if (sax_read_dep (attrs, "Input", &swc->dep, xin))
 
1915
                else if (sax_read_dep (attrs, "Input", &swc->dep, xin, convs))
1707
1916
                        ; /* ??? */
1708
1917
}
1709
1918
 
1713
1922
                                    xmlNodePtr tree)
1714
1923
{
1715
1924
        SheetWidgetCheckbox *swc = SHEET_WIDGET_CHECKBOX (so);
1716
 
        gchar *label = (gchar *)xmlGetProp (tree, (xmlChar *)"Label");
 
1925
        xmlChar *label = xmlGetProp (tree, CC2XML ("Label"));
1717
1926
 
1718
1927
        if (!label) {
1719
1928
                g_warning ("Could not read a CheckBoxWidget object because it lacks a label property");
1720
1929
                return TRUE;
1721
1930
        }
1722
1931
 
1723
 
        swc->label = g_strdup (label);
 
1932
        swc->label = g_strdup (CC2XML (label));
1724
1933
        xmlFree (label);
1725
1934
 
1726
1935
        read_dep (&swc->dep, "Input", tree, context);
1739
1948
                dependent_link (&swc->dep);
1740
1949
}
1741
1950
 
 
1951
GnmExprTop const *
 
1952
sheet_widget_checkbox_get_link   (SheetObject *so)
 
1953
{
 
1954
        SheetWidgetCheckbox *swc = SHEET_WIDGET_CHECKBOX (so);
 
1955
        GnmExprTop const *texpr = swc->dep.texpr;
 
1956
 
 
1957
        if (texpr)
 
1958
                gnm_expr_top_ref (texpr);
 
1959
 
 
1960
        return texpr;
 
1961
}
 
1962
 
 
1963
 
1742
1964
void
1743
1965
sheet_widget_checkbox_set_label (SheetObject *so, char const *str)
1744
1966
{
1763
1985
SOW_MAKE_TYPE (checkbox, Checkbox,
1764
1986
               sheet_widget_checkbox_user_config,
1765
1987
               sheet_widget_checkbox_set_sheet,
1766
 
               sheet_widget_checkbox_clear_sheet,
 
1988
               so_clear_sheet,
1767
1989
               sheet_widget_checkbox_foreach_dep,
1768
1990
               sheet_widget_checkbox_copy,
1769
1991
               sheet_widget_checkbox_read_xml_dom,
1805
2027
 
1806
2028
GSF_CLASS (SheetWidgetToggleButton, sheet_widget_toggle_button,
1807
2029
           &sheet_widget_toggle_button_class_init, NULL,
1808
 
           SHEET_WIDGET_CHECKBOX_TYPE);
 
2030
           SHEET_WIDGET_CHECKBOX_TYPE)
 
2031
 
1809
2032
/****************************************************************************/
1810
2033
 
1811
2034
#define SHEET_WIDGET_RADIO_BUTTON_TYPE  (sheet_widget_radio_button_get_type ())
1843
2066
static void
1844
2067
radio_button_debug_name (GnmDependent const *dep, GString *target)
1845
2068
{
1846
 
        g_string_append_printf (target, "RadioButton%p", dep);
 
2069
        g_string_append_printf (target, "RadioButton%p", (void *)dep);
1847
2070
}
1848
2071
 
1849
2072
static DEPENDENT_MAKE_TYPE (radio_button, NULL)
1888
2111
static GtkWidget *
1889
2112
sheet_widget_radio_button_create_widget (SheetObjectWidget *sow)
1890
2113
{
1891
 
        GtkWidget *w = gtk_radio_button_new_with_label (NULL, "RadioButton");
 
2114
        SheetWidgetRadioButton *swrb = SHEET_WIDGET_RADIO_BUTTON (sow);
 
2115
        /* FIXME: NULL group?  */
 
2116
        GtkWidget *w = gtk_radio_button_new_with_label (NULL,
 
2117
                                                        swrb->label);
1892
2118
        g_signal_connect (G_OBJECT (w),
1893
 
                "toggled",
1894
 
                G_CALLBACK (sheet_widget_radio_button_toggled), sow);
 
2119
                          "toggled",
 
2120
                          G_CALLBACK (sheet_widget_radio_button_toggled), sow);
1895
2121
        return w;
1896
2122
}
1897
2123
 
1905
2131
        return FALSE;
1906
2132
}
1907
2133
 
1908
 
static gboolean
1909
 
sheet_widget_radio_button_clear_sheet (SheetObject *so)
1910
 
{
1911
 
        SheetWidgetRadioButton *swrb = SHEET_WIDGET_RADIO_BUTTON (so);
1912
 
 
1913
 
        g_return_val_if_fail (swrb != NULL, TRUE);
1914
 
 
1915
 
        if (dependent_is_linked (&swrb->dep))
1916
 
                dependent_unlink (&swrb->dep);
1917
 
        swrb->dep.sheet = NULL;
1918
 
        return FALSE;
1919
 
}
1920
 
 
1921
2134
static void
1922
2135
sheet_widget_radio_button_foreach_dep (SheetObject *so,
1923
2136
                                       SheetObjectForeachDepFunc func,
1961
2174
        SheetWidgetRadioButton *swrb = SHEET_WIDGET_RADIO_BUTTON (obj);
1962
2175
 
1963
2176
        switch (param_id) {
1964
 
        case SOC_PROP_TEXT:
 
2177
        case SOR_PROP_TEXT:
1965
2178
                g_value_set_string (value, swrb->label);
1966
2179
                break;
1967
 
        case SOC_PROP_MARKUP:
 
2180
        case SOR_PROP_MARKUP:
1968
2181
                g_value_set_boxed (value, NULL); /* swrb->markup */
1969
2182
                break;
1970
2183
        default :
1980
2193
        SheetWidgetRadioButton *swrb = SHEET_WIDGET_RADIO_BUTTON (obj);
1981
2194
 
1982
2195
        switch (param_id) {
1983
 
        case SOC_PROP_TEXT:
 
2196
        case SOR_PROP_TEXT:
1984
2197
                sheet_widget_radio_button_set_label (SHEET_OBJECT (swrb),
1985
 
                        g_value_get_string (value));
 
2198
                                                     g_value_get_string (value));
1986
2199
                break;
1987
 
        case SOC_PROP_MARKUP:
 
2200
        case SOR_PROP_MARKUP:
1988
2201
#if 0
1989
 
                sheet_widget_radio_button_set_markup (SHEET_OBJECT (swc),
1990
 
                        g_value_peek_pointer (value));
 
2202
                sheet_widget_radio_button_set_markup (SHEET_OBJECT (swrb),
 
2203
                                                      g_value_peek_pointer (value));
1991
2204
#endif
1992
2205
                break;
1993
2206
        default:
1999
2212
SOW_MAKE_TYPE (radio_button, RadioButton,
2000
2213
               NULL,
2001
2214
               sheet_widget_radio_button_set_sheet,
2002
 
               sheet_widget_radio_button_clear_sheet,
 
2215
               so_clear_sheet,
2003
2216
               sheet_widget_radio_button_foreach_dep,
2004
2217
               NULL,
2005
2218
               NULL,
2013
2226
                                g_param_spec_string ("text", NULL, NULL, NULL,
2014
2227
                                                     GSF_PARAM_STATIC | G_PARAM_READWRITE));
2015
2228
                       g_object_class_install_property
2016
 
                               (object_class, SOC_PROP_MARKUP,
 
2229
                               (object_class, SOR_PROP_MARKUP,
2017
2230
                                g_param_spec_boxed ("markup", NULL, NULL, PANGO_TYPE_ATTR_LIST,
2018
2231
                                                    GSF_PARAM_STATIC | G_PARAM_READWRITE));
2019
2232
               })
2049
2262
static guint list_base_signals [LIST_BASE_LAST_SIGNAL] = { 0 };
2050
2263
static GType sheet_widget_list_base_get_type (void);
2051
2264
 
2052
 
static GnmCellRef *
2053
 
sheet_widget_list_base_get_ref (SheetWidgetListBase const *swl,
2054
 
                                GnmCellRef *res, gboolean force_sheet)
2055
 
{
2056
 
        GnmValue *target;
2057
 
 
2058
 
        g_return_val_if_fail (swl != NULL, NULL);
2059
 
 
2060
 
        if (swl->output_dep.texpr == NULL)
2061
 
                return NULL;
2062
 
 
2063
 
        target = gnm_expr_top_get_range (swl->output_dep.texpr);
2064
 
        if (target == NULL)
2065
 
                return NULL;
2066
 
 
2067
 
        *res = target->v_range.cell.a;
2068
 
        value_release (target);
2069
 
 
2070
 
        if (force_sheet && res->sheet == NULL)
2071
 
                res->sheet = sheet_object_get_sheet (SHEET_OBJECT (swl));
2072
 
        return res;
2073
 
}
2074
 
 
2075
2265
static void
2076
2266
sheet_widget_list_base_set_selection (SheetWidgetListBase *swl, int selection,
2077
2267
                                      WorkbookControl *wbc)
2088
2278
        if (swl->selection != selection) {
2089
2279
                swl->selection = selection;
2090
2280
                if (NULL!= wbc &&
2091
 
                    sheet_widget_list_base_get_ref (swl, &ref, TRUE) != NULL)
 
2281
                    so_get_ref (SHEET_OBJECT (swl), &ref, TRUE) != NULL)
2092
2282
                        cmd_so_set_value (wbc,
2093
2283
                                _("Clicking in list"),
2094
 
                                &ref, value_new_int (swl->selection));
 
2284
                                          &ref, value_new_int (swl->selection),
 
2285
                                          sheet_object_get_sheet (SHEET_OBJECT (swl)));
2095
2286
 
2096
2287
                g_signal_emit (G_OBJECT (swl),
2097
2288
                        list_base_signals [LIST_BASE_SELECTION_CHANGED], 0);
2113
2304
static void
2114
2305
list_output_debug_name (GnmDependent const *dep, GString *target)
2115
2306
{
2116
 
        g_string_append_printf (target, "ListOutput%p", dep);
 
2307
        g_string_append_printf (target, "ListOutput%p", (void *)dep);
2117
2308
}
2118
2309
 
2119
2310
static DEPENDENT_MAKE_TYPE (list_output, NULL)
2141
2332
{
2142
2333
        SheetWidgetListBase *swl = DEP_TO_LIST_BASE_CONTENT (dep);
2143
2334
        GnmEvalPos ep;
2144
 
        GnmValue *v = gnm_expr_top_eval (dep->texpr,
2145
 
                eval_pos_init_dep (&ep, dep),
2146
 
                GNM_EXPR_EVAL_PERMIT_NON_SCALAR | GNM_EXPR_EVAL_PERMIT_EMPTY);
 
2335
        GnmValue *v = NULL;
2147
2336
        GtkListStore *model;
2148
2337
 
2149
 
        if (NULL == v)
2150
 
                return;
 
2338
        if (dep->texpr != NULL) {
 
2339
                v = gnm_expr_top_eval (dep->texpr,
 
2340
                                       eval_pos_init_dep (&ep, dep),
 
2341
                                       GNM_EXPR_EVAL_PERMIT_NON_SCALAR |
 
2342
                                       GNM_EXPR_EVAL_PERMIT_EMPTY);
 
2343
        }
2151
2344
        model = gtk_list_store_new (1, G_TYPE_STRING);
2152
 
        value_area_foreach (v, &ep, CELL_ITER_ALL,
2153
 
                 (GnmValueIterFunc) cb_collect, model);
2154
 
        value_release (v);
 
2345
        if ((dep != NULL) && (v != NULL)) {
 
2346
                value_area_foreach (v, &ep, CELL_ITER_ALL,
 
2347
                                    (GnmValueIterFunc) cb_collect, model);
 
2348
                value_release (v);
 
2349
        }
2155
2350
 
2156
2351
        if (NULL != swl->model)
2157
2352
                g_object_unref (G_OBJECT (swl->model));
2162
2357
static void
2163
2358
list_content_debug_name (GnmDependent const *dep, GString *target)
2164
2359
{
2165
 
        g_string_append_printf (target, "ListContent%p", dep);
 
2360
        g_string_append_printf (target, "ListContent%p", (void *)dep);
2166
2361
}
2167
2362
 
2168
2363
static DEPENDENT_MAKE_TYPE (list_content, NULL)
2217
2412
        return FALSE;
2218
2413
}
2219
2414
 
2220
 
static gboolean
2221
 
sheet_widget_list_base_clear_sheet (SheetObject *so)
2222
 
{
2223
 
        SheetWidgetListBase *swl = SHEET_WIDGET_LIST_BASE (so);
2224
 
 
2225
 
        g_return_val_if_fail (swl != NULL, TRUE);
2226
 
 
2227
 
        if (dependent_is_linked (&swl->content_dep))
2228
 
                dependent_unlink (&swl->content_dep);
2229
 
        if (dependent_is_linked (&swl->output_dep))
2230
 
                dependent_unlink (&swl->output_dep);
2231
 
        swl->content_dep.sheet = swl->output_dep.sheet = NULL;
2232
 
        return FALSE;
2233
 
}
2234
 
 
2235
2415
static void
2236
2416
sheet_widget_list_base_foreach_dep (SheetObject *so,
2237
2417
                                    SheetObjectForeachDepFunc func,
2243
2423
}
2244
2424
 
2245
2425
static void
2246
 
sheet_widget_list_base_write_xml_sax (SheetObject const *so, GsfXMLOut *output)
 
2426
sheet_widget_list_base_write_xml_sax (SheetObject const *so, GsfXMLOut *output,
 
2427
                                      GnmConventions const *convs)
2247
2428
{
2248
2429
        SheetWidgetListBase const *swl = SHEET_WIDGET_LIST_BASE (so);
2249
 
        sax_write_dep (output, &swl->content_dep, "Content");
2250
 
        sax_write_dep (output, &swl->output_dep, "Output");
 
2430
        sax_write_dep (output, &swl->content_dep, "Content", convs);
 
2431
        sax_write_dep (output, &swl->output_dep, "Output", convs);
2251
2432
}
2252
2433
 
2253
2434
static void
2254
 
sheet_widget_list_base_prep_sax_parser (SheetObject *so, GsfXMLIn *xin, xmlChar const **attrs)
 
2435
sheet_widget_list_base_prep_sax_parser (SheetObject *so, GsfXMLIn *xin,
 
2436
                                        xmlChar const **attrs,
 
2437
                                        GnmConventions const *convs)
2255
2438
{
2256
2439
        SheetWidgetListBase *swl = SHEET_WIDGET_LIST_BASE (so);
2257
2440
 
2258
2441
        for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
2259
 
                if (sax_read_dep (attrs, "Content", &swl->content_dep, xin)) ;
2260
 
                else if (sax_read_dep (attrs, "Output", &swl->output_dep, xin)) ;
 
2442
                if (sax_read_dep (attrs, "Content", &swl->content_dep, xin, convs)) ;
 
2443
                else if (sax_read_dep (attrs, "Output", &swl->output_dep, xin, convs)) ;
2261
2444
}
2262
2445
 
2263
2446
static gboolean
2285
2468
SOW_MAKE_TYPE (list_base, ListBase,
2286
2469
               sheet_widget_list_base_user_config,
2287
2470
               sheet_widget_list_base_set_sheet,
2288
 
               sheet_widget_list_base_clear_sheet,
 
2471
               so_clear_sheet,
2289
2472
               sheet_widget_list_base_foreach_dep,
2290
2473
               NULL,
2291
2474
               sheet_widget_list_base_read_xml_dom,
2320
2503
        if (NULL != output)
2321
2504
                dependent_link (&swl->output_dep);
2322
2505
        dependent_set_expr (&swl->content_dep, content);
2323
 
        if (NULL != content) {
 
2506
        if (NULL != content)
2324
2507
                dependent_link (&swl->content_dep);
2325
 
                list_content_eval (&swl->content_dep); /* populate the list */
2326
 
        }
 
2508
        list_content_eval (&swl->content_dep); /* populate the list */
2327
2509
}
 
2510
 
2328
2511
GnmDependent const *
2329
2512
sheet_widget_list_base_get_result_dep  (SheetObject const *so)
2330
2513
{
2423
2606
 
2424
2607
GSF_CLASS (SheetWidgetList, sheet_widget_list,
2425
2608
           &sheet_widget_list_class_init, NULL,
2426
 
           SHEET_WIDGET_LIST_BASE_TYPE);
 
2609
           SHEET_WIDGET_LIST_BASE_TYPE)
2427
2610
 
2428
2611
/****************************************************************************/
2429
2612
#define SHEET_WIDGET_COMBO_TYPE (sheet_widget_combo_get_type ())
2498
2681
 
2499
2682
GSF_CLASS (SheetWidgetCombo, sheet_widget_combo,
2500
2683
           &sheet_widget_combo_class_init, NULL,
2501
 
           SHEET_WIDGET_LIST_BASE_TYPE);
 
2684
           SHEET_WIDGET_LIST_BASE_TYPE)
 
2685
 
2502
2686
/**************************************************************************/
2503
2687
 
2504
2688
/**