file-commands.c 11.3 KB
Newer Older
Michael Natterer's avatar
Michael Natterer committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/* The GIMP -- an image manipulation program
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 *
 * 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"

21 22
#include <string.h>

Michael Natterer's avatar
Michael Natterer committed
23 24
#include <gtk/gtk.h>

25 26
#include "libgimpwidgets/gimpwidgets.h"

Michael Natterer's avatar
Michael Natterer committed
27
#include "actions-types.h"
Michael Natterer's avatar
Michael Natterer committed
28

29 30
#include "config/gimpguiconfig.h"

31
#include "core/gimp.h"
32
#include "core/gimpcontainer.h"
33
#include "core/gimpcontext.h"
34
#include "core/gimpimage.h"
35
#include "core/gimpprogress.h"
36
#include "core/gimptemplate.h"
37

Michael Natterer's avatar
Michael Natterer committed
38 39
#include "file/file-open.h"
#include "file/file-save.h"
40
#include "file/file-utils.h"
Michael Natterer's avatar
Michael Natterer committed
41

42
#include "widgets/gimpdialogfactory.h"
43
#include "widgets/gimphelp-ids.h"
44

45
#include "display/gimpdisplay.h"
46
#include "display/gimpdisplay-foreach.h"
47

48 49
#include "menus/menus.h"

50 51 52
#include "dialogs/dialogs.h"
#include "dialogs/file-open-dialog.h"
#include "dialogs/file-save-dialog.h"
Michael Natterer's avatar
Michael Natterer committed
53

54
#include "actions.h"
Michael Natterer's avatar
Michael Natterer committed
55 56
#include "file-commands.h"

57
#include "gimp-intl.h"
Michael Natterer's avatar
Michael Natterer committed
58 59


60 61
#define REVERT_DATA_KEY "revert-confirm-dialog"

62

63 64
/*  local function prototypes  */

65 66 67 68
static void   file_new_template_callback   (GtkWidget   *widget,
                                            const gchar *name,
                                            gpointer     data);
static void   file_revert_confirm_callback (GtkWidget   *widget,
69 70
                                            gboolean     revert,
                                            gpointer     data);
71 72 73 74


/*  public functions  */

