source: trunk/third/nautilus/libbackground/preview-file-selection.c @ 18663

Revision 18663, 7.5 KB checked in by ghudson, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18662, which included commits to RCS files with non-trunk default branches.
Line 
1/* -*- mode: c; style: linux -*- */
2
3/* preview-file-selection.c
4 * Copyright (C) 2001 Ximian, Inc.
5 *
6 * Written by Rachel Hestilow <hestilow@ximian.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21 * 02111-1307, USA.
22 */
23
24#ifdef HAVE_CONFIG_H
25# include "config.h"
26#endif
27
28#include <libgnome/libgnome.h>
29#include <gtk/gtkimage.h>
30#include <gtk/gtkhbox.h>
31#include <gtk/gtkframe.h>
32#include <gtk/gtklabel.h>
33#include <gtk/gtktreeview.h>
34#include <gtk/gtkmain.h>
35#include "preview-file-selection.h"
36
37#define SCALE 100
38
39struct _PreviewFileSelectionPrivate
40{
41        GtkWidget *preview;     
42        GtkWidget *label;
43};
44
45enum
46{
47        PROP_0,
48        PROP_DO_PREVIEW
49};
50
51static GObjectClass *parent_class;
52
53static void preview_file_selection_set_property (GObject *object, guint arg_id, const GValue *value, GParamSpec *spec);
54static void preview_file_selection_get_property (GObject *object, guint arg_id, GValue *value, GParamSpec *spec);
55
56static void
57preview_file_selection_finalize (GObject *object)
58{
59        PreviewFileSelection *fsel = PREVIEW_FILE_SELECTION (object);
60
61        g_free (fsel->priv);
62
63        parent_class->finalize (object);
64}
65
66static void
67preview_file_selection_class_init (GObjectClass *object_class)
68{
69        parent_class = g_type_class_ref (GTK_TYPE_FILE_SELECTION);
70       
71        object_class->set_property = preview_file_selection_set_property;
72        object_class->get_property = preview_file_selection_get_property;
73        object_class->finalize = preview_file_selection_finalize;
74
75        g_object_class_install_property
76                (object_class, PROP_DO_PREVIEW,
77                 g_param_spec_boolean ("do_preview",
78                                       "Preview images",
79                                       "Whether to preview images",
80                                       TRUE,
81                                       G_PARAM_READWRITE |
82                                       G_PARAM_CONSTRUCT_ONLY));
83}
84
85static void
86preview_file_selection_init (GObject *object)
87{
88        PreviewFileSelection *fsel = PREVIEW_FILE_SELECTION (object);
89
90        fsel->priv = g_new0 (PreviewFileSelectionPrivate, 1);
91}
92
93GType
94preview_file_selection_get_type (void)
95{
96        static GType type = 0;
97
98        if (!type)
99        {
100                GTypeInfo info =
101                {
102                        sizeof (PreviewFileSelectionClass),
103                        NULL,
104                        NULL,
105                        (GClassInitFunc) preview_file_selection_class_init,
106                        NULL,
107                        NULL,
108                        sizeof (PreviewFileSelection),
109                        0,
110                        (GInstanceInitFunc) preview_file_selection_init,
111                        NULL
112                };
113
114                type = g_type_register_static (GTK_TYPE_FILE_SELECTION,
115                                               "PreviewFileSelection",
116                                               &info, 0);
117        }
118
119        return type;
120}
121
122GtkWidget*
123preview_file_selection_new (const gchar *title, gboolean do_preview)
124{
125        return GTK_WIDGET (
126                g_object_new (PREVIEW_FILE_SELECTION_TYPE,
127                              "title", title,
128                              "do_preview", do_preview,
129                              NULL));
130}
131
132GdkPixbuf*
133preview_file_selection_intelligent_scale (GdkPixbuf *buf, guint scale)
134{
135        GdkPixbuf *scaled;
136        int w, h;
137        guint ow = gdk_pixbuf_get_width (buf);
138        guint oh = gdk_pixbuf_get_height (buf);
139
140        if (ow <= scale && oh <= scale)
141                scaled = gdk_pixbuf_ref (buf);
142        else
143        {
144                if (ow > oh)
145                {
146                        w = scale;
147                        h = scale * (((double)oh)/(double)ow);
148                }
149                else
150                {
151                        h = scale;
152                        w = scale * (((double)ow)/(double)ow);
153                }
154                       
155                scaled = gdk_pixbuf_scale_simple (buf, w, h, GDK_INTERP_BILINEAR);
156        }
157       
158        return scaled;
159}
160
161static void
162preview_file_selection_update (PreviewFileSelection *fsel, gpointer data)
163{
164        GdkPixbuf *buf;
165        const gchar *filename;
166
167        g_return_if_fail (IS_PREVIEW_FILE_SELECTION (fsel));
168       
169        filename = gtk_file_selection_get_filename (GTK_FILE_SELECTION (fsel));
170        if (filename && (buf = gdk_pixbuf_new_from_file (filename, NULL)))
171        {
172                int w, h;
173                char *size;
174                GdkPixbuf *scaled = preview_file_selection_intelligent_scale (buf, SCALE);
175                gtk_image_set_from_pixbuf (GTK_IMAGE (fsel->priv->preview),
176                                           scaled);
177                g_object_unref (scaled);
178
179                w = gdk_pixbuf_get_width (buf);
180                h = gdk_pixbuf_get_height (buf);
181
182                size = g_strdup_printf ("%d x %d", w, h);
183                gtk_label_set_text (GTK_LABEL (fsel->priv->label), size);
184                g_free (size);
185
186                g_object_unref (buf);
187        }
188        else {
189                gtk_image_set_from_file (GTK_IMAGE (fsel->priv->preview), NULL);
190                gtk_label_set_text (GTK_LABEL (fsel->priv->label), " ");
191        }
192}
193
194static void
195preview_file_selection_add_preview (PreviewFileSelection *fsel)
196{
197        GtkWidget *hbox, *frame, *vbox;
198       
199        g_return_if_fail (IS_PREVIEW_FILE_SELECTION (fsel));
200
201        hbox = GTK_FILE_SELECTION (fsel)->file_list;
202        do
203        {
204                hbox = hbox->parent;
205                if (!hbox)
206                {
207                        g_warning (_("Can't find an hbox, using a normal file selection"));
208                        return;
209                }
210        } while (!GTK_IS_HBOX (hbox));
211       
212        frame = gtk_frame_new (_("Preview"));
213        gtk_widget_set_size_request (frame, SCALE + 10, SCALE + 10);
214        gtk_widget_show (frame);
215        gtk_box_pack_end (GTK_BOX (hbox), frame, FALSE, FALSE, 0);
216
217        vbox = gtk_vbox_new (FALSE, 2);
218        gtk_widget_show (vbox);
219        gtk_container_add (GTK_CONTAINER (frame), vbox);
220       
221        fsel->priv->preview = gtk_image_new ();
222        gtk_box_pack_start (GTK_BOX (vbox), fsel->priv->preview, FALSE, FALSE, 0);
223        gtk_widget_show (fsel->priv->preview);
224       
225        fsel->priv->label = gtk_label_new ("");
226        gtk_box_pack_start (GTK_BOX (vbox), fsel->priv->label, FALSE, FALSE, 0);
227        gtk_widget_show (fsel->priv->label);
228
229        g_signal_connect_data (G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (GTK_FILE_SELECTION (fsel)->file_list))), "changed", (GCallback) preview_file_selection_update, fsel, NULL, G_CONNECT_AFTER | G_CONNECT_SWAPPED);
230
231        preview_file_selection_update (fsel, NULL);
232}
233
234static void
235preview_file_selection_set_property (GObject *object, guint arg_id, const GValue *value, GParamSpec *spec)
236{
237        PreviewFileSelection *fsel = PREVIEW_FILE_SELECTION (object);
238
239        switch (arg_id)
240        {
241        case PROP_DO_PREVIEW:
242                if (g_value_get_boolean (value))
243                        preview_file_selection_add_preview (fsel);
244                break;
245        }
246}
247
248static void preview_file_selection_get_property (GObject *object, guint arg_id, GValue *value, GParamSpec *spec)
249{
250        PreviewFileSelection *fsel = PREVIEW_FILE_SELECTION (object);
251
252        switch (arg_id)
253        {
254        case PROP_DO_PREVIEW:
255                g_value_set_boolean (value, fsel->priv->preview != NULL);
256                break;
257        }
258}
259
260static void
261browse_dialog_ok (GtkWidget *button, GnomeFileEntry *entry)
262{
263        gnome_file_entry_set_filename (entry, gtk_file_selection_get_filename (GTK_FILE_SELECTION (entry->fsw)));
264        g_signal_emit_by_name (entry, "activate");
265        gtk_widget_destroy (entry->fsw);
266}
267
268static void
269browse_dialog_kill (GtkFileSelection *fsel, GnomeFileEntry *entry)
270{
271        entry->fsw = NULL;
272}
273
274static void
275browse_clicked_cb (GnomeFileEntry *entry, const gchar *title)
276{
277        GtkFileSelection *fs = GTK_FILE_SELECTION (preview_file_selection_new (title, TRUE));
278       
279        entry->fsw = GTK_WIDGET (fs);
280       
281        g_signal_connect (fs->ok_button, "clicked",
282                          (GCallback) browse_dialog_ok, entry);
283       
284        g_signal_connect_swapped (fs->cancel_button, "clicked",
285                                  (GCallback) gtk_widget_destroy, fs);
286
287        g_signal_connect (fs, "destroy",
288                          (GCallback) browse_dialog_kill, entry);
289
290        if (gtk_grab_get_current ())
291                gtk_grab_add (entry->fsw);
292}
293
294void
295preview_file_selection_hookup_file_entry (GnomeFileEntry *entry, const gchar *title)
296{
297        g_return_if_fail (GNOME_IS_FILE_ENTRY (entry));
298        g_return_if_fail (title != NULL);
299       
300        g_signal_connect (G_OBJECT (entry), "browse_clicked",
301                          (GCallback) browse_clicked_cb, (gpointer) title);
302}
Note: See TracBrowser for help on using the repository browser.