file-save-dialog.c 10.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
/* The GIMP -- an image manipulation program
 * Copyright (C) 1995, 1996, 1997 Spencer Kimball and Peter Mattis
 * Copyright (C) 1997 Josh MacDonald
 *
 * 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 2 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, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include "config.h"

#include <string.h>

#include <gtk/gtk.h>

#include "libgimpwidgets/gimpwidgets.h"

Michael Natterer's avatar
Michael Natterer committed
28
#include "gui-types.h"
29

Michael Natterer's avatar
Michael Natterer committed
30
#include "core/gimp.h"
31
#include "core/gimpimage.h"
32
#include "core/gimpprogress.h"
33

Michael Natterer's avatar
Michael Natterer committed
34 35 36
#include "file/file-save.h"
#include "file/file-utils.h"

37 38
#include "widgets/gimpdialogfactory.h"
#include "widgets/gimpfiledialog.h"
39
#include "widgets/gimphelp-ids.h"
40
#include "widgets/gimpmenufactory.h"
41

42
#include "dialogs.h"
43 44 45
#include "file-dialog-utils.h"
#include "file-save-dialog.h"

46
#include "gimp-intl.h"
47 48


49 50
/*  local function prototypes  */

51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
static GtkWidget * file_save_dialog_create      (Gimp          *gimp);
static void        file_save_dialog_response    (GtkWidget     *save_dialog,
                                                 gint           response_id,
                                                 Gimp          *gimp);
static void        file_save_overwrite          (GtkWidget     *save_dialog,
                                                 const gchar   *uri,
                                                 const gchar   *raw_filename);
static void        file_save_overwrite_callback (GtkWidget     *widget,
                                                 gboolean       overwrite,
                                                 gpointer       data);
static gboolean    file_save_dialog_save_image  (GtkWidget     *save_dialog,
                                                 GimpImage     *gimage,
                                                 const gchar   *uri,
                                                 const gchar   *raw_filename,
                                                 PlugInProcDef *save_proc,
                                                 gboolean       set_uri_and_proc,
                                                 gboolean       set_image_clean);
68 69


70 71
/*  private variables  */

72
static GtkWidget *filesave = NULL;
73 74 75 76 77


/*  public functions  */

void
78 79
file_save_dialog_show (GimpImage *gimage,
                       GtkWidget *parent)
80
{
Michael Natterer's avatar
Michael Natterer committed
81
  g_return_if_fail (GIMP_IS_IMAGE (gimage));
82
  g_return_if_fail (parent == NULL || GTK_IS_WIDGET (parent));
Michael Natterer's avatar
Michael Natterer committed
83

84
  if (! gimp_image_active_drawable (gimage))
85 86 87
    return;

  if (! filesave)
88
    filesave = file_save_dialog_create (gimage->gimp);
89

90
  gimp_file_dialog_set_sensitive (GIMP_FILE_DIALOG (filesave), TRUE);
91

92
  if (GTK_WIDGET_VISIBLE (filesave))
93 94 95 96
    {
      gtk_window_present (GTK_WINDOW (filesave));
      return;
    }
97 98 99

  gtk_window_set_title (GTK_WINDOW (filesave), _("Save Image"));

100 101
  gimp_file_dialog_set_image (GIMP_FILE_DIALOG (filesave),
                              gimage, TRUE, TRUE);
102

103
  file_dialog_show (filesave, parent);
104 105 106
}

void
107 108
file_save_a_copy_dialog_show (GimpImage *gimage,
                              GtkWidget *parent)
109
{
Michael Natterer's avatar
Michael Natterer committed
110
  g_return_if_fail (GIMP_IS_IMAGE (gimage));
111
  g_return_if_fail (parent == NULL || GTK_IS_WIDGET (parent));
Michael Natterer's avatar
Michael Natterer committed
112

113
  if (! gimp_image_active_drawable (gimage))
114 115
    return;

116
  if (! filesave)
117
    filesave = file_save_dialog_create (gimage->gimp);
118

119
  gimp_file_dialog_set_sensitive (GIMP_FILE_DIALOG (filesave), TRUE);
120

121
  if (GTK_WIDGET_VISIBLE (filesave))
122 123 124 125
    {
      gtk_window_present (GTK_WINDOW (filesave));
      return;
    }
126 127 128

  gtk_window_set_title (GTK_WINDOW (filesave), _("Save a Copy of the Image"));

129 130
  gimp_file_dialog_set_image (GIMP_FILE_DIALOG (filesave),
                              gimage, FALSE, FALSE);
131

132
  file_dialog_show (filesave, parent);
133 134 135 136 137
}


/*  private functions  */

138
static GtkWidget *
139
file_save_dialog_create (Gimp *gimp)
140
{
141
  GtkWidget *dialog;
142

143 144 145 146 147
  dialog = gimp_file_dialog_new (gimp,
                                 GTK_FILE_CHOOSER_ACTION_SAVE,
                                 _("Save Image"), "gimp-file-save",
                                 GTK_STOCK_SAVE,
                                 GIMP_HELP_FILE_SAVE);
148 149

  gimp_dialog_factory_add_foreign (global_dialog_factory,
150
                                   "gimp-file-save-dialog", dialog);
151

152
  g_signal_connect (dialog, "response",
153
                    G_CALLBACK (file_save_dialog_response),
154 155
                    gimp);

156
  return dialog;
157 158 159
}

static void
160 161 162
file_save_dialog_response (GtkWidget *save_dialog,
                           gint       response_id,
                           Gimp      *gimp)
163
{
164
  GimpFileDialog *dialog = GIMP_FILE_DIALOG (save_dialog);
165 166
  gchar          *uri;
  gchar          *filename;
167

168 169
  if (response_id != GTK_RESPONSE_OK)
    {
170 171 172
      if (! dialog->busy)
        file_dialog_hide (save_dialog);

173 174 175
      return;
    }

176
  uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (save_dialog));
