~ubuntu-branches/ubuntu/vivid/gimp/vivid

« back to all changes in this revision

Viewing changes to app/core/gimpviewable.c

  • Committer: Package Import Robot
  • Author(s): Jordi Mallach
  • Date: 2012-05-08 18:50:03 UTC
  • mto: (1.1.26) (0.5.1 experimental)
  • mto: This revision was merged to the branch mainline in revision 71.
  • Revision ID: package-import@ubuntu.com-20120508185003-tltkvbaysf8d2426
ImportĀ upstreamĀ versionĀ 2.8.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
 * gimpviewable.c
5
5
 * Copyright (C) 2001 Michael Natterer <mitch@gimp.org>
6
6
 *
7
 
 * This program is free software; you can redistribute it and/or modify
 
7
 * This program is free software: you can redistribute it and/or modify
8
8
 * it under the terms of the GNU General Public License as published by
9
 
 * the Free Software Foundation; either version 2 of the License, or
 
9
 * the Free Software Foundation; either version 3 of the License, or
10
10
 * (at your option) any later version.
11
11
 *
12
12
 * This program is distributed in the hope that it will be useful,
15
15
 * GNU General Public License for more details.
16
16
 *
17
17
 * You should have received a copy of the GNU General Public License
18
 
 * along with this program; if not, write to the Free Software
19
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
19
 */
21
20
 
22
21
#include "config.h"
55
54
};
56
55
 
57
56
 
 
57
typedef struct _GimpViewablePrivate GimpViewablePrivate;
 
58
 
 
59
struct _GimpViewablePrivate
 
60
{
 
61
  gchar        *stock_id;
 
62
  gint          freeze_count;
 
63
  GimpViewable *parent;
 
64
 
 
65
  TempBuf      *preview_temp_buf;
 
66
  GdkPixbuf    *preview_pixbuf;
 
67
};
 
68
 
 
69
#define GET_PRIVATE(viewable) G_TYPE_INSTANCE_GET_PRIVATE (viewable, \
 
70
                                                           GIMP_TYPE_VIEWABLE, \
 
71
                                                           GimpViewablePrivate)
 
72
 
 
73
 
58
74
static void    gimp_viewable_config_iface_init (GimpConfigInterface *iface);
59
75
 
60
76
static void    gimp_viewable_finalize               (GObject        *object);
90
106
                                                      gint          *popup_height);
91
107
static gchar * gimp_viewable_real_get_description    (GimpViewable  *viewable,
92
108
                                                      gchar        **tooltip);
 
109
static GimpContainer * gimp_viewable_real_get_children (GimpViewable *viewable);
 
110
 
93
111
static gboolean gimp_viewable_serialize_property     (GimpConfig    *config,
94
112
                                                      guint          property_id,
95
113
                                                      const GValue  *value,
103
121
 
104
122
#define parent_class gimp_viewable_parent_class
105
123
 
106
 
static guint  viewable_signals[LAST_SIGNAL] = { 0 };
107
 
static GQuark quark_preview_temp_buf        = 0;
108
 
static GQuark quark_preview_pixbuf          = 0;
 
124
static guint viewable_signals[LAST_SIGNAL] = { 0 };
109
125
 
110
126
 
111
127
static void
114
130
  GObjectClass    *object_class      = G_OBJECT_CLASS (klass);
115
131
  GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass);
116
132
 
117
 
  quark_preview_temp_buf = g_quark_from_static_string ("viewable-preview-temp-buf");
118
 
  quark_preview_pixbuf   = g_quark_from_static_string ("viewable-preview-pixbuf");
119
 
 
120
133
  viewable_signals[INVALIDATE_PREVIEW] =
