gimpcolorprofilechooserdialog.c 10.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/* GIMP - The GNU Image Manipulation Program
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 *
 * GimpColorProfileChooserDialog
 * Copyright (C) 2006-2014 Sven Neumann <sven@gimp.org>
 *                         Michael Natterer <mitch@gimp.org>
 *
 * 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
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20 21 22 23 24 25
 */

#include "config.h"

#include <string.h>

26 27 28 29
#ifdef PLATFORM_OSX
#include <AppKit/AppKit.h>
#endif

30 31 32 33 34 35 36 37
#include <gegl.h>
#include <gtk/gtk.h>

#include "libgimpcolor/gimpcolor.h"

#include "gimpwidgetstypes.h"

#include "gimpcolorprofilechooserdialog.h"
38
#include "gimpcolorprofileview.h"
39
#include "gimpdialog.h"
40 41 42 43 44 45

#include "libgimp/libgimp-intl.h"


struct _GimpColorProfileChooserDialogPrivate
{
46
  GimpColorProfileView *profile_view;
47 48 49
};


50 51 52 53 54 55 56
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);
57 58


59 60 61
G_DEFINE_TYPE_WITH_PRIVATE (GimpColorProfileChooserDialog,
                            gimp_color_profile_chooser_dialog,
                            GTK_TYPE_FILE_CHOOSER_DIALOG)
62 63 64 65 66 67 68

#define parent_class gimp_color_profile_chooser_dialog_parent_class


static void
gimp_color_profile_chooser_dialog_class_init (GimpColorProfileChooserDialogClass *klass)
{
69 70 71 72
  GObjectClass   *object_class = G_OBJECT_CLASS (klass);
  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);

  object_class->constructed  = gimp_color_profile_chooser_dialog_constructed;
73

74
  widget_class->delete_event = gimp_color_profile_chooser_dialog_delete_event;
75 76 77 78 79
}

static void
gimp_color_profile_chooser_dialog_init (GimpColorProfileChooserDialog *dialog)
{
80
  dialog->priv =
81
    gimp_color_profile_chooser_dialog_get_instance_private (dialog);
82 83 84 85 86 87 88
}

static void
gimp_color_profile_chooser_dialog_constructed (GObject *object)
{
  GimpColorProfileChooserDialog *dialog;
  GtkFileFilter                 *filter;
89 90
  GtkWidget                     *scrolled_window;
  GtkWidget                     *profile_view;
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110

  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);

111
  /*  the preview widget  */
112

113
  scrolled_window = gtk_scrolled_window_new (NULL, NULL);
114 115 116
  gtk_widget_set_size_request (scrolled_window, 300, -1);
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window),
                                       GTK_SHADOW_IN);
117 118 119
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
                                  GTK_POLICY_AUTOMATIC,
                                  GTK_POLICY_AUTOMATIC);
120

121 122 123
  profile_view = gimp_color_profile_view_new ();
  gtk_container_add (GTK_CONTAINER (scrolled_window), profile_view);
  gtk_widget_show (profile_view);
124

125
  dialog->priv->profile_view = GIMP_COLOR_PROFILE_VIEW (profile_view);
126

127 128
  gtk_file_chooser_set_preview_widget (GTK_FILE_CHOOSER (dialog),
                                       scrolled_window);
129

130 131 132
  g_signal_connect (dialog, "update-preview",
                    G_CALLBACK (gimp_color_profile_chooser_dialog_update_preview),
                    NULL);
133 134
}

135 136 137 138 139 140 141
static gboolean
gimp_color_profile_chooser_dialog_delete_event (GtkWidget   *widget,
                                                GdkEventAny *event)
{
  return TRUE;
}

142
GtkWidget *
143 144 145
gimp_color_profile_chooser_dialog_new (const gchar          *title,
                                       GtkWindow            *parent,
                                       GtkFileChooserAction  action)
146
{
147
  GtkWidget *dialog;
148

149 150 151 152 153 154 155 156 157 158 159
  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);

160 161 162 163
  if (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog)) ==
      GTK_FILE_CHOOSER_ACTION_SAVE)
    {
      gtk_dialog_add_buttons (GTK_DIALOG (dialog),
164 165
                              _("_Cancel"), GTK_RESPONSE_CANCEL,
                              _("_Save"),   GTK_RESPONSE_ACCEPT,
166 167 168 169 170 171 172 173
                              NULL);

      gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog),
                                                      TRUE);
    }
  else
    {
      gtk_dialog_add_buttons (GTK_DIALOG (dialog),
174 175
                              _("_Cancel"), GTK_RESPONSE_CANCEL,
                              _("_Open"),   GTK_RESPONSE_ACCEPT,
176 177 178
                              NULL);
    }

179
  gimp_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
180 181 182 183 184 185 186 187
                                           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));

188
  return dialog;
189 190
}

191 192 193 194 195 196 197 198 199 200
/* 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));
}

201 202 203
static void
gimp_color_profile_chooser_dialog_add_shortcut (GimpColorProfileChooserDialog *dialog)
{
204 205 206
  gboolean save = (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog)) ==
                   GTK_FILE_CHOOSER_ACTION_SAVE);

207 208 209 210 211 212 213 214 215 216
#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);

217
    add_shortcut (dialog, folder);
218 219 220

    g_free (folder);
  }
221 222
#elif defined(PLATFORM_OSX)
  {
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
    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);

240
        folder_set = add_shortcut (dialog, folder);
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257
        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];
258
  }
259 260
#else
  {
261 262 263 264 265 266 267 268 269
    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);

270 271 272 273 274 275 276 277 278 279 280 281 282
        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);
          }

283 284 285 286 287 288 289 290 291 292 293 294 295
        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)
296
      add_shortcut (dialog, COLOR_PROFILE_DIRECTORY);
297 298 299 300 301 302 303
  }
#endif
}

static void
gimp_color_profile_chooser_dialog_update_preview (GimpColorProfileChooserDialog *dialog)
{
304
  GimpColorProfile *profile;
305
  GFile            *file;
306
  GError           *error = NULL;
307

308
  file = gtk_file_chooser_get_preview_file (GTK_FILE_CHOOSER (dialog));
309

310
  if (! file)
311
    {
312
      gimp_color_profile_view_set_profile (dialog->priv->profile_view, NULL);
313 314
      return;
    }
315

316
  switch (g_file_query_file_type (file, G_FILE_QUERY_INFO_NONE, NULL))
317
    {
318
    case G_FILE_TYPE_REGULAR:
319
      profile = gimp_color_profile_new_from_file (file, &error);
320 321 322 323 324 325 326 327 328 329 330

      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);
331
          g_object_unref (profile);
332 333 334 335
        }
      break;

    case G_FILE_TYPE_DIRECTORY:
336
      gimp_color_profile_view_set_error (dialog->priv->profile_view,
337 338 339 340 341 342 343
                                         _("Folder"));
      break;

    default:
      gimp_color_profile_view_set_error (dialog->priv->profile_view,
                                         _("Not a regular file."));
      break;
344
    }
345

346
  g_object_unref (file);
347
}