~ubuntu-branches/ubuntu/jaunty/gimp/jaunty-security

« back to all changes in this revision

Viewing changes to app/widgets/gimppropwidgets.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Holbach
  • Date: 2007-05-02 16:33:03 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070502163303-bvzhjzbpw8qglc4y
Tags: 2.3.16-1ubuntu1
* Resynchronized with Debian, remaining Ubuntu changes:
  - debian/rules: i18n magic.
* debian/control.in:
  - Maintainer: Ubuntu Core Developers <ubuntu-devel@lists.ubuntu.com>
* debian/patches/02_help-message.patch,
  debian/patches/03_gimp.desktop.in.in.patch,
  debian/patches/10_dont_show_wizard.patch: updated.
* debian/patches/04_composite-signedness.patch,
  debian/patches/05_add-letter-spacing.patch: dropped, used upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* The GIMP -- an image manipulation program
 
1
/* GIMP - The GNU Image Manipulation Program
2
2
 * Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
3
3
 *
4
4
 * gimppropwidgets.c
23
23
#include "config.h"
24
24
 
25
25
#include <string.h>
 
26
#include <stdlib.h>
26
27
 
27
28
#include <gtk/gtk.h>
28
29
 
29
30
#include "libgimpcolor/gimpcolor.h"
30
31
#include "libgimpmath/gimpmath.h"
31
32
#include "libgimpbase/gimpbase.h"
 
33
#include "libgimpconfig/gimpconfig.h"
32
34
#include "libgimpwidgets/gimpwidgets.h"
33
35
 
34
36
#include "widgets-types.h"
35
37
 
36
 
#include "config/gimpconfig-params.h"
37
 
#include "config/gimpconfig-path.h"
38
 
 
39
38
#include "core/gimpviewable.h"
40
39
 
41
40
#include "gimpcolorpanel.h"
42
41
#include "gimpdnd.h"
43
 
#include "gimpenumcombobox.h"
44
 
#include "gimpenumstore.h"
45
 
#include "gimpenumwidgets.h"
46
42
#include "gimpview.h"
47
43
#include "gimppropwidgets.h"
48
44
#include "gimpwidgets-constructors.h"
 
45
#include "gimpwidgets-utils.h"
49
46
 
50
47
#include "gimp-intl.h"
51
48
 
55
52
static void         set_param_spec     (GObject     *object,
56
53
                                        GtkWidget   *widget,
57
54
                                        GParamSpec  *param_spec);
58
 
static void         set_radio_spec     (GObject     *object,
59
 
                                        GParamSpec  *param_spec);
60
55
static GParamSpec * get_param_spec     (GObject     *object);
61
56
 
62
57
static GParamSpec * find_param_spec    (GObject     *object,
66
61
                                        const gchar *property_name,
67
62
                                        GType         type,
68
63
                                        const gchar *strloc);
69
 
 
70
 
static gboolean     get_numeric_values (GObject     *object,
71
 
                                        GParamSpec  *param_spec,
72
 
                                        gdouble     *value,
73
 
                                        gdouble     *lower,
74
 
                                        gdouble     *upper,
 
64
static GParamSpec * check_param_spec_w (GObject     *object,
 
65
                                        const gchar *property_name,
 
66
                                        GType         type,
75
67
                                        const gchar *strloc);
76
68
 
77
69
static void         connect_notify     (GObject     *config,
80
72
                                        gpointer     callback_data);
81
73
 
82
74
 
83
 
/******************/
84
 
/*  check button  */
85
 
/******************/
86
 
 
87
 
static void   gimp_prop_check_button_callback (GtkWidget  *widget,
88
 
                                               GObject    *config);
89
 
static void   gimp_prop_check_button_notify   (GObject    *config,
90
 
                                               GParamSpec *param_spec,
91
 
                                               GtkWidget  *button);
92
 
 
93
 
GtkWidget *
94
 
gimp_prop_check_button_new (GObject     *config,
95
 
                            const gchar *property_name,
96
 
                            const gchar *label)
97
 
{
98
 
  GParamSpec  *param_spec;
99
 
  GtkWidget   *button;
100
 
  gboolean     value;
101
 
 
102
 
  param_spec = check_param_spec (config, property_name,
103
 
                                 G_TYPE_PARAM_BOOLEAN, G_STRFUNC);
104
 
  if (! param_spec)
105
 
    return NULL;
106
 
 
107
 
  g_object_get (config,
108
 
                property_name, &value,
109
 
                NULL);
110
 
 
111
 
  button = gtk_check_button_new_with_mnemonic (label);
112
 
  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), value);
113
 
 
114
 
  set_param_spec (G_OBJECT (button), button, param_spec);
115
 
 
116
 
  g_signal_connect (button, "toggled",
117
 
                    G_CALLBACK (gimp_prop_check_button_callback),
118
 
                    config);
119
 
 
120
 
  connect_notify (config, property_name,
121
 
                  G_CALLBACK (gimp_prop_check_button_notify),
122
 
                  button);
123
 
 
124
 
  return button;
125
 
}
126
 
 
127
 
static void
128
 
gimp_prop_check_button_callback (GtkWidget *widget,
129
 
                                 GObject   *config)
130
 
{
131
 
  GParamSpec *param_spec;
132
 
 
133
 
  param_spec = get_param_spec (G_OBJECT (widget));
134
 
  if (! param_spec)
135
 
    return;
136
 
 
137
 
  g_object_set (config,
138
 
                param_spec->name, GTK_TOGGLE_BUTTON (widget)->active,
139
 
                NULL);
140
 
 
141
 
  gimp_toggle_button_sensitive_update (GTK_TOGGLE_BUTTON (widget));
142
 
}
143
 
 
144
 
static void
145
 
gimp_prop_check_button_notify (GObject    *config,
146
 
                               GParamSpec *param_spec,
147
 
                               GtkWidget  *button)
148
 
{
149
 
  gboolean value;
150
 
 
151
 
  g_object_get (config,
152
 
                param_spec->name, &value,
153
 
                NULL);
154
 
 
155
 
  if (GTK_TOGGLE_BUTTON (button)->active != value)
156
 
    {
157
 
      g_signal_handlers_block_by_func (button,
158
 
                                       gimp_prop_check_button_callback,
159
 
                                       config);
160
 
 
161
 
      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), value);
162
 
      gimp_toggle_button_sensitive_update (GTK_TOGGLE_BUTTON (button));
163
 
 
164
 
      g_signal_handlers_unblock_by_func (button,
165
 
                                         gimp_prop_check_button_callback,
166
 
                                         config);
167
 
    }
168
 
}
169
 
 
170
 
 
171
 
static void   gimp_prop_enum_check_button_callback (GtkWidget  *widget,
172
 
                                                    GObject    *config);
173
 
static void   gimp_prop_enum_check_button_notify   (GObject    *config,
174
 
                                                    GParamSpec *param_spec,
175
 
                                                    GtkWidget  *button);
176
 
 
177
 
GtkWidget *
178
 
gimp_prop_enum_check_button_new (GObject     *config,
179
 
                                 const gchar *property_name,
180
 
                                 const gchar *label,
181
 
                                 gint         false_value,
182
 
                                 gint         true_value)
183
 
{
184
 
  GParamSpec  *param_spec;
185
 
  GtkWidget   *button;
186
 
  gint        value;
187
 
 
188
 
  param_spec = check_param_spec (config, property_name,
189
 
                                 G_TYPE_PARAM_ENUM, G_STRFUNC);
190
 
  if (! param_spec)
191
 
    return NULL;
192
 
 
193
 
  g_object_get (config,
194
 
                property_name, &value,
195
 
                NULL);
196
 
 
197
 
  button = gtk_check_button_new_with_mnemonic (label);
198
 
  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), value == true_value);
199
 
 
200
 
  if (value != false_value && value != true_value)
201
 
    gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (button), TRUE);
202
 
 
203
 
  set_param_spec (G_OBJECT (button), button, param_spec);
204
 
 
205
 
  g_object_set_data (G_OBJECT (button), "false-value",
206
 
                     GINT_TO_POINTER (false_value));
207
 
  g_object_set_data (G_OBJECT (button), "true-value",
208
 
                     GINT_TO_POINTER (true_value));
209
 
 
210
 
  g_signal_connect (button, "toggled",
211
 
                    G_CALLBACK (gimp_prop_enum_check_button_callback),
212
 
                    config);
213
 
 
214
 
  connect_notify (config, property_name,
215
 
                  G_CALLBACK (gimp_prop_enum_check_button_notify),
216
 
                  button);
217
 
 
218
 
  return button;
219
 
}
220
 
 
221
 
static void
222
 
gimp_prop_enum_check_button_callback (GtkWidget *widget,
223
 
                                      GObject   *config)
224
 
{
225
 
  GParamSpec *param_spec;
226
 
  gint        false_value;
227
 
  gint        true_value;
228
 
 
229
 
  param_spec = get_param_spec (G_OBJECT (widget));
230
 
  if (! param_spec)
231
 
    return;
232
 
 
233
 
  false_value = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget),
234
 
                                                    "false-value"));
235
 
  true_value  = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget),
236
 
                                                    "true-value"));
237
 
 
238
 
  g_object_set (config,
239
 
                param_spec->name,
240
 
                GTK_TOGGLE_BUTTON (widget)->active ? true_value : false_value,
241
 
                NULL);
242
 
 
243
 
  gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (widget), FALSE);
244
 
 
245
 
  gimp_toggle_button_sensitive_update (GTK_TOGGLE_BUTTON (widget));
246
 
}
247
 
 
248
 
static void
249
 
gimp_prop_enum_check_button_notify (GObject    *config,
250
 
                                    GParamSpec *param_spec,
251
 
                                    GtkWidget  *button)
252
 
{
253
 
  gint     value;
254
 
  gint     false_value;
255
 
  gint     true_value;
256
 
  gboolean active       = FALSE;
257
 
  gboolean inconsistent = FALSE;
258
 
 
259
 
  g_object_get (config,
260
 
                param_spec->name, &value,
261
 
                NULL);
262
 
 
263
 
  false_value = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (button),
264
 
                                                    "false-value"));
265
 
  true_value  = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (button),
266
 
                                                    "true-value"));
267
 
 
268
 
  if (value == true_value)
269
 
    active = TRUE;
270
 
  else if (value != false_value)
271
 
    inconsistent = TRUE;
272
 
 
273
 
  gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (button),
274
 
                                      inconsistent);
275
 
 
276
 
  if (GTK_TOGGLE_BUTTON (button)->active != active)
277
 
    {
278
 
      g_signal_handlers_block_by_func (button,
279
 
                                       gimp_prop_enum_check_button_callback,
280
 
                                       config);
281
 
 
282
 
      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), active);
283
 
      gimp_toggle_button_sensitive_update (GTK_TOGGLE_BUTTON (button));
284
 
 
285
 
      g_signal_handlers_unblock_by_func (button,
286
 
                                         gimp_prop_enum_check_button_callback,
287
 
                                         config);
288
 
    }
289
 
}
290
 
 
291
 
 
292
 
/*************************/
293
 
/*  int/enum combo box   */
294
 
/*************************/
295
 
 
296
 
static void   gimp_prop_int_combo_box_callback (GtkWidget   *widget,
297
 
                                                GObject     *config);
298
 
static void   gimp_prop_int_combo_box_notify   (GObject     *config,
299
 
                                                GParamSpec  *param_spec,
300
 
                                                GtkWidget   *widget);
301
 
 
302
 
GtkWidget *
303
 
gimp_prop_int_combo_box_new (GObject      *config,
304
 
                             const gchar  *property_name,
305
 
                             GimpIntStore *store)
306
 
{
307
 
  GParamSpec *param_spec;
308
 
  GtkWidget  *combo_box;
309
 
  GtkWidget  *widget;
310
 
  gint        value;
311
 
 
312
 
  param_spec = check_param_spec (config, property_name,
313
 
                                 G_TYPE_PARAM_INT, G_STRFUNC);
314
 
  if (! param_spec)
315
 
    return NULL;
316
 
 
317
 
  g_object_get (config,
318
 
                property_name, &value,
319
 
                NULL);
320
 
 
321
 
  combo_box = g_object_new (GIMP_TYPE_INT_COMBO_BOX,
322
 
                            "model", store,
323
 
                            NULL);
324
 
 
325
 
  gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (combo_box), value);
326
 
 
327
 
  g_signal_connect (combo_box, "changed",
328
 
                    G_CALLBACK (gimp_prop_int_combo_box_callback),
329
 
                    config);
330
 
 
331
 
  /*  can't set a tooltip on a combo_box  */
332
 
  if (g_param_spec_get_blurb (param_spec))
333
 
    {
334
 
      widget = gtk_event_box_new ();
335
 
      gtk_container_add (GTK_CONTAINER (widget), combo_box);
336
 
      gtk_widget_show (combo_box);
337
 
    }
338
 
  else
339
 
    {
340
 
      widget = combo_box;
341
 
    }
342
 
 
343
 
  set_param_spec (G_OBJECT (combo_box), widget, param_spec);
344
 
 
345
 
  connect_notify (config, property_name,
346
 
                  G_CALLBACK (gimp_prop_int_combo_box_notify),
347
 
                  combo_box);
348
 
 
349
 
  return widget;
350
 
}
351
 
 
352
 
GtkWidget *
353
 
gimp_prop_enum_combo_box_new (GObject     *config,
354
 
                              const gchar *property_name,
355
 
                              gint         minimum,
356
 
                              gint         maximum)
357
 
{
358
 
  GParamSpec *param_spec;
359
 
  GtkWidget  *combo_box;
360
 
  GtkWidget  *widget;
361
 
  gint        value;
362
 
 
363
 
  param_spec = check_param_spec (config, property_name,
364
 
                                 G_TYPE_PARAM_ENUM, G_STRFUNC);
365
 
  if (! param_spec)
366
 
    return NULL;
367
 
 
368
 
  g_object_get (config,
369
 
                property_name, &value,
370
 
                NULL);
371
 
 
372
 
  if (minimum != maximum)
373
 
    {
374
 
      GtkListStore *store;
375
 
 
376
 
      store = gimp_enum_store_new_with_range (param_spec->value_type,
377
 
                                              minimum, maximum);
378
 
 
379
 
      combo_box = g_object_new (GIMP_TYPE_ENUM_COMBO_BOX,
380
 
                                "model", store,
381
 
                                NULL);
382
 
 
383
 
      g_object_unref (store);
384
 
    }
385
 
  else
386
 
    {
387
 
      combo_box = gimp_enum_combo_box_new (param_spec->value_type);
388
 
    }
389
 
 
390
 
  gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (combo_box), value);
391
 
 
392
 
  g_signal_connect (combo_box, "changed",
393
 
                    G_CALLBACK (gimp_prop_int_combo_box_callback),
394
 
                    config);
395
 
 
396
 
  /*  can't set a tooltip on a combo_box  */
397
 
  if (g_param_spec_get_blurb (param_spec))
398
 
    {
399
 
      widget = gtk_event_box_new ();
400
 
      gtk_container_add (GTK_CONTAINER (widget), combo_box);
401
 
      gtk_widget_show (combo_box);
402
 
    }
403
 
  else
404
 
    {
405
 
      widget = combo_box;
406
 
    }
407
 
 
408
 
  set_param_spec (G_OBJECT (combo_box), widget, param_spec);
409
 
 
410
 
  connect_notify (config, property_name,
411
 
                  G_CALLBACK (gimp_prop_int_combo_box_notify),
412
 
                  combo_box);
413
 
 
414
 
  return widget;
415
 
}
416
 
 
417
 
static void
418
 
gimp_prop_int_combo_box_callback (GtkWidget *widget,
419
 
                                  GObject   *config)
420
 
{
421
 
  GParamSpec  *param_spec;
422
 
  gint         value;
423
 
 
424
 
  param_spec = get_param_spec (G_OBJECT (widget));
425
 
  if (! param_spec)
426
 
    return;
427
 
 
428
 
  if (gimp_int_combo_box_get_active (GIMP_INT_COMBO_BOX (widget), &value))
429
 
    {
430
 
      g_object_set (config,
431
 
                    param_spec->name, value,
432
 
                    NULL);
433
 
    }
434
 
}
435
 
 
436
 
static void
437
 
gimp_prop_int_combo_box_notify (GObject    *config,
438
 
                                GParamSpec *param_spec,
439
 
                                GtkWidget  *combo_box)
440
 
{
441
 
  gint value;
442
 
 
443
 
  g_object_get (config,
444
 
                param_spec->name, &value,
445
 
                NULL);
446
 
 
447
 
  g_signal_handlers_block_by_func (combo_box,
448
 
                                   gimp_prop_int_combo_box_callback,
449
 
                                   config);
450
 
 
451
 
  gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (combo_box), value);
