5
5
* Copyright (C) 2001 Michael Natterer <mitch@gimp.org>
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.
12
12
* This program is distributed in the hope that it will be useful,
15
15
* GNU General Public License for more details.
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/>.
22
21
#include "config.h"
57
typedef struct _GimpViewablePrivate GimpViewablePrivate;
59
struct _GimpViewablePrivate
65
TempBuf *preview_temp_buf;
66
GdkPixbuf *preview_pixbuf;
69
#define GET_PRIVATE(viewable) G_TYPE_INSTANCE_GET_PRIVATE (viewable, \
58
74
static void gimp_viewable_config_iface_init (GimpConfigInterface *iface);
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,
109
static GimpContainer * gimp_viewable_real_get_children (GimpViewable *viewable);
93
111
static gboolean gimp_viewable_serialize_property (GimpConfig *config,
94
112
guint property_id,
95
113
const GValue *value,
104
122
#define parent_class gimp_viewable_parent_class
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 };
114
130
GObjectClass *object_class = G_OBJECT_CLASS (klass);
115
131
GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass);
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");
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;
159
175
GIMP_CONFIG_INSTALL_PROP_STRING (object_class, PROP_STOCK_ID, "stock-id",
167
183
GIMP_PARAM_READABLE));
185
g_type_class_add_private (klass, sizeof (GimpViewablePrivate));
171
189
gimp_viewable_init (GimpViewable *viewable)
173
viewable->stock_id = NULL;
174
viewable->freeze_count = 0;
184
200
gimp_viewable_finalize (GObject *object)
186
GimpViewable *viewable = GIMP_VIEWABLE (object);
188
if (viewable->stock_id)
190
g_free (viewable->stock_id);
191
viewable->stock_id = NULL;
202
GimpViewablePrivate *private = GET_PRIVATE (object);
204
if (private->stock_id)
206
g_free (private->stock_id);
207
private->stock_id = NULL;
210
if (private->preview_temp_buf)
212
temp_buf_free (private->preview_temp_buf);
213
private->preview_temp_buf = NULL;
216
if (private->preview_pixbuf)
218
g_object_unref (private->preview_pixbuf);
219
private->preview_pixbuf = NULL;
194
222
G_OBJECT_CLASS (parent_class)->finalize (object);
243
271
gimp_viewable_get_memsize (GimpObject *object,
244
272
gint64 *gui_size)
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);
252
*gui_size += temp_buf_get_memsize (temp_buf);
274
GimpViewablePrivate *private = GET_PRIVATE (object);
276
*gui_size += temp_buf_get_memsize (private->preview_temp_buf);
278
if (private->preview_pixbuf)
256
static gsize pixbuf_instance_size = 0;
258
if (! pixbuf_instance_size)
260
GTypeQuery type_query;
262
g_type_query (G_TYPE_FROM_INSTANCE (pixbuf), &type_query);
264
pixbuf_instance_size = type_query.instance_size;
267
*gui_size += (pixbuf_instance_size +
268
(gsize) gdk_pixbuf_get_height (pixbuf) *
269
gdk_pixbuf_get_rowstride (pixbuf));
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));
272
286
return GIMP_OBJECT_CLASS (parent_class)->get_memsize (object, gui_size);
276
290
gimp_viewable_real_invalidate_preview (GimpViewable *viewable)
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);
294
if (private->preview_temp_buf)
296
temp_buf_free (private->preview_temp_buf);
297
private->preview_temp_buf = NULL;
300
if (private->preview_pixbuf)
302
g_object_unref (private->preview_pixbuf);
303
private->preview_pixbuf = NULL;
372
397
gimp_viewable_real_get_description (GimpViewable *viewable,
375
return g_strdup (gimp_object_get_name (GIMP_OBJECT (viewable)));
400
return g_strdup (gimp_object_get_name (viewable));
403
static GimpContainer *
404
gimp_viewable_real_get_children (GimpViewable *viewable)
382
413
GParamSpec *pspec,
383
414
GimpConfigWriter *writer)
385
GimpViewable *viewable = GIMP_VIEWABLE (config);
416
GimpViewablePrivate *private = GET_PRIVATE (config);
387
418
switch (property_id)
389
420
case PROP_STOCK_ID:
390
if (viewable->stock_id)
421
if (private->stock_id)
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);
413
444
gimp_viewable_invalidate_preview (GimpViewable *viewable)
446
GimpViewablePrivate *private;
415
448
g_return_if_fail (GIMP_IS_VIEWABLE (viewable));
417
if (viewable->freeze_count == 0)
450
private = GET_PRIVATE (viewable);
452
if (private->freeze_count == 0)
418
453
g_signal_emit (viewable, viewable_signals[INVALIDATE_PREVIEW], 0);
671
GimpViewableClass *viewable_class;
672
TempBuf *temp_buf = NULL;
706
GimpViewablePrivate *private;
707
GimpViewableClass *viewable_class;
708
TempBuf *temp_buf = NULL;
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);
715
private = GET_PRIVATE (viewable);
679
717
if (G_UNLIKELY (context == NULL))
680
718
g_warning ("%s: context is NULL", G_STRFUNC);
690
temp_buf = g_object_get_qdata (G_OBJECT (viewable), quark_preview_temp_buf);
693
temp_buf->width == width &&
694
temp_buf->height == height)
728
if (private->preview_temp_buf)
730
if (private->preview_temp_buf->width == width &&
731
private->preview_temp_buf->height == height)
733
return private->preview_temp_buf;
736
temp_buf_free (private->preview_temp_buf);
737
private->preview_temp_buf = NULL;
699
740
if (viewable_class->get_new_preview)
700
741
temp_buf = viewable_class->get_new_preview (viewable, context,
703
g_object_set_qdata_full (G_OBJECT (viewable), quark_preview_temp_buf,
705
(GDestroyNotify) temp_buf_free);
744
private->preview_temp_buf = temp_buf;
793
832
buf = temp_buf_new (width, height, bpp, 0, 0, NULL);
795
834
src = gdk_pixbuf_get_pixels (pixbuf);
796
dest = temp_buf_data (buf);
835
dest = temp_buf_get_data (buf);
837
GimpViewableClass *viewable_class;
838
GdkPixbuf *pixbuf = NULL;
876
GimpViewablePrivate *private;
877
GimpViewableClass *viewable_class;
878
GdkPixbuf *pixbuf = NULL;
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);
885
private = GET_PRIVATE (viewable);
845
887
if (G_UNLIKELY (context == NULL))
846
888
g_warning ("%s: context is NULL", G_STRFUNC);
856
pixbuf = g_object_get_qdata (G_OBJECT (viewable), quark_preview_pixbuf);
859
gdk_pixbuf_get_width (pixbuf) == width &&
860
gdk_pixbuf_get_height (pixbuf) == height)
898
if (private->preview_pixbuf)
900
if (gdk_pixbuf_get_width (private->preview_pixbuf) == width &&
901
gdk_pixbuf_get_height (private->preview_pixbuf) == height)
906
g_object_unref (private->preview_pixbuf);
907
private->preview_pixbuf = NULL;
865
910
if (viewable_class->get_new_pixbuf)
866
911
pixbuf = viewable_class->get_new_pixbuf (viewable, context, width, height);
868
g_object_set_qdata_full (G_OBJECT (viewable), quark_preview_pixbuf,
870
(GDestroyNotify) g_object_unref);
913
private->preview_pixbuf = pixbuf;
1021
1064
gimp_viewable_get_stock_id (GimpViewable *viewable)
1066
GimpViewablePrivate *private;
1023
1068
g_return_val_if_fail (GIMP_IS_VIEWABLE (viewable), NULL);
1025
if (viewable->stock_id)
1026
return (const gchar *) viewable->stock_id;
1070
private = GET_PRIVATE (viewable);
1072
if (private->stock_id)
1073
return (const gchar *) private->stock_id;
1028
1075
return GIMP_VIEWABLE_GET_CLASS (viewable)->default_stock_id;
1041
1088
gimp_viewable_set_stock_id (GimpViewable *viewable,
1042
1089
const gchar *stock_id)
1044
GimpViewableClass *viewable_class;
1091
GimpViewablePrivate *private;
1092
GimpViewableClass *viewable_class;
1046
1094
g_return_if_fail (GIMP_IS_VIEWABLE (viewable));
1048
g_free (viewable->stock_id);
1049
viewable->stock_id = NULL;
1096
private = GET_PRIVATE (viewable);
1098
g_free (private->stock_id);
1099
private->stock_id = NULL;
1051
1101
viewable_class = GIMP_VIEWABLE_GET_CLASS (viewable);
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);
1060
1110
g_object_notify (G_OBJECT (viewable), "stock-id");
1064
1114
gimp_viewable_preview_freeze (GimpViewable *viewable)
1116
GimpViewablePrivate *private;
1066
1118
g_return_if_fail (GIMP_IS_VIEWABLE (viewable));
1068
viewable->freeze_count++;
1070
if (viewable->freeze_count == 1)
1120
private = GET_PRIVATE (viewable);
1122
private->freeze_count++;
1124
if (private->freeze_count == 1)
1071
1125
g_object_notify (G_OBJECT (viewable), "frozen");
1075
1129
gimp_viewable_preview_thaw (GimpViewable *viewable)
1131
GimpViewablePrivate *private;
1077
1133
g_return_if_fail (GIMP_IS_VIEWABLE (viewable));
1078
g_return_if_fail (viewable->freeze_count > 0);
1080
viewable->freeze_count--;
1082
if (viewable->freeze_count == 0)
1135
private = GET_PRIVATE (viewable);
1137
g_return_if_fail (private->freeze_count > 0);
1139
private->freeze_count--;
1141
if (private->freeze_count == 0)
1084
1143
gimp_viewable_invalidate_preview (viewable);
1085
1144
g_object_notify (G_OBJECT (viewable), "frozen");
1092
1151
g_return_val_if_fail (GIMP_IS_VIEWABLE (viewable), FALSE);
1094
return viewable->freeze_count != 0;
1153
return GET_PRIVATE (viewable)->freeze_count != 0;
1157
gimp_viewable_get_parent (GimpViewable *viewable)
1159
g_return_val_if_fail (GIMP_IS_VIEWABLE (viewable), NULL);
1161
return GET_PRIVATE (viewable)->parent;
1165
gimp_viewable_set_parent (GimpViewable *viewable,
1166
GimpViewable *parent)
1168
g_return_if_fail (GIMP_IS_VIEWABLE (viewable));
1169
g_return_if_fail (parent == NULL || GIMP_IS_VIEWABLE (parent));
1171
GET_PRIVATE (viewable)->parent = parent;
1175
gimp_viewable_get_children (GimpViewable *viewable)
1177
g_return_val_if_fail (GIMP_IS_VIEWABLE (viewable), NULL);
1179
return GIMP_VIEWABLE_GET_CLASS (viewable)->get_children (viewable);
1183
gimp_viewable_get_expanded (GimpViewable *viewable)
1185
g_return_val_if_fail (GIMP_IS_VIEWABLE (viewable), FALSE);
1187
if (GIMP_VIEWABLE_GET_CLASS (viewable)->get_expanded)
1188
return GIMP_VIEWABLE_GET_CLASS (viewable)->get_expanded (viewable);
1194
gimp_viewable_set_expanded (GimpViewable *viewable,
1197
g_return_if_fail (GIMP_IS_VIEWABLE (viewable));
1199
if (GIMP_VIEWABLE_GET_CLASS (viewable)->set_expanded)
1200
GIMP_VIEWABLE_GET_CLASS (viewable)->set_expanded (viewable, expanded);
1204
gimp_viewable_is_ancestor (GimpViewable *ancestor,
1205
GimpViewable *descendant)
1207
g_return_val_if_fail (GIMP_IS_VIEWABLE (ancestor), FALSE);
1208
g_return_val_if_fail (GIMP_IS_VIEWABLE (descendant), FALSE);
1212
GimpViewable *parent = gimp_viewable_get_parent (descendant);
1214
if (parent == ancestor)
1217
descendant = parent;