14 # define WIN32_MEAN_AND_LEAN
15 # include <windows.h> /* ExtractAssociatedIcon */
17 # define localtime_r(t,b) localtime(t)
19 # define S_ISREG(m) ((m) & _S_IFREG)
21 # include <gdk/win32/gdkwin32.h> /* gdk_win32_hdc_get */
24 #include "prop-editor.h"
26 static GtkWidget *preview_label;
27 static GtkWidget *preview_image;
28 static GtkFileChooserAction action;
31 print_current_folder (GtkFileChooser *chooser)
35 uri = gtk_file_chooser_get_current_folder_uri (chooser);
36 g_print ("Current folder changed :\n %s\n", uri ? uri : "(null)");
41 print_selected (GtkFileChooser *chooser)
43 GSList *uris = gtk_file_chooser_get_uris (chooser);
46 g_print ("Selection changed :\n");
47 for (tmp_list = uris; tmp_list; tmp_list = tmp_list->next)
49 gchar *uri = tmp_list->data;
50 g_print (" %s\n", uri);
58 response_cb (GtkDialog *dialog,
61 if (response_id == GTK_RESPONSE_OK)
65 list = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
71 g_print ("Selected files:\n");
73 for (l = list; l; l = l->next)
75 g_print ("%s\n", (char *) l->data);
82 g_print ("No selected files\n");
85 g_print ("Dialog was closed\n");
91 no_backup_files_filter (const GtkFileFilterInfo *filter_info,
94 gsize len = filter_info->display_name ? strlen (filter_info->display_name) : 0;
95 if (len > 0 && filter_info->display_name[len - 1] == '~')
102 format_time (time_t t)
106 time_t now = time (NULL);
109 if (abs (now - t) < 24*60*60)
114 localtime_r (&t, &tm_buf);
115 if (strftime (buf, sizeof (buf), format, &tm_buf) == 0)
116 return g_strdup ("<unknown>");
118 return g_strdup (buf);
122 format_size (gint64 size)
124 if (size < (gint64)1024)
125 return g_strdup_printf ("%d bytes", (gint)size);
126 else if (size < (gint64)1024*1024)
127 return g_strdup_printf ("%.1f K", size / (1024.));
128 else if (size < (gint64)1024*1024*1024)
129 return g_strdup_printf ("%.1f M", size / (1024.*1024.));
131 return g_strdup_printf ("%.1f G", size / (1024.*1024.*1024.));
139 size_prepared_cb (GdkPixbufLoader *loader,
144 int des_width = data[0];
145 int des_height = data[1];
147 if (des_height >= height && des_width >= width) {
149 } else if ((double)height * des_width > (double)width * des_height) {
150 width = 0.5 + (double)width * des_height / (double)height;
153 height = 0.5 + (double)height * des_width / (double)width;
157 gdk_pixbuf_loader_set_size (loader, width, height);
161 my_new_from_file_at_size (const char *filename,
166 GdkPixbufLoader *loader;
171 guchar buffer [4096];
175 g_return_val_if_fail (filename != NULL, NULL);
176 g_return_val_if_fail (width > 0 && height > 0, NULL);
178 if (stat (filename, &st) != 0) {
181 g_file_error_from_errno (errno),
182 _("Could not get information for file '%s': %s"),
183 filename, g_strerror (errno));
187 if (!S_ISREG (st.st_mode))
190 f = fopen (filename, "rb");
194 g_file_error_from_errno (errno),
195 _("Failed to open file '%s': %s"),
196 filename, g_strerror (errno));
200 loader = gdk_pixbuf_loader_new ();
201 #ifdef DONT_PRESERVE_ASPECT
202 gdk_pixbuf_loader_set_size (loader, width, height);
206 g_signal_connect (loader, "size-prepared", G_CALLBACK (size_prepared_cb), info);
210 length = fread (buffer, 1, sizeof (buffer), f);
212 if (!gdk_pixbuf_loader_write (loader, buffer, length, error)) {
213 gdk_pixbuf_loader_close (loader, NULL);
215 g_object_unref (G_OBJECT (loader));
222 if (!gdk_pixbuf_loader_close (loader, error)) {
223 g_object_unref (G_OBJECT (loader));
227 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
230 g_object_unref (G_OBJECT (loader));
233 GDK_PIXBUF_ERROR_FAILED,
234 _("Failed to load image '%s': reason not known, probably a corrupt image file"),
239 g_object_ref (pixbuf);
241 g_object_unref (G_OBJECT (loader));
247 update_preview_cb (GtkFileChooser *chooser)
249 gchar *filename = gtk_file_chooser_get_preview_filename (chooser);
250 gboolean have_preview = FALSE;
255 GError *error = NULL;
257 pixbuf = my_new_from_file_at_size (filename, 128, 128, &error);
260 gtk_image_set_from_pixbuf (GTK_IMAGE (preview_image), pixbuf);
261 g_object_unref (pixbuf);
262 gtk_widget_show (preview_image);
263 gtk_widget_hide (preview_label);
269 if (stat (filename, &buf) == 0)
273 gchar *modified_time;
275 size_str = format_size (buf.st_size);
276 modified_time = format_time (buf.st_mtime);
278 preview_text = g_strdup_printf ("<i>Modified:</i>\t%s\n"
279 "<i>Size:</i>\t%s\n",
282 gtk_label_set_markup (GTK_LABEL (preview_label), preview_text);
283 g_free (modified_time);
285 g_free (preview_text);
287 gtk_widget_hide (preview_image);
288 gtk_widget_show (preview_label);
296 gtk_file_chooser_set_preview_widget_active (chooser, have_preview);
300 set_folder_nonexistent_cb (GtkButton *button,
301 GtkFileChooser *chooser)
303 gtk_file_chooser_set_current_folder (chooser, "/nonexistent");
307 set_folder_existing_nonexistent_cb (GtkButton *button,
308 GtkFileChooser *chooser)
310 gtk_file_chooser_set_current_folder (chooser, "/usr/nonexistent");
314 set_filename_nonexistent_cb (GtkButton *button,
315 GtkFileChooser *chooser)
317 gtk_file_chooser_set_filename (chooser, "/nonexistent");
321 set_filename_existing_nonexistent_cb (GtkButton *button,
322 GtkFileChooser *chooser)
324 gtk_file_chooser_set_filename (chooser, "/usr/nonexistent");
328 main (int argc, char **argv)
330 GtkWidget *control_window;
334 GtkWidget *prop_editor;
336 GtkFileFilter *filter;
337 GtkWidget *preview_vbox;
340 gtk_init (&argc, &argv);
342 action = GTK_FILE_CHOOSER_ACTION_OPEN;
344 /* lame-o arg parsing */
345 for (i = 1; i < argc; i++)
347 if (! strcmp ("--action=open", argv[i]))
348 action = GTK_FILE_CHOOSER_ACTION_OPEN;
349 else if (! strcmp ("--action=save", argv[i]))
350 action = GTK_FILE_CHOOSER_ACTION_SAVE;
351 else if (! strcmp ("--action=select_folder", argv[i]))
352 action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER;
353 else if (! strcmp ("--action=create_folder", argv[i]))
354 action = GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER;
357 dialog = g_object_new (GTK_TYPE_FILE_CHOOSER_DIALOG,
359 "file-system-backend", "gnome-vfs",
363 case GTK_FILE_CHOOSER_ACTION_OPEN:
364 case GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER:
365 gtk_window_set_title (GTK_WINDOW (dialog), "Select a file");
366 gtk_dialog_add_buttons (GTK_DIALOG (dialog),
367 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
368 GTK_STOCK_OPEN, GTK_RESPONSE_OK,
371 case GTK_FILE_CHOOSER_ACTION_SAVE:
372 case GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER:
373 gtk_window_set_title (GTK_WINDOW (dialog), "Save a file");
374 gtk_dialog_add_buttons (GTK_DIALOG (dialog),
375 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
376 GTK_STOCK_SAVE, GTK_RESPONSE_OK,
380 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
382 g_signal_connect (dialog, "selection-changed",
383 G_CALLBACK (print_selected), NULL);
384 g_signal_connect (dialog, "current-folder-changed",
385 G_CALLBACK (print_current_folder), NULL);
386 g_signal_connect (dialog, "response",
387 G_CALLBACK (response_cb), NULL);
390 filter = gtk_file_filter_new ();
391 gtk_file_filter_set_name (filter, "All Files");
392 gtk_file_filter_add_pattern (filter, "*");
393 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
395 filter = gtk_file_filter_new ();
396 gtk_file_filter_set_name (filter, "No backup files");
397 gtk_file_filter_add_custom (filter, GTK_FILE_FILTER_DISPLAY_NAME,
398 no_backup_files_filter, NULL, NULL);
399 gtk_file_filter_add_mime_type (filter, "image/png");
400 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
402 /* Make this filter the default */
403 gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), filter);
405 filter = gtk_file_filter_new ();
406 gtk_file_filter_set_name (filter, "PNG and JPEG");
407 gtk_file_filter_add_mime_type (filter, "image/jpeg");
408 gtk_file_filter_add_mime_type (filter, "image/png");
409 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
412 preview_vbox = gtk_vbox_new (0, FALSE);
413 gtk_file_chooser_set_preview_widget (GTK_FILE_CHOOSER (dialog), preview_vbox);
415 preview_label = gtk_label_new (NULL);
416 gtk_box_pack_start (GTK_BOX (preview_vbox), preview_label, TRUE, TRUE, 0);
417 gtk_misc_set_padding (GTK_MISC (preview_label), 6, 6);
419 preview_image = gtk_image_new ();
420 gtk_box_pack_start (GTK_BOX (preview_vbox), preview_image, TRUE, TRUE, 0);
421 gtk_misc_set_padding (GTK_MISC (preview_image), 6, 6);
423 update_preview_cb (GTK_FILE_CHOOSER (dialog));
424 g_signal_connect (dialog, "update-preview",
425 G_CALLBACK (update_preview_cb), NULL);
429 extra = gtk_check_button_new_with_mnemonic ("Lar_t whoever asks about this button");
430 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (extra), TRUE);
431 gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (dialog), extra);
435 gtk_file_chooser_add_shortcut_folder_uri (GTK_FILE_CHOOSER (dialog),
436 "file:///usr/share/pixmaps",
439 /* show_all() to reveal bugs in composite widget handling */
440 gtk_widget_show_all (dialog);
442 /* Extra controls for manipulating the test environment
444 prop_editor = create_prop_editor (G_OBJECT (dialog), GTK_TYPE_FILE_CHOOSER);
446 control_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
448 vbbox = gtk_vbutton_box_new ();
449 gtk_container_add (GTK_CONTAINER (control_window), vbbox);
451 button = gtk_button_new_with_mnemonic ("_Select all");
452 gtk_container_add (GTK_CONTAINER (vbbox), button);
453 g_signal_connect_swapped (button, "clicked",
454 G_CALLBACK (gtk_file_chooser_select_all), dialog);
456 button = gtk_button_new_with_mnemonic ("_Unselect all");
457 gtk_container_add (GTK_CONTAINER (vbbox), button);
458 g_signal_connect_swapped (button, "clicked",
459 G_CALLBACK (gtk_file_chooser_unselect_all), dialog);
461 button = gtk_button_new_with_label ("set_current_folder (\"/nonexistent\")");
462 gtk_container_add (GTK_CONTAINER (vbbox), button);
463 g_signal_connect (button, "clicked",
464 G_CALLBACK (set_folder_nonexistent_cb), dialog);
466 button = gtk_button_new_with_label ("set_current_folder (\"/usr/nonexistent\"");
467 gtk_container_add (GTK_CONTAINER (vbbox), button);
468 g_signal_connect (button, "clicked",
469 G_CALLBACK (set_folder_existing_nonexistent_cb), dialog);
471 button = gtk_button_new_with_label ("set_filename (\"/nonexistent\"");
472 gtk_container_add (GTK_CONTAINER (vbbox), button);
473 g_signal_connect (button, "clicked",
474 G_CALLBACK (set_filename_nonexistent_cb), dialog);
476 button = gtk_button_new_with_label ("set_filename (\"/usr/nonexistent\"");
477 gtk_container_add (GTK_CONTAINER (vbbox), button);
478 g_signal_connect (button, "clicked",
479 G_CALLBACK (set_filename_existing_nonexistent_cb), dialog);
481 gtk_widget_show_all (control_window);