452
 
 
453
 
  g_signal_handlers_unblock_by_func (combo_box,
454
 
                                     gimp_prop_int_combo_box_callback,
455
 
                                     config);
456
 
}
457
 
 
458
 
 
459
 
/************************/
460
 
/*  boolean combo box   */
461
 
/************************/
462
 
 
463
 
static void   gimp_prop_boolean_combo_box_callback (GtkWidget   *widget,
464
 
                                                    GObject     *config);
465
 
static void   gimp_prop_boolean_combo_box_notify   (GObject     *config,
466
 
                                                    GParamSpec  *param_spec,
467
 
                                                    GtkWidget   *widget);
468
 
 
469
 
 
470
 
GtkWidget *
471
 
gimp_prop_boolean_combo_box_new (GObject     *config,
472
 
                                 const gchar *property_name,
473
 
                                 const gchar *true_text,
474
 
                                 const gchar *false_text)
475
 
{
476
 
  GParamSpec *param_spec;
477
 
  GtkWidget  *combo_box;
478
 
  GtkWidget  *widget;
479
 
  gboolean    value;
480
 
 
481
 
  param_spec = check_param_spec (config, property_name,
482
 
                                 G_TYPE_PARAM_BOOLEAN, G_STRFUNC);
483
 
  if (! param_spec)
484
 
    return NULL;
485
 
 
486
 
  g_object_get (config,
487
 
                property_name, &value,
488
 
                NULL);
489
 
 
490
 
  combo_box = gtk_combo_box_new_text ();
491
 
 
492
 
  gtk_combo_box_append_text (GTK_COMBO_BOX (combo_box), true_text);
493
 
  gtk_combo_box_append_text (GTK_COMBO_BOX (combo_box), false_text);
494
 
 
495
 
  gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), value ? 0 : 1);
496
 
 
497
 
  g_signal_connect (combo_box, "changed",
498
 
                    G_CALLBACK (gimp_prop_boolean_combo_box_callback),
499
 
                    config);
500
 
 
501
 
  /*  can't set a tooltip on a combo_box  */
502
 
  if (g_param_spec_get_blurb (param_spec))
503
 
    {
504
 
      widget = gtk_event_box_new ();
505
 
      gtk_container_add (GTK_CONTAINER (widget), combo_box);
506
 
      gtk_widget_show (combo_box);
507
 
    }
508
 
  else
509
 
    {
510
 
      widget = combo_box;
511
 
    }
512
 
 
513
 
  set_param_spec (G_OBJECT (combo_box), widget, param_spec);
514
 
 
515
 
  connect_notify (config, property_name,
516
 
                  G_CALLBACK (gimp_prop_boolean_combo_box_notify),
517
 
                  combo_box);
518
 
 
519
 
  return widget;
520
 
}
521
 
 
522
 
static void
523
 
gimp_prop_boolean_combo_box_callback (GtkWidget *widget,
524
 
                                      GObject   *config)
525
 
{
526
 
  GParamSpec  *param_spec;
527
 
  gint         value;
528
 
 
529
 
  param_spec = get_param_spec (G_OBJECT (widget));
530
 
  if (! param_spec)
531
 
    return;
532
 
 
533
 
  value = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));
534
 
 
535
 
  g_object_set (config,
536
 
                param_spec->name, value ? FALSE : TRUE,
537
 
                NULL);
538
 
}
539
 
 
540
 
static void
541
 
gimp_prop_boolean_combo_box_notify (GObject    *config,
542
 
                                    GParamSpec *param_spec,
543
 
                                    GtkWidget  *combo_box)
544
 
{
545
 
  gint value;
546
 
 
547
 
  g_object_get (config,
548
 
                param_spec->name, &value,
549
 
                NULL);
550
 
 
551
 
  g_signal_handlers_block_by_func (combo_box,
552
 
                                   gimp_prop_boolean_combo_box_callback,
553
 
                                   config);
554
 
 
555
 
  gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), value ? 0 : 1);
556
 
 
557
 
  g_signal_handlers_unblock_by_func (combo_box,
558
 
                                     gimp_prop_boolean_combo_box_callback,
559
 
                                     config);
 
75
/*********************/
 
76
/*  expanding frame  */
 
77
/*********************/
 
78
 
 
79
GtkWidget *
 
80
gimp_prop_expanding_frame_new (GObject      *config,
 
81
                               const gchar  *property_name,
 
82
                               const gchar  *button_label,
 
83
                               GtkWidget    *child,
 
84
                               GtkWidget   **button)
 
85
{
 
86
  GtkWidget *frame;
 
87
  GtkWidget *toggle;
 
88
  gboolean   value;
 
89
 
 
90
  if (! check_param_spec_w (config, property_name,
 
91
                            G_TYPE_PARAM_BOOLEAN, G_STRFUNC))
 
92
    return NULL;
 
93
 
 
94
  frame = gimp_frame_new (NULL);
 
95
 
 
96
  toggle = gimp_prop_check_button_new (config, property_name, button_label);
 
97
  gtk_frame_set_label_widget (GTK_FRAME (frame), toggle);
 
98
  gtk_widget_show (toggle);
 
99
 
 
100
  gtk_container_add (GTK_CONTAINER (frame), child);
 
101
 
 
102
  g_object_get (config,
 
103
                property_name, &value,
 
104
                NULL);
 
105
 
 
106
  if (value)
 
107
    gtk_widget_show (child);
 
108
 
 
109
  g_signal_connect_object (toggle, "toggled",
 
110
                           G_CALLBACK (gimp_toggle_button_set_visible),
 
111
                           child, 0);
 
112
 
 
113
  if (button)
 
114
    *button = toggle;
 
115
 
 
116
  return frame;
560
117
}
561
118
 
562
119
 
570
127
                                             GParamSpec  *param_spec,
571
128
                                             GtkWidget   *menu);
572
129
 
 
130
/**
 
131
 * gimp_prop_paint_mode_menu_new:
 
132
 * @config:             #GimpConfig object to which property is attached.
 
133
 * @property_name:      Name of Enum property.
 
134
 * @with_behind_mode:   Whether to include "Behind" mode in the menu.
 
135
 * @with_replace_modes: Whether to include the "Replace", "Erase" and
 
136
 *                      "Anti Erase" modes in the menu.
 
137
 *
 
138
 * Creates a #GimpPaintModeMenu widget to display and set the specified
 
139
 * Enum property, for which the enum must be #GimpLayerModeEffects.
 
140
 *
 
141
 * Return value: The newly created #GimpPaintModeMenu widget.
 
142
 *
 
143
 * Since GIMP 2.4
 
144
 */
573
145
GtkWidget *
574
146
gimp_prop_paint_mode_menu_new (GObject     *config,
575
147
                               const gchar *property_name,
576
 
                               gboolean     with_behind_mode)
 
148
                               gboolean     with_behind_mode,
 
149
                               gboolean     with_replace_modes)
577
150
{
578
151
  GParamSpec *param_spec;
579
152
  GtkWidget  *menu;
580
153
  gint        value;
581
154
 
582
 
  param_spec = check_param_spec (config, property_name,
583
 
                                 G_TYPE_PARAM_ENUM, G_STRFUNC);
 
155
  param_spec = check_param_spec_w (config, property_name,
 
156
                                   G_TYPE_PARAM_ENUM, G_STRFUNC);
584
157
  if (! param_spec)
585
158
    return NULL;
586
159
 
588
161
                property_name, &value,
589
162
                NULL);
590
163
 
591
 
  menu = gimp_paint_mode_menu_new (G_CALLBACK (gimp_prop_paint_menu_callback),
592
 
                                   config,
593
 
                                   with_behind_mode,
594
 
                                   value);
 
164
  menu = gimp_paint_mode_menu_new (with_behind_mode, with_replace_modes);
 
165
 
 
166
  gimp_int_combo_box_connect (GIMP_INT_COMBO_BOX (menu),
 
167
                              value,
 
168
                              G_CALLBACK (gimp_prop_paint_menu_callback),
 
169
                              config);
595
170
 
596
171
  set_param_spec (G_OBJECT (menu), menu, param_spec);
597
172
 
606
181
gimp_prop_paint_menu_callback (GtkWidget *widget,
607
182
                               GObject   *config)
608
183
{
609
 
  if (GTK_IS_MENU (widget->parent))
 
184
  GParamSpec *param_spec;
 
185
  gint        value;
 
186
 
 
187
  param_spec = get_param_spec (G_OBJECT (widget));
 
188
  if (! param_spec)
 
189
    return;
 
190
 
 
191
  if (gimp_int_combo_box_get_active (GIMP_INT_COMBO_BOX (widget), &value))
610
192
    {
611
 
      GtkWidget *menu;
612
 
 
613
 
      menu = gtk_menu_get_attach_widget (GTK_MENU (widget->parent));
614
 
 
615
 
      if (menu)
616
 
        {
617
 
          GParamSpec *param_spec;
618
 
          gint        value;
619
 
 
620
 
          param_spec = get_param_spec (G_OBJECT (menu));
621
 
          if (! param_spec)
622
 
            return;
623
 
 
624
 
          value = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget),
625
 
                                                      "gimp-item-data"));
626
 
 
627
 
          g_object_set (config,
628
 
                        param_spec->name, value,
629
 
                        NULL);
630
 
        }
 
193
      g_object_set (config,
 
194
                    param_spec->name, value,
 
195
                    NULL);
631
196
    }
632
197
}
633
198
 
642
207
                param_spec->name, &value,
643
208
                NULL);
644
209
 
645
 
  gimp_paint_mode_menu_set_history (GTK_OPTION_MENU (menu), value);
646
 
}
647
 
 
648
 
 
649
 
/*****************/
650
 
/*  radio boxes  */
651
 
/*****************/
652
 
 
653
 
static void  gimp_prop_radio_button_callback (GtkWidget   *widget,
654
 
                                              GObject     *config);
655
 
static void  gimp_prop_radio_button_notify   (GObject     *config,
656
 
                                              GParamSpec  *param_spec,
657
 
                                              GtkWidget   *button);
658
 
 
659
 
 
660
 
GtkWidget *
661
 
gimp_prop_enum_radio_frame_new (GObject     *config,
662
 
                                const gchar *property_name,
663
 
                                const gchar *label,
664
 
                                gint         minimum,
665
 
                                gint         maximum)
666
 
{
667
 
  GParamSpec *param_spec;
668
 
  GtkWidget  *frame;
669
 
  GtkWidget  *button;
670
 
  gint        value;
671
 
 
672
 
  param_spec = check_param_spec (config, property_name,
673
 
                                 G_TYPE_PARAM_ENUM, G_STRFUNC);
674
 
  if (! param_spec)
675
 
    return NULL;
676
 
 
677
 
  g_object_get (config,
678
 
                property_name, &value,
679
 
                NULL);
680
 
 
681
 
  if (minimum != maximum)
682
 
    {
683
 
      frame = gimp_enum_radio_frame_new_with_range (param_spec->value_type,
684
 
                                                    minimum, maximum,
685
 
                                                    gtk_label_new (label),
686
 
                                                    G_CALLBACK (gimp_prop_radio_button_callback),
687
 
                                                    config,
688
 
                                                    &button);
689
 
    }
690
 
  else
691
 
    {
692
 
      frame = gimp_enum_radio_frame_new (param_spec->value_type,
693
 
                                         gtk_label_new (label),
694
 
                                         G_CALLBACK (gimp_prop_radio_button_callback),
695
 
                                         config,
696
 
                                         &button);
697
 
    }
698
 
 
699
 
  gimp_int_radio_group_set_active (GTK_RADIO_BUTTON (button), value);
700
 
 
701
 
  set_radio_spec (G_OBJECT (button), param_spec);
702
 
 
703
 
  connect_notify (config, property_name,
704
 
                  G_CALLBACK (gimp_prop_radio_button_notify),
705
 
                  button);
706
 
 
707
 
  g_object_set_data (G_OBJECT (frame), "radio-button", button);
708
 
 
709
 
  return frame;
710
 
}
711
 
 
712
 
GtkWidget *
713
 
gimp_prop_enum_radio_box_new (GObject     *config,
714
 
                              const gchar *property_name,
715
 
                              gint         minimum,
716
 
                              gint         maximum)
717
 
{
718
 
  GParamSpec *param_spec;
719
 
  GtkWidget  *vbox;
720
 
  GtkWidget  *button;
721
 
  gint        value;
722
 
 
723
 
  param_spec = check_param_spec (config, property_name,
724
 
                                 G_TYPE_PARAM_ENUM, G_STRFUNC);
725
 
  if (! param_spec)
726
 
    return NULL;
727
 
 
728
 
  g_object_get (config,
729
 
                property_name, &value,
730
 
                NULL);
731
 
 
732
 
  if (minimum != maximum)
733
 
    {
734
 
      vbox = gimp_enum_radio_box_new_with_range (param_spec->value_type,
735
 
                                                 minimum, maximum,
736
 
                                                 G_CALLBACK (gimp_prop_radio_button_callback),
737
 
                                                 config,
738
 
                                                 &button);
739
 
    }
740
 
  else
741
 
    {
742
 
      vbox = gimp_enum_radio_box_new (param_spec->value_type,
743
 
                                      G_CALLBACK (gimp_prop_radio_button_callback),
744
 
                                      config,
745
 
                                      &button);
746
 
    }
747
 
 
748
 
  gimp_int_radio_group_set_active (GTK_RADIO_BUTTON (button), value);
749
 
 
750
 
  set_radio_spec (G_OBJECT (button), param_spec);
751
 
 
752
 
  connect_notify (config, property_name,
753
 
                  G_CALLBACK (gimp_prop_radio_button_notify),
754
 
                  button);
755
 
 
756
 
  g_object_set_data (G_OBJECT (vbox), "radio-button", button);
757
 
 
758
 
  return vbox;
759
 
}
760
 
 
761
 
GtkWidget *
762
 
gimp_prop_boolean_radio_frame_new (GObject     *config,
763
 
                                   const gchar *property_name,
764
 
                                   const gchar *title,
765
 
                                   const gchar *true_text,
766
 
                                   const gchar *false_text)
767
 
{
768
 
  GParamSpec *param_spec;
769
 
  GtkWidget  *frame;
770
 
  GtkWidget  *button;
771
 
  gboolean    value;
772
 
 
773
 
  param_spec = check_param_spec (config, property_name,
774
 
                                 G_TYPE_PARAM_BOOLEAN, G_STRFUNC);
775
 
  if (! param_spec)
776
 
    return NULL;
777
 
 
778
 
  g_object_get (config,
779
 
                property_name, &value,
780
 
                NULL);
781
 
 
782
 
  frame =
783
 
    gimp_int_radio_group_new (TRUE, title,
784
 
                              G_CALLBACK (gimp_prop_radio_button_callback),
785
 
                              config, value,
786
 
 
787
 
                              false_text, FALSE, &button,
788
 
                              true_text,  TRUE,  NULL,
789
 
 
790
 
                              NULL);
791
 
 
792
 
  set_radio_spec (G_OBJECT (button), param_spec);
793
 
 
794
 
  connect_notify (config, property_name,
795
 
                  G_CALLBACK (gimp_prop_radio_button_notify),
796
 
                  button);
797
 
 
798
 
  g_object_set_data (G_OBJECT (frame), "radio-button", button);
799
 
 
800
 
  return frame;
801
 
}
802
 
 
803
 
GtkWidget *
804
 
gimp_prop_enum_stock_box_new (GObject     *config,
805
 
                              const gchar *property_name,
806
 
                              const gchar *stock_prefix,
807
 
                              gint         minimum,
808
 
                              gint         maximum)
809
 
