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 g_error_free (error);
299 gtk_file_chooser_set_preview_widget_active (chooser, have_preview);
303 set_folder_nonexistent_cb (GtkButton *button,
304 GtkFileChooser *chooser)
306 gtk_file_chooser_set_current_folder (chooser, "/nonexistent");
310 set_folder_existing_nonexistent_cb (GtkButton *button,
311 GtkFileChooser *chooser)
313 gtk_file_chooser_set_current_folder (chooser, "/usr/nonexistent");
317 set_filename_nonexistent_cb (GtkButton *button,
318 GtkFileChooser *chooser)
320 gtk_file_chooser_set_filename (chooser, "/nonexistent");
324 set_filename_existing_nonexistent_cb (GtkButton *button,
325 GtkFileChooser *chooser)
327 gtk_file_chooser_set_filename (chooser, "/usr/nonexistent");
331 main (int argc, char **argv)
333 GtkWidget *control_window;
337 GtkWidget *prop_editor;
339 GtkFileFilter *filter;
340 GtkWidget *preview_vbox;
343 gtk_init (&argc, &argv);
345 action = GTK_FILE_CHOOSER_ACTION_OPEN;
347 /* lame-o arg parsing */
348 for (i = 1; i < argc; i++)
350 if (! strcmp ("--action=open", argv[i]))
351 action = GTK_FILE_CHOOSER_ACTION_OPEN;
352 else if (! strcmp ("--action=save", argv[i]))
353 action = GTK_FILE_CHOOSER_ACTION_SAVE;
354 else if (! strcmp ("--action=select_folder", argv[i]))
355 action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER;
356 else if (! strcmp ("--action=create_folder", argv[i]))
357 action = GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER;
360 dialog = g_object_new (GTK_TYPE_FILE_CHOOSER_DIALOG,
362 "file-system-backend", "gtk+",
366 case GTK_FILE_CHOOSER_ACTION_OPEN:
367 case GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER:
368 gtk_window_set_title (GTK_WINDOW (dialog), "Select a file");
369 gtk_dialog_add_buttons (GTK_DIALOG (dialog),
370 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
371 GTK_STOCK_OPEN, GTK_RESPONSE_OK,
374 case GTK_FILE_CHOOSER_ACTION_SAVE:
375 case GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER:
376 gtk_window_set_title (GTK_WINDOW (dialog), "Save a file");
377 gtk_dialog_add_buttons (GTK_DIALOG (dialog),
378 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
379 GTK_STOCK_SAVE, GTK_RESPONSE_OK,
383 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
385 g_signal_connect (dialog, "selection-changed",
386 G_CALLBACK (print_selected), NULL);
387 g_signal_connect (dialog, "current-folder-changed",
388 G_CALLBACK (print_current_folder), NULL);
389 g_signal_connect (dialog, "response",
390 G_CALLBACK (response_cb), NULL);
393 filter = gtk_file_filter_new ();
394 gtk_file_filter_set_name (filter, "All Files");
395 gtk_file_filter_add_pattern (filter, "*");
396 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
398 filter = gtk_file_filter_new ();
399 gtk_file_filter_set_name (filter, "No backup files");
400 gtk_file_filter_add_custom (filter, GTK_FILE_FILTER_DISPLAY_NAME,
401 no_backup_files_filter, NULL, NULL);
402 gtk_file_filter_add_mime_type (filter, "image/png");
403 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
405 /* Make this filter the default */
406 gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), filter);
408 filter = gtk_file_filter_new ();
409 gtk_file_filter_set_name (filter, "PNG and JPEG");
410 gtk_file_filter_add_mime_type (filter, "image/jpeg");
411 gtk_file_filter_add_mime_type (filter, "image/png");
412 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
415 preview_vbox = gtk_vbox_new (0, FALSE);
416 gtk_file_chooser_set_preview_widget (GTK_FILE_CHOOSER (dialog), preview_vbox);
418 preview_label = gtk_label_new (NULL);
419 gtk_box_pack_start (GTK_BOX (preview_vbox), preview_label, TRUE, TRUE, 0);
420 gtk_misc_set_padding (GTK_MISC (preview_label), 6, 6);
422 preview_image = gtk_image_new ();
423 gtk_box_pack_start (GTK_BOX (preview_vbox), preview_image, TRUE, TRUE, 0);
424 gtk_misc_set_padding (GTK_MISC (preview_image), 6, 6);
426 update_preview_cb (GTK_FILE_CHOOSER (dialog));
427 g_signal_connect (dialog, "update-preview",
428 G_CALLBACK (update_preview_cb), NULL);
432 extra = gtk_check_button_new_with_mnemonic ("Lar_t whoever asks about this button");
433 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (extra), TRUE);
434 gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (dialog), extra);
438 gtk_file_chooser_add_shortcut_folder_uri (GTK_FILE_CHOOSER (dialog),
439 "file:///usr/share/pixmaps",
442 /* show_all() to reveal bugs in composite widget handling */
443 gtk_widget_show_all (dialog);
445 /* Extra controls for manipulating the test environment
447 prop_editor = create_prop_editor (G_OBJECT (dialog), GTK_TYPE_FILE_CHOOSER);
449 control_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
451 vbbox = gtk_vbutton_box_new ();
452 gtk_container_add (GTK_CONTAINER (control_window), vbbox);
454 button = gtk_button_new_with_mnemonic ("_Select all");
455 gtk_container_add (GTK_CONTAINER (vbbox), button);
456 g_signal_connect_swapped (button, "clicked",
457 G_CALLBACK (gtk_file_chooser_select_all), dialog);
459 button = gtk_button_new_with_mnemonic ("_Unselect all");
460 gtk_container_add (GTK_CONTAINER (vbbox), button);
461 g_signal_connect_swapped (button, "clicked",
462 G_CALLBACK (gtk_file_chooser_unselect_all), dialog);
464 button = gtk_button_new_with_label ("set_current_folder (\"/nonexistent\")");
465 gtk_container_add (GTK_CONTAINER (vbbox), button);
466 g_signal_connect (button, "clicked",
467 G_CALLBACK (set_folder_nonexistent_cb), dialog);
469 button = gtk_button_new_with_label ("set_current_folder (\"/usr/nonexistent\"");
470 gtk_container_add (GTK_CONTAINER (vbbox), button);
471 g_signal_connect (button, "clicked",
472 G_CALLBACK (set_folder_existing_nonexistent_cb), dialog);
474 button = gtk_button_new_with_label ("set_filename (\"/nonexistent\"");
475 gtk_container_add (GTK_CONTAINER (vbbox), button);
476 g_signal_connect (button, "clicked",
477 G_CALLBACK (set_filename_nonexistent_cb), dialog);
479 button = gtk_button_new_with_label ("set_filename (\"/usr/nonexistent\"");
480 gtk_container_add (GTK_CONTAINER (vbbox), button);
481 g_signal_connect (button, "clicked",
482 G_CALLBACK (set_filename_existing_nonexistent_cb), dialog);
484 gtk_widget_show_all (control_window);