177

178
  filename = g_filename_from_uri (uri, NULL, NULL);
179

180
  if (g_file_test (filename, G_FILE_TEST_EXISTS))
181
    {
182
      file_save_overwrite (save_dialog, uri, uri);
183 184 185
    }
  else
    {
186
      gimp_file_dialog_set_sensitive (dialog, FALSE);
187

188 189 190
      if (file_save_dialog_save_image (save_dialog,
                                       dialog->gimage,
                                       uri,
191
                                       uri,
192 193 194 195 196 197
                                       dialog->file_proc,
                                       dialog->set_uri_and_proc,
                                       dialog->set_image_clean))
        {
          file_dialog_hide (save_dialog);
        }
198

199
      gimp_file_dialog_set_sensitive (dialog, TRUE);
200
    }
201 202

  g_free (uri);
203
  g_free (filename);
204 205
}

206 207 208 209 210 211 212 213 214
typedef struct _OverwriteData OverwriteData;

struct _OverwriteData
{
  GtkWidget *save_dialog;
  gchar     *uri;
  gchar     *raw_filename;
};

215
static void
216 217 218
file_save_overwrite (GtkWidget   *save_dialog,
                     const gchar *uri,
                     const gchar *raw_filename)
219 220
{
  OverwriteData *overwrite_data;
221
  GtkWidget     *query_box;
222 223
  gchar         *filename;
  gchar         *message;
224

Michael Natterer's avatar
Michael Natterer committed
225 226
  overwrite_data = g_new0 (OverwriteData, 1);

227
  overwrite_data->save_dialog  = save_dialog;
228 229
  overwrite_data->uri          = g_strdup (uri);
  overwrite_data->raw_filename = g_strdup (raw_filename);
230

231
  filename = file_utils_uri_to_utf8_filename (uri);
Sven Neumann's avatar
Sven Neumann committed
232 233 234
  message = g_strdup_printf (_("A file named '%s' already exists.\n\n"
                               "Do you want to replace it with the image "
                               "you are saving?"), filename);
235
  g_free (filename);
236

237
  query_box = gimp_query_boolean_box (_("File exists!"),
238
                                      save_dialog,
239 240 241 242
                                      gimp_standard_help_func,
                                      GIMP_HELP_FILE_SAVE_OVERWRITE,
                                      GIMP_STOCK_QUESTION,
                                      message,
Sven Neumann's avatar
Sven Neumann committed
243
                                      _("Replace"), GTK_STOCK_CANCEL,
244 245 246
                                      NULL, NULL,
                                      file_save_overwrite_callback,
                                      overwrite_data);
247

248
  g_free (message);
249

250
  gtk_window_set_transient_for (GTK_WINDOW (query_box),
251
                                GTK_WINDOW (save_dialog));
252

253 254 255
  gimp_file_dialog_set_sensitive (GIMP_FILE_DIALOG (save_dialog), FALSE);
  gtk_dialog_set_response_sensitive (GTK_DIALOG (save_dialog),
                                     GTK_RESPONSE_CANCEL, FALSE);
256 257

  gtk_widget_show (query_box);
258 259 260
}

static void
261 262 263
file_save_overwrite_callback (GtkWidget *widget,
                              gboolean   overwrite,
                              gpointer   data)
264
{
265 266 267 268 269
  OverwriteData  *overwrite_data = data;
  GimpFileDialog *dialog = GIMP_FILE_DIALOG (overwrite_data->save_dialog);

  gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog),
                                     GTK_RESPONSE_CANCEL, TRUE);
270 271 272

  if (overwrite)
    {
273 274
      gtk_widget_hide (widget);

275 276 277 278 279 280 281 282 283 284
      if (file_save_dialog_save_image (overwrite_data->save_dialog,
                                       dialog->gimage,
                                       overwrite_data->uri,
                                       overwrite_data->raw_filename,
                                       dialog->file_proc,
                                       dialog->set_uri_and_proc,
                                       dialog->set_image_clean))
        {
          file_dialog_hide (overwrite_data->save_dialog);
        }
285

286 287
    }

288
  gimp_file_dialog_set_sensitive (dialog, TRUE);
289

290
  g_free (overwrite_data->uri);
291 292 293
  g_free (overwrite_data->raw_filename);
  g_free (overwrite_data);
}
294

295
static gboolean
296 297 298 299 300
file_save_dialog_save_image (GtkWidget     *save_dialog,
                             GimpImage     *gimage,
                             const gchar   *uri,
                             const gchar   *raw_filename,
                             PlugInProcDef *save_proc,
301 302
                             gboolean       set_uri_and_proc,
                             gboolean       set_image_clean)
303
{
304 305
  GimpPDBStatusType  status;
  GError            *error = NULL;
306

307
  status = file_save_as (gimage,
308
                         gimp_get_user_context (gimage->gimp),
309
                         GIMP_PROGRESS (save_dialog),
310 311 312 313
                         uri,
                         raw_filename,
                         save_proc,
                         GIMP_RUN_INTERACTIVE,
314
                         set_uri_and_proc,
315
                         set_image_clean,
316
                         &error);
317 318 319 320

  if (status != GIMP_PDB_SUCCESS &&
      status != GIMP_PDB_CANCEL)
    {
321
      gchar *filename = file_utils_uri_to_utf8_filename (uri);
322 323 324 325 326 327

      g_message (_("Saving '%s' failed:\n\n%s"),
                 filename, error->message);
      g_clear_error (&error);

      g_free (filename);
328 329

      return FALSE;
330
    }
331 332

  return TRUE;
333
}