{
810
 
  GParamSpec *param_spec;
811
 
  GtkWidget  *box;
812
 
  GtkWidget  *button;
813
 
  gint        value;
814
 
 
815
 
  param_spec = check_param_spec (config, property_name,
816
 
                                 G_TYPE_PARAM_ENUM, G_STRFUNC);
817
 
  if (! param_spec)
818
 
    return NULL;
819
 
 
820
 
  g_object_get (config,
821
 
                property_name, &value,
822
 
                NULL);
823
 
 
824
 
  if (minimum != maximum)
825
 
    {
826
 
      box = gimp_enum_stock_box_new_with_range (param_spec->value_type,
827
 
                                                minimum, maximum,
828
 
                                                stock_prefix,
829
 
                                                GTK_ICON_SIZE_MENU,
830
 
                                                G_CALLBACK (gimp_prop_radio_button_callback),
831
 
                                                config,
832
 
                                                &button);
833
 
    }
834
 
  else
835
 
    {
836
 
      box = gimp_enum_stock_box_new (param_spec->value_type,
837
 
                                     stock_prefix,
838
 
                                     GTK_ICON_SIZE_MENU,
839
 
                                     G_CALLBACK (gimp_prop_radio_button_callback),
840
 
                                     config,
841
 
                                     &button);
842
 
    }
843
 
 
844
 
  gimp_int_radio_group_set_active (GTK_RADIO_BUTTON (button), value);
845
 
 
846
 
  set_radio_spec (G_OBJECT (button), param_spec);
847
 
 
848
 
  connect_notify (config, property_name,
849
 
                  G_CALLBACK (gimp_prop_radio_button_notify),
850
 
                  button);
851
 
 
852
 
  return box;
853
 
}
854
 
 
855
 
static void
856
 
gimp_prop_radio_button_callback (GtkWidget *widget,
857
 
                                 GObject   *config)
858
 
{
859
 
  if (GTK_TOGGLE_BUTTON (widget)->active)
860
 
    {
861
 
      GParamSpec *param_spec;
862
 
      gint        value;
863
 
 
864
 
      param_spec = get_param_spec (G_OBJECT (widget));
865
 
      if (! param_spec)
866
 
        return;
867
 
 
868
 
      value = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget),
869
 
                                                  "gimp-item-data"));
870
 
 
871
 
      g_object_set (config,
872
 
                    param_spec->name, value,
873
 
                    NULL);
874
 
    }
875
 
}
876
 
 
877
 
static void
878
 
gimp_prop_radio_button_notify (GObject    *config,
879
 
                               GParamSpec *param_spec,
880
 
                               GtkWidget  *button)
881
 
{
882
 
  gint value;
883
 
 
884
 
  g_object_get (config,
885
 
                param_spec->name, &value,
886
 
                NULL);
887
 
 
888
 
  gimp_int_radio_group_set_active (GTK_RADIO_BUTTON (button), value);
889
 
}
890
 
 
891
 
 
892
 
/*****************/
893
 
/*  adjustments  */
894
 
/*****************/
895
 
 
896
 
static void   gimp_prop_adjustment_callback (GtkAdjustment *adjustment,
897
 
                                             GObject       *config);
898
 
static void   gimp_prop_adjustment_notify   (GObject       *config,
899
 
                                             GParamSpec    *param_spec,
900
 
                                             GtkAdjustment *adjustment);
901
 
 
902
 
GtkWidget *
903
 
gimp_prop_spin_button_new (GObject     *config,
904
 
                           const gchar *property_name,
905
 
                           gdouble      step_increment,
906
 
                           gdouble      page_increment,
907
 
                           gint         digits)
908
 
{
909
 
  GParamSpec *param_spec;
910
 
  GtkWidget  *spinbutton;
911
 
  GtkObject  *adjustment;
912
 
  gdouble     value;
913
 
  gdouble     lower;
914
 
  gdouble     upper;
915
 
 
916
 
  param_spec = find_param_spec (config, property_name, G_STRFUNC);
917
 
  if (! param_spec)
918
 
    return NULL;
919
 
 
920
 
  if (! get_numeric_values (config,
921
 
                            param_spec, &value, &lower, &upper, G_STRFUNC))
922
 
    return NULL;
923
 
 
924
 
  if (! G_IS_PARAM_SPEC_DOUBLE (param_spec))
925
 
    digits = 0;
926
 
 
927
 
  spinbutton = gimp_spin_button_new (&adjustment,
928
 
                                     value, lower, upper,
929
 
                                     step_increment, page_increment,
930
 
                                     0.0, 1.0, digits);
931
 
 
932
 
  set_param_spec (G_OBJECT (adjustment), spinbutton, param_spec);
933
 
 
934
 
  g_signal_connect (adjustment, "value_changed",
935
 
                    G_CALLBACK (gimp_prop_adjustment_callback),
936
 
                    config);
937
 
 
938
 
  connect_notify (config, property_name,
939
 
                  G_CALLBACK (gimp_prop_adjustment_notify),
940
 
                  adjustment);
941
 
 
942
 
  return spinbutton;
943
 
}
944
 
 
945
 
GtkObject *
946
 
gimp_prop_scale_entry_new (GObject     *config,
947
 
                           const gchar *property_name,
948
 
                           GtkTable    *table,
949
 
                           gint         column,
950
 
                           gint         row,
951
 
                           const gchar *label,
952
 
                           gdouble      step_increment,
953
 
                           gdouble      page_increment,
954
 
                           gint         digits,
955
 
                           gboolean     restrict_scale,
956
 
                           gdouble      restricted_lower,
957
 
                           gdouble      restricted_upper)
958
 
{
959
 
  GParamSpec  *param_spec;
960
 
  GtkObject   *adjustment;
961
 
  const gchar *tooltip;
962
 
  gdouble      value;
963
 
  gdouble      lower;
964
 
  gdouble      upper;
965
 
 
966
 
  param_spec = find_param_spec (config, property_name, G_STRFUNC);
967
 
  if (! param_spec)
968
 
    return NULL;
969
 
 
970
 
  if (! get_numeric_values (config,
971
 
                            param_spec, &value, &lower, &upper, G_STRFUNC))
972
 
    return NULL;
973
 
 
974
 
  tooltip = gettext (g_param_spec_get_blurb (param_spec));
975
 
 
976
 
  if (! restrict_scale)
977
 
    {
978
 
      adjustment = gimp_scale_entry_new (table, column, row,
979
 
                                         label, -1, -1,
980
 
                                         value, lower, upper,
981
 
                                         step_increment, page_increment, digits,
982
 
                                         TRUE, 0.0, 0.0,
983
 
                                         tooltip,
984
 
                                         NULL);
985
 
    }
986
 
  else
987
 
    {
988
 
      adjustment = gimp_scale_entry_new (table, column, row,
989
 
                                         label, -1, -1,
990
 
                                         value,
991
 
                                         restricted_lower,
992
 
                                         restricted_upper,
993
 
                                         step_increment, page_increment, digits,
994
 
                                         FALSE, lower, upper,
995
 
                                         tooltip,
996
 
                                         NULL);
997
 
    }
998
 
 
999
 
  set_param_spec (G_OBJECT (adjustment), NULL,  param_spec);
1000
 
 
1001
 
  g_signal_connect (adjustment, "value_changed",
1002
 
                    G_CALLBACK (gimp_prop_adjustment_callback),
1003
 
                    config);
1004
 
 
1005
 
  connect_notify (config, property_name,
1006
 
                  G_CALLBACK (gimp_prop_adjustment_notify),
1007
 
                  adjustment);
1008
 
 
1009
 
  return adjustment;
1010
 
}
1011
 
 
1012
 
GtkObject *
1013
 
gimp_prop_opacity_entry_new (GObject     *config,
1014
 
                             const gchar *property_name,
1015
 
                             GtkTable    *table,
1016
 
                             gint         column,
1017
 
                             gint         row,
1018
 
                             const gchar *label)
1019
 
{
1020
 
  GParamSpec  *param_spec;
1021
 
  GtkObject   *adjustment;
1022
 
  const gchar *tooltip;
1023
 
  gdouble      value;
1024
 
  gdouble      lower;
1025
 
  gdouble      upper;
1026
 
 
1027
 
  param_spec = check_param_spec (config, property_name,
1028
 
                                 G_TYPE_PARAM_DOUBLE, G_STRFUNC);
1029
 
  if (! param_spec)
1030
 
    return NULL;
1031
 
 
1032
 
  g_object_get (config, property_name, &value, NULL);
1033
 
 
1034
 
  tooltip = gettext (g_param_spec_get_blurb (param_spec));
1035
 
 
1036
 
  value *= 100.0;
1037
 
  lower = G_PARAM_SPEC_DOUBLE (param_spec)->minimum * 100.0;
1038
 
  upper = G_PARAM_SPEC_DOUBLE (param_spec)->maximum * 100.0;
1039
 
 
1040
 
  adjustment = gimp_scale_entry_new (table, column, row,
1041
 
                                     label, -1, -1,
1042
 
                                     value, lower, upper,
1043
 
                                     1.0, 10.0, 1,
1044
 
                                     TRUE, 0.0, 0.0,
1045
 
                                     tooltip,
1046
 
                                     NULL);
1047
 
 
1048
 
  set_param_spec (G_OBJECT (adjustment), NULL,  param_spec);
1049
 
  g_object_set_data (G_OBJECT (adjustment),
1050
 
                     "opacity-scale", GINT_TO_POINTER (TRUE));
1051
 
 
1052
 
  g_signal_connect (adjustment, "value_changed",
1053
 
                    G_CALLBACK (gimp_prop_adjustment_callback),
1054
 
                    config);
1055
 
 
1056
 
  connect_notify (config, property_name,
1057
 
                  G_CALLBACK (gimp_prop_adjustment_notify),
1058
 
                  adjustment);
1059
 
 
1060
 
  return adjustment;
1061
 
}
1062
 
 
1063
 
 
1064
 
static void
1065
 
gimp_prop_adjustment_callback (GtkAdjustment *adjustment,
1066
 
                               GObject       *config)
1067
 
{
1068
 
  GParamSpec *param_spec;
1069
 
 
1070
 
  param_spec = get_param_spec (G_OBJECT (adjustment));
1071
 
  if (! param_spec)
1072
 
    return;
1073
 
 
1074
 
  if (G_IS_PARAM_SPEC_INT (param_spec))
1075
 
    {
1076
 
      g_object_set (config,
1077
 
                    param_spec->name, (gint) adjustment->value,
1078
 
                    NULL);
1079
 
    }
1080
 
  else if (G_IS_PARAM_SPEC_UINT (param_spec))
1081
 
    {
1082
 
      g_object_set (config,
1083
 
                    param_spec->name, (guint) adjustment->value,
1084
 
                    NULL);
1085
 
    }
1086
 
  else if (G_IS_PARAM_SPEC_LONG (param_spec))
1087
 
    {
1088
 
      g_object_set (config,
1089
 
                    param_spec->name, (glong) adjustment->value,
1090
 
                    NULL);
1091
 
    }
1092
 
  else if (G_IS_PARAM_SPEC_ULONG (param_spec))
1093
 
    {
1094
 
      g_object_set (config,
1095
 
                    param_spec->name, (gulong) adjustment->value,
1096
 
                    NULL);
1097
 
    }
1098
 
  else if (G_IS_PARAM_SPEC_INT64 (param_spec))
1099
 
    {
1100
 
      g_object_set (config,
1101
 
                    param_spec->name, (gint64) adjustment->value,
1102
 
                    NULL);
1103
 
    }
1104
 
  else if (G_IS_PARAM_SPEC_UINT64 (param_spec))
1105
 
    {
1106
 
      g_object_set (config,
1107
 
                    param_spec->name, (guint64) adjustment->value,
1108
 
                    NULL);
1109
 
    }
1110
 
  else if (G_IS_PARAM_SPEC_DOUBLE (param_spec))
1111
 
    {
1112
 
      gdouble value;
1113
 
 
1114
 
      if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (adjustment),
1115
 
                                              "opacity-scale")))
1116
 
        value = adjustment->value / 100.0;
1117
 
      else
1118
 
        value = adjustment->value;
1119
 
 
1120
 
      g_object_set (config, param_spec->name, value, NULL);
1121
 
    }
1122
 
}
1123
 
 
1124
 
static void
1125
 
gimp_prop_adjustment_notify (GObject       *config,
1126
 
                             GParamSpec    *param_spec,
1127
 
                             GtkAdjustment *adjustment)
1128
 
{
1129
 
  gdouble value;
1130
 
 
1131
 
  if (G_IS_PARAM_SPEC_INT (param_spec))
1132
 
    {
1133
 
      gint int_value;
1134
 
 
1135
 
      g_object_get (config, param_spec->name, &int_value, NULL);
1136
 
 
1137
 
      value = int_value;
1138
 
    }
1139
 
  else if (G_IS_PARAM_SPEC_UINT (param_spec))
1140
 
    {
1141
 
      guint uint_value;
1142
 
 
1143
 
      g_object_get (config, param_spec->name, &uint_value, NULL);
1144
 
 
1145
 
      value = uint_value;
1146
 
    }
1147
 
  else if (G_IS_PARAM_SPEC_LONG (param_spec))
1148
 
    {
1149
 
      glong long_value;
1150
 
 
1151
 
      g_object_get (config, param_spec->name, &long_value, NULL);
1152
 
 
1153
 
      value = long_value;
1154
 
    }
1155
 
  else if (G_IS_PARAM_SPEC_ULONG (param_spec))
1156
 
    {
1157
 
      gulong ulong_value;
1158
 
 
1159
 
      g_object_get (config, param_spec->name, &ulong_value, NULL);
1160
 
 
1161
 
      value = ulong_value;
1162
 
    }
1163
 
  else if (G_IS_PARAM_SPEC_INT64 (param_spec))
1164
 
    {
1165
 
      gint64 int64_value;
1166
 
 
1167
 
      g_object_get (config, param_spec->name, &int64_value, NULL);
1168
 
 
1169
 
      value = int64_value;
1170
 
    }
1171
 
  else if (G_IS_PARAM_SPEC_UINT64 (param_spec))
1172
 
    {
1173
 
      guint64 uint64_value;
1174
 
 
1175
 
      g_object_get (config, param_spec->name, &uint64_value, NULL);
1176
 
 
1177
 
#if defined _MSC_VER && (_MSC_VER < 1300)
1178
 
      value = (gint64) uint64_value;
1179
 
#else
1180
 
      value = uint64_value;
1181
 
#endif
1182
 
    }
1183
 
  else if (G_IS_PARAM_SPEC_DOUBLE (param_spec))
1184
 
    {
1185
 
      g_object_get (config, param_spec->name, &value, NULL);
1186
 
 
1187
 
      if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (adjustment),
1188
 
                                              "opacity-scale")))
1189
 
        value *= 100.0;
1190
 
    }
1191
 
  else
1192
 
    {
1193
 
      g_warning ("%s: unhandled param spec of type %s",
1194
 
                 G_STRFUNC, G_PARAM_SPEC_TYPE_NAME (param_spec));
1195
 
      return;
1196
 
    }
1197
 
 
1198
 
  if (adjustment->value != value)
1199
 
    {
1200
 
      g_signal_handlers_block_by_func (adjustment,
1201
 
                                       gimp_prop_adjustment_callback,
1202
 
                                       config);
1203
 
 
1204
 
      gtk_adjustment_set_value (adjustment, value);
1205
 
 
1206
 
      g_signal_handlers_unblock_by_func (adjustment,
1207
 
                                         gimp_prop_adjustment_callback,
1208
 
                                         config);
1209
 
    }
1210
 
}
1211
 
 
1212
 
 
1213
 
/*************/
1214
 
/*  memsize  */
1215
 
/*************/
1216
 
 
1217
 
static void   gimp_prop_memsize_callback (GimpMemsizeEntry *entry,
1218
 
                                          GObject          *config);
1219
 
static void   gimp_prop_memsize_notify   (GObject          *config,
1220
 
                                          GParamSpec       *param_spec,
1221
 
                                          GimpMemsizeEntry *entry);
1222
 
 
1223
 
GtkWidget *
1224
 
gimp_prop_memsize_entry_new (GObject     *config,
1225
 
                             const gchar *property_name)
1226
 
{
1227
 
  GParamSpec       *param_spec;
1228
 
  GParamSpecUInt64 *uint64_spec;
1229
 
  GtkWidget        *entry;
1230
 
  guint64           value;
1231
 
 
1232
 
  param_spec = check_param_spec (config, property_name,
1233
 
                                 GIMP_TYPE_PARAM_MEMSIZE, G_STRFUNC);
1234
 
  if (! param_spec)
1235
 
    return NULL;
1236
 
 
1237
 
  g_object_get (config,
1238
 
                property_name, &value,
1239
 
                NULL);
1240
 
 
1241
 
  uint64_spec = G_PARAM_SPEC_UINT64 (param_spec);
1242
 
 
1243
 
  g_return_val_if_fail (uint64_spec->minimum <= GIMP_MAX_MEMSIZE, NULL);
1244
 
  g_return_val_if_fail (uint64_spec->maximum <= GIMP_MAX_MEMSIZE, NULL);
1245
 
 
1246
 
  entry = gimp_memsize_entry_new (value,
1247
 
                                  uint64_spec->minimum,
1248
 
                                  uint64_spec->maximum);
1249
 
 
1250
 
  set_param_spec (G_OBJECT (entry),
1251
 
                  GIMP_MEMSIZE_ENTRY (entry)->spinbutton,
1252
 
                  param_spec);
1253
 
 
1254
 
  g_signal_connect (entry, "value_changed",
1255
 
                    G_CALLBACK (gimp_prop_memsize_callback),
1256
 
                    config);
1257
 
 
1258
 
  connect_notify (config, property_name,
1259
 
                  G_CALLBACK (gimp_prop_memsize_notify),
1260
 
                  entry);
1261
 
 
1262
 
  return entry;
1263
 
}
1264
 
 
1265
 
 
1266
 