121
134
    g_signal_new ("invalidate-preview",
122
135
                  G_TYPE_FROM_CLASS (klass),
155
168
  klass->get_pixbuf              = NULL;
156
169
  klass->get_new_pixbuf          = gimp_viewable_real_get_new_pixbuf;
157
170
  klass->get_description         = gimp_viewable_real_get_description;
 
171
  klass->get_children            = gimp_viewable_real_get_children;
 
172
  klass->set_expanded            = NULL;
 
173
  klass->get_expanded            = NULL;
158
174
 
159
175
  GIMP_CONFIG_INSTALL_PROP_STRING (object_class, PROP_STOCK_ID, "stock-id",
160
176
                                   NULL, NULL,
165
181
                                                         NULL, NULL,
166
182
                                                         FALSE,
167
183
                                                         GIMP_PARAM_READABLE));
 
184
 
 
185
  g_type_class_add_private (klass, sizeof (GimpViewablePrivate));
168
186
}
169
187
 
170
188
static void
171
189
gimp_viewable_init (GimpViewable *viewable)
172
190
{
173
 
  viewable->stock_id     = NULL;
174
 
  viewable->freeze_count = 0;
175
191
}
176
192
 
177
193
static void
183
199
static void
184
200
gimp_viewable_finalize (GObject *object)
185
201
{
186
 
  GimpViewable *viewable = GIMP_VIEWABLE (object);
187
 
 
188
 
  if (viewable->stock_id)
189
 
    {
190
 
      g_free (viewable->stock_id);
191
 
      viewable->stock_id = NULL;
 
202
  GimpViewablePrivate *private = GET_PRIVATE (object);
 
203
 
 
204
  if (private->stock_id)
 
205
    {
 
206
      g_free (private->stock_id);
 
207
      private->stock_id = NULL;
 
208
    }
 
209
 
 
210
  if (private->preview_temp_buf)
 
211
    {
 
212
      temp_buf_free (private->preview_temp_buf);
 
213
      private->preview_temp_buf = NULL;
 
214
    }
 
215
 
 
216
  if (private->preview_pixbuf)
 
217
    {
 
218
      g_object_unref (private->preview_pixbuf);
 
219
      private->preview_pixbuf = NULL;
192
220
    }
193
221
 
194
222
  G_OBJECT_CLASS (parent_class)->finalize (object);
243
271
gimp_viewable_get_memsize (GimpObject *object,
244
272
                           gint64     *gui_size)
245
273
{
246
 
  TempBuf   *temp_buf;
247
 
  GdkPixbuf *pixbuf;
248
 
 
249
 
  temp_buf = g_object_get_qdata (G_OBJECT (object), quark_preview_temp_buf);
250
 
  pixbuf   = g_object_get_qdata (G_OBJECT (object), quark_preview_pixbuf);
251
 
 
252
 
  *gui_size += temp_buf_get_memsize (temp_buf);
253
 
 
254
 
  if (pixbuf)
 
274
  GimpViewablePrivate *private = GET_PRIVATE (object);
 
275
 
 
276
  *gui_size += temp_buf_get_memsize (private->preview_temp_buf);
 
277
 
 
278
  if (private->preview_pixbuf)
255
279
    {
256
 
      static gsize pixbuf_instance_size = 0;
257
 
 
258
 
      if (! pixbuf_instance_size)
259
 
        {
260
 
          GTypeQuery type_query;
261
 
 
262
 
          g_type_query (G_TYPE_FROM_INSTANCE (pixbuf), &type_query);
263
 
 
264
 
          pixbuf_instance_size = type_query.instance_size;
265
 
        }
266
 
 
267
 
      *gui_size += (pixbuf_instance_size +
268
 
                    (gsize) gdk_pixbuf_get_height (pixbuf) *
269
 
                            gdk_pixbuf_get_rowstride (pixbuf));
 
280
      *gui_size +=
 
281
        (gimp_g_object_get_memsize (G_OBJECT (private->preview_pixbuf)) +
 
282
         (gsize) gdk_pixbuf_get_height (private->preview_pixbuf) *
 
283
         gdk_pixbuf_get_rowstride (private->preview_pixbuf));
270
284
    }
271
285
 
272
286
  return GIMP_OBJECT_CLASS (parent_class)->get_memsize (object, gui_size);
275
289
static void
276
290
gimp_viewable_real_invalidate_preview (GimpViewable *viewable)
277
291
{
278
 
  g_object_set_qdata (G_OBJECT (viewable), quark_preview_temp_buf, NULL);
279
 
  g_object_set_qdata (G_OBJECT (viewable), quark_preview_pixbuf, NULL);
 
292
  GimpViewablePrivate *private = GET_PRIVATE (viewable);
 
293
 
 
294
  if (private->preview_temp_buf)
 
295
    {
 
296
      temp_buf_free (private->preview_temp_buf);
 
297
      private->preview_temp_buf = NULL;
 
298
    }
 
299
 
 
300
  if (private->preview_pixbuf)
 
301
    {
 
302
      g_object_unref (private->preview_pixbuf);
 
303
      private->preview_pixbuf = NULL;
 
304
    }
280
305
}
281
306
 
282
307
static void
350
375
          bytes    = color_bytes;
351
376
        }
352
377
 
353
 
      pixbuf = gdk_pixbuf_new_from_data (g_memdup (temp_buf_data (temp_buf),
 
378
      pixbuf = gdk_pixbuf_new_from_data (g_memdup (temp_buf_get_data (temp_buf),
354
379
                                                   width * height * bytes),
355
380
                                         GDK_COLORSPACE_RGB,
356
381
                                         (bytes == 4),
372
397
gimp_viewable_real_get_description (GimpViewable  *viewable,
373
398
                                    gchar        **tooltip)
374
399
{
375
 
  return g_strdup (gimp_object_get_name (GIMP_OBJECT (viewable)));
 
400
  return g_strdup (gimp_object_get_name (viewable));
 
401
}
 
402
 
 
403
static GimpContainer *
 
404
gimp_viewable_real_get_children (GimpViewable *viewable)
 
405
{
 
406
  return NULL;
376
407
}
377
408
 
378
409
static gboolean
382
413
                                  GParamSpec       *pspec,
383
414
                                  GimpConfigWriter *writer)
384
415
{
385
 
  GimpViewable *viewable = GIMP_VIEWABLE (config);
 
416
  GimpViewablePrivate *private = GET_PRIVATE (config);
386
417
 
387
418
  switch (property_id)
388
419
    {
389
420
    case PROP_STOCK_ID:
390
 
      if (viewable->stock_id)
 
421
      if (private->stock_id)
391
422
        {
392
423
          gimp_config_writer_open (writer, pspec->name);
393
 
          gimp_config_writer_string (writer, viewable->stock_id);
 
424
          gimp_config_writer_string (writer, private->stock_id);
394
425
          gimp_config_writer_close (writer);
395
426
        }
396
427
      return TRUE;
412
443
void
413
444
gimp_viewable_invalidate_preview (GimpViewable *viewable)
414
445
{
 
446
  GimpViewablePrivate *private;
 
447
 
415
448
  g_return_if_fail (GIMP_IS_VIEWABLE (viewable));
416
449
 
417
 
  if (viewable->freeze_count == 0)
 
450
  private = GET_PRIVATE (viewable);
 
451
 
 
452
  if (private->freeze_count == 0)
418
453
    g_signal_emit (viewable, viewable_signals[INVALIDATE_PREVIEW], 0);
419
454
}
420
455
 
668
703
                           gint          width,
669
704
                           gint          height)
670
705
{
671
 
  GimpViewableClass *viewable_class;
672
 
  TempBuf           *temp_buf = NULL;
 
706
  GimpViewablePrivate *private;
 
707
  GimpViewableClass   *viewable_class;
 
708
  TempBuf             *temp_buf = NULL;
673
709
 
674
710
  g_return_val_if_fail (GIMP_IS_VIEWABLE (viewable), NULL);
675
711
  g_return_val_if_fail (context == NULL || GIMP_IS_CONTEXT (context), NULL);
676
712
  g_return_val_if_fail (width  > 0, NULL);
677
713
  g_return_val_if_fail (height > 0, NULL);
678
714
 
 
715
  private = GET_PRIVATE (viewable);
 
716
 
679
717
  if (G_UNLIKELY (context == NULL))
680
718
    g_warning ("%s: context is NULL", G_STRFUNC);
681
719
 
687
725
  if (temp_buf)
688
726
    return temp_buf;
689
727
 
690
 
  temp_buf = g_object_get_qdata (G_OBJECT (viewable), quark_preview_temp_buf);
691
 
 
692
 
  if (temp_buf                   &&
693
 
      temp_buf->width  == width  &&
694
 
      temp_buf->height == height)
695
 
    return temp_buf;
696
 
 
697
 
  temp_buf = NULL;
 
728
  if (private->preview_temp_buf)
 
729
    {
 
730
      if (private->preview_temp_buf->width  == width  &&
 
731
          private->preview_temp_buf->height == height)
 
732
        {
 
733
          return private->preview_temp_buf;
 
734
        }
 
735
 
 
736
      temp_buf_free (private->preview_temp_buf);
 
737
      private->preview_temp_buf = NULL;
 
738
    }
698
739
 
699
740
  if (viewable_class->get_new_preview)
700
741
    temp_buf = viewable_class->get_new_preview (viewable, context,
701
742
                                                width, height);
702
743
 
703
 
  g_object_set_qdata_full (G_OBJECT (viewable), quark_preview_temp_buf,
704
 
                           temp_buf,
705
 
                           (GDestroyNotify) temp_buf_free);
 
744
  private->preview_temp_buf = temp_buf;
706
745
 
707
746
  return temp_buf;
708
747
}
793
832
  buf = temp_buf_new (width, height, bpp, 0, 0, NULL);
794
833
 
795
834
  src  = gdk_pixbuf_get_pixels (pixbuf);
796
 
  dest = temp_buf_data (buf);
 
835
  dest = temp_buf_get_data (buf);
797
836
 
798
837
  while (height--)
799
838
    {
834
873
                          gint          width,
835
874
                          gint          height)
836
875
{
837
 
  GimpViewableClass *viewable_class;
838
 
  GdkPixbuf         *pixbuf = NULL;
 
876
  GimpViewablePrivate *private;
 
877
  GimpViewableClass   *viewable_class;
 
878
  GdkPixbuf           *pixbuf = NULL;
839
879
 
840
880
  g_return_val_if_fail (GIMP_IS_VIEWABLE (viewable), NULL);
841
881
  g_return_val_if_fail (context == NULL || GIMP_IS_CONTEXT (context), NULL);
842
882
  g_return_val_if_fail (width  > 0, NULL);
843
883
  g_return_val_if_fail (height > 0, NULL);
844
884
 
 
885
  private = GET_PRIVATE (viewable);
 
886
 
845
887
  if (G_UNLIKELY (context == NULL))
846
888
    g_warning ("%s: context is NULL", G_STRFUNC);
847
889
 
853
895
  if (pixbuf)
854
896
    return pixbuf;
855
897
 
856
 
  pixbuf = g_object_get_qdata (G_OBJECT (viewable), quark_preview_pixbuf);
857
 
 
858
 
  if (pixbuf                                  &&
859
 
      gdk_pixbuf_get_width (pixbuf)  == width &&
860
 
      gdk_pixbuf_get_height (pixbuf) == height)
861
 
    return pixbuf;
862
 
 
863
 
  pixbuf = NULL;
 
898
  if (private->preview_pixbuf)
 
899
    {
 
900
      if (gdk_pixbuf_get_width  (private->preview_pixbuf) == width &&
 
901
          gdk_pixbuf_get_height (private->preview_pixbuf) == height)
 
902
        {
 
903
          return pixbuf;
 
904
        }
 
905
 
 
906
      g_object_unref (private->preview_pixbuf);
 
907
      private->preview_pixbuf = NULL;
 
908
    }
864
909
 
865
910
  if (viewable_class->get_new_pixbuf)
866
911
    pixbuf = viewable_class->get_new_pixbuf (viewable, context, width, height);
867
912
 
868
 
  g_object_set_qdata_full (G_OBJECT (viewable), quark_preview_pixbuf,
869
 
                           pixbuf,
870
 
                           (GDestroyNotify) g_object_unref);
 
913
  private->preview_pixbuf = pixbuf;
871
914
 
872
915
  return pixbuf;
873
916
}
1020
1063
const gchar *
1021
1064
gimp_viewable_get_stock_id (GimpViewable *viewable)
1022
1065
{
 
1066
  GimpViewablePrivate *private;
 
1067
 
1023
1068
  g_return_val_if_fail (GIMP_IS_VIEWABLE (viewable), NULL);
1024
1069
 
1025
 
  if (viewable->stock_id)
1026
 
    return (const gchar *) viewable->stock_id;
 
1070
  private = GET_PRIVATE (viewable);
 
1071
 
 
1072
  if (private->stock_id)
 
1073
    return (const gchar *) private->stock_id;
1027
1074
 
1028
1075
  return GIMP_VIEWABLE_GET_CLASS (viewable)->default_stock_id;
1029
1076
}
1041
1088
gimp_viewable_set_stock_id (GimpViewable *viewable,
1042
1089
                            const gchar  *stock_id)
1043
1090
{
1044
 
  GimpViewableClass *viewable_class;
 
1091
  GimpViewablePrivate *private;
 
1092
  GimpViewableClass   *viewable_class;
1045
1093
 
1046
1094
  g_return_if_fail (GIMP_IS_VIEWABLE (viewable));
1047
1095
 
1048
 
  g_free (viewable->stock_id);
1049
 
  viewable->stock_id = NULL;
 
1096
  private = GET_PRIVATE (viewable);
 
1097
 
 
1098
  g_free (private->stock_id);
 
1099
  private->stock_id = NULL;
1050
1100
 
1051
1101
  viewable_class = GIMP_VIEWABLE_GET_CLASS (viewable);
1052
1102
 
1054
1104
    {
1055
1105
      if (viewable_class->default_stock_id == NULL ||
1056
1106
          strcmp (stock_id, viewable_class->default_stock_id))
1057
 
        viewable->stock_id = g_strdup (stock_id);
 
1107
        private->stock_id = g_strdup (stock_id);
1058
1108
    }
1059
1109
 
1060
1110
  g_object_notify (G_OBJECT (viewable), "stock-id");
1063
1113
void
1064
1114
gimp_viewable_preview_freeze (GimpViewable *viewable)
1065
1115
{
 
1116
  GimpViewablePrivate *private;
 
1117
 
1066
1118
  g_return_if_fail (GIMP_IS_VIEWABLE (viewable));
1067
1119
 
1068
 
  viewable->freeze_count++;
1069
 
 
1070
 
  if (viewable->freeze_count == 1)
 
1120
  private = GET_PRIVATE (viewable);
 
1121
 
 
1122
  private->freeze_count++;
 
1123
 
 
1124
  if (private->freeze_count == 1)
1071
1125
    g_object_notify (G_OBJECT (viewable), "frozen");
1072
1126
}
1073
1127
 
1074
1128
void
1075
1129
gimp_viewable_preview_thaw (GimpViewable *viewable)
1076
1130
{
 
1131
  GimpViewablePrivate *private;
 
1132
 
1077
1133
  g_return_if_fail (GIMP_IS_VIEWABLE (viewable));
1078
 
  g_return_if_fail (viewable->freeze_count > 0);
1079
 
 
1080
 
  viewable->freeze_count--;
1081
 
 
1082
 
  if (viewable->freeze_count == 0)
 
1134
 
 
1135
  private = GET_PRIVATE (viewable);
 
1136
 
 
1137
  g_return_if_fail (private->freeze_count > 0);
 
1138
 
 
1139
  private->freeze_count--;
 
1140
 
 
1141
  if (private->freeze_count == 0)
1083
1142
    {
1084
1143
      gimp_viewable_invalidate_preview (viewable);
1085
1144
      g_object_notify (G_OBJECT (viewable), "frozen");
1091
1150
{
1092
1151
  g_return_val_if_fail (GIMP_IS_VIEWABLE (viewable), FALSE);
1093
1152
 
1094
 
  return viewable->freeze_count != 0;
 
1153
  return GET_PRIVATE (viewable)->freeze_count != 0;
 
1154
}
 
1155
 
 
1156
GimpViewable *
 
1157
gimp_viewable_get_parent (GimpViewable *viewable)
 
1158
{
 
1159
  g_return_val_if_fail (GIMP_IS_VIEWABLE (viewable), NULL);
 
1160
 
 
1161
  return GET_PRIVATE (viewable)->parent;
 
1162
}
 
1163
 
 
1164
void
 
1165
gimp_viewable_set_parent (GimpViewable *viewable,
 
1166
                          GimpViewable *parent)
 
1167
{
 
1168
  g_return_if_fail (GIMP_IS_VIEWABLE (viewable));
 
1169
  g_return_if_fail (parent == NULL || GIMP_IS_VIEWABLE (parent));
 
1170
 
 
1171
  GET_PRIVATE (viewable)->parent = parent;
 
1172
}
 
1173
 
 
1174
GimpContainer *
 
1175
gimp_viewable_get_children (GimpViewable *viewable)
 
1176
{
 
1177
  g_return_val_if_fail (GIMP_IS_VIEWABLE (viewable), NULL);
 
1178
 
 
1179
  return GIMP_VIEWABLE_GET_CLASS (viewable)->get_children (viewable);
 
1180
}
 
1181
 
 
1182
gboolean
 
1183
gimp_viewable_get_expanded (GimpViewable *viewable)
 
1184
{
 
1185
  g_return_val_if_fail (GIMP_IS_VIEWABLE (viewable), FALSE);
 
1186
 
 
1187
  if (GIMP_VIEWABLE_GET_CLASS (viewable)->get_expanded)
 
1188
    return GIMP_VIEWABLE_GET_CLASS (viewable)->get_expanded (viewable);
 
1189
 
 
1190
  return FALSE;
 
1191
}
 
1192
 
 
1193
void
 
1194
gimp_viewable_set_expanded (GimpViewable *viewable,
 
1195
                            gboolean       expanded)
 
1196
{
 
1197
  g_return_if_fail (GIMP_IS_VIEWABLE (viewable));
 
1198
 
 
1199
  if (GIMP_VIEWABLE_GET_CLASS (viewable)->set_expanded)
 
1200
    GIMP_VIEWABLE_GET_CLASS (viewable)->set_expanded (viewable, expanded);
 
1201
}
 
1202
 
 
1203
gboolean
 
1204
gimp_viewable_is_ancestor (GimpViewable *ancestor,
 
1205
                           GimpViewable *descendant)
 
1206
{
 
1207
  g_return_val_if_fail (GIMP_IS_VIEWABLE (ancestor), FALSE);
 
1208
  g_return_val_if_fail (GIMP_IS_VIEWABLE (descendant), FALSE);
 
1209
 
 
1210
  while (descendant)
 
1211
    {
 
1212
      GimpViewable *parent = gimp_viewable_get_parent (descendant);
 
1213
 
 
1214
      if (parent == ancestor)
 
1215
        return TRUE;
 
1216
 
 
1217
      descendant = parent;
 
1218
    }
 
1219
 
 
1220
  return FALSE;
1095
1221
}