Michael Natterer's avatar
Michael Natterer committed
75
void
76
file_open_cmd_callback (GtkAction *action,
77
                        gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
78
{
Michael Natterer's avatar
Michael Natterer committed
79
  Gimp      *gimp;
80
  GtkWidget *widget;
81
  return_if_no_gimp (gimp, data);
82
  return_if_no_widget (widget, data);
Michael Natterer's avatar
Michael Natterer committed
83

84
  file_open_dialog_show (gimp, NULL, NULL, widget);
Michael Natterer's avatar
Michael Natterer committed
85 86 87
}

void
88 89
file_open_from_image_cmd_callback (GtkAction *action,
                                   gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
90
{
91
  Gimp      *gimp;
92
  GtkWidget *widget;
93
  return_if_no_gimp (gimp, data);
94
  return_if_no_widget (widget, data);
95

96
  file_open_dialog_show (gimp, action_data_get_image (data), NULL, widget);
Michael Natterer's avatar
Michael Natterer committed
97 98
}

99 100 101 102 103 104 105
void
file_open_location_cmd_callback (GtkAction *action,
                                 gpointer   data)
{
  GtkWidget *widget;
  return_if_no_widget (widget, data);

106 107 108
  gimp_dialog_factory_dialog_new (global_dialog_factory,
                                  gtk_widget_get_screen (widget),
                                  "gimp-file-open-location-dialog", -1, TRUE);
109 110
}

Michael Natterer's avatar
Michael Natterer committed
111
void
112 113
file_last_opened_cmd_callback (GtkAction *action,
                               gint       value,
114
                               gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
115
{
Michael Natterer's avatar
Michael Natterer committed
116
  Gimp          *gimp;
117
  GimpImagefile *imagefile;
118
  gint           num_entries;
119
  return_if_no_gimp (gimp, data);
Michael Natterer's avatar
Michael Natterer committed
120 121

  num_entries = gimp_container_num_children (gimp->documents);
Michael Natterer's avatar
Michael Natterer committed
122

123
  if (value >= num_entries)
Michael Natterer's avatar
Michael Natterer committed
124 125
    return;

126
  imagefile = (GimpImagefile *)
127
    gimp_container_get_child_by_index (gimp->documents, value);
Michael Natterer's avatar
Michael Natterer committed
128

129
  if (imagefile)
Michael Natterer's avatar
Michael Natterer committed
130
    {
131 132 133 134
      GimpImage         *gimage;
      GimpPDBStatusType  status;
      GError            *error = NULL;

135
      gimage = file_open_with_display (gimp, action_data_get_context (data),
136
                                       NULL,
137
                                       GIMP_OBJECT (imagefile)->name,
138 139 140 141 142
                                       &status, &error);

      if (! gimage && status != GIMP_PDB_CANCEL)
        {
          gchar *filename;
143

144 145 146 147 148 149 150 151 152
          filename =
            file_utils_uri_to_utf8_filename (GIMP_OBJECT (imagefile)->name);

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

          g_free (filename);
        }
Michael Natterer's avatar
Michael Natterer committed
153 154 155
    }
}

Michael Natterer's avatar
Michael Natterer committed
156
void
157
file_save_cmd_callback (GtkAction *action,
158
                        gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
159
{
160
  GimpDisplay *gdisp;
Michael Natterer's avatar
Michael Natterer committed
161
  return_if_no_display (gdisp, data);
162

163
  g_return_if_fail (gimp_image_active_drawable (gdisp->gimage));
164 165

  /*  Only save if the gimage has been modified  */
166 167
  if (gdisp->gimage->dirty ||
      ! GIMP_GUI_CONFIG (gdisp->gimage->gimp->config)->trust_dirty_flag)
168
    {
169
      const gchar *uri = gimp_object_get_name (GIMP_OBJECT (gdisp->gimage));
170

171
      if (! uri)
172 173 174
        {
          file_save_as_cmd_callback (action, data);
        }
175
      else
176 177
        {
          GimpPDBStatusType  status;
178
          GError            *error = NULL;
179

180
          status = file_save (gdisp->gimage, action_data_get_context (data),
181
                              GIMP_PROGRESS (gdisp),
182
                              GIMP_RUN_WITH_LAST_VALS, &error);
183

184 185 186
          if (status != GIMP_PDB_SUCCESS &&
              status != GIMP_PDB_CANCEL)
            {
187 188
              gchar *filename;

189
              filename = file_utils_uri_to_utf8_filename (uri);
190

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

              g_free (filename);
196 197
            }
        }
198
    }
Michael Natterer's avatar
Michael Natterer committed
199 200 201
}

void
202
file_save_as_cmd_callback (GtkAction *action,
203
                           gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
204
{
205
  GimpDisplay *gdisp;
Michael Natterer's avatar
Michael Natterer committed
206
  return_if_no_display (gdisp, data);
207

208
  file_save_dialog_show (gdisp->gimage, gdisp->shell);
Michael Natterer's avatar
Michael Natterer committed
209 210 211
}

void
212
file_save_a_copy_cmd_callback (GtkAction *action,
213
                               gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
214
{
215
  GimpDisplay *gdisp;
Michael Natterer's avatar
Michael Natterer committed
216
  return_if_no_display (gdisp, data);
217

218
  file_save_a_copy_dialog_show (gdisp->gimage, gdisp->shell);
Michael Natterer's avatar
Michael Natterer committed
219 220
}

221
void
222
file_save_template_cmd_callback (GtkAction *action,
223
                                 gpointer   data)
224 225 226 227 228 229
{
  GimpDisplay *gdisp;
  GtkWidget   *qbox;
  return_if_no_display (gdisp, data);

  qbox = gimp_query_string_box (_("Create New Template"),
230
                                gdisp->shell,
231 232 233 234 235 236
                                gimp_standard_help_func,
                                GIMP_HELP_FILE_SAVE_AS_TEMPLATE,
                                _("Enter a name for this template"),
                                NULL,
                                G_OBJECT (gdisp->gimage), "disconnect",
                                file_new_template_callback, gdisp->gimage);
237 238 239
  gtk_widget_show (qbox);
}

Michael Natterer's avatar
Michael Natterer committed
240
void
241
file_revert_cmd_callback (GtkAction *action,
242
                          gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
243
{
244
  GimpDisplay *gdisp;
245
  GtkWidget   *query_box;
246
  const gchar *uri;
Michael Natterer's avatar
Michael Natterer committed
247
  return_if_no_display (gdisp, data);
248

249
  uri = gimp_object_get_name (GIMP_OBJECT (gdisp->gimage));
250

251
  query_box = g_object_get_data (G_OBJECT (gdisp->gimage), REVERT_DATA_KEY);
252

253
  if (! uri)
254
    {
255
      g_message (_("Revert failed. No file name associated with this image."));
256 257 258
    }
  else if (query_box)
    {
259
      gtk_window_present (GTK_WINDOW (query_box->window));
260 261 262
    }
  else
    {
263
      gchar *basename;
264 265
      gchar *text;

266
      basename = g_path_get_basename (uri);
267

268
      text = g_strdup_printf (_("Revert '%s' to\n"
269 270 271 272
                                "'%s'?\n\n"
                                "You will lose all your changes, "
                                "including all undo information."),
                              basename, uri);
273 274

      g_free (basename);
275

276 277 278 279 280 281 282
      query_box = gimp_query_boolean_box (_("Revert Image"),
                                          gdisp->shell,
                                          gimp_standard_help_func,
                                          GIMP_HELP_FILE_REVERT,
                                          GIMP_STOCK_QUESTION,
                                          text,
                                          GTK_STOCK_YES, GTK_STOCK_NO,
283
                                          G_OBJECT (gdisp), "disconnect",
284
                                          file_revert_confirm_callback,
285
                                          gdisp);
286

287
      g_free (text);
288 289 290

      g_object_set_data (G_OBJECT (gdisp->gimage), REVERT_DATA_KEY,
                         query_box);
291

292 293
      gtk_window_set_transient_for (GTK_WINDOW (query_box),
                                    GTK_WINDOW (gdisp->shell));
294

295
      gtk_widget_show (query_box);
296
    }
Michael Natterer's avatar
Michael Natterer committed
297 298 299
}

void
300
file_quit_cmd_callback (GtkAction *action,
301
                        gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
302
{
303 304 305 306
  Gimp *gimp;
  return_if_no_gimp (gimp, data);

  gimp_exit (gimp, FALSE);
Michael Natterer's avatar
Michael Natterer committed
307
}
308

309 310
void
file_file_open_dialog (Gimp        *gimp,
311 312
                       const gchar *uri,
                       GtkWidget   *parent)
313
{
314
  file_open_dialog_show (gimp, NULL, uri, parent);
315
}
316

317

318 319
/*  private functions  */

320
static void
321 322 323
file_new_template_callback (GtkWidget   *widget,
                            const gchar *name,
                            gpointer     data)
324 325 326 327 328 329 330 331 332 333 334
{
  GimpTemplate *template;
  GimpImage    *gimage;

  gimage = (GimpImage *) data;

  if (! (name && strlen (name)))
    name = _("(Unnamed Template)");

  template = gimp_template_new (name);
  gimp_template_set_from_image (template, gimage);
335
  gimp_container_add (gimage->gimp->templates, GIMP_OBJECT (template));
336 337 338
  g_object_unref (template);
}

339 340
static void
file_revert_confirm_callback (GtkWidget *widget,
341 342
                              gboolean   revert,
                              gpointer   data)
343
{
344 345
  GimpDisplay *gdisp      = GIMP_DISPLAY (data);
  GimpImage   *old_gimage = gdisp->gimage;
346

347
  g_object_set_data (G_OBJECT (old_gimage), REVERT_DATA_KEY, NULL);
348 349 350

  if (revert)
    {
351
      Gimp              *gimp;
Michael Natterer's avatar
Michael Natterer committed
352
      GimpImage         *new_gimage;
353
      const gchar       *uri;
Michael Natterer's avatar
Michael Natterer committed
354
      GimpPDBStatusType  status;
355
      GError            *error = NULL;
356

357 358
      gimp = old_gimage->gimp;

359
      uri = gimp_object_get_name (GIMP_OBJECT (old_gimage));
360

361
      new_gimage = file_open_image (gimp, gimp_get_user_context (gimp),
362
                                    GIMP_PROGRESS (gdisp),
363
                                    uri, uri, NULL,
364 365
                                    GIMP_RUN_INTERACTIVE,
                                    &status, NULL, &error);
366

367
      if (new_gimage)
368
        {
369 370
          GList *contexts = NULL;
          GList *list;
Michael Natterer's avatar
Michael Natterer committed
371

372 373 374 375
          /*  remember which contexts refer to old_gimage  */
          for (list = gimp->context_list; list; list = g_list_next (list))
            {
              GimpContext *context = list->data;
Michael Natterer's avatar
Michael Natterer committed
376

377 378 379
              if (gimp_context_get_image (context) == old_gimage)
                contexts = g_list_prepend (contexts, list->data);
            }
Michael Natterer's avatar
Michael Natterer committed
380

381
          gimp_displays_reconnect (gimp, old_gimage, new_gimage);
382
          gimp_image_flush (new_gimage);
383 384 385 386 387 388 389 390 391 392

          /*  set the new_gimage on the remembered contexts (in reverse
           *  order, since older contexts are usually the parents of
           *  newer ones)
           */
          g_list_foreach (contexts, (GFunc) gimp_context_set_image, new_gimage);
          g_list_free (contexts);

          /*  the displays own the image now  */
          g_object_unref (new_gimage);
393
        }
394
      else if (status != GIMP_PDB_CANCEL)
395
        {
396 397 398 399
          gchar *filename;

          filename = file_utils_uri_to_utf8_filename (uri);

400
          g_message (_("Reverting to '%s' failed:\n\n%s"),
401
                     filename, error->message);
402
          g_clear_error (&error);
403 404

          g_free (filename);
405
        }
406 407
    }
}