static void
1267
 
gimp_prop_memsize_callback (GimpMemsizeEntry *entry,
1268
 
                            GObject          *config)
1269
 
{
1270
 
  GParamSpec *param_spec;
1271
 
 
1272
 
  param_spec = get_param_spec (G_OBJECT (entry));
1273
 
  if (! param_spec)
1274
 
    return;
1275
 
 
1276
 
  g_return_if_fail (G_IS_PARAM_SPEC_UINT64 (param_spec));
1277
 
 
1278
 
  g_object_set (config,
1279
 
                param_spec->name, gimp_memsize_entry_get_value (entry),
1280
 
                NULL);
1281
 
}
1282
 
 
1283
 
static void
1284
 
gimp_prop_memsize_notify (GObject          *config,
1285
 
                          GParamSpec       *param_spec,
1286
 
                          GimpMemsizeEntry *entry)
1287
 
{
1288
 
  guint64  value;
1289
 
 
1290
 
  g_return_if_fail (G_IS_PARAM_SPEC_UINT64 (param_spec));
1291
 
 
1292
 
  g_object_get (config,
1293
 
                param_spec->name, &value,
1294
 
                NULL);
1295
 
 
1296
 
  if (entry->value != value)
1297
 
    {
1298
 
      g_signal_handlers_block_by_func (entry,
1299
 
                                       gimp_prop_memsize_callback,
1300
 
                                       config);
1301
 
 
1302
 
      gimp_memsize_entry_set_value (entry, value);
1303
 
 
1304
 
      g_signal_handlers_unblock_by_func (entry,
1305
 
                                         gimp_prop_memsize_callback,
1306
 
                                         config);
1307
 
    }
1308
 
}
1309
 
 
1310
 
 
1311
 
/***********/
1312
 
/*  label  */
1313
 
/***********/
1314
 
 
1315
 
static void   gimp_prop_label_notify (GObject    *config,
1316
 
                                      GParamSpec *param_spec,
1317
 
                                      GtkWidget  *label);
1318
 
 
1319
 
GtkWidget *
1320
 
gimp_prop_label_new (GObject     *config,
1321
 
                     const gchar *property_name)
1322
 
{
1323
 
  GParamSpec *param_spec;
1324
 
  GtkWidget  *label;
1325
 
  gchar      *value;
1326
 
 
1327
 
  param_spec = check_param_spec (config, property_name,
1328
 
                                 G_TYPE_PARAM_STRING, G_STRFUNC);
1329
 
  if (! param_spec)
1330
 
    return NULL;
1331
 
 
1332
 
  g_object_get (config,
1333
 
                property_name, &value,
1334
 
                NULL);
1335
 
 
1336
 
  label = gtk_label_new (value ? value : "");
1337
 
  g_free (value);
1338
 
 
1339
 
  set_param_spec (G_OBJECT (label), label, param_spec);
1340
 
 
1341
 
  connect_notify (config, property_name,
1342
 
                  G_CALLBACK (gimp_prop_label_notify),
1343
 
                  label);
1344
 
 
1345
 
  return label;
1346
 
}
1347
 
 
1348
 
static void
1349
 
gimp_prop_label_notify (GObject    *config,
1350
 
                        GParamSpec *param_spec,
1351
 
                        GtkWidget  *label)
1352
 
{
1353
 
  gchar *value;
1354
 
 
1355
 
  g_object_get (config,
1356
 
                param_spec->name, &value,
1357
 
                NULL);
1358
 
 
1359
 
  gtk_label_set_text (GTK_LABEL (label), value ? value : "");
1360
 
 
1361
 
  g_free (value);
1362
 
}
1363
 
 
1364
 
 
1365
 
/***********/
1366
 
/*  entry  */
1367
 
/***********/
1368
 
 
1369
 
static void   gimp_prop_entry_callback (GtkWidget  *entry,
1370
 
                                        GObject    *config);
1371
 
static void   gimp_prop_entry_notify   (GObject    *config,
1372
 
                                        GParamSpec *param_spec,
1373
 
                                        GtkWidget  *entry);
1374
 
 
1375
 
GtkWidget *
1376
 
gimp_prop_entry_new (GObject     *config,
1377
 
                     const gchar *property_name,
1378
 
                     gint         max_len)
1379
 
{
1380
 
  GParamSpec *param_spec;
1381
 
  GtkWidget  *entry;
1382
 
  gchar      *value;
1383
 
 
1384
 
  param_spec = check_param_spec (config, property_name,
1385
 
                                 G_TYPE_PARAM_STRING, G_STRFUNC);
1386
 
  if (! param_spec)
1387
 
    return NULL;
1388
 
 
1389
 
  g_object_get (config,
1390
 
                property_name, &value,
1391
 
                NULL);
1392
 
 
1393
 
  entry = gtk_entry_new ();
1394
 
  gtk_entry_set_text (GTK_ENTRY (entry), value);
1395
 
 
1396
 
  g_free (value);
1397
 
 
1398
 
  if (max_len > 0)
1399
 
    gtk_entry_set_max_length (GTK_ENTRY (entry), max_len);
1400
 
 
1401
 
  set_param_spec (G_OBJECT (entry), entry, param_spec);
1402
 
 
1403
 
  g_signal_connect (entry, "changed",
1404
 
                    G_CALLBACK (gimp_prop_entry_callback),
1405
 
                    config);
1406
 
 
1407
 
  connect_notify (config, property_name,
1408
 
                  G_CALLBACK (gimp_prop_entry_notify),
1409
 
                  entry);
1410
 
 
1411
 
  return entry;
1412
 
}
1413
 
 
1414
 
static void
1415
 
gimp_prop_entry_callback (GtkWidget *entry,
1416
 
                          GObject   *config)
1417
 
{
1418
 
  GParamSpec  *param_spec;
1419
 
  const gchar *text;
1420
 
 
1421
 
  param_spec = get_param_spec (G_OBJECT (entry));
1422
 
  if (! param_spec)
1423
 
    return;
1424
 
 
1425
 
  text = gtk_entry_get_text (GTK_ENTRY (entry));
1426
 
 
1427
 
  g_signal_handlers_block_by_func (config,
1428
 
                                   gimp_prop_entry_notify,
1429
 
                                   entry);
1430
 
 
1431
 
  g_object_set (config,
1432
 
                param_spec->name, text,
1433
 
                NULL);
1434
 
 
1435
 
  g_signal_handlers_unblock_by_func (config,
1436
 
                                     gimp_prop_entry_notify,
1437
 
                                     entry);
1438
 
}
1439
 
 
1440
 
static void
1441
 
gimp_prop_entry_notify (GObject    *config,
1442
 
                        GParamSpec *param_spec,
1443
 
                        GtkWidget  *entry)
1444
 
{
1445
 
  gchar *value;
1446
 
 
1447
 
  g_object_get (config,
1448
 
                param_spec->name, &value,
1449
 
                NULL);
1450
 
 
1451
 
  g_signal_handlers_block_by_func (entry,
1452
 
                                   gimp_prop_entry_callback,
1453
 
                                   config);
1454
 
 
1455
 
  gtk_entry_set_text (GTK_ENTRY (entry), value);
1456
 
 
1457
 
  g_signal_handlers_unblock_by_func (entry,
1458
 
                                     gimp_prop_entry_callback,
1459
 
                                     config);
1460
 
 
1461
 
  g_free (value);
1462
 
}
1463
 
 
1464
 
 
1465
 
/*****************/
1466
 
/*  text buffer  */
1467
 
/*****************/
1468
 
 
1469
 
static void   gimp_prop_text_buffer_callback (GtkTextBuffer *text_buffer,
1470
 
                                              GObject       *config);
1471
 
static void   gimp_prop_text_buffer_notify   (GObject       *config,
1472
 
                                              GParamSpec    *param_spec,
1473
 
                                              GtkTextBuffer *text_buffer);
1474
 
 
1475
 
GtkTextBuffer *
1476
 
gimp_prop_text_buffer_new (GObject     *config,
1477
 
                           const gchar *property_name,
1478
 
                           gint         max_len)
1479
 
{
1480
 
  GParamSpec    *param_spec;
1481
 
  GtkTextBuffer *text_buffer;
1482
 
  gchar         *value;
1483
 
 
1484
 
  param_spec = check_param_spec (config, property_name,
1485
 
                                 G_TYPE_PARAM_STRING, G_STRFUNC);
1486
 
  if (! param_spec)
1487
 
    return NULL;
1488
 
 
1489
 
  g_object_get (config,
1490
 
                property_name, &value,
1491
 
                NULL);
1492
 
 
1493
 
  text_buffer = gtk_text_buffer_new (NULL);
1494
 
  gtk_text_buffer_set_text (text_buffer, value ? value : "", -1);
1495
 
 
1496
 
  g_free (value);
1497
 
 
1498
 
  if (max_len > 0)
1499
 
    g_object_set_data (G_OBJECT (text_buffer), "max-len",
1500
 
                       GINT_TO_POINTER (max_len));
1501
 
 
1502
 
  set_param_spec (G_OBJECT (text_buffer), NULL, param_spec);
1503
 
 
1504
 
  g_signal_connect (text_buffer, "changed",
1505
 
                    G_CALLBACK (gimp_prop_text_buffer_callback),
1506
 
                    config);
1507
 
 
1508
 
  connect_notify (config, property_name,
1509
 
                  G_CALLBACK (gimp_prop_text_buffer_notify),
1510
 
                  text_buffer);
1511
 
 
1512
 
  return text_buffer;
1513
 
}
1514
 
 
1515
 
static void
1516
 
gimp_prop_text_buffer_callback (GtkTextBuffer *text_buffer,
1517
 
                                GObject       *config)
1518
 
{
1519
 
  GParamSpec  *param_spec;
1520
 
  GtkTextIter  start_iter;
1521
 
  GtkTextIter  end_iter;
1522
 
  gchar       *text;
1523
 
  gint         max_len;
1524
 
 
1525
 
  param_spec = get_param_spec (G_OBJECT (text_buffer));
1526
 
  if (! param_spec)
1527
 
    return;
1528
 
 
1529
 
  gtk_text_buffer_get_bounds (text_buffer, &start_iter, &end_iter);
1530
 
  text = gtk_text_buffer_get_text (text_buffer, &start_iter, &end_iter, FALSE);
1531
 
 
1532
 
  max_len = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (text_buffer),
1533
 
                                                "max-length"));
1534
 
 
1535
 
  if (max_len > 0 && g_utf8_strlen (text, -1) > max_len)
1536
 
    {
1537
 
      g_message (_("This text input field is limited to %d characters."),
1538
 
                 max_len);
1539
 
 
1540
 
      gtk_text_buffer_get_iter_at_offset (text_buffer, &start_iter,
1541
 
                                          max_len - 1);
1542
 
      gtk_text_buffer_get_end_iter (text_buffer, &end_iter);
1543
 
 
1544
 
      /*  this calls us recursivaly, but in the else branch  */
1545
 
      gtk_text_buffer_delete (text_buffer, &start_iter, &end_iter);
1546
 
    }
1547
 
  else
1548
 
    {
1549
 
      g_signal_handlers_block_by_func (config,
1550
 
                                       gimp_prop_text_buffer_notify,
1551
 
                                       text_buffer);
1552
 
 
1553
 
      g_object_set (config,
1554
 
                    param_spec->name, text,
1555
 
                    NULL);
1556
 
 
1557
 
      g_signal_handlers_unblock_by_func (config,
1558
 
                                         gimp_prop_text_buffer_notify,
1559
 
                                         text_buffer);
1560
 
    }
1561
 
 
1562
 
  g_free (text);
1563
 
}
1564
 
 
1565
 
static void
1566
 
gimp_prop_text_buffer_notify (GObject       *config,
1567
 
                              GParamSpec    *param_spec,
1568
 
                              GtkTextBuffer *text_buffer)
1569
 
{
1570
 
  gchar *value;
1571
 
 
1572
 
  g_object_get (config,
1573
 
                param_spec->name, &value,
1574
 
                NULL);
1575
 
 
1576
 
  g_signal_handlers_block_by_func (text_buffer,
1577
 
                                   gimp_prop_text_buffer_callback,
1578
 
                                   config);
1579
 
 
1580
 
  gtk_text_buffer_set_text (text_buffer, value ? value : "", -1);
1581
 
 
1582
 
  g_signal_handlers_unblock_by_func (text_buffer,
1583
 
                                     gimp_prop_text_buffer_callback,
1584
 
                                     config);
1585
 
 
1586
 
  g_free (value);
1587
 
}
1588
 
 
1589
 
 
1590
 
/****************/
1591
 
/*  file entry  */
1592
 
/****************/
1593
 
 
1594
 
 
1595
 
static void   gimp_prop_file_entry_callback (GimpFileEntry *entry,
1596
 
                                             GObject       *config);
1597
 
static void   gimp_prop_file_entry_notify   (GObject       *config,
1598
 
                                             GParamSpec    *param_spec,
1599
 
                                             GimpFileEntry *entry);
1600
 
 
1601
 
GtkWidget *
1602
 
gimp_prop_file_entry_new (GObject     *config,
1603
 
                          const gchar *property_name,
1604
 
                          const gchar *filesel_title,
1605
 
                          gboolean     dir_only,
1606
 
                          gboolean     check_valid)
1607
 
{
1608
 
  GParamSpec *param_spec;
1609
 
  GtkWidget  *entry;
1610
 
  gchar      *filename;
1611
 
  gchar      *value;
1612
 
 
1613
 
  param_spec = check_param_spec (config, property_name,
1614
 
                                 GIMP_TYPE_PARAM_PATH, G_STRFUNC);
1615
 
  if (! param_spec)
1616
 
    return NULL;
1617
 
 
1618
 
  g_object_get (config,
1619
 
                property_name, &value,
1620
 
                NULL);
1621
 
 
1622
 
  filename = value ? gimp_config_path_expand (value, TRUE, NULL) : NULL;
1623
 
  g_free (value);
1624
 
 
1625
 
  entry = gimp_file_entry_new (filesel_title, filename, dir_only, check_valid);
1626
 
  g_free (filename);
1627
 
 
1628
 
  set_param_spec (G_OBJECT (entry),
1629
 
                  GIMP_FILE_ENTRY (entry)->entry,
1630
 
                  param_spec);
1631
 
 
1632
 
  g_signal_connect (entry, "filename_changed",
1633
 
                    G_CALLBACK (gimp_prop_file_entry_callback),
1634
 
                    config);
1635
 
 
1636
 
  connect_notify (config, property_name,
1637
 
                  G_CALLBACK (gimp_prop_file_entry_notify),
1638
 
                  entry);
1639
 
 
1640
 
  return entry;
1641
 
}
1642
 
 
1643
 
static void
1644
 
gimp_prop_file_entry_callback (GimpFileEntry *entry,
1645
 
                               GObject       *config)
1646
 
{
1647
 
  GParamSpec *param_spec;
1648
 
  gchar      *value;
1649
 
  gchar      *utf8;
1650
 
 
1651
 
  param_spec = get_param_spec (G_OBJECT (entry));
1652
 
  if (! param_spec)
1653
 
    return;
1654
 
 
1655
 
  value = gimp_file_entry_get_filename (entry);
1656
 
  utf8 = g_filename_to_utf8 (value, -1, NULL, NULL, NULL);
1657
 
  g_free (value);
1658
 
 
1659
 
  g_signal_handlers_block_by_func (config,
1660
 
                                   gimp_prop_file_entry_notify,
1661
 
                                   entry);
1662
 
 
1663
 
  g_object_set (config,
1664
 
                param_spec->name, utf8,
1665
 
                NULL);
1666
 
 
1667
 
  g_signal_handlers_block_by_func (config,
1668
 
                                   gimp_prop_file_entry_notify,
1669
 
                                   entry);
1670
 
 
1671
 
  g_free (utf8);
1672
 
}
1673
 
 
1674
 
static void
1675
 
gimp_prop_file_entry_notify (GObject       *config,
1676
 
                             GParamSpec    *param_spec,
1677
 
                             GimpFileEntry *entry)
