1
/* LIBGIMP - The GIMP Library
2
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
5
* Copyright (C) 2004 Sven Neumann <sven@gimp.org>
7
* This library is free software: you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 3 of the License, or (at your option) any later version.
12
* This library is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with this library. If not, see
19
* <http://www.gnu.org/licenses/>.
26
#include "libgimpbase/gimpbase.h"
28
#include "gimpwidgetstypes.h"
30
#include "gimpunitstore.h"
54
} GimpUnitStorePrivate;
56
#define GET_PRIVATE(obj) G_TYPE_INSTANCE_GET_PRIVATE (obj, \
57
GIMP_TYPE_UNIT_STORE, \
61
static void gimp_unit_store_tree_model_init (GtkTreeModelIface *iface);
63
static void gimp_unit_store_finalize (GObject *object);
64
static void gimp_unit_store_set_property (GObject *object,
68
static void gimp_unit_store_get_property (GObject *object,
73
static GtkTreeModelFlags gimp_unit_store_get_flags (GtkTreeModel *tree_model);
74
static gint gimp_unit_store_get_n_columns (GtkTreeModel *tree_model);
75
static GType gimp_unit_store_get_column_type (GtkTreeModel *tree_model,
77
static gboolean gimp_unit_store_get_iter (GtkTreeModel *tree_model,
80
static GtkTreePath *gimp_unit_store_get_path (GtkTreeModel *tree_model,
82
static void gimp_unit_store_tree_model_get_value (GtkTreeModel *tree_model,
86
static gboolean gimp_unit_store_iter_next (GtkTreeModel *tree_model,
88
static gboolean gimp_unit_store_iter_children (GtkTreeModel *tree_model,
91
static gboolean gimp_unit_store_iter_has_child (GtkTreeModel *tree_model,
93
static gint gimp_unit_store_iter_n_children (GtkTreeModel *tree_model,
95
static gboolean gimp_unit_store_iter_nth_child (GtkTreeModel *tree_model,
99
static gboolean gimp_unit_store_iter_parent (GtkTreeModel *tree_model,
104
G_DEFINE_TYPE_WITH_CODE (GimpUnitStore, gimp_unit_store, G_TYPE_OBJECT,
105
G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL,
106
gimp_unit_store_tree_model_init))
108
#define parent_class gimp_unit_store_parent_class
111
static GType column_types[GIMP_UNIT_STORE_UNIT_COLUMNS] =
127
gimp_unit_store_class_init (GimpUnitStoreClass *klass)
129
GObjectClass *object_class = G_OBJECT_CLASS (klass);
131
column_types[GIMP_UNIT_STORE_UNIT] = GIMP_TYPE_UNIT;
133
object_class->finalize = gimp_unit_store_finalize;
134
object_class->set_property = gimp_unit_store_set_property;
135
object_class->get_property = gimp_unit_store_get_property;
137
g_object_class_install_property (object_class, PROP_NUM_VALUES,
138
g_param_spec_int ("num-values",
141
GIMP_PARAM_READWRITE |
142
G_PARAM_CONSTRUCT_ONLY));
144
g_object_class_install_property (object_class, PROP_HAS_PIXELS,
145
g_param_spec_boolean ("has-pixels",
148
GIMP_PARAM_READWRITE));
150
g_object_class_install_property (object_class, PROP_HAS_PERCENT,
151
g_param_spec_boolean ("has-percent",
154
GIMP_PARAM_READWRITE));
156
g_object_class_install_property (object_class, PROP_SHORT_FORMAT,
157
g_param_spec_string ("short-format",
160
GIMP_PARAM_READWRITE));
162
g_object_class_install_property (object_class, PROP_LONG_FORMAT,
163
g_param_spec_string ("long-format",
166
GIMP_PARAM_READWRITE));
168
g_type_class_add_private (object_class, sizeof (GimpUnitStorePrivate));
172
gimp_unit_store_init (GimpUnitStore *store)
174
GimpUnitStorePrivate *private = GET_PRIVATE (store);
176
private->has_pixels = TRUE;
177
private->has_percent = FALSE;
178
private->short_format = g_strdup ("%a");
179
private->long_format = g_strdup ("%p");
183
gimp_unit_store_tree_model_init (GtkTreeModelIface *iface)
185
iface->get_flags = gimp_unit_store_get_flags;
186
iface->get_n_columns = gimp_unit_store_get_n_columns;
187
iface->get_column_type = gimp_unit_store_get_column_type;
188
iface->get_iter = gimp_unit_store_get_iter;
189
iface->get_path = gimp_unit_store_get_path;
190
iface->get_value = gimp_unit_store_tree_model_get_value;
191
iface->iter_next = gimp_unit_store_iter_next;
192
iface->iter_children = gimp_unit_store_iter_children;
193
iface->iter_has_child = gimp_unit_store_iter_has_child;
194
iface->iter_n_children = gimp_unit_store_iter_n_children;
195
iface->iter_nth_child = gimp_unit_store_iter_nth_child;
196
iface->iter_parent = gimp_unit_store_iter_parent;
200
gimp_unit_store_finalize (GObject *object)
202
GimpUnitStorePrivate *private = GET_PRIVATE (object);
204
if (private->short_format)
206
g_free (private->short_format);
207
private->short_format = NULL;
210
if (private->long_format)
212
g_free (private->long_format);
213
private->long_format = NULL;
216
if (private->num_values > 0)
218
g_free (private->values);
219
g_free (private->resolutions);
220
private->num_values = 0;
223
G_OBJECT_CLASS (parent_class)->finalize (object);
227
gimp_unit_store_set_property (GObject *object,
232
GimpUnitStorePrivate *private = GET_PRIVATE (object);
236
case PROP_NUM_VALUES:
237
g_return_if_fail (private->num_values == 0);
238
private->num_values = g_value_get_int (value);
239
if (private->num_values)
241
private->values = g_new0 (gdouble, private->num_values);
242
private->resolutions = g_new0 (gdouble, private->num_values);
245
case PROP_HAS_PIXELS:
246
gimp_unit_store_set_has_pixels (GIMP_UNIT_STORE (object),
247
g_value_get_boolean (value));
249
case PROP_HAS_PERCENT:
250
gimp_unit_store_set_has_percent (GIMP_UNIT_STORE (object),
251
g_value_get_boolean (value));
253
case PROP_SHORT_FORMAT:
254
g_free (private->short_format);
255
private->short_format = g_value_dup_string (value);
256
if (! private->short_format)
257
private->short_format = g_strdup ("%a");
259
case PROP_LONG_FORMAT:
260
g_free (private->long_format);
261
private->long_format = g_value_dup_string (value);
262
if (! private->long_format)
263
private->long_format = g_strdup ("%a");
267
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
273
gimp_unit_store_get_property (GObject *object,
278
GimpUnitStorePrivate *private = GET_PRIVATE (object);
282
case PROP_NUM_VALUES:
283
g_value_set_int (value, private->num_values);
285
case PROP_HAS_PIXELS:
286
g_value_set_boolean (value, private->has_pixels);
288
case PROP_HAS_PERCENT:
289
g_value_set_boolean (value, private->has_percent);
291
case PROP_SHORT_FORMAT:
292
g_value_set_string (value, private->short_format);
294
case PROP_LONG_FORMAT:
295
g_value_set_string (value, private->long_format);
299
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
304
static GtkTreeModelFlags
305
gimp_unit_store_get_flags (GtkTreeModel *tree_model)
307
return GTK_TREE_MODEL_ITERS_PERSIST | GTK_TREE_MODEL_LIST_ONLY;
311
gimp_unit_store_get_n_columns (GtkTreeModel *tree_model)
313
GimpUnitStorePrivate *private = GET_PRIVATE (tree_model);
315
return GIMP_UNIT_STORE_UNIT_COLUMNS + private->num_values;
319
gimp_unit_store_get_column_type (GtkTreeModel *tree_model,
322
g_return_val_if_fail (index >= 0, G_TYPE_INVALID);
324
if (index < GIMP_UNIT_STORE_UNIT_COLUMNS)
325
return column_types[index];
327
return G_TYPE_DOUBLE;
331
gimp_unit_store_get_iter (GtkTreeModel *tree_model,
335
GimpUnitStorePrivate *private = GET_PRIVATE (tree_model);
339
g_return_val_if_fail (gtk_tree_path_get_depth (path) > 0, FALSE);
341
index = gtk_tree_path_get_indices (path)[0];
345
if (! private->has_pixels)
348
if (private->has_percent)
352
if (private->has_pixels)
355
unit = GIMP_UNIT_PIXEL;
357
unit = GIMP_UNIT_PERCENT;
362
unit = GIMP_UNIT_PERCENT;
366
if ((unit >= 0 && unit < gimp_unit_get_number_of_units ()) ||
367
((unit == GIMP_UNIT_PERCENT && private->has_percent)))
369
iter->user_data = GINT_TO_POINTER (unit);
377
gimp_unit_store_get_path (GtkTreeModel *tree_model,
380
GimpUnitStorePrivate *private = GET_PRIVATE (tree_model);
381
GtkTreePath *path = gtk_tree_path_new ();
382
GimpUnit unit = GPOINTER_TO_INT (iter->user_data);
387
if (! private->has_pixels)
390
if (private->has_percent)
394
if (private->has_pixels)
396
if (unit == GIMP_UNIT_PIXEL)
398
else if (unit == GIMP_UNIT_PERCENT)
403
if (unit == GIMP_UNIT_PERCENT)
408
gtk_tree_path_append_index (path, index);
414
gimp_unit_store_tree_model_get_value (GtkTreeModel *tree_model,
419
GimpUnitStorePrivate *private = GET_PRIVATE (tree_model);
422
g_return_if_fail (column >= 0 &&
423
column < GIMP_UNIT_STORE_UNIT_COLUMNS + private->num_values);
426
column < GIMP_UNIT_STORE_UNIT_COLUMNS ?
427
column_types[column] :
430
unit = GPOINTER_TO_INT (iter->user_data);
432
if ((unit >= 0 && unit < gimp_unit_get_number_of_units ()) ||
433
((unit == GIMP_UNIT_PERCENT && private->has_percent)))
437
case GIMP_UNIT_STORE_UNIT:
438
g_value_set_int (value, unit);
440
case GIMP_UNIT_STORE_UNIT_FACTOR:
441
g_value_set_double (value, gimp_unit_get_factor (unit));
443
case GIMP_UNIT_STORE_UNIT_DIGITS:
444
g_value_set_int (value, gimp_unit_get_digits (unit));
446
case GIMP_UNIT_STORE_UNIT_IDENTIFIER:
447
g_value_set_static_string (value, gimp_unit_get_identifier (unit));
449
case GIMP_UNIT_STORE_UNIT_SYMBOL:
450
g_value_set_static_string (value, gimp_unit_get_symbol (unit));
452
case GIMP_UNIT_STORE_UNIT_ABBREVIATION:
453
g_value_set_static_string (value, gimp_unit_get_abbreviation (unit));
455
case GIMP_UNIT_STORE_UNIT_SINGULAR:
456
g_value_set_static_string (value, gimp_unit_get_singular (unit));
458
case GIMP_UNIT_STORE_UNIT_PLURAL:
459
g_value_set_static_string (value, gimp_unit_get_plural (unit));
461
case GIMP_UNIT_STORE_UNIT_SHORT_FORMAT:
462
g_value_take_string (value,
463
gimp_unit_format_string (private->short_format,
466
case GIMP_UNIT_STORE_UNIT_LONG_FORMAT:
467
g_value_take_string (value,
468
gimp_unit_format_string (private->long_format,
473
column -= GIMP_UNIT_STORE_UNIT_COLUMNS;
474
if (unit == GIMP_UNIT_PIXEL)
476
g_value_set_double (value, private->values[column]);
478
else if (private->resolutions[column])
480
g_value_set_double (value,
481
private->values[column] *
482
gimp_unit_get_factor (unit) /
483
private->resolutions[column]);
491
gimp_unit_store_iter_next (GtkTreeModel *tree_model,
494
GimpUnitStorePrivate *private = GET_PRIVATE (tree_model);
495
GimpUnit unit = GPOINTER_TO_INT (iter->user_data);
497
if (unit == GIMP_UNIT_PIXEL && private->has_percent)
499
unit = GIMP_UNIT_PERCENT;
501
else if (unit == GIMP_UNIT_PERCENT)
503
unit = GIMP_UNIT_INCH;
505
else if (unit >= 0 && unit < gimp_unit_get_number_of_units () - 1)
514
iter->user_data = GINT_TO_POINTER (unit);
520
gimp_unit_store_iter_children (GtkTreeModel *tree_model,
524
GimpUnitStorePrivate *private = GET_PRIVATE (tree_model);
527
/* this is a list, nodes have no children */
531
if (private->has_pixels)
533
unit = GIMP_UNIT_PIXEL;
535
else if (private->has_percent)
537
unit = GIMP_UNIT_PERCENT;
541
unit = GIMP_UNIT_INCH;
544
iter->user_data = GINT_TO_POINTER (unit);
550
gimp_unit_store_iter_has_child (GtkTreeModel *tree_model,
557
gimp_unit_store_iter_n_children (GtkTreeModel *tree_model,
560
GimpUnitStorePrivate *private = GET_PRIVATE (tree_model);
566
n_children = gimp_unit_get_number_of_units ();
568
if (! private->has_pixels)
571
if (private->has_percent)
578
gimp_unit_store_iter_nth_child (GtkTreeModel *tree_model,
583
GimpUnitStorePrivate *private = GET_PRIVATE (tree_model);
589
n_children = gimp_unit_store_iter_n_children (tree_model, NULL);
591
if (n >= 0 && n < n_children)
595
if (! private->has_pixels)
598
if (private->has_percent)
602
if (private->has_pixels)
605
unit = GIMP_UNIT_PIXEL;
607
unit = GIMP_UNIT_PERCENT;
612
unit = GIMP_UNIT_PERCENT;
616
iter->user_data = GINT_TO_POINTER (unit);
625
gimp_unit_store_iter_parent (GtkTreeModel *tree_model,
634
gimp_unit_store_new (gint num_values)
636
return g_object_new (GIMP_TYPE_UNIT_STORE,
637
"num-values", num_values,
642
gimp_unit_store_set_has_pixels (GimpUnitStore *store,
645
GimpUnitStorePrivate *private;
647
g_return_if_fail (GIMP_IS_UNIT_STORE (store));
649
private = GET_PRIVATE (store);
651
has_pixels = has_pixels ? TRUE : FALSE;
653
if (has_pixels != private->has_pixels)
655
GtkTreeModel *model = GTK_TREE_MODEL (store);
656
GtkTreePath *deleted_path = NULL;
662
gtk_tree_model_get_iter_first (model, &iter);
663
deleted_path = gtk_tree_model_get_path (model, &iter);
666
private->has_pixels = has_pixels;
673
gtk_tree_model_get_iter_first (model, &iter);
674
path = gtk_tree_model_get_path (model, &iter);
675
gtk_tree_model_row_inserted (model, path, &iter);
676
gtk_tree_path_free (path);
678
else if (deleted_path)
680
gtk_tree_model_row_deleted (model, deleted_path);
681
gtk_tree_path_free (deleted_path);
684
g_object_notify (G_OBJECT (store), "has-pixels");
689
gimp_unit_store_get_has_pixels (GimpUnitStore *store)
691
GimpUnitStorePrivate *private;
693
g_return_val_if_fail (GIMP_IS_UNIT_STORE (store), FALSE);
695
private = GET_PRIVATE (store);
697
return private->has_pixels;
701
gimp_unit_store_set_has_percent (GimpUnitStore *store,
702
gboolean has_percent)
704
GimpUnitStorePrivate *private;
706
g_return_if_fail (GIMP_IS_UNIT_STORE (store));
708
private = GET_PRIVATE (store);
710
has_percent = has_percent ? TRUE : FALSE;
712
if (has_percent != private->has_percent)
714
GtkTreeModel *model = GTK_TREE_MODEL (store);
715
GtkTreePath *deleted_path = NULL;
721
gtk_tree_model_get_iter_first (model, &iter);
722
if (private->has_pixels)
723
gtk_tree_model_iter_next (model, &iter);
724
deleted_path = gtk_tree_model_get_path (model, &iter);
727
private->has_percent = has_percent;
734
gtk_tree_model_get_iter_first (model, &iter);
735
if (private->has_pixels)
736
gtk_tree_model_iter_next (model, &iter);
737
path = gtk_tree_model_get_path (model, &iter);
738
gtk_tree_model_row_inserted (model, path, &iter);
739
gtk_tree_path_free (path);
741
else if (deleted_path)
743
gtk_tree_model_row_deleted (model, deleted_path);
744
gtk_tree_path_free (deleted_path);
747
g_object_notify (G_OBJECT (store), "has-percent");
752
gimp_unit_store_get_has_percent (GimpUnitStore *store)
754
GimpUnitStorePrivate *private;
756
g_return_val_if_fail (GIMP_IS_UNIT_STORE (store), FALSE);
758
private = GET_PRIVATE (store);
760
return private->has_percent;
764
gimp_unit_store_set_pixel_value (GimpUnitStore *store,
768
GimpUnitStorePrivate *private;
770
g_return_if_fail (GIMP_IS_UNIT_STORE (store));
772
private = GET_PRIVATE (store);
774
g_return_if_fail (index > 0 && index < private->num_values);
776
private->values[index] = value;
780
gimp_unit_store_set_pixel_values (GimpUnitStore *store,
784
GimpUnitStorePrivate *private;
788
g_return_if_fail (GIMP_IS_UNIT_STORE (store));
790
private = GET_PRIVATE (store);
792
va_start (args, first_value);
794
for (i = 0; i < private->num_values; )
796
private->values[i] = first_value;
798
if (++i < private->num_values)
799
first_value = va_arg (args, gdouble);
806
gimp_unit_store_set_resolution (GimpUnitStore *store,
810
GimpUnitStorePrivate *private;
812
g_return_if_fail (GIMP_IS_UNIT_STORE (store));
814
private = GET_PRIVATE (store);
816
g_return_if_fail (index > 0 && index < private->num_values);
818
private->resolutions[index] = resolution;
822
gimp_unit_store_set_resolutions (GimpUnitStore *store,
823
gdouble first_resolution,
826
GimpUnitStorePrivate *private;
830
g_return_if_fail (GIMP_IS_UNIT_STORE (store));
832
private = GET_PRIVATE (store);
834
va_start (args, first_resolution);
836
for (i = 0; i < private->num_values; )
838
private->resolutions[i] = first_resolution;
840
if (++i < private->num_values)
841
first_resolution = va_arg (args, gdouble);
848
gimp_unit_store_get_value (GimpUnitStore *store,
852
GimpUnitStorePrivate *private;
854
GValue value = { 0, };
856
g_return_val_if_fail (GIMP_IS_UNIT_STORE (store), 0.0);
858
private = GET_PRIVATE (store);
860
g_return_val_if_fail (index >= 0 && index < private->num_values, 0.0);
862
iter.user_data = GINT_TO_POINTER (unit);
864
gimp_unit_store_tree_model_get_value (GTK_TREE_MODEL (store),
866
GIMP_UNIT_STORE_FIRST_VALUE + index,
869
return g_value_get_double (&value);
873
gimp_unit_store_get_values (GimpUnitStore *store,
875
gdouble *first_value,
878
GimpUnitStorePrivate *private;
882
g_return_if_fail (GIMP_IS_UNIT_STORE (store));
884
private = GET_PRIVATE (store);
886
va_start (args, first_value);
888
for (i = 0; i < private->num_values; )
891
*first_value = gimp_unit_store_get_value (store, unit, i);
893
if (++i < private->num_values)
894
first_value = va_arg (args, gdouble *);