/* GIMP - The GNU Image Manipulation Program * Copyright (C) 1995 Spencer Kimball and Peter Mattis * * GimpColorProfileChooserDialog * Copyright (C) 2006-2014 Sven Neumann * Michael Natterer * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "config.h" #include #ifdef PLATFORM_OSX #include #endif #include #include #include "libgimpcolor/gimpcolor.h" #include "gimpwidgetstypes.h" #include "gimpcolorprofilechooserdialog.h" #include "gimpcolorprofileview.h" #include "libgimp/libgimp-intl.h" /** * SECTION: gimpcolorprofilechooserdialog * @title: GimpColorProfileChooserDialog * @short_description: A file chooser for selecting color profiles. * * A #GtkFileChooser subclass for selecting color profiles. **/ struct _GimpColorProfileChooserDialogPrivate { GimpColorProfileView *profile_view; }; static void gimp_color_profile_chooser_dialog_constructed (GObject *object); static gboolean gimp_color_profile_chooser_dialog_delete_event (GtkWidget *widget, GdkEventAny *event); static void gimp_color_profile_chooser_dialog_add_shortcut (GimpColorProfileChooserDialog *dialog); static void gimp_color_profile_chooser_dialog_update_preview (GimpColorProfileChooserDialog *dialog); G_DEFINE_TYPE_WITH_PRIVATE (GimpColorProfileChooserDialog, gimp_color_profile_chooser_dialog, GTK_TYPE_FILE_CHOOSER_DIALOG) #define parent_class gimp_color_profile_chooser_dialog_parent_class static void gimp_color_profile_chooser_dialog_class_init (GimpColorProfileChooserDialogClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); object_class->constructed = gimp_color_profile_chooser_dialog_constructed; widget_class->delete_event = gimp_color_profile_chooser_dialog_delete_event; } static void gimp_color_profile_chooser_dialog_init (GimpColorProfileChooserDialog *dialog) { dialog->priv = gimp_color_profile_chooser_dialog_get_instance_private (dialog); } static void gimp_color_profile_chooser_dialog_constructed (GObject *object) { GimpColorProfileChooserDialog *dialog; GtkFileFilter *filter; GtkWidget *scrolled_window; GtkWidget *profile_view; dialog = GIMP_COLOR_PROFILE_CHOOSER_DIALOG (object); G_OBJECT_CLASS (parent_class)->constructed (object); gtk_window_set_role (GTK_WINDOW (dialog), "gimp-profile-chooser-dialog"); filter = gtk_file_filter_new (); gtk_file_filter_set_name (filter, _("All files (*.*)")); gtk_file_filter_add_pattern (filter, "*"); gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter); filter = gtk_file_filter_new (); gtk_file_filter_set_name (filter, _("ICC color profile (*.icc, *.icm)")); gtk_file_filter_add_pattern (filter, "*.[Ii][Cc][Cc]"); gtk_file_filter_add_pattern (filter, "*.[Ii][Cc][Mm]"); gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter); gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), filter); /* the preview widget */ scrolled_window = gtk_scrolled_window_new (NULL, NULL); gtk_widget_set_size_request (scrolled_window, 300, -1); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_IN); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); profile_view = gimp_color_profile_view_new (); gtk_container_add (GTK_CONTAINER (scrolled_window), profile_view); gtk_widget_show (profile_view); dialog->priv->profile_view = GIMP_COLOR_PROFILE_VIEW (profile_view); gtk_file_chooser_set_preview_widget (GTK_FILE_CHOOSER (dialog), scrolled_window); g_signal_connect (dialog, "update-preview", G_CALLBACK (gimp_color_profile_chooser_dialog_update_preview), NULL); } static gboolean gimp_color_profile_chooser_dialog_delete_event (GtkWidget *widget, GdkEventAny *event) { return TRUE; } GtkWidget * gimp_color_profile_chooser_dialog_new (const gchar *title, GtkWindow *parent, GtkFileChooserAction action) { GtkWidget *dialog; g_return_val_if_fail (title != NULL, NULL); g_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), NULL); dialog = g_object_new (GIMP_TYPE_COLOR_PROFILE_CHOOSER_DIALOG, "title", title, "action", action, NULL); if (parent) gtk_window_set_transient_for (GTK_WINDOW (dialog), parent); if (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog)) == GTK_FILE_CHOOSER_ACTION_SAVE) { gtk_dialog_add_buttons (GTK_DIALOG (dialog), _("_Cancel"), GTK_RESPONSE_CANCEL, _("_Save"), GTK_RESPONSE_ACCEPT, NULL); gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE); } else { gtk_dialog_add_buttons (GTK_DIALOG (dialog), _("_Cancel"), GTK_RESPONSE_CANCEL, _("_Open"), GTK_RESPONSE_ACCEPT, NULL); } gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT, GTK_RESPONSE_CANCEL, -1); gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT); gimp_color_profile_chooser_dialog_add_shortcut (GIMP_COLOR_PROFILE_CHOOSER_DIALOG (dialog)); return dialog; } /* Add shortcuts for default ICC profile locations */ static gboolean add_shortcut (GimpColorProfileChooserDialog *dialog, const gchar *folder) { return (g_file_test (folder, G_FILE_TEST_IS_DIR) && gtk_file_chooser_add_shortcut_folder (GTK_FILE_CHOOSER (dialog), folder, NULL)); } static void gimp_color_profile_chooser_dialog_add_shortcut (GimpColorProfileChooserDialog *dialog) { gboolean save = (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog)) == GTK_FILE_CHOOSER_ACTION_SAVE); #ifdef G_OS_WIN32 { const gchar *prefix = g_getenv ("SystemRoot"); gchar *folder; if (! prefix) prefix = "c:\\windows"; folder = g_strconcat (prefix, "\\system32\\spool\\drivers\\color", NULL); add_shortcut (dialog, folder); g_free (folder); } #elif defined(PLATFORM_OSX) { NSAutoreleasePool *pool; NSArray *path; NSString *library_dir; gchar *folder; gboolean folder_set = FALSE; pool = [[NSAutoreleasePool alloc] init]; if (save) { path = NSSearchPathForDirectoriesInDomains (NSLibraryDirectory, NSUserDomainMask, YES); library_dir = [path objectAtIndex:0]; folder = g_build_filename ([library_dir UTF8String], "ColorSync", "Profiles", NULL); folder_set = add_shortcut (dialog, folder); g_free (folder); } if (! folder_set) { path = NSSearchPathForDirectoriesInDomains (NSLibraryDirectory, NSSystemDomainMask, YES); library_dir = [path objectAtIndex:0]; folder = g_build_filename ([library_dir UTF8String], "ColorSync", "Profiles", NULL); add_shortcut (dialog, folder); g_free (folder); } [pool drain]; } #else { gboolean folder_set = FALSE; if (save) { gchar *folder = g_build_filename (g_get_user_data_dir (), "color", "icc", NULL); folder_set = add_shortcut (dialog, folder); if (! folder_set) { g_free (folder); /* Some software, like GNOME color, will save profiles in * $XDG_DATA_HOME/icc/ */ folder = g_build_filename (g_get_user_data_dir (), "icc", NULL); folder_set = add_shortcut (dialog, folder); } if (! folder_set) { g_free (folder); folder = g_build_filename (g_get_home_dir (), ".color", "icc", NULL); folder_set = add_shortcut (dialog, folder); } g_free (folder); } if (! folder_set) add_shortcut (dialog, COLOR_PROFILE_DIRECTORY); } #endif } static void gimp_color_profile_chooser_dialog_update_preview (GimpColorProfileChooserDialog *dialog) { GimpColorProfile *profile; GFile *file; GError *error = NULL; file = gtk_file_chooser_get_preview_file (GTK_FILE_CHOOSER (dialog)); if (! file) { gimp_color_profile_view_set_profile (dialog->priv->profile_view, NULL); return; } switch (g_file_query_file_type (file, G_FILE_QUERY_INFO_NONE, NULL)) { case G_FILE_TYPE_REGULAR: profile = gimp_color_profile_new_from_file (file, &error); if (! profile) { gimp_color_profile_view_set_error (dialog->priv->profile_view, error->message); g_clear_error (&error); } else { gimp_color_profile_view_set_profile (dialog->priv->profile_view, profile); g_object_unref (profile); } break; case G_FILE_TYPE_DIRECTORY: gimp_color_profile_view_set_error (dialog->priv->profile_view, _("Folder")); break; default: gimp_color_profile_view_set_error (dialog->priv->profile_view, _("Not a regular file.")); break; } g_object_unref (file); }