1678
 
{
1679
 
  gchar *value;
1680
 
  gchar *filename;
1681
 
 
1682
 
  g_object_get (config,
1683
 
                param_spec->name, &value,
1684
 
                NULL);
1685
 
 
1686
 
  filename = value ? gimp_config_path_expand (value, TRUE, NULL) : NULL;
1687
 
  g_free (value);
1688
 
 
1689
 
  g_signal_handlers_block_by_func (entry,
1690
 
                                   gimp_prop_file_entry_callback,
1691
 
                                   config);
1692
 
 
1693
 
  gimp_file_entry_set_filename (entry, filename);
1694
 
 
1695
 
  g_signal_handlers_unblock_by_func (entry,
1696
 
                                     gimp_prop_file_entry_callback,
1697
 
                                     config);
1698
 
 
1699
 
  g_free (filename);
1700
 
}
1701
 
 
1702
 
 
1703
 
/*****************/
1704
 
/*  path editor  */
1705
 
/*****************/
1706
 
 
1707
 
static void   gimp_prop_path_editor_path_callback     (GimpPathEditor *editor,
1708
 
                                                       GObject        *config);
1709
 
static void   gimp_prop_path_editor_writable_callback (GimpPathEditor *editor,
1710
 
                                                       GObject        *config);
1711
 
static void   gimp_prop_path_editor_path_notify       (GObject        *config,
1712
 
                                                       GParamSpec     *param_spec,
1713
 
                                                       GimpPathEditor *editor);
1714
 
static void   gimp_prop_path_editor_writable_notify   (GObject        *config,
1715
 
                                                       GParamSpec     *param_spec,
1716
 
                                                       GimpPathEditor *editor);
1717
 
 
1718
 
GtkWidget *
1719
 
gimp_prop_path_editor_new (GObject     *config,
1720
 
                           const gchar *path_property_name,
1721
 
                           const gchar *writable_property_name,
1722
 
                           const gchar *filesel_title)
1723
 
{
1724
 
  GParamSpec *path_param_spec;
1725
 
  GParamSpec *writable_param_spec = NULL;
1726
 
  GtkWidget  *editor;
1727
 
  gchar      *value;
1728
 
  gchar      *filename;
1729
 
 
1730
 
  path_param_spec = check_param_spec (config, path_property_name,
1731
 
                                      GIMP_TYPE_PARAM_PATH, G_STRFUNC);
1732
 
  if (! path_param_spec)
1733
 
    return NULL;
1734
 
 
1735
 
  if (writable_property_name)
1736
 
    {
1737
 
      writable_param_spec = check_param_spec (config, writable_property_name,
1738
 
                                              GIMP_TYPE_PARAM_PATH, G_STRFUNC);
1739
 
      if (! writable_param_spec)
1740
 
        return NULL;
1741
 
    }
1742
 
 
1743
 
  g_object_get (config,
1744
 
                path_property_name, &value,
1745
 
                NULL);
1746
 
 
1747
 
  filename = value ? gimp_config_path_expand (value, TRUE, NULL) : NULL;
1748
 
  g_free (value);
1749
 
 
1750
 
  editor = gimp_path_editor_new (filesel_title, filename);
1751
 
  g_free (filename);
1752
 
 
1753
 
  if (writable_property_name)
1754
 
    {
1755
 
      g_object_get (config,
1756
 
                    writable_property_name, &value,
1757
 
                    NULL);
1758
 
 
1759
 
      filename = value ? gimp_config_path_expand (value, TRUE, NULL) : NULL;
1760
 
      g_free (value);
1761
 
 
1762
 
      gimp_path_editor_set_writable_path (GIMP_PATH_EDITOR (editor), filename);
1763
 
      g_free (filename);
1764
 
    }
1765
 
 
1766
 
  g_object_set_data (G_OBJECT (editor), "gimp-config-param-spec-path",
1767
 
                     path_param_spec);
1768
 
 
1769
 
  g_signal_connect (editor, "path_changed",
1770
 
                    G_CALLBACK (gimp_prop_path_editor_path_callback),
1771
 
                    config);
1772
 
 
1773
 
  connect_notify (config, path_property_name,
1774
 
                  G_CALLBACK (gimp_prop_path_editor_path_notify),
1775
 
                  editor);
1776
 
 
1777
 
  if (writable_property_name)
1778
 
    {
1779
 
      g_object_set_data (G_OBJECT (editor), "gimp-config-param-spec-writable",
1780
 
                         writable_param_spec);
1781
 
 
1782
 
      g_signal_connect (editor, "writable_changed",
1783
 
                        G_CALLBACK (gimp_prop_path_editor_writable_callback),
1784
 
                        config);
1785
 
 
1786
 
      connect_notify (config, writable_property_name,
1787
 
                      G_CALLBACK (gimp_prop_path_editor_writable_notify),
1788
 
                      editor);
1789
 
    }
1790
 
 
1791
 
  return editor;
1792
 
}
1793
 
 
1794
 
static void
1795
 
gimp_prop_path_editor_path_callback (GimpPathEditor *editor,
1796
 
                                     GObject        *config)
1797
 
{
1798
 
  GParamSpec *path_param_spec;
1799
 
  GParamSpec *writable_param_spec;
1800
 
  gchar      *value;
1801
 
  gchar      *utf8;
1802
 
 
1803
 
  path_param_spec     = g_object_get_data (G_OBJECT (editor),
1804
 
                                           "gimp-config-param-spec-path");
1805
 
  writable_param_spec = g_object_get_data (G_OBJECT (editor),
1806
 
                                           "gimp-config-param-spec-writable");
1807
 
  if (! path_param_spec)
1808
 
    return;
1809
 
 
1810
 
  value = gimp_path_editor_get_path (editor);
1811
 
  utf8 = g_filename_to_utf8 (value, -1, NULL, NULL, NULL);
1812
 
  g_free (value);
1813
 
 
1814
 
  g_signal_handlers_block_by_func (config,
1815
 
                                   gimp_prop_path_editor_path_notify,
1816
 
                                   editor);
1817
 
 
1818
 
  g_object_set (config,
1819
 
                path_param_spec->name, utf8,
1820
 
                NULL);
1821
 
 
1822
 
  g_signal_handlers_unblock_by_func (config,
1823
 
                                     gimp_prop_path_editor_path_notify,
1824
 
                                     editor);
1825
 
 
1826
 
  g_free (utf8);
1827
 
 
1828
 
  if (writable_param_spec)
1829
 
    {
1830
 
      value = gimp_path_editor_get_writable_path (editor);
1831
 
      utf8 = g_filename_to_utf8 (value, -1, NULL, NULL, NULL);
1832
 
      g_free (value);
1833
 
 
1834
 
      g_signal_handlers_block_by_func (config,
1835
 
                                       gimp_prop_path_editor_writable_notify,
1836
 
                                       editor);
1837
 
 
1838
 
      g_object_set (config,
1839
 
                    writable_param_spec->name, utf8,
1840
 
                    NULL);
1841
 
 
1842
 
      g_signal_handlers_unblock_by_func (config,
1843
 
                                         gimp_prop_path_editor_writable_notify,
1844
 
                                         editor);
1845
 
 
1846
 
      g_free (utf8);
1847
 
    }
1848
 
}
1849
 
 
1850
 
static void
1851
 
gimp_prop_path_editor_writable_callback (GimpPathEditor *editor,
1852
 
                                         GObject        *config)
1853
 
{
1854
 
  GParamSpec *param_spec;
1855
 
  gchar      *value;
1856
 
  gchar      *utf8;
1857
 
 
1858
 
  param_spec = g_object_get_data (G_OBJECT (editor),
1859
 
                                  "gimp-config-param-spec-writable");
1860
 
  if (! param_spec)
1861
 
    return;
1862
 
 
1863
 
  value = gimp_path_editor_get_writable_path (editor);
1864
 
  utf8 = g_filename_to_utf8 (value, -1, NULL, NULL, NULL);
1865
 
  g_free (value);
1866
 
 
1867
 
  g_signal_handlers_block_by_func (config,
1868
 
                                   gimp_prop_path_editor_writable_notify,
1869
 
                                   editor);
1870
 
 
1871
 
  g_object_set (config,
1872
 
                param_spec->name, utf8,
1873
 
                NULL);
1874
 
 
1875
 
  g_signal_handlers_unblock_by_func (config,
1876
 
                                     gimp_prop_path_editor_writable_notify,
1877
 
                                     editor);
1878
 
 
1879
 
  g_free (utf8);
1880
 
}
1881
 
 
1882
 
static void
1883
 
gimp_prop_path_editor_path_notify (GObject        *config,
1884
 
                                   GParamSpec     *param_spec,
1885
 
                                   GimpPathEditor *editor)
1886
 
{
1887
 
  gchar *value;
1888
 
  gchar *filename;
1889
 
 
1890
 
  g_object_get (config,
1891
 
                param_spec->name, &value,
1892
 
                NULL);
1893
 
 
1894
 
  filename = value ? gimp_config_path_expand (value, TRUE, NULL) : NULL;
1895
 
  g_free (value);
1896
 
 
1897
 
  g_signal_handlers_block_by_func (editor,
1898
 
                                   gimp_prop_path_editor_path_callback,
1899
 
                                   config);
1900
 
 
1901
 
  gimp_path_editor_set_path (editor, filename);
1902
 
 
1903
 
  g_signal_handlers_unblock_by_func (editor,
1904
 
                                     gimp_prop_path_editor_path_callback,
1905
 
                                     config);
1906
 
 
1907
 
  g_free (filename);
1908
 
}
1909
 
 
1910
 
static void
1911
 
gimp_prop_path_editor_writable_notify (GObject        *config,
1912
 
                                       GParamSpec     *param_spec,
1913
 
                                       GimpPathEditor *editor)
1914
 
{
1915
 
  gchar *value;
1916
 
  gchar *filename;
1917
 
 
1918
 
  g_object_get (config,
1919
 
                param_spec->name, &value,
1920
 
                NULL);
1921
 
 
1922
 
  filename = value ? gimp_config_path_expand (value, TRUE, NULL) : NULL;
1923
 
  g_free (value);
1924
 
 
1925
 
  g_signal_handlers_block_by_func (editor,
1926
 
                                   gimp_prop_path_editor_writable_callback,
1927
 
                                   config);
1928
 
 
1929
 
  gimp_path_editor_set_writable_path (editor, filename);
1930
 
 
1931
 
  g_signal_handlers_unblock_by_func (editor,
1932
 
                                     gimp_prop_path_editor_writable_callback,
1933
 
                                     config);
1934
 
 
1935
 
  g_free (filename);
1936
 
}
1937
 
 
1938
 
 
1939
 
/***************/
1940
 
/*  sizeentry  */
1941
 
/***************/
1942
 
 
1943
 
static void   gimp_prop_size_entry_callback    (GimpSizeEntry *sizeentry,
1944
 
                                                GObject       *config);
1945
 
static void   gimp_prop_size_entry_notify      (GObject       *config,
1946
 
                                                GParamSpec    *param_spec,
1947
 
                                                GimpSizeEntry *sizeentry);
1948
 
static void   gimp_prop_size_entry_notify_unit (GObject       *config,
1949
 
                                                GParamSpec    *param_spec,
1950
 
                                                GimpSizeEntry *sizeentry);
1951
 
 
1952
 
 
1953
 
GtkWidget *
1954
 
gimp_prop_size_entry_new (GObject                   *config,
1955
 
                          const gchar               *property_name,
1956
 
                          const gchar               *unit_property_name,
1957
 
                          const gchar               *unit_format,
1958
 
                          GimpSizeEntryUpdatePolicy  update_policy,
1959
 
                          gdouble                    resolution)
1960
 
{
1961
 
  GtkWidget  *sizeentry;
1962
 
  GParamSpec *param_spec;
1963
 
  GParamSpec *unit_param_spec;
1964
 
  gboolean    show_pixels;
1965
 
  gdouble     value;
1966
 
  gdouble     lower;
1967
 
  gdouble     upper;
1968
 
  GimpUnit    unit_value;
1969
 
 
1970
 
  param_spec = find_param_spec (config, property_name, G_STRFUNC);
1971
 
  if (! param_spec)
1972
 
    return NULL;
1973
 
 
1974
 
  if (! get_numeric_values (config,
1975
 
                            param_spec, &value, &lower, &upper, G_STRFUNC))
1976
 
    return NULL;
1977
 
 
1978
 
  if (unit_property_name)
1979
 
    {
1980
 
      GValue value = { 0 };
1981
 
 
1982
 
      unit_param_spec = check_param_spec (config, unit_property_name,
1983
 
                                          GIMP_TYPE_PARAM_UNIT, G_STRFUNC);
1984
 
      if (! unit_param_spec)
1985
 
        return NULL;
1986
 
 
1987
 
      g_value_init (&value, unit_param_spec->value_type);
1988
 
      g_value_set_int (&value, GIMP_UNIT_PIXEL);
1989
 
      show_pixels =
1990
 
        (g_param_value_validate (unit_param_spec, &value) == FALSE);
1991
 
      g_value_unset (&value);
1992
 
 
1993
 
      g_object_get (config,
1994
 
                    unit_property_name, &unit_value,
1995
 
                    NULL);
1996
 
    }
1997
 
  else
1998
 
    {
1999
 
      unit_param_spec = NULL;
2000
 
      unit_value      = GIMP_UNIT_INCH;
2001
 
      show_pixels     = FALSE;
2002
 
    }
2003
 
 
2004
 
  sizeentry = gimp_size_entry_new (1, unit_value, unit_format,
2005
 
                                   TRUE, FALSE, FALSE,
2006
 
                                   ceil (log (upper) / log (10) + 2),
2007
 
                                   update_policy);
2008
 
  gtk_table_set_col_spacing (GTK_TABLE (sizeentry), 1, 4);
2009
 
 
2010
 
  set_param_spec (NULL,
2011
 
                  gimp_size_entry_get_help_widget (GIMP_SIZE_ENTRY (sizeentry),
2012
 
                                                   0),
2013
 
                  param_spec);
2014
 
 
2015
 
  if (unit_param_spec)
2016
 
    set_param_spec (NULL,
2017
 
                    GIMP_SIZE_ENTRY (sizeentry)->unitmenu, unit_param_spec);
2018
 
 
2019
 
  gimp_size_entry_set_unit (GIMP_SIZE_ENTRY (sizeentry), unit_value);
2020
 
 
2021
 
  if (update_policy == GIMP_SIZE_ENTRY_UPDATE_SIZE)
2022
 
    gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (sizeentry), 0,
2023
 
                                    resolution, FALSE);
2024
 
 
2025
 
  gimp_size_entry_set_value_boundaries (GIMP_SIZE_ENTRY (sizeentry), 0,
2026
 
                                        lower, upper);
2027
 
 
2028
 
  gimp_size_entry_set_value (GIMP_SIZE_ENTRY (sizeentry), 0, value);
2029
 
 
2030
 
  g_object_set_data (G_OBJECT (sizeentry), "gimp-config-param-spec",
2031
 
                     param_spec);
2032
 
 
2033
 
  g_signal_connect (sizeentry, "value_changed",
2034
 
                    G_CALLBACK (gimp_prop_size_entry_callback),
2035
 
                    config);
2036
 
 
2037
 
  connect_notify (config, property_name,
2038
 
                  G_CALLBACK (gimp_prop_size_entry_notify),
2039
 
                  sizeentry);
2040
 
 
2041
 
  if (unit_property_name)
2042
 
    {
2043
 
      g_object_set_data (G_OBJECT (sizeentry), "gimp-config-param-spec-unit",
2044
 
                         unit_param_spec);
2045
 
 
2046
 
      g_signal_connect (sizeentry, "unit_changed",
2047
 
                        G_CALLBACK (gimp_prop_size_entry_callback),
2048
 
                        config);
2049
 
 
2050
 
      connect_notify (config, unit_property_name,
2051
 
                      G_CALLBACK (gimp_prop_size_entry_notify_unit),
2052
 
                      sizeentry);
2053
 
    }
2054
 
 
2055
 
  return sizeentry;
2056
 
}
2057
 
 
2058
 
static void
2059
 
gimp_prop_size_entry_callback (GimpSizeEntry *sizeentry,
2060
 
                               GObject       *config)
2061
 
