~valavanisalex/ubuntu/precise/inkscape/fix-943984

« back to all changes in this revision

Viewing changes to inkscape-0.47pre1/src/helper/unit-menu.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Bryce Harrington
  • Date: 2009-07-02 17:09:45 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20090702170945-nn6d6zswovbwju1t
Tags: 0.47~pre1-0ubuntu1
* New upstream release.
  - Don't constrain maximization on small resolution devices (pre0)
    (LP: #348842)
  - Fixes segfault on startup (pre0)
    (LP: #391149)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#define __SP_UNIT_MENU_C__
 
2
 
 
3
/*
 
4
 * Unit selector with autupdate capability
 
5
 *
 
6
 * Authors:
 
7
 *   Lauris Kaplinski <lauris@kaplinski.com>
 
8
 *   bulia byak <buliabyak@users.sf.net>
 
9
 *
 
10
 * Copyright (C) 2000-2002 Authors
 
11
 *
 
12
 * Released under GNU GPL, read the file 'COPYING' for more information
 
13
 */
 
14
 
 
15
#define noUNIT_SELECTOR_VERBOSE
 
16
 
 
17
#ifdef HAVE_CONFIG_H
 
18
# include "config.h"
 
19
#endif
 
20
#include <gtk/gtksignal.h>
 
21
#include <gtk/gtkhbox.h>
 
22
#include <gtk/gtkmenu.h>
 
23
#include <gtk/gtkmenuitem.h>
 
24
#include "helper/sp-marshal.h"
 
25
#include "helper/units.h"
 
26
#include "helper/unit-menu.h"
 
27
#include "widgets/spw-utilities.h"
 
28
 
 
29
struct SPUnitSelector {
 
30
    GtkHBox box;
 
31
 
 
32
    GtkWidget *menu;
 
33
 
 
34
    guint bases;
 
35
    GSList *units;
 
36
    SPUnit const *unit;
 
37
    gdouble ctmscale;
 
38
    guint plural : 1;
 
39
    guint abbr : 1;
 
40
 
 
41
    guint update : 1;
 
42
 
 
43
    GSList *adjustments;
 
44
};
 
45
 
 
46
struct SPUnitSelectorClass {
 
47
    GtkHBoxClass parent_class;
 
48
 
 
49
    gboolean (* set_unit)(SPUnitSelector *us, SPUnit const *old, SPUnit const *new_unit);
 
50
};
 
51
 
 
52
enum {SET_UNIT, LAST_SIGNAL};
 
53
 
 
54
static void sp_unit_selector_class_init(SPUnitSelectorClass *klass);
 
55
static void sp_unit_selector_init(SPUnitSelector *selector);
 
56
static void sp_unit_selector_finalize(GObject *object);
 
57
 
 
58
static GtkHBoxClass *unit_selector_parent_class;
 
59
static guint signals[LAST_SIGNAL] = {0};
 
60
 
 
61
GType sp_unit_selector_get_type(void)
 
62
{
 
63
    static GType type = 0;
 
64
    if (!type) {
 
65
        GTypeInfo info = {
 
66
            sizeof(SPUnitSelectorClass),
 
67
            0, // base_init
 
68
            0, // base_finalize
 
69
            (GClassInitFunc)sp_unit_selector_class_init,
 
70
            0, // class_finalize
 
71
            0, // class_data
 
72
            sizeof(SPUnitSelector),
 
73
            0, // n_preallocs
 
74
            (GInstanceInitFunc)sp_unit_selector_init,
 
75
            0 // value_table
 
76
        };
 
77
        type = g_type_register_static(GTK_TYPE_HBOX, "SPUnitSelector", &info, static_cast<GTypeFlags>(0));
 
78
    }
 
79
    return type;
 
80
}
 
81
 
 
82
static void
 
83
sp_unit_selector_class_init(SPUnitSelectorClass *klass)
 
84
{
 
85
    GObjectClass *object_class;
 
86
    GtkWidgetClass *widget_class;
 
87
 
 
88
    object_class = G_OBJECT_CLASS(klass);
 
89
    widget_class = GTK_WIDGET_CLASS(klass);
 
90
 
 
91
    unit_selector_parent_class = (GtkHBoxClass*)gtk_type_class(GTK_TYPE_HBOX);
 
92
 
 
93
    signals[SET_UNIT] = g_signal_new("set_unit",
 
94
                                     G_TYPE_FROM_CLASS(klass),
 
95
                                     G_SIGNAL_RUN_LAST,
 
96
                                     G_STRUCT_OFFSET(SPUnitSelectorClass, set_unit),
 
97
                                     NULL, NULL,
 
98
                                     sp_marshal_BOOLEAN__POINTER_POINTER,
 
99
                                     G_TYPE_BOOLEAN, 2,
 
100
                                     G_TYPE_POINTER, G_TYPE_POINTER);
 
101
 
 
102
    object_class->finalize = sp_unit_selector_finalize;
 
103
}
 
104
 
 
105
static void
 
106
sp_unit_selector_init(SPUnitSelector *us)
 
107
{
 
108
    us->ctmscale = 1.0;
 
109
    us->abbr = FALSE;
 
110
    us->plural = TRUE;
 
111
 
 
112
    us->menu = gtk_option_menu_new();
 
113
 
 
114
    gtk_widget_show(us->menu);
 
115
    gtk_box_pack_start(GTK_BOX(us), us->menu, TRUE, TRUE, 0);
 
116
}
 
117
 
 
118
static void
 
119
sp_unit_selector_finalize(GObject *object)
 
120
{
 
121
    SPUnitSelector *selector = SP_UNIT_SELECTOR(object);
 
122
 
 
123
    if (selector->menu) {
 
124
        selector->menu = NULL;
 
125
    }
 
126
 
 
127
    while (selector->adjustments) {
 
128
        gtk_object_unref(GTK_OBJECT(selector->adjustments->data));
 
129
        selector->adjustments = g_slist_remove(selector->adjustments, selector->adjustments->data);
 
130
    }
 
131
 
 
132
    if (selector->units) {
 
133
        sp_unit_free_list(selector->units);
 
134
    }
 
135
 
 
136
    selector->unit = NULL;
 
137
 
 
138
    G_OBJECT_CLASS(unit_selector_parent_class)->finalize(object);
 
139
}
 
140
 
 
141
GtkWidget *
 
142
sp_unit_selector_new(guint bases)
 
143
{
 
144
    SPUnitSelector *us = (SPUnitSelector*)gtk_type_new(SP_TYPE_UNIT_SELECTOR);
 
145
 
 
146
    sp_unit_selector_set_bases(us, bases);
 
147
 
 
148
    return (GtkWidget *) us;
 
149
}
 
150
 
 
151
void
 
152
sp_unit_selector_setsize(GtkWidget *us, guint w, guint h)
 
153
{
 
154
    gtk_widget_set_size_request(((SPUnitSelector *) us)->menu, w, h);
 
155
}
 
156
 
 
157
SPUnit const *
 
158
sp_unit_selector_get_unit(SPUnitSelector const *us)
 
159
{
 
160
    g_return_val_if_fail(us != NULL, NULL);
 
161
    g_return_val_if_fail(SP_IS_UNIT_SELECTOR(us), NULL);
 
162
 
 
163
    return us->unit;
 
164
}
 
165
 
 
166
static void
 
167
spus_unit_activate(GtkWidget *widget, SPUnitSelector *us)
 
168
{
 
169
    SPUnit const *unit = (SPUnit const *) gtk_object_get_data(GTK_OBJECT(widget), "unit");
 
170
    g_return_if_fail(unit != NULL);
 
171
 
 
172
#ifdef UNIT_SELECTOR_VERBOSE
 
173
    g_print("Old unit %s new unit %s\n", us->unit->name, unit->name);
 
174
#endif
 
175
 
 
176
    SPUnit const *old = us->unit;
 
177
    us->unit = unit;
 
178
 
 
179
    us->update = TRUE;
 
180
 
 
181
    gboolean consumed = FALSE;
 
182
    g_signal_emit(G_OBJECT(us), signals[SET_UNIT], 0, old, unit, &consumed);
 
183
 
 
184
    if ( !consumed
 
185
         && ( unit->base == old->base
 
186
              || ( unit->base == SP_UNIT_ABSOLUTE && old->base == SP_UNIT_DEVICE )
 
187
              || ( old->base == SP_UNIT_ABSOLUTE && unit->base == SP_UNIT_DEVICE ) ) ) {
 
188
        // Either the same base, or absolute<->device:
 
189
        /* Recalculate adjustments. */
 
190
        for (GSList *l = us->adjustments; l != NULL; l = g_slist_next(l)) {
 
191
            GtkAdjustment *adj = GTK_ADJUSTMENT(l->data);
 
192
            gdouble val = adj->value;
 
193
#ifdef UNIT_SELECTOR_VERBOSE
 
194
            g_print("Old val %g ... ", val);
 
195
#endif
 
196
            val = sp_convert_distance_full(val, *old, *unit);
 
197
#ifdef UNIT_SELECTOR_VERBOSE
 
198
            g_print("new val %g\n", val);
 
199
#endif
 
200
            adj->value = val;
 
201
        }
 
202
        /* need to separate the value changing from the notification
 
203
         * or else the unit changes can break the calculations */
 
204
        for (GSList *l = us->adjustments; l != NULL; l = g_slist_next(l)) {
 
205
            gtk_adjustment_value_changed(GTK_ADJUSTMENT(l->data));
 
206
        }
 
207
    } else if (!consumed && unit->base != old->base) {
 
208
        /* when the base changes, signal all the adjustments to get them
 
209
         * to recalculate */
 
210
        for (GSList *l = us->adjustments; l != NULL; l = g_slist_next(l)) {
 
211
            gtk_signal_emit_by_name(GTK_OBJECT(l->data), "value_changed");
 
212
        }
 
213
    }
 
214
 
 
215
    us->update = FALSE;
 
216
}
 
217
 
 
218
static void
 
219
spus_rebuild_menu(SPUnitSelector *us)
 
220
{
 
221
    if (GTK_OPTION_MENU(us->menu)->menu) {
 
222
        gtk_option_menu_remove_menu(GTK_OPTION_MENU(us->menu));
 
223
    }
 
224
 
 
225
    GtkWidget *m = gtk_menu_new();
 
226
 
 
227
    gtk_widget_show(m);
 
228
 
 
229
    gint pos = 0;
 
230
    gint p = 0;
 
231
    for (GSList *l = us->units; l != NULL; l = l->next) {
 
232
        SPUnit const *u = (SPUnit*)l->data;
 
233
 
 
234
        // use only abbreviations in the menu
 
235
        //        i = gtk_menu_item_new_with_label((us->abbr) ? (us->plural) ? u->abbr_plural : u->abbr : (us->plural) ? u->plural : u->name);
 
236
        GtkWidget *i = gtk_menu_item_new_with_label( u->abbr );
 
237
 
 
238
        gtk_object_set_data(GTK_OBJECT(i), "unit", (gpointer) u);
 
239
        gtk_signal_connect(GTK_OBJECT(i), "activate", GTK_SIGNAL_FUNC(spus_unit_activate), us);
 
240
 
 
241
        sp_set_font_size_smaller (i);
 
242
 
 
243
        gtk_widget_show(i);
 
244
 
 
245
        gtk_menu_shell_append(GTK_MENU_SHELL(m), i);
 
246
        if (u == us->unit) pos = p;
 
247
        p += 1;
 
248
    }
 
249
 
 
250
    gtk_option_menu_set_menu(GTK_OPTION_MENU(us->menu), m);
 
251
 
 
252
    gtk_option_menu_set_history(GTK_OPTION_MENU(us->menu), pos);
 
253
}
 
254
 
 
255
void
 
256
sp_unit_selector_set_bases(SPUnitSelector *us, guint bases)
 
257
{
 
258
    g_return_if_fail(us != NULL);
 
259
    g_return_if_fail(SP_IS_UNIT_SELECTOR(us));
 
260
 
 
261
    if (bases == us->bases) return;
 
262
 
 
263
    GSList *units = sp_unit_get_list(bases);
 
264
    g_return_if_fail(units != NULL);
 
265
    sp_unit_free_list(us->units);
 
266
    us->units = units;
 
267
    us->unit = (SPUnit*)units->data;
 
268
 
 
269
    spus_rebuild_menu(us);
 
270
}
 
271
 
 
272
void
 
273
sp_unit_selector_add_unit(SPUnitSelector *us, SPUnit const *unit, int position)
 
274
{
 
275
    if (!g_slist_find(us->units, (gpointer) unit)) {
 
276
        us->units = g_slist_insert(us->units, (gpointer) unit, position);
 
277
 
 
278
        spus_rebuild_menu(us);
 
279
    }
 
280
}
 
281
 
 
282
void
 
283
sp_unit_selector_set_unit(SPUnitSelector *us, SPUnit const *unit)
 
284
{
 
285
    g_return_if_fail(us != NULL);
 
286
    g_return_if_fail(SP_IS_UNIT_SELECTOR(us));
 
287
 
 
288
    if (unit == NULL) {
 
289
        return; // silently return, by default a newly created selector uses pt
 
290
    }
 
291
    if (unit == us->unit) {
 
292
        return;
 
293
    }
 
294
 
 
295
    gint const pos = g_slist_index(us->units, (gpointer) unit);
 
296
    g_return_if_fail(pos >= 0);
 
297
 
 
298
    gtk_option_menu_set_history(GTK_OPTION_MENU(us->menu), pos);
 
299
 
 
300
    SPUnit const *old = us->unit;
 
301
    us->unit = unit;
 
302
 
 
303
    /* Recalculate adjustments */
 
304
    for (GSList *l = us->adjustments; l != NULL; l = l->next) {
 
305
        GtkAdjustment *adj = GTK_ADJUSTMENT(l->data);
 
306
        gdouble const val = sp_convert_distance_full(adj->value, *old, *unit);
 
307
        gtk_adjustment_set_value(adj, val);
 
308
    }
 
309
}
 
310
 
 
311
void
 
312
sp_unit_selector_add_adjustment(SPUnitSelector *us, GtkAdjustment *adj)
 
313
{
 
314
    g_return_if_fail(us != NULL);
 
315
    g_return_if_fail(SP_IS_UNIT_SELECTOR(us));
 
316
    g_return_if_fail(adj != NULL);
 
317
    g_return_if_fail(GTK_IS_ADJUSTMENT(adj));
 
318
 
 
319
    g_return_if_fail(!g_slist_find(us->adjustments, adj));
 
320
 
 
321
    gtk_object_ref(GTK_OBJECT(adj));
 
322
    us->adjustments = g_slist_prepend(us->adjustments, adj);
 
323
}
 
324
 
 
325
void
 
326
sp_unit_selector_remove_adjustment(SPUnitSelector *us, GtkAdjustment *adj)
 
327
{
 
328
    g_return_if_fail(us != NULL);
 
329
    g_return_if_fail(SP_IS_UNIT_SELECTOR(us));
 
330
    g_return_if_fail(adj != NULL);
 
331
    g_return_if_fail(GTK_IS_ADJUSTMENT(adj));
 
332
 
 
333
    g_return_if_fail(g_slist_find(us->adjustments, adj));
 
334
 
 
335
    us->adjustments = g_slist_remove(us->adjustments, adj);
 
336
    gtk_object_unref(GTK_OBJECT(adj));
 
337
}
 
338
 
 
339
gboolean
 
340
sp_unit_selector_update_test(SPUnitSelector const *selector)
 
341
{
 
342
    g_return_val_if_fail(selector != NULL, FALSE);
 
343
    g_return_val_if_fail(SP_IS_UNIT_SELECTOR(selector), FALSE);
 
344
 
 
345
    return selector->update;
 
346
}
 
347
 
 
348
double
 
349
sp_unit_selector_get_value_in_pixels(SPUnitSelector const *selector, GtkAdjustment *adj)
 
350
{
 
351
    g_return_val_if_fail(selector != NULL, adj->value);
 
352
    g_return_val_if_fail(SP_IS_UNIT_SELECTOR(selector), adj->value);
 
353
 
 
354
    return sp_units_get_pixels(adj->value, *(selector->unit));
 
355
}
 
356
 
 
357
void
 
358
sp_unit_selector_set_value_in_pixels(SPUnitSelector *selector, GtkAdjustment *adj, double value)
 
359
{
 
360
    g_return_if_fail(selector != NULL);
 
361
    g_return_if_fail(SP_IS_UNIT_SELECTOR(selector));
 
362
 
 
363
    gtk_adjustment_set_value(adj, sp_pixels_get_units(value, *(selector->unit)));
 
364
}
 
365
 
 
366
/*
 
367
  Local Variables:
 
368
  mode:c++
 
369
  c-file-style:"stroustrup"
 
370
  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
 
371
  indent-tabs-mode:nil
 
372
  fill-column:99
 
373
  End:
 
374
*/
 
375
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :