1
/* LIBGIMP - The GIMP Library
2
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
5
* Copyright (C) 1999-2004 Michael Natterer <mitch@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 2 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
* Library 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, write to the
19
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20
* Boston, MA 02111-1307, USA.
29
#include "gimpwidgetstypes.h"
31
#include "gimpfileentry.h"
33
#include "libgimp/libgimp-intl.h"
43
static void gimp_file_entry_class_init (GimpFileEntryClass *klass);
44
static void gimp_file_entry_init (GimpFileEntry *entry);
46
static void gimp_file_entry_destroy (GtkObject *object);
48
static void gimp_file_entry_entry_activate (GtkWidget *widget,
49
GimpFileEntry *entry);
50
static gint gimp_file_entry_entry_focus_out (GtkWidget *widget,
52
GimpFileEntry *entry);
53
static void gimp_file_entry_browse_clicked (GtkWidget *widget,
54
GimpFileEntry *entry);
55
static void gimp_file_entry_check_filename (GimpFileEntry *entry);
58
static guint gimp_file_entry_signals[LAST_SIGNAL] = { 0 };
60
static GtkHBoxClass *parent_class = NULL;
64
gimp_file_entry_get_type (void)
66
static GType entry_type = 0;
70
static const GTypeInfo entry_info =
72
sizeof (GimpFileEntryClass),
74
(GBaseFinalizeFunc) NULL,
75
(GClassInitFunc) gimp_file_entry_class_init,
76
NULL, /* class_finalize */
77
NULL, /* class_data */
78
sizeof (GimpFileEntry),
80
(GInstanceInitFunc) gimp_file_entry_init,
83
entry_type = g_type_register_static (GTK_TYPE_HBOX,
92
gimp_file_entry_class_init (GimpFileEntryClass *klass)
94
GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass);
96
parent_class = g_type_class_peek_parent (klass);
99
* GimpFileEntry::filename-changed:
101
* This signal is emitted whenever the user changes the filename.
103
gimp_file_entry_signals[FILENAME_CHANGED] =
104
g_signal_new ("filename_changed",
105
G_TYPE_FROM_CLASS (klass),
107
G_STRUCT_OFFSET (GimpFileEntryClass, filename_changed),
109
g_cclosure_marshal_VOID__VOID,
112
object_class->destroy = gimp_file_entry_destroy;
114
klass->filename_changed = NULL;
118
gimp_file_entry_init (GimpFileEntry *entry)
121
entry->file_dialog = NULL;
122
entry->check_valid = FALSE;
123
entry->file_exists = NULL;
125
gtk_box_set_spacing (GTK_BOX (entry), 4);
126
gtk_box_set_homogeneous (GTK_BOX (entry), FALSE);
128
entry->browse_button = gtk_button_new_with_label (" ... ");
129
gtk_box_pack_end (GTK_BOX (entry), entry->browse_button, FALSE, FALSE, 0);
130
gtk_widget_show (entry->browse_button);
132
g_signal_connect (entry->browse_button, "clicked",
133
G_CALLBACK (gimp_file_entry_browse_clicked),
136
entry->entry = gtk_entry_new ();
137
gtk_box_pack_end (GTK_BOX (entry), entry->entry, TRUE, TRUE, 0);
138
gtk_widget_show (entry->entry);
140
g_signal_connect (entry->entry, "activate",
141
G_CALLBACK (gimp_file_entry_entry_activate),
143
g_signal_connect (entry->entry, "focus_out_event",
144
G_CALLBACK (gimp_file_entry_entry_focus_out),
149
gimp_file_entry_destroy (GtkObject *object)
151
GimpFileEntry *entry = GIMP_FILE_ENTRY (object);
153
if (entry->file_dialog)
155
gtk_widget_destroy (entry->file_dialog);
156
entry->file_dialog = NULL;
161
g_free (entry->title);
165
GTK_OBJECT_CLASS (parent_class)->destroy (object);
169
* gimp_file_entry_new:
170
* @title: The title of the #GtkFileEntry dialog.
171
* @filename: The initial filename.
172
* @dir_only: %TRUE if the file entry should accept directories only.
173
* @check_valid: %TRUE if the widget should check if the entered file
176
* Creates a new #GimpFileEntry widget.
178
* Returns: A pointer to the new #GimpFileEntry widget.
181
gimp_file_entry_new (const gchar *title,
182
const gchar *filename,
184
gboolean check_valid)
186
GimpFileEntry *entry;
188
entry = g_object_new (GIMP_TYPE_FILE_ENTRY, NULL);
190
entry->title = g_strdup (title);
191
entry->dir_only = dir_only;
192
entry->check_valid = check_valid;
196
entry->file_exists = gtk_image_new_from_stock (GTK_STOCK_NO,
197
GTK_ICON_SIZE_BUTTON);
198
gtk_box_pack_start (GTK_BOX (entry), entry->file_exists, FALSE, FALSE, 0);
199
gtk_widget_show (entry->file_exists);
202
gimp_file_entry_set_filename (entry, filename);
204
return GTK_WIDGET (entry);
208
* gimp_file_entry_get_filename:
209
* @entry: The file entry you want to know the filename from.
211
* Note that you have to g_free() the returned string.
213
* Returns: The file or directory the user has entered.
216
gimp_file_entry_get_filename (GimpFileEntry *entry)
221
g_return_val_if_fail (GIMP_IS_FILE_ENTRY (entry), NULL);
223
utf8 = gtk_editable_get_chars (GTK_EDITABLE (entry->entry), 0, -1);
225
filename = g_filename_from_utf8 (utf8, -1, NULL, NULL, NULL);
233
* gimp_file_entry_set_filename:
234
* @entry: The file entry you want to set the filename for.
235
* @filename: The new filename.
237
* If you specified @check_valid as %TRUE in gimp_file_entry_new()
238
* the #GimpFileEntry will immediately check the validity of the file
242
gimp_file_entry_set_filename (GimpFileEntry *entry,
243
const gchar *filename)
247
g_return_if_fail (GIMP_IS_FILE_ENTRY (entry));
250
utf8 = g_filename_to_utf8 (filename, -1, NULL, NULL, NULL);
252
utf8 = g_strdup ("");
254
gtk_entry_set_text (GTK_ENTRY (entry->entry), utf8);
259
gimp_file_entry_entry_activate (entry->entry, entry);
263
gimp_file_entry_entry_activate (GtkWidget *widget,
264
GimpFileEntry *entry)
270
/* filenames still need more sanity checking
271
* (erase double G_DIR_SEPARATORS, ...)
273
utf8 = gtk_editable_get_chars (GTK_EDITABLE (widget), 0, -1);
274
utf8 = g_strstrip (utf8);
276
while (((len = strlen (utf8)) > 1) &&
277
(utf8[len - 1] == G_DIR_SEPARATOR))
278
utf8[len - 1] = '\0';
280
filename = g_filename_from_utf8 (utf8, -1, NULL, NULL, NULL);
282
g_signal_handlers_block_by_func (entry->entry,
283
gimp_file_entry_entry_activate,
285
gtk_entry_set_text (GTK_ENTRY (entry->entry), utf8);
286
g_signal_handlers_unblock_by_func (entry->entry,
287
gimp_file_entry_entry_activate,
290
if (entry->file_dialog)
291
gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (entry->file_dialog),
297
gimp_file_entry_check_filename (entry);
299
gtk_editable_set_position (GTK_EDITABLE (entry->entry), -1);
301
g_signal_emit (entry, gimp_file_entry_signals[FILENAME_CHANGED], 0);
305
gimp_file_entry_entry_focus_out (GtkWidget *widget,
307
GimpFileEntry *entry)
309
gimp_file_entry_entry_activate (widget, entry);
314
/* local callback of gimp_file_entry_browse_clicked() */
316
gimp_file_entry_chooser_response (GtkWidget *dialog,
318
GimpFileEntry *entry)
320
if (response_id == GTK_RESPONSE_OK)
324
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
325
gimp_file_entry_set_filename (entry, filename);
329
gtk_widget_hide (dialog);
333
gimp_file_entry_browse_clicked (GtkWidget *widget,
334
GimpFileEntry *entry)
336
GtkFileChooser *chooser;
340
utf8 = gtk_editable_get_chars (GTK_EDITABLE (entry->entry), 0, -1);
341
filename = g_filename_from_utf8 (utf8, -1, NULL, NULL, NULL);
344
if (! entry->file_dialog)
346
const gchar *title = entry->title;
351
title = _("Select Folder");
353
title = _("Select File");
357
gtk_file_chooser_dialog_new (title, NULL,
359
GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER :
360
GTK_FILE_CHOOSER_ACTION_OPEN,
362
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
363
GTK_STOCK_OK, GTK_RESPONSE_OK,
367
chooser = GTK_FILE_CHOOSER (entry->file_dialog);
369
gtk_window_set_position (GTK_WINDOW (chooser), GTK_WIN_POS_MOUSE);
370
gtk_window_set_role (GTK_WINDOW (chooser),
371
"gimp-file-entry-file-dialog");
373
g_signal_connect (chooser, "response",
374
G_CALLBACK (gimp_file_entry_chooser_response),
376
g_signal_connect (chooser, "delete_event",
377
G_CALLBACK (gtk_true),
380
g_signal_connect_swapped (entry, "unmap",
381
G_CALLBACK (gtk_widget_hide),
386
chooser = GTK_FILE_CHOOSER (entry->file_dialog);
389
gtk_file_chooser_set_filename (chooser, filename);
393
gtk_window_set_screen (GTK_WINDOW (chooser), gtk_widget_get_screen (widget));
394
gtk_window_present (GTK_WINDOW (chooser));
398
gimp_file_entry_check_filename (GimpFileEntry *entry)
404
if (! entry->check_valid || ! entry->file_exists)
407
utf8 = gtk_editable_get_chars (GTK_EDITABLE (entry->entry), 0, -1);
408
filename = g_filename_from_utf8 (utf8, -1, NULL, NULL, NULL);
412
exists = g_file_test (filename, G_FILE_TEST_IS_DIR);
414
exists = g_file_test (filename, G_FILE_TEST_IS_REGULAR);
418
gtk_image_set_from_stock (GTK_IMAGE (entry->file_exists),
419
exists ? GTK_STOCK_YES : GTK_STOCK_NO,
420
GTK_ICON_SIZE_BUTTON);