{
2062
 
  GParamSpec *param_spec;
2063
 
  GParamSpec *unit_param_spec;
2064
 
  gdouble     value;
2065
 
  GimpUnit    unit_value;
2066
 
 
2067
 
  param_spec = g_object_get_data (G_OBJECT (sizeentry),
2068
 
                                  "gimp-config-param-spec");
2069
 
  if (! param_spec)
2070
 
    return;
2071
 
 
2072
 
  unit_param_spec = g_object_get_data (G_OBJECT (sizeentry),
2073
 
                                       "gimp-config-param-spec-unit");
2074
 
 
2075
 
  value      = gimp_size_entry_get_value (sizeentry, 0);
2076
 
  unit_value = gimp_size_entry_get_unit (sizeentry);
2077
 
 
2078
 
  if (unit_param_spec)
2079
 
    {
2080
 
      GimpUnit  old_unit;
2081
 
 
2082
 
      g_object_get (config,
2083
 
                    unit_param_spec->name, &old_unit,
2084
 
                    NULL);
2085
 
 
2086
 
      if (unit_value == old_unit)
2087
 
        unit_param_spec = NULL;
2088
 
    }
2089
 
 
2090
 
  if (G_IS_PARAM_SPEC_INT (param_spec))
2091
 
    {
2092
 
      g_object_set (config,
2093
 
                    param_spec->name, ROUND (value),
2094
 
 
2095
 
                    unit_param_spec ?
2096
 
                    unit_param_spec->name : NULL, unit_value,
2097
 
 
2098
 
                    NULL);
2099
 
    }
2100
 
  else if (G_IS_PARAM_SPEC_DOUBLE (param_spec))
2101
 
    {
2102
 
      g_object_set (config,
2103
 
                    param_spec->name, value,
2104
 
 
2105
 
                    unit_param_spec ?
2106
 
                    unit_param_spec->name : NULL, unit_value,
2107
 
 
2108
 
                    NULL);
2109
 
    }
2110
 
}
2111
 
 
2112
 
static void
2113
 
gimp_prop_size_entry_notify (GObject       *config,
2114
 
                             GParamSpec    *param_spec,
2115
 
                             GimpSizeEntry *sizeentry)
2116
 
{
2117
 
  gdouble value;
2118
 
 
2119
 
  if (G_IS_PARAM_SPEC_INT (param_spec))
2120
 
    {
2121
 
      gint int_value;
2122
 
 
2123
 
      g_object_get (config,
2124
 
                    param_spec->name, &int_value,
2125
 
                    NULL);
2126
 
 
2127
 
      value = int_value;
2128
 
    }
2129
 
  else
2130
 
    {
2131
 
      g_object_get (config,
2132
 
                    param_spec->name, &value,
2133
 
                    NULL);
2134
 
    }
2135
 
 
2136
 
  if (value != gimp_size_entry_get_value (sizeentry, 0))
2137
 
    {
2138
 
      g_signal_handlers_block_by_func (sizeentry,
2139
 
                                       gimp_prop_size_entry_callback,
2140
 
                                       config);
2141
 
 
2142
 
      gimp_size_entry_set_value (sizeentry, 0, value);
2143
 
 
2144
 
      g_signal_handlers_unblock_by_func (sizeentry,
2145
 
                                         gimp_prop_size_entry_callback,
2146
 
                                         config);
2147
 
    }
2148
 
}
2149
 
 
2150
 
static void
2151
 
gimp_prop_size_entry_notify_unit (GObject       *config,
2152
 
                                  GParamSpec    *param_spec,
2153
 
                                  GimpSizeEntry *sizeentry)
2154
 
{
2155
 
  GimpUnit value;
2156
 
 
2157
 
  g_object_get (config,
2158
 
                param_spec->name, &value,
2159
 
                NULL);
2160
 
 
2161
 
  if (value != gimp_size_entry_get_unit (sizeentry))
2162
 
    {
2163
 
      g_signal_handlers_block_by_func (sizeentry,
2164
 
                                       gimp_prop_size_entry_callback,
2165
 
                                       config);
2166
 
 
2167
 
      gimp_size_entry_set_unit (sizeentry, value);
2168
 
 
2169
 
      g_signal_handlers_unblock_by_func (sizeentry,
2170
 
                                         gimp_prop_size_entry_callback,
2171
 
                                         config);
2172
 
    }
2173
 
}
2174
 
 
2175
 
 
2176
 
/*****************/
2177
 
/*  coordinates  */
2178
 
/*****************/
2179
 
 
2180
 
static void   gimp_prop_coordinates_callback    (GimpSizeEntry *sizeentry,
2181
 
                                                 GObject       *config);
2182
 
static void   gimp_prop_coordinates_notify_x    (GObject       *config,
2183
 
                                                 GParamSpec    *param_spec,
2184
 
                                                 GimpSizeEntry *sizeentry);
2185
 
static void   gimp_prop_coordinates_notify_y    (GObject       *config,
2186
 
                                                 GParamSpec    *param_spec,
2187
 
                                                 GimpSizeEntry *sizeentry);
2188
 
static void   gimp_prop_coordinates_notify_unit (GObject       *config,
2189
 
                                                 GParamSpec    *param_spec,
2190
 
                                                 GimpSizeEntry *sizeentry);
2191
 
 
2192
 
 
2193
 
GtkWidget *
2194
 
gimp_prop_coordinates_new (GObject                   *config,
2195
 
                           const gchar               *x_property_name,
2196
 
                           const gchar               *y_property_name,
2197
 
                           const gchar               *unit_property_name,
2198
 
                           const gchar               *unit_format,
2199
 
                           GimpSizeEntryUpdatePolicy  update_policy,
2200
 
                           gdouble                    xresolution,
2201
 
                           gdouble                    yresolution,
2202
 
                           gboolean                   has_chainbutton)
2203
 
{
2204
 
  GtkWidget *sizeentry;
2205
 
  GtkWidget *chainbutton = NULL;
2206
 
 
2207
 
  sizeentry = gimp_size_entry_new (2, GIMP_UNIT_INCH, unit_format,
2208
 
                                   FALSE, FALSE, TRUE, 10,
2209
 
                                   update_policy);
2210
 
 
2211
 
  if (has_chainbutton)
2212
 
    {
2213
 
      chainbutton = gimp_chain_button_new (GIMP_CHAIN_BOTTOM);
2214
 
      gtk_table_attach_defaults (GTK_TABLE (sizeentry), chainbutton,
2215
 
                                 1, 3, 3, 4);
2216
 
      gtk_widget_show (chainbutton);
2217
 
    }
2218
 
 
2219
 
  if (! gimp_prop_coordinates_connect (config,
2220
 
                                       x_property_name,
2221
 
                                       y_property_name,
2222
 
                                       unit_property_name,
2223
 
                                       sizeentry,
2224
 
                                       chainbutton,
2225
 
                                       xresolution,
2226
 
                                       yresolution))
2227
 
    {
2228
 
      gtk_widget_destroy (sizeentry);
2229
 
      return NULL;
2230
 
    }
2231
 
 
2232
 
  return sizeentry;
2233
 
}
2234
 
 
2235
 
gboolean
2236
 
gimp_prop_coordinates_connect (GObject     *config,
2237
 
                               const gchar *x_property_name,
2238
 
                               const gchar *y_property_name,
2239
 
                               const gchar *unit_property_name,
2240
 
                               GtkWidget   *sizeentry,
2241
 
                               GtkWidget   *chainbutton,
2242
 
                               gdouble      xresolution,
2243
 
                               gdouble      yresolution)
2244
 
{
2245
 
  GParamSpec *x_param_spec;
2246
 
  GParamSpec *y_param_spec;
2247
 
  GParamSpec *unit_param_spec;
2248
 
  gdouble     x_value, x_lower, x_upper;
2249
 
  gdouble     y_value, y_lower, y_upper;
2250
 
  GimpUnit    unit_value;
2251
 
  gdouble    *old_x_value;
2252
 
  gdouble    *old_y_value;
2253
 
  GimpUnit   *old_unit_value;
2254
 
  gboolean    chain_checked;
2255
 
 
2256
 
  g_return_val_if_fail (GIMP_IS_SIZE_ENTRY (sizeentry), FALSE);
2257
 
  g_return_val_if_fail (GIMP_SIZE_ENTRY (sizeentry)->number_of_fields == 2,
2258
 
                        FALSE);
2259
 
  g_return_val_if_fail (chainbutton == NULL ||
2260
 
                        GIMP_IS_CHAIN_BUTTON (chainbutton), FALSE);
2261
 
 
2262
 
  x_param_spec = find_param_spec (config, x_property_name, G_STRFUNC);
2263
 
  if (! x_param_spec)
2264
 
    return FALSE;
2265
 
 
2266
 
  y_param_spec = find_param_spec (config, y_property_name, G_STRFUNC);
2267
 
  if (! y_param_spec)
2268
 
    return FALSE;
2269
 
 
2270
 
  if (! get_numeric_values (config, x_param_spec,
2271
 
                            &x_value, &x_lower, &x_upper, G_STRFUNC) ||
2272
 
      ! get_numeric_values (config, y_param_spec,
2273
 
                            &y_value, &y_lower, &y_upper, G_STRFUNC))
2274
 
    return FALSE;
2275
 
 
2276
 
  if (unit_property_name)
2277
 
    {
2278
 
      unit_param_spec = check_param_spec (config, unit_property_name,
2279
 
                                          GIMP_TYPE_PARAM_UNIT, G_STRFUNC);
2280
 
      if (! unit_param_spec)
2281
 
        return FALSE;
2282
 
 
2283
 
      g_object_get (config,
2284
 
                    unit_property_name, &unit_value,
2285
 
                    NULL);
2286
 
    }
2287
 
  else
2288
 
    {
2289
 
      unit_param_spec = NULL;
2290
 
      unit_value      = GIMP_UNIT_INCH;
2291
 
    }
2292
 
 
2293
 
  set_param_spec (NULL,
2294
 
                  gimp_size_entry_get_help_widget (GIMP_SIZE_ENTRY (sizeentry),
2295
 
                                                   0),
2296
 
                  x_param_spec);
2297
 
  set_param_spec (NULL,
2298
 
                  gimp_size_entry_get_help_widget (GIMP_SIZE_ENTRY (sizeentry),
2299
 
                                                   1),
2300
 
                  y_param_spec);
2301
 
 
2302
 
  if (unit_param_spec)
2303
 
    set_param_spec (NULL,
2304
 
                    GIMP_SIZE_ENTRY (sizeentry)->unitmenu, unit_param_spec);
2305
 
 
2306
 
  gimp_size_entry_set_unit (GIMP_SIZE_ENTRY (sizeentry), unit_value);
2307
 
 
2308
 
  switch (GIMP_SIZE_ENTRY (sizeentry)->update_policy)
2309
 
    {
2310
 
    case GIMP_SIZE_ENTRY_UPDATE_SIZE:
2311
 
      gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (sizeentry), 0,
2312
 
                                      xresolution, FALSE);
2313
 
      gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (sizeentry), 1,
2314
 
                                      yresolution, FALSE);
2315
 
      chain_checked = (ABS (x_value - y_value) < 1);
2316
 
      break;
2317
 
 
2318
 
    case GIMP_SIZE_ENTRY_UPDATE_RESOLUTION:
2319
 
      chain_checked = (ABS (x_value - y_value) < GIMP_MIN_RESOLUTION);
2320
 
      break;
2321
 
 
2322
 
    default:
2323
 
      chain_checked = (x_value == y_value);
2324
 
      break;
2325
 
    }
2326
 
 
2327
 
  gimp_size_entry_set_refval_boundaries (GIMP_SIZE_ENTRY (sizeentry), 0,
2328
 
                                         x_lower, x_upper);
2329
 
  gimp_size_entry_set_refval_boundaries (GIMP_SIZE_ENTRY (sizeentry), 1,
2330
 
                                         y_lower, y_upper);
2331
 
 
2332
 
  gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (sizeentry), 0, x_value);
2333
 
  gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (sizeentry), 1, y_value);
2334
 
 
2335
 
  g_object_set_data (G_OBJECT (sizeentry), "gimp-config-param-spec-x",
2336
 
                     x_param_spec);
2337
 
  g_object_set_data (G_OBJECT (sizeentry), "gimp-config-param-spec-y",
2338
 
                     y_param_spec);
2339
 
 
2340
 
  old_x_value  = g_new0 (gdouble, 1);
2341
 
  *old_x_value = x_value;
2342
 
  g_object_set_data_full (G_OBJECT (sizeentry), "old-x-value",
2343
 
                          old_x_value,
2344
 
                          (GDestroyNotify) g_free);
2345
 
 
2346
 
  old_y_value  = g_new0 (gdouble, 1);
2347
 
  *old_y_value = y_value;
2348
 
  g_object_set_data_full (G_OBJECT (sizeentry), "old-y-value",
2349
 
                          old_y_value,
2350
 
                          (GDestroyNotify) g_free);
2351
 
 
2352
 
  if (chainbutton)
2353
 
    {
2354
 
      if (chain_checked)
2355
 
        gimp_chain_button_set_active (GIMP_CHAIN_BUTTON (chainbutton), TRUE);
2356
 
 
2357
 
      g_object_set_data (G_OBJECT (sizeentry), "chainbutton", chainbutton);
2358
 
    }
2359
 
 
2360
 
  g_signal_connect (sizeentry, "value_changed",
2361
 
                    G_CALLBACK (gimp_prop_coordinates_callback),
2362
 
                    config);
2363
 
  g_signal_connect (sizeentry, "refval_changed",
2364
 
                    G_CALLBACK (gimp_prop_coordinates_callback),
2365
 
                    config);
2366
 
 
2367
 
  connect_notify (config, x_property_name,
2368
 
                  G_CALLBACK (gimp_prop_coordinates_notify_x),
2369
 
                  sizeentry);
2370
 
  connect_notify (config, y_property_name,
2371
 
                  G_CALLBACK (gimp_prop_coordinates_notify_y),
2372
 
                  sizeentry);
2373
 
 
2374
 
  if (unit_property_name)
2375
 
    {
2376
 
      g_object_set_data (G_OBJECT (sizeentry), "gimp-config-param-spec-unit",
2377
 
                         unit_param_spec);
2378
 
 
2379
 
      old_unit_value  = g_new0 (GimpUnit, 1);
2380
 
      *old_unit_value = unit_value;
2381
 
      g_object_set_data_full (G_OBJECT (sizeentry), "old-unit-value",
2382
 
                              old_unit_value,
2383
 
                              (GDestroyNotify) g_free);
2384
 
 
2385
 
      g_signal_connect (sizeentry, "unit_changed",
2386
 
                        G_CALLBACK (gimp_prop_coordinates_callback),
2387
 
                        config);
2388
 
 
2389
 
      connect_notify (config, unit_property_name,
2390
 
                      G_CALLBACK (gimp_prop_coordinates_notify_unit),
2391
 
                      sizeentry);
2392
 
    }
2393
 
 
2394
 
  return TRUE;
2395
 
}
2396
 
 
2397
 
static void
2398
 
gimp_prop_coordinates_callback (GimpSizeEntry *sizeentry,
2399
 
                                GObject       *config)
2400
 
{
2401
 
  GParamSpec *x_param_spec;
2402
 
  GParamSpec *y_param_spec;
2403
 
  GParamSpec *unit_param_spec;
2404
 
  gdouble     x_value;
2405
 
  gdouble     y_value;
2406
 
  GimpUnit    unit_value;
2407
 
  gdouble    *old_x_value;
2408
 
  gdouble    *old_y_value;
2409
 
  GimpUnit   *old_unit_value;
2410
 
  gboolean    backwards;
2411
 
 
2412
 
  x_param_spec = g_object_get_data (G_OBJECT (sizeentry),
2413
 
                                    "gimp-config-param-spec-x");
2414
 
  y_param_spec = g_object_get_data (G_OBJECT (sizeentry),
2415
 
                                    "gimp-config-param-spec-y");
2416
 
 
2417
 
  if (! x_param_spec || ! y_param_spec)
2418
 
    return;
2419
 
 
2420
 
  unit_param_spec = g_object_get_data (G_OBJECT (sizeentry),
2421
 
                                       "gimp-config-param-spec-unit");
2422
 
 
2423
 
  x_value    = gimp_size_entry_get_refval (sizeentry, 0);
2424
 
  y_value    = gimp_size_entry_get_refval (sizeentry, 1);
2425
 
  unit_value = gimp_size_entry_get_unit (sizeentry);
2426
 
 
2427
 
  old_x_value    = g_object_get_data (G_OBJECT (sizeentry), "old-x-value");
2428
 
  old_y_value    = g_object_get_data (G_OBJECT (sizeentry), "old-y-value");
2429
 
  old_unit_value = g_object_get_data (G_OBJECT (sizeentry), "old-unit-value");
2430
 
 
2431
 
  if (! old_x_value || ! old_y_value || (unit_param_spec && ! old_unit_value))
2432
 
    return;
2433
 
 
2434
 
  /*
2435
 
   * FIXME: if the entry was created using gimp_coordinates_new, then
2436
 
   * the chain button is handled automatically and the following block
2437
 
   * of code is unnecessary (and, in fact, redundant).
2438
 
   */
2439
 
  if (x_value != y_value)
2440
 
    {
2441
 
      GtkWidget *chainbutton;
2442
 
 
2443
 
      chainbutton = g_object_get_data (G_OBJECT (sizeentry), "chainbutton");
2444
 
 
2445
 
      if (chainbutton &&
2446
 
          gimp_chain_button_get_active (GIMP_CHAIN_BUTTON (chainbutton)) &&
2447
 
          ! g_object_get_data (G_OBJECT (chainbutton), "constrains-ratio"))
2448
 
        {
2449
 
          if (x_value != *old_x_value)
2450
 
            y_value = x_value;
2451
 
          else if (y_value != *old_y_value)
2452
 
            x_value = y_value;
2453
 
        }
2454
 
    }
2455
 
 
2456
 
  backwards = (*old_x_value == x_value);
2457
 
 
2458
 
  if (*old_x_value == x_value &&
2459
 
      *old_y_value == y_value &&
2460
 
      (old_unit_value == NULL || *old_unit_value == unit_value))
2461
 
    return;
2462
 
 
2463
 
  *old_x_value = x_value;
2464
 
  *old_y_value = y_value;
2465
 
 
2466
 
  if (old_unit_value)
2467
 
    *old_unit_value = unit_value;
2468
 
 
2469
 
  if (unit_param_spec)
2470
 
    g_object_set (config,
2471
 
                  unit_param_spec->name, unit_value,
2472
 
                  NULL);
2473
 
 
2474
 
  if (G_IS_PARAM_SPEC_INT (x_param_spec) &&
2475
 
      G_IS_PARAM_SPEC_INT (y_param_spec))
2476
 
    {
2477
 
      if (backwards)
2478
 
        g_object_set (config,
2479
 
                      y_param_spec->name, ROUND (y_value),
2480
 
                      x_param_spec->name, ROUND (x_value),
2481
 
                      NULL);
2482
 
      else
2483
 
        g_object_set (config,
2484
 
                      x_param_spec->name, ROUND (x_value),
2485
 
                      y_param_spec->name, ROUND (y_value),
2486
 
                      NULL);
2487
 
 
2488
 
    }
2489
 
  else if (G_IS_PARAM_SPEC_DOUBLE (x_param_spec) &&
2490
 
           G_IS_PARAM_SPEC_DOUBLE (y_param_spec))
2491
 
    {
2492
 
      if (backwards)
2493
 
        g_object_set (config,
2494
 
                      y_param_spec->name, y_value,
2495
 
                      x_param_spec->name, x_value,
2496
 
                      NULL);
2497
 
      else
2498
 
        g_object_set (config,
2499
 
                      x_param_spec->name, x_value,
2500
 
                      y_param_spec->name, y_value,
2501
 
                      NULL);
2502
 
    }
2503
 
}
2504
 
 
2505
 
static void
2506
 
gimp_prop_coordinates_notify_x (GObject       *config,
2507
 
                                GParamSpec    *param_spec,
2508
 
                                GimpSizeEntry *sizeentry)
2509
 
{
2510
 
  gdouble value;
2511
 
 
2512
 
  if (G_IS_PARAM_SPEC_INT (param_spec))
2513
 
    {
2514
 
      gint int_value;
2515
 
 
2516
 
      g_object_get (config,
2517
 
                    param_spec->name, &int_value,
2518
 
                    NULL);
2519
 
 
2520
 
      value = int_value;
2521
 
    }
2522
 
  else
2523
 
    {
2524
 
      g_object_get (config,
2525
 
                    param_spec->name, &value,
2526
 
                    NULL);
2527
 
    }
2528
 
 
2529
 
  if (value != gimp_size_entry_get_refval (sizeentry, 0))
2530
 
    {
2531
 
      g_signal_handlers_block_by_func (sizeentry,
2532
 
                                       gimp_prop_coordinates_callback,
2533
 
                                       config);
2534
 
 
2535
 
      gimp_size_entry_set_refval (sizeentry, 0, value);
2536
 
 
2537
 
      g_signal_handlers_unblock_by_func (sizeentry,
2538
 
                                         gimp_prop_coordinates_callback,
2539
 
                                         config);
2540
 
    }
2541
 
}
2542
 
 
2543
 
static void
2544
 
gimp_prop_coordinates_notify_y (GObject       *config,
2545
 
                                GParamSpec    *param_spec,
2546
 
                                GimpSizeEntry *sizeentry)
2547
 
{
2548
 
  gdouble value;
2549
 
 
2550
 
  if (G_IS_PARAM_SPEC_INT (param_spec))
2551
 
    {
2552
 
      gint int_value;
2553
 
 
2554
 
      g_object_get (config,
2555
 
                    param_spec->name, &int_value,
2556
 
                    NULL);
2557
 
 
2558
 
      value = int_value;
2559
 
    }
2560
 
  else
2561
 
    {
2562
 
      g_object_get (config,
2563
 
                    param_spec->name, &value,
2564
 
                    NULL);
2565
 
    }
2566
 
 
2567
 
  if (value != gimp_size_entry_get_refval (sizeentry, 1))
2568
 
    {
2569
 
      g_signal_handlers_block_by_func (sizeentry,
2570
 
                                       gimp_prop_coordinates_callback,
2571
 
                                       config);
2572
 
 
2573
 
      gimp_size_entry_set_refval (sizeentry, 1, value);
2574
 
 
2575
 
      g_signal_handlers_unblock_by_func (sizeentry,
2576
 
                                         gimp_prop_coordinates_callback,
2577
 
                                         config);
2578
 
    }
2579
 
}
2580
 
 
2581
 
static void
2582
 
gimp_prop_coordinates_notify_unit (GObject       *config,
2583
 
                                   GParamSpec    *param_spec,
2584
 
                                   GimpSizeEntry *sizeentry)
2585
 
{
2586
 
  GimpUnit value;
2587
 
 
2588
 
  g_object_get (config,
2589
 
                param_spec->name, &value,
2590
 
                NULL);
2591
 
 
2592
 
  if (value != gimp_size_entry_get_unit (sizeentry))
2593
 
    {
2594
 
      g_signal_handlers_block_by_func (sizeentry,
2595
 
                                       gimp_prop_coordinates_callback,
2596
 
                                       config);
2597
 
 
2598
 
      gimp_size_entry_set_unit (sizeentry, value);
2599
 
 
2600
 
      g_signal_handlers_unblock_by_func (sizeentry,
2601
 
                                         gimp_prop_coordinates_callback,
2602
 
                                         config);
2603
 
    }
2604
 
}
2605
 
 
2606
 
 
2607
 
/****************/
2608
 
/*  color area  */
2609
 
/****************/
2610
 
 
2611
 
static void   gimp_prop_color_area_callback (GtkWidget  *widget,
2612
 
                                             GObject    *config);
2613
 
static void   gimp_prop_color_area_notify   (GObject    *config,
2614
 
                                             GParamSpec *param_spec,
2615
 
                                             GtkWidget  *area);
2616
 
 
2617
 
GtkWidget *
2618
 
gimp_prop_color_area_new (GObject           *config,
2619
 
                          const gchar       *property_name,
2620
 
                          gint               width,
2621
 
                          gint               height,
2622
 
                          GimpColorAreaType  type)
2623
 
{
2624
 
  GParamSpec *param_spec;
2625
 
  GtkWidget  *area;
2626
 
  GimpRGB    *value;
2627
 
 
2628
 
  param_spec = check_param_spec (config, property_name,
2629
 
                                 GIMP_TYPE_PARAM_RGB, G_STRFUNC);
2630
 
  if (! param_spec)
2631
 
    return NULL;
2632
 
 
2633
 
  g_object_get (config,
2634
 
                property_name, &value,
2635
 
                NULL);
2636
 
 
2637
 
  area = gimp_color_area_new (value, type,
2638
 
                              GDK_BUTTON1_MASK | GDK_BUTTON2_MASK);
2639
 
  gtk_widget_set_size_request (area, width, height);
2640
 
 
2641
 
  g_free (value);
2642
 
 
2643
 
  set_param_spec (G_OBJECT (area), area, param_spec);
2644
 
 
2645
 
  g_signal_connect (area, "color_changed",
2646
 
                    G_CALLBACK (gimp_prop_color_area_callback),
2647
 
                    config);
2648
 
 
2649
 
  connect_notify (config, property_name,
2650
 
                  G_CALLBACK (gimp_prop_color_area_notify),
2651
 
                  area);
2652
 
 
2653
 
  return area;
2654
 
}
2655
 
 
2656
 
static void
2657
 
gimp_prop_color_area_callback (GtkWidget *area,
2658
 
                               GObject   *config)
2659
 
{
2660
 
  GParamSpec *param_spec;
2661
 
  GimpRGB     value;
2662
 
 
2663
 
  param_spec = get_param_spec (G_OBJECT (area));
2664
 
  if (! param_spec)
2665
 
    return;
2666
 
 
2667
 
  gimp_color_area_get_color (GIMP_COLOR_AREA (area), &value);
2668
 
 
2669
 
  g_signal_handlers_block_by_func (config,
2670
 
                                   gimp_prop_color_area_notify,
2671
 
                                   area);
2672
 
 
2673
 
  g_object_set (config,
2674
 
                param_spec->name, &value,
2675
 
                NULL);
2676
 
 
2677
 
  g_signal_handlers_unblock_by_func (config,
2678
 
                                     gimp_prop_color_area_notify,
2679
 
                                     area);
2680
 
}
2681
 
 
2682
 
static void
2683
 
gimp_prop_color_area_notify (GObject    *config,
2684
 
                             GParamSpec *param_spec,
2685
 
                             GtkWidget  *area)
2686
 
{
2687
 
  GimpRGB *value;
2688
 
 
2689
 
  g_object_get (config,
2690
 
                param_spec->name, &value,
2691
 
                NULL);
2692
 
 
2693
 
  g_signal_handlers_block_by_func (area,
2694
 
                                   gimp_prop_color_area_callback,
2695
 
                                   config);
2696
 
 
2697
 
  gimp_color_area_set_color (GIMP_COLOR_AREA (area), value);
2698
 
 
2699
 
  g_free (value);
2700
 
 
2701
 
  g_signal_handlers_unblock_by_func (area,
2702
 
                                     gimp_prop_color_area_callback,
2703
 
                                     config);
 
210
  g_signal_handlers_block_by_func (menu,
 
211
                                   gimp_prop_paint_menu_callback,
 
212
                                   config);
 
213
 
 
214
  gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (menu), value);
 
215
 
 
216
  g_signal_handlers_unblock_by_func (menu,
 
217
                                     gimp_prop_paint_menu_callback,
 
218
                                     config);
 
219
 
2704
220
}
2705
221
 
2706
222
 
2714
230
                                               GParamSpec *param_spec,
2715
231
                                               GtkWidget  *button);
2716
232
 
 
233
/**
 
234
 * gimp_prop_color_button_new:
 
235
 * @config:        #GimpConfig object to which property is attached.
 
236
 * @property_name: Name of #GimpRGB property.
 
237
 * @title:         Title of the #GimpColorPanel that is to be created
 
238
 * @width:         Width of color button.
 
239
 * @height:        Height of color button.
 
240
 * @type:          How transparency is represented.
 
241
 *
 
242
 * Creates a #GimpColorPanel to set and display the value of a #GimpRGB
 
243
 * property.  Pressing the button brings up a color selector dialog.
 
244
 *
 
245
 * Return value:  A new #GimpColorPanel widget.
 
246
 *
 
247
 * Since GIMP 2.4
 
248
 */
2717
249
GtkWidget *
2718
250
gimp_prop_color_button_new (GObject           *config,
2719
251
                            const gchar       *property_name,
2726
258
  GtkWidget  *button;
2727
259
  GimpRGB    *value;
2728
260
 
2729
 
  param_spec = check_param_spec (config, property_name,
2730
 
                                 GIMP_TYPE_PARAM_RGB, G_STRFUNC);
 
261
  param_spec = check_param_spec_w (config, property_name,
 
262
                                   GIMP_TYPE_PARAM_RGB, G_STRFUNC);
2731
263
  if (! param_spec)
2732
264
    return NULL;
2733
265
 
2736
268
                NULL);
2737
269
 
2738
270
  button = gimp_color_panel_new (title, value, type, width, height);
2739
 
 
2740
271
  g_free (value);
2741
272
 
2742
273
  set_param_spec (G_OBJECT (button), button, param_spec);
2743
274
 
2744
 
  g_signal_connect (button, "color_changed",
2745
 
                    G_CALLBACK (gimp_prop_color_button_callback),
2746
 
                    config);
 
275
  g_signal_connect (button, "color-changed",
 
276
                    G_CALLBACK (gimp_prop_color_button_callback),
 
277
                    config);
2747
278
 
2748
279
  connect_notify (config, property_name,
2749
280
                  G_CALLBACK (gimp_prop_color_button_notify),
2803
334
}
2804
335
 
2805
336
 
2806
 
/***************/
2807
 
/*  unit menu  */
2808
 
/***************/
2809
 
 
2810
 
static void   gimp_prop_unit_menu_callback (GtkWidget  *menu,
2811
 
                                            GObject    *config);
2812
 
static void   gimp_prop_unit_menu_notify   (GObject    *config,
2813
 
                                            GParamSpec *param_spec,
2814
 
                                            GtkWidget  *menu);
2815
 
 
2816
 
GtkWidget *
2817
 
gimp_prop_unit_menu_new (GObject     *config,
2818
 
                         const gchar *property_name,
2819
 
                         const gchar *unit_format)
2820
 
{
2821
 
  GParamSpec *param_spec;
2822
 
  GtkWidget  *menu;
2823
 
  GimpUnit    unit;
2824
 
  GValue      value = { 0, };
2825
 
  gboolean    show_pixels;
2826
 
  gboolean    show_percent;
2827
 
 
2828
 
  param_spec = check_param_spec (config, property_name,
2829
 
                                 GIMP_TYPE_PARAM_UNIT, G_STRFUNC);
2830
 
  if (! param_spec)
2831
 
    return NULL;
2832
 
 
2833
 
  g_value_init (&value, param_spec->value_type);
2834
 
 
2835
 
  g_value_set_int (&value, GIMP_UNIT_PIXEL);
2836
 
  show_pixels = (g_param_value_validate (param_spec, &value) == FALSE);
2837
 
 
2838
 
  g_value_set_int (&value, GIMP_UNIT_PERCENT);
2839
 
  show_percent = (g_param_value_validate (param_spec, &value) == FALSE);
2840
 
 
2841
 
  g_value_unset (&value);
2842
 
 
2843
 
  g_object_get (config,
2844
 
                property_name, &unit,
2845
 
                NULL);
2846
 
 
2847
 
  menu = gimp_unit_menu_new (unit_format, unit, show_pixels, show_percent, TRUE);
2848
 
 
2849
 
  set_param_spec (G_OBJECT (menu), menu, param_spec);
2850
 
 
2851
 
  g_signal_connect (menu, "unit_changed",
2852
 
                    G_CALLBACK (gimp_prop_unit_menu_callback),
2853
 
                    config);
2854
 
 
2855
 
  connect_notify (config, property_name,
2856
 
                  G_CALLBACK (gimp_prop_unit_menu_notify),
2857
 
                  menu);
2858
 
 
2859
 
  return menu;
2860
 
}
2861
 
 
2862
 
static void
2863
 
gimp_prop_unit_menu_callback (GtkWidget *menu,
2864
 
                              GObject   *config)
2865
 
{
2866
 
  GParamSpec *param_spec;
2867
 
  GimpUnit    unit;
2868
 
 
2869
 
  param_spec = get_param_spec (G_OBJECT (menu));
2870
 
  if (! param_spec)
2871
 
    return;
2872
 
 
2873
 
  gimp_unit_menu_update (menu, &unit);
2874
 
 
2875
 
  g_signal_handlers_block_by_func (config,
2876
 
                                   gimp_prop_unit_menu_notify,
2877
 
                                   menu);
2878
 
 
2879
 
  g_object_set (config,
2880
 
                param_spec->name, unit,
2881
 
                NULL);
2882
 
 
2883
 
  g_signal_handlers_unblock_by_func (config,
2884
 
                                     gimp_prop_unit_menu_notify,
2885
 
                                     menu);
2886
 
}
2887
 
 
2888
 
static void
2889
 
gimp_prop_unit_menu_notify (GObject    *config,
2890
 
                            GParamSpec *param_spec,
2891
 
                            GtkWidget  *menu)
2892
 
{
2893
 
  GimpUnit  unit;
2894
 
 
2895
 
  g_object_get (config,
2896
 
                param_spec->name, &unit,
2897
 
                NULL);
2898
 
 
2899
 
  g_signal_handlers_block_by_func (menu,
2900
 
                                   gimp_prop_unit_menu_callback,
2901
 
                                   config);
2902
 
 
2903
 
  gimp_unit_menu_set_unit (GIMP_UNIT_MENU (menu), unit);
2904
 
  gimp_unit_menu_update (menu, &unit);
2905
 
 
2906
 
  g_signal_handlers_unblock_by_func (menu,
2907
 
                                     gimp_prop_unit_menu_callback,
2908
 
                                     config);
2909
 
}
2910
 
 
2911
 
 
2912
 
/*************/
2913
 
/*  preview  */
2914
 
/*************/
2915
 
 
2916
 
static void   gimp_prop_preview_drop   (GtkWidget    *menu,
2917
 
                                        GimpViewable *viewable,
2918
 
                                        gpointer      data);
2919
 
static void   gimp_prop_preview_notify (GObject      *config,
2920
 
                                        GParamSpec   *param_spec,
2921
 
                                        GtkWidget    *preview);
2922
 
 
2923
 
GtkWidget *
2924
 
gimp_prop_preview_new (GObject     *config,
2925
 
                       const gchar *property_name,
2926
 
                       gint         size)
 
337
/*************/
 
338
/*  view  */
 
339
/*************/
 
340
 
 
341
static void   gimp_prop_view_drop   (GtkWidget    *menu,
 
342
                                     gint          x,
 
343
                                     gint          y,
 
344
                                     GimpViewable *viewable,
 
345
                                     gpointer      data);
 
346
static void   gimp_prop_view_notify (GObject      *config,
 
347
                                     GParamSpec   *param_spec,
 
348
                                     GtkWidget    *view);
 
349
 
 
350
/**
 
351
 * gimp_prop_view_new:
 
352
 * @config:        #GimpConfig object to which property is attached.
 
353
 * @context:       a #Gimpcontext.
 
354
 * @property_name: Name of #GimpViewable property.
 
355
 * @size:          Width and height of preview display.
 
356
 *
 
357
 * Creates a widget to display the value of a #GimpViewable property.
 
358
 *
 
359
 * Return value:  A new #GimpView widget.
 
360
 *
 
361
 * Since GIMP 2.4
 
362
 */
 
363
GtkWidget *
 
364
gimp_prop_view_new (GObject     *config,
 
365
                    const gchar *property_name,
 
366
                    GimpContext *context,
 
367
                    gint         size)
2927
368
{
2928
369
  GParamSpec   *param_spec;
2929
 
  GtkWidget    *preview;
 
370
  GtkWidget    *view;
2930
371
  GimpViewable *viewable;
2931
372
 
2932
 
  param_spec = check_param_spec (config, property_name,
2933
 
                                 G_TYPE_PARAM_OBJECT, G_STRFUNC);
 
373
  param_spec = check_param_spec_w (config, property_name,
 
374
                                   G_TYPE_PARAM_OBJECT, G_STRFUNC);
2934
375
  if (! param_spec)
2935
376
    return NULL;
2936
377
 
2942
383
      return NULL;
2943
384
    }
2944
385
 
2945
 
  preview = gimp_view_new_by_types (GIMP_TYPE_VIEW,
2946
 
                                    param_spec->value_type,
2947
 
                                    size, 0, FALSE);
 
386
  view = gimp_view_new_by_types (context,
 
387
                                 GIMP_TYPE_VIEW,
 
388
                                 param_spec->value_type,
 
389
                                 size, 0, FALSE);
2948
390
 
2949
 
  if (! preview)
 
391
  if (! view)
2950
392
    {
2951
 
      g_warning ("%s: cannot create preview for type '%s'",
 
393
      g_warning ("%s: cannot create view for type '%s'",
2952
394
                 G_STRFUNC, g_type_name (param_spec->value_type));
2953
395
      return NULL;
2954
396
    }
2959
401
 
2960
402
  if (viewable)
2961
403
    {
2962
 
      gimp_view_set_viewable (GIMP_VIEW (preview), viewable);
 
404
      gimp_view_set_viewable (GIMP_VIEW (view), viewable);
2963
405
      g_object_unref (viewable);
2964
406
    }
2965
407
 
2966
 
  set_param_spec (G_OBJECT (preview), preview, param_spec);
 
408
  set_param_spec (G_OBJECT (view), view, param_spec);
2967
409
 
2968
 
  gimp_dnd_viewable_dest_add (preview, param_spec->value_type,
2969
 
                              gimp_prop_preview_drop,
 
410
  gimp_dnd_viewable_dest_add (view, param_spec->value_type,
 
411
                              gimp_prop_view_drop,
2970
412
                              config);
2971
413
 
2972
414
  connect_notify (config, property_name,
2973
 
                  G_CALLBACK (gimp_prop_preview_notify),
2974
 
                  preview);
 
415
                  G_CALLBACK (gimp_prop_view_notify),
 
416
                  view);
2975
417
 
2976
 
  return preview;
 
418
  return view;
2977
419
}
2978
420
 
2979
421
static void
2980
 
gimp_prop_preview_drop (GtkWidget    *preview,
2981
 
                        GimpViewable *viewable,
2982
 
                        gpointer      data)
 
422
gimp_prop_view_drop (GtkWidget    *view,
 
423
                     gint          x,
 
424
                     gint          y,
 
425
                     GimpViewable *viewable,
 
426
                     gpointer      data)
2983
427
{
2984
428
  GObject    *config;
2985
429
  GParamSpec *param_spec;
2986
430
 
2987
 
  param_spec = get_param_spec (G_OBJECT (preview));
 
431
  param_spec = get_param_spec (G_OBJECT (view));
2988
432
  if (! param_spec)
2989
433
    return;
2990
434
 
2996
440
}
2997
441
 
2998
442
static void
2999
 
gimp_prop_preview_notify (GObject      *config,
3000
 
                          GParamSpec   *param_spec,
3001
 
                          GtkWidget    *preview)
 
443
gimp_prop_view_notify (GObject      *config,
 
444
                       GParamSpec   *param_spec,
 
445
                       GtkWidget    *view)
3002
446
{
3003
447
  GimpViewable *viewable;
3004
448
 
3006
450
                param_spec->name, &viewable,
3007
451
                NULL);
3008
452
 
3009
 
  gimp_view_set_viewable (GIMP_VIEW (preview), viewable);
 
453
  gimp_view_set_viewable (GIMP_VIEW (view), viewable);
3010
454
 
3011
455
  if (viewable)
3012
456
    g_object_unref (viewable);
3013
457
}
3014
458
 
3015
459
 
3016
 
/*****************/
3017
 
/*  stock image  */
3018
 
/*****************/
3019
 
 
3020
 
static void   gimp_prop_stock_image_notify (GObject    *config,
3021
 
                                            GParamSpec *param_spec,
3022
 
                                            GtkWidget  *image);
3023
 
 
 
460
typedef struct
 
461
{
 
462
  GObject     *config;
 
463
  const gchar *numerator_property;
 
464
  const gchar *denominator_property;
 
465
  const gchar *fixed_aspect_property;
 
466
} AspectData;
 
467
 
 
468
static void  gimp_prop_ratio_entry_notify   (GObject    *config,
 
469
                                             GParamSpec *param_spec,
 
470
                                             GtkEntry   *entry);
 
471
static void  gimp_prop_aspect_ratio_changed (GtkWidget  *widget,
 
472
                                             AspectData *data);
 
473
 
 
474
 
 
475
/**
 
476
 * gimp_prop_aspect_ratio_new:
 
477
 * @config:                Object to which property is attached.
 
478
 * @numerator_property:    Name of double property for numerator.
 
479
 * @denominator_property:  Name of double property for denominator.
 
480
 * @fixed_aspect_property: Name of boolean property for fixed aspect (or %NULL).
 
481
 *
 
482
 * Return value: a #GimpRatioEntry widget
 
483
 */
3024
484
GtkWidget *
3025
 
gimp_prop_stock_image_new (GObject     *config,
3026
 
                           const gchar *property_name,
3027
 
                           GtkIconSize  icon_size)
 
485
gimp_prop_aspect_ratio_new (GObject     *config,
 
486
                            const gchar *numerator_property,
 
487
                            const gchar *denominator_property,
 
488
                            const gchar *fixed_aspect_property)
3028
489
{
3029
 
  GParamSpec *param_spec;
3030
 
  GtkWidget  *image;
3031
 
  gchar      *stock_id;
3032
 
 
3033
 
  param_spec = check_param_spec (config, property_name,
3034
 
                                 G_TYPE_PARAM_STRING, G_STRFUNC);
3035
 
  if (! param_spec)
3036
 
    return NULL;
 
490
  AspectData *aspect_data;
 
491
  GtkWidget  *entry;
 
492
  gdouble     numerator;
 
493
  gdouble     denominator;
3037
494
 
3038
495
  g_object_get (config,
3039
 
                property_name, &stock_id,
 
496
                numerator_property,   &numerator,
 
497
                denominator_property, &denominator,
3040
498
                NULL);
3041
499
 
3042
 
  image = gtk_image_new_from_stock (stock_id, icon_size);
3043
 
 
3044
 
  if (stock_id)
3045
 
    g_free (stock_id);
3046
 
 
3047
 
  set_param_spec (G_OBJECT (image), image, param_spec);
3048
 
 
3049
 
  connect_notify (config, property_name,
3050
 
                  G_CALLBACK (gimp_prop_stock_image_notify),
3051
 
                  image);
3052
 
 
3053
 
  return image;
 
500
  aspect_data = g_new0 (AspectData, 1);
 
501
 
 
502
  aspect_data->config                = config;
 
503
  aspect_data->numerator_property    = numerator_property;
 
504
  aspect_data->denominator_property  = denominator_property;
 
505
  aspect_data->fixed_aspect_property = fixed_aspect_property;
 
506
 
 
507
  entry = gimp_ratio_entry_new ();
 
508
  gtk_entry_set_width_chars (GTK_ENTRY (entry), 7);
 
509
 
 
510
  g_object_set_data (G_OBJECT (entry),
 
511
                     "gimp-ratio-entry-aspect-data", aspect_data);
 
512
 
 
513
  gimp_ratio_entry_set_fraction (GIMP_RATIO_ENTRY (entry),
 
514
                                 numerator, denominator);
 
515
 
 
516
  g_signal_connect (entry, "ratio-changed",
 
517
                    G_CALLBACK (gimp_prop_aspect_ratio_changed),
 
518
                    aspect_data);
 
519
 
 
520
  connect_notify (config, numerator_property,
 
521
                  G_CALLBACK (gimp_prop_ratio_entry_notify),
 
522
                  entry);
 
523
  connect_notify (config, denominator_property,
 
524
                  G_CALLBACK (gimp_prop_ratio_entry_notify),
 
525
                  entry);
 
526
 
 
527
  return entry;
3054
528
}
3055
529
 
3056
530
static void
3057
 
gimp_prop_stock_image_notify (GObject    *config,
 
531
gimp_prop_ratio_entry_notify (GObject    *config,
3058
532
                              GParamSpec *param_spec,
3059
 
                              GtkWidget  *image)
 
533
                              GtkEntry   *entry)
3060
534
{
3061
 
  gchar *stock_id;
 
535
  AspectData *aspect_data = g_object_get_data (G_OBJECT (entry),
 
536
                                               "gimp-ratio-entry-aspect-data");
 
537
  gdouble     num, denom;
 
538
 
 
539
  g_return_if_fail (aspect_data != NULL);
3062
540
 
3063
541
  g_object_get (config,
3064
 
                param_spec->name, &stock_id,
3065
 
                NULL);
3066
 
 
3067
 
  gtk_image_set_from_stock (GTK_IMAGE (image), stock_id,
3068
 
                            GTK_IMAGE (image)->icon_size);
3069
 
 
3070
 
  if (stock_id)
3071
 
    g_free (stock_id);
 
542
                aspect_data->numerator_property,   &num,
 
543
                aspect_data->denominator_property, &denom,
 
544
                NULL);
 
545
 
 
546
  gimp_ratio_entry_set_fraction (GIMP_RATIO_ENTRY (entry), num, denom);
 
547
}
 
548
 
 
549
 
 
550
static void
 
551
gimp_prop_aspect_ratio_changed (GtkWidget  *widget,
 
552
                                AspectData *data)
 
553
{
 
554
  gdouble num, denom;
 
555
 
 
556
  gimp_ratio_entry_get_fraction (GIMP_RATIO_ENTRY (widget), &num, &denom);
 
557
 
 
558
  g_object_set (data->config,
 
559
                data->numerator_property,    num,
 
560
                data->denominator_property,  denom,
 
561
                data->fixed_aspect_property, TRUE,
 
562
                NULL);
3072
563
}
3073
564
 
3074
565
 
3100
591
    }
3101
592
}
3102
593
 
3103
 
static void
3104
 
set_radio_spec (GObject    *object,
3105
 
                GParamSpec *param_spec)
3106
 
{
3107
 
  GSList *list;
3108
 
 
3109
 
  for (list = gtk_radio_button_get_group (GTK_RADIO_BUTTON (object));
3110
 
       list;
3111
 
       list = g_slist_next (list))
3112
 
    {
3113
 
      set_param_spec (list->data, NULL, param_spec);
3114
 
    }
3115
 
}
3116
 
 
3117
594
static GParamSpec *
3118
595
get_param_spec (GObject *object)
3119
596
{
3165
642
  return param_spec;
3166
643
}
3167
644
 
3168
 
static gboolean
3169
 
get_numeric_values (GObject     *object,
3170
 
                    GParamSpec  *param_spec,
3171
 
                    gdouble     *value,
3172
 
                    gdouble     *lower,
3173
 
                    gdouble     *upper,
 
645
static GParamSpec *
 
646
check_param_spec_w (GObject     *object,
 
647
                    const gchar *property_name,
 
648
                    GType        type,
3174
649
                    const gchar *strloc)
3175
650
{
3176
 
  if (G_IS_PARAM_SPEC_INT (param_spec))
3177
 
    {
3178
 
      GParamSpecInt *int_spec = G_PARAM_SPEC_INT (param_spec);
3179
 
      gint           int_value;
3180
 
 
3181
 
      g_object_get (object, param_spec->name, &int_value, NULL);
3182
 
 
3183
 
      *value = int_value;
3184
 
      *lower = int_spec->minimum;
3185
 
      *upper = int_spec->maximum;
3186
 
    }
3187
 
  else if (G_IS_PARAM_SPEC_UINT (param_spec))
3188
 
    {
3189
 
      GParamSpecUInt *uint_spec = G_PARAM_SPEC_UINT (param_spec);
3190
 
      guint           uint_value;
3191
 
 
3192
 
      g_object_get (object, param_spec->name, &uint_value, NULL);
3193
 
 
3194
 
      *value = uint_value;
3195
 
      *lower = uint_spec->minimum;
3196
 
      *upper = uint_spec->maximum;
3197
 
    }
3198
 
  else if (G_IS_PARAM_SPEC_DOUBLE (param_spec))
3199
 
    {
3200
 
      GParamSpecDouble *double_spec = G_PARAM_SPEC_DOUBLE (param_spec);
3201
 
 
3202
 
      g_object_get (object, param_spec->name, value, NULL);
3203
 
 
3204
 
      *lower = double_spec->minimum;
3205
 
      *upper = double_spec->maximum;
3206
 
    }
3207
 
  else
3208
 
    {
3209
 
      g_warning ("%s: property '%s' of %s is not numeric",
 
651
  GParamSpec *param_spec;
 
652
 
 
653
  param_spec = check_param_spec (object, property_name, type, strloc);
 
654
 
 
655
  if (param_spec &&
 
656
      (param_spec->flags & G_PARAM_WRITABLE) == 0)
 
657
    {
 
658
      g_warning ("%s: property '%s' of %s is writable",
3210
659
                 strloc,
3211
660
                 param_spec->name,
3212
 
                 g_type_name (G_TYPE_FROM_INSTANCE (object)));
3213
 
      return FALSE;
 
661
                 g_type_name (param_spec->owner_type));
 
662
      return NULL;
3214
663
    }
3215
664
 
3216
 
  return TRUE;
 
665
  return param_spec;
3217
666
}
3218
667
 
3219
668
static void