/* PIKA - Photo and Image Kooker Application
 * a rebranding of The GNU Image Manipulation Program (created with heckimp)
 * A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
 *
 * Original copyright, applying to most contents (license remains unchanged): 
 * 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 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 <https://www.gnu.org/licenses/>.
 */

#include "config.h"

#include <string.h>

#include <gegl.h>
#include <gtk/gtk.h>

#include "libpikabase/pikabase.h"
#include "libpikawidgets/pikawidgets.h"

#include "actions-types.h"

#include "config/pikaguiconfig.h"

#include "core/pika.h"
#include "core/pikacontainer.h"
#include "core/pikaimage.h"
#include "core/pikaimagefile.h"
#include "core/pikaprogress.h"
#include "core/pikatemplate.h"

#include "plug-in/pikapluginmanager-file.h"

#include "file/file-open.h"
#include "file/file-save.h"
#include "file/pika-file.h"

#include "widgets/pikaactiongroup.h"
#include "widgets/pikaclipboard.h"
#include "widgets/pikadialogfactory.h"
#include "widgets/pikaexportdialog.h"
#include "widgets/pikafiledialog.h"
#include "widgets/pikahelp-ids.h"
#include "widgets/pikamessagebox.h"
#include "widgets/pikamessagedialog.h"
#include "widgets/pikaopendialog.h"
#include "widgets/pikasavedialog.h"
#include "widgets/pikawidgets-utils.h"

#include "display/pikadisplay.h"
#include "display/pikadisplay-foreach.h"

#include "dialogs/dialogs.h"
#include "dialogs/file-save-dialog.h"

#include "actions.h"
#include "file-commands.h"

#include "pika-intl.h"


/*  local function prototypes  */

static void        file_open_dialog_show        (Pika         *pika,
                                                 GtkWidget    *parent,
                                                 const gchar  *title,
                                                 PikaImage    *image,
                                                 GFile        *file,
                                                 gboolean      open_as_layers);
static GtkWidget * file_save_dialog_show        (Pika         *pika,
                                                 PikaImage    *image,
                                                 GtkWidget    *parent,
                                                 const gchar  *title,
                                                 gboolean      save_a_copy,
                                                 gboolean      close_after_saving,
                                                 PikaDisplay  *display);
static GtkWidget * file_export_dialog_show      (Pika         *pika,
                                                 PikaImage    *image,
                                                 GtkWidget    *parent,
                                                 PikaDisplay  *display);
static void        file_save_dialog_response    (GtkWidget    *dialog,
                                                 gint          response_id,
                                                 gpointer      data);
static void        file_export_dialog_response  (GtkWidget    *dialog,
                                                 gint          response_id,
                                                 gpointer      data);
static void        file_new_template_callback   (GtkWidget    *widget,
                                                 const gchar  *name,
                                                 gpointer      data);
static void        file_revert_confirm_response (GtkWidget    *dialog,
                                                 gint          response_id,
                                                 PikaDisplay  *display);



/*  public functions  */


void
file_open_cmd_callback (PikaAction *action,
                        GVariant   *value,
                        gpointer    data)
{
  Pika        *pika;
  GtkWidget   *widget;
  PikaImage   *image;
  return_if_no_pika (pika, data);
  return_if_no_widget (widget, data);

  image = action_data_get_image (data);

  file_open_dialog_show (pika, widget,
                         _("Open Image"),
                         image, NULL, FALSE);
}

void
file_open_as_layers_cmd_callback (PikaAction *action,
                                  GVariant   *value,
                                  gpointer    data)
{
  Pika        *pika;
  GtkWidget   *widget;
  PikaDisplay *display;
  PikaImage   *image = NULL;
  return_if_no_pika (pika, data);
  return_if_no_widget (widget, data);

  display = action_data_get_display (data);

  if (display)
    image = pika_display_get_image (display);

  file_open_dialog_show (pika, widget,
                         _("Open Image as Layers"),
                         image, NULL, TRUE);
}

void
file_open_location_cmd_callback (PikaAction *action,
                                 GVariant   *value,
                                 gpointer    data)
{
  GtkWidget *widget;
  return_if_no_widget (widget, data);

  pika_dialog_factory_dialog_new (pika_dialog_factory_get_singleton (),
                                  pika_widget_get_monitor (widget),
                                  NULL /*ui_manager*/,
                                  widget,
                                  "pika-file-open-location-dialog", -1, TRUE);
}

void
file_open_recent_cmd_callback (PikaAction *action,
                               GVariant   *value,
                               gpointer    data)
{
  Pika          *pika;
  PikaImagefile *imagefile;
  gint           index;
  gint           num_entries;
  return_if_no_pika (pika, data);

  index = g_variant_get_int32 (value);

  num_entries = pika_container_get_n_children (pika->documents);

  if (index >= num_entries)
    return;

  imagefile = (PikaImagefile *)
    pika_container_get_child_by_index (pika->documents, index);

  if (imagefile)
    {
      GFile             *file;
      PikaDisplay       *display;
      GtkWidget         *widget;
      PikaProgress      *progress;
      PikaImage         *image;
      PikaPDBStatusType  status;
      GError            *error = NULL;
      return_if_no_display (display, data);
      return_if_no_widget (widget, data);

      g_object_ref (display);
      g_object_ref (imagefile);

      file = pika_imagefile_get_file (imagefile);

      progress = pika_display_get_image (display) ?
                 NULL : PIKA_PROGRESS (display);

      image = file_open_with_display (pika, action_data_get_context (data),
                                      progress,
                                      file, FALSE,
                                      G_OBJECT (pika_widget_get_monitor (widget)),
                                      &status, &error);

      if (! image && status != PIKA_PDB_CANCEL)
        {
          pika_message (pika, G_OBJECT (display), PIKA_MESSAGE_ERROR,
                        _("Opening '%s' failed:\n\n%s"),
                        pika_file_get_utf8_name (file), error->message);
          g_clear_error (&error);
        }

      g_object_unref (imagefile);
      g_object_unref (display);
    }
}

void
file_save_cmd_callback (PikaAction *action,
                        GVariant   *value,
                        gpointer    data)
{
  Pika         *pika;
  PikaDisplay  *display;
  PikaImage    *image;
  GList        *drawables;
  GtkWidget    *widget;
  PikaSaveMode  save_mode;
  GFile        *file  = NULL;
  gboolean      saved = FALSE;
  return_if_no_pika (pika, data);
  return_if_no_display (display, data);
  return_if_no_widget (widget, data);

  image = pika_display_get_image (display);

  save_mode = (PikaSaveMode) g_variant_get_int32 (value);

  drawables = pika_image_get_selected_drawables (image);
  if (! drawables)
    {
      g_list_free (drawables);
      return;
    }
  g_list_free (drawables);

  file = pika_image_get_file (image);

  switch (save_mode)
    {
    case PIKA_SAVE_MODE_SAVE:
    case PIKA_SAVE_MODE_SAVE_AND_CLOSE:
      /*  Only save if the image has been modified, or if it is new.  */
      if ((pika_image_is_dirty (image) ||
           ! PIKA_GUI_CONFIG (image->pika->config)->trust_dirty_flag) ||
          file == NULL)
        {
          PikaPlugInProcedure *save_proc  = pika_image_get_save_proc (image);
          gboolean             valid_file = FALSE;

          if (file)
            {
              gchar *uri = g_file_get_uri (file);

              /* Non-valid URI (such as "Untitled.xcd" without a scheme) are
               * considered non-native by GLib and will trigger remote file code
               * path in file_save_dialog_save_image(), eventually failing with
               * a weird error. When we encounter such non-valid URI, we just
               * consider that the file was entered manually with a bogus name
               * (possibly by some script or plug-in) and we fall through
               * directly to showing the file dialog. The file name will still
               * be useful as default file name.
               */
              valid_file = g_uri_is_valid (uri, G_URI_FLAGS_NONE, NULL);
              g_free (uri);
            }

          if (valid_file && ! save_proc)
            {
              save_proc =
                pika_plug_in_manager_file_procedure_find (image->pika->plug_in_manager,
                                                          PIKA_FILE_PROCEDURE_GROUP_SAVE,
                                                          file, NULL);
            }

          if (valid_file && save_proc)
            {
              saved = file_save_dialog_save_image (PIKA_PROGRESS (display),
                                                   pika, image, file,
                                                   save_proc,
                                                   PIKA_RUN_WITH_LAST_VALS,
                                                   TRUE, FALSE, FALSE,
                                                   pika_image_get_xcf_compression (image),
                                                   TRUE);
              break;
            }

          /* fall thru */
        }
      else
        {
          pika_message_literal (image->pika,
                                G_OBJECT (display), PIKA_MESSAGE_INFO,
                                _("No changes need to be saved"));
          saved = TRUE;
          break;
        }

    case PIKA_SAVE_MODE_SAVE_AS:
      file_save_dialog_show (pika, image, widget,
                             _("Save Image"), FALSE,
                             save_mode == PIKA_SAVE_MODE_SAVE_AND_CLOSE, display);
      break;

    case PIKA_SAVE_MODE_SAVE_A_COPY:
      file_save_dialog_show (pika, image, widget,
                             _("Save a Copy of the Image"), TRUE,
                             FALSE, display);
      break;

    case PIKA_SAVE_MODE_EXPORT_AS:
      file_export_dialog_show (pika, image, widget, display);
      break;

    case PIKA_SAVE_MODE_EXPORT:
    case PIKA_SAVE_MODE_OVERWRITE:
      {
        GFile               *file        = NULL;
        PikaPlugInProcedure *export_proc = NULL;
        gboolean             overwrite   = FALSE;

        if (save_mode == PIKA_SAVE_MODE_EXPORT)
          {
            file        = pika_image_get_exported_file (image);
            export_proc = pika_image_get_export_proc (image);

            if (! file)
              {
                /* Behave as if Export As... was invoked */
                file_export_dialog_show (pika, image, widget, display);
                break;
              }

            overwrite = FALSE;
          }
        else if (save_mode == PIKA_SAVE_MODE_OVERWRITE)
          {
            file = pika_image_get_imported_file (image);

            overwrite = TRUE;
          }

        if (file && ! export_proc)
          {
            export_proc =
              pika_plug_in_manager_file_procedure_find (image->pika->plug_in_manager,
                                                        PIKA_FILE_PROCEDURE_GROUP_EXPORT,
                                                        file, NULL);
          }

        if (file && export_proc)
          {
            saved = file_save_dialog_save_image (PIKA_PROGRESS (display),
                                                 pika, image, file,
                                                 export_proc,
                                                 PIKA_RUN_WITH_LAST_VALS,
                                                 FALSE,
                                                 overwrite, ! overwrite,
                                                 FALSE, TRUE);
          }
      }
      break;
    }

  if (save_mode == PIKA_SAVE_MODE_SAVE_AND_CLOSE &&
      saved &&
      ! pika_image_is_dirty (image))
    {
      pika_display_close (display);
    }
}

void
file_create_template_cmd_callback (PikaAction *action,
                                   GVariant   *value,
                                   gpointer    data)
{
  PikaDisplay *display;
  PikaImage   *image;
  GtkWidget   *dialog;
  return_if_no_display (display, data);

  image = pika_display_get_image (display);

  dialog = pika_query_string_box (_("Create New Template"),
                                  GTK_WIDGET (pika_display_get_shell (display)),
                                  pika_standard_help_func,
                                  PIKA_HELP_FILE_CREATE_TEMPLATE,
                                  _("Enter a name for this template"),
                                  NULL,
                                  G_OBJECT (image), "disconnect",
                                  file_new_template_callback,
                                  image, NULL);
  gtk_widget_show (dialog);
}

void
file_revert_cmd_callback (PikaAction *action,
                          GVariant   *value,
                          gpointer    data)
{
  PikaDisplay *display;
  PikaImage   *image;
  GtkWidget   *dialog;
  GFile       *file;
  return_if_no_display (display, data);

  image = pika_display_get_image (display);

  file = pika_image_get_file (image);

  if (! file)
    file = pika_image_get_imported_file (image);

  if (! file)
    {
      pika_message_literal (image->pika,
                            G_OBJECT (display), PIKA_MESSAGE_ERROR,
                            _("Revert failed. "
                              "No file name associated with this image."));
      return;
    }

#define REVERT_DIALOG_KEY "pika-revert-confirm-dialog"

  dialog = dialogs_get_dialog (G_OBJECT (image), REVERT_DIALOG_KEY);

  if (! dialog)
    {
      dialog =
        pika_message_dialog_new (_("Revert Image"), PIKA_ICON_DOCUMENT_REVERT,
                                 GTK_WIDGET (pika_display_get_shell (display)),
                                 0,
                                 pika_standard_help_func, PIKA_HELP_FILE_REVERT,

                                 _("_Cancel"), GTK_RESPONSE_CANCEL,
                                 _("_Revert"), GTK_RESPONSE_OK,

                                 NULL);

      pika_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
                                               GTK_RESPONSE_OK,
                                               GTK_RESPONSE_CANCEL,
                                               -1);

      g_signal_connect_object (display, "disconnect",
                               G_CALLBACK (gtk_widget_destroy),
                               dialog, G_CONNECT_SWAPPED);

      g_signal_connect (dialog, "response",
                        G_CALLBACK (file_revert_confirm_response),
                        display);

      pika_message_box_set_primary_text (PIKA_MESSAGE_DIALOG (dialog)->box,
                                         _("Revert '%s' to '%s'?"),
                                         pika_image_get_display_name (image),
                                         pika_file_get_utf8_name (file));

      pika_message_box_set_text (PIKA_MESSAGE_DIALOG (dialog)->box,
                                 _("By reverting the image to the state saved "
                                   "on disk, you will lose all changes, "
                                   "including all undo information."));

      dialogs_attach_dialog (G_OBJECT (image), REVERT_DIALOG_KEY, dialog);
    }

  gtk_window_present (GTK_WINDOW (dialog));
}

void
file_close_all_cmd_callback (PikaAction *action,
                             GVariant   *value,
                             gpointer    data)
{
  Pika *pika;
  return_if_no_pika (pika, data);

  if (! pika_displays_dirty (pika))
    {
      pika_displays_close (pika);
    }
  else
    {
      GtkWidget *widget;
      return_if_no_widget (widget, data);

      pika_dialog_factory_dialog_raise (pika_dialog_factory_get_singleton (),
                                        pika_widget_get_monitor (widget),
                                        widget,
                                        "pika-close-all-dialog", -1);
    }
}

void
file_copy_location_cmd_callback (PikaAction *action,
                                 GVariant   *value,
                                 gpointer    data)
{
  Pika         *pika;
  PikaDisplay  *display;
  PikaImage    *image;
  GFile        *file;
  return_if_no_pika (pika, data);
  return_if_no_display (display, data);

  image = pika_display_get_image (display);

  file = pika_image_get_any_file (image);

  if (file)
    {
      gchar *uri = g_file_get_uri (file);

      pika_clipboard_set_text (pika, uri);
      g_free (uri);
    }
}

void
file_show_in_file_manager_cmd_callback (PikaAction *action,
                                        GVariant   *value,
                                        gpointer    data)
{
  Pika         *pika;
  PikaDisplay  *display;
  PikaImage    *image;
  GFile        *file;
  return_if_no_pika (pika, data);
  return_if_no_display (display, data);

  image = pika_display_get_image (display);

  file = pika_image_get_any_file (image);

  if (file)
    {
      GError *error = NULL;

      if (! pika_file_show_in_file_manager (file, &error))
        {
          pika_message (pika, G_OBJECT (display), PIKA_MESSAGE_ERROR,
                        _("Can't show file in file manager: %s"),
                        error->message);
          g_clear_error (&error);
        }
    }
}

void
file_quit_cmd_callback (PikaAction *action,
                        GVariant   *value,
                        gpointer    data)
{
  Pika *pika;
  return_if_no_pika (pika, data);

  pika_exit (pika, FALSE);
}

void
file_file_open_dialog (Pika      *pika,
                       GFile     *file,
                       GtkWidget *parent)
{
  file_open_dialog_show (pika, parent,
                         _("Open Image"),
                         NULL, file, FALSE);
}


/*  private functions  */

static void
file_open_dialog_show (Pika        *pika,
                       GtkWidget   *parent,
                       const gchar *title,
                       PikaImage   *image,
                       GFile       *file,
                       gboolean     open_as_layers)
{
  GtkWidget *dialog;

  dialog = pika_dialog_factory_dialog_new (pika_dialog_factory_get_singleton (),
                                           pika_widget_get_monitor (parent),
                                           NULL /*ui_manager*/,
                                           parent,
                                           "pika-file-open-dialog", -1, FALSE);

  if (dialog)
    {
      if (! file && image)
        file = pika_image_get_file (image);

      if (! file)
        file = g_object_get_data (G_OBJECT (pika),
                                  PIKA_FILE_OPEN_LAST_FILE_KEY);

      if (file)
        {
          gtk_file_chooser_set_file (GTK_FILE_CHOOSER (dialog), file, NULL);
        }
      else if (pika->default_folder)
        {
          gtk_file_chooser_set_current_folder_file (GTK_FILE_CHOOSER (dialog),
                                                    pika->default_folder, NULL);
        }

      gtk_window_set_title (GTK_WINDOW (dialog), title);

      pika_open_dialog_set_image (PIKA_OPEN_DIALOG (dialog),
                                  image, open_as_layers);

      gtk_window_set_transient_for (GTK_WINDOW (dialog),
                                    GTK_WINDOW (gtk_widget_get_toplevel (parent)));

      gtk_window_present (GTK_WINDOW (dialog));
    }
}

static GtkWidget *
file_save_dialog_show (Pika        *pika,
                       PikaImage   *image,
                       GtkWidget   *parent,
                       const gchar *title,
                       gboolean     save_a_copy,
                       gboolean     close_after_saving,
                       PikaDisplay *display)
{
  GtkWidget *dialog;

#define SAVE_DIALOG_KEY "pika-file-save-dialog"

  dialog = dialogs_get_dialog (G_OBJECT (image), SAVE_DIALOG_KEY);

  if (! dialog)
    {
      dialog = pika_dialog_factory_dialog_new (pika_dialog_factory_get_singleton (),
                                               pika_widget_get_monitor (parent),
                                               NULL /*ui_manager*/,
                                               parent,
                                               "pika-file-save-dialog",
                                               -1, FALSE);

      if (dialog)
        {
          gtk_window_set_transient_for (GTK_WINDOW (dialog),
                                        GTK_WINDOW (gtk_widget_get_toplevel (parent)));

          dialogs_attach_dialog (G_OBJECT (image), SAVE_DIALOG_KEY, dialog);
          g_signal_connect_object (image, "disconnect",
                                   G_CALLBACK (gtk_widget_destroy),
                                   dialog, G_CONNECT_SWAPPED);

          g_signal_connect (dialog, "response",
                            G_CALLBACK (file_save_dialog_response),
                            image);
        }
    }

  if (dialog)
    {
      gtk_window_set_title (GTK_WINDOW (dialog), title);

      pika_save_dialog_set_image (PIKA_SAVE_DIALOG (dialog),
                                  image, save_a_copy,
                                  close_after_saving, PIKA_OBJECT (display));

      gtk_window_present (GTK_WINDOW (dialog));
    }

  return dialog;
}

static void
file_save_dialog_response (GtkWidget *dialog,
                           gint       response_id,
                           gpointer   data)
{
  if (response_id == FILE_SAVE_RESPONSE_OTHER_DIALOG)
    {
      PikaFileDialog *file_dialog = PIKA_FILE_DIALOG (dialog);
      GtkWindow      *parent;
      GtkWidget      *other;
      GFile          *file;
      gchar          *folder;
      gchar          *basename;

      parent   = gtk_window_get_transient_for (GTK_WINDOW (dialog));
      file     = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
      folder   = g_path_get_dirname (pika_file_get_utf8_name (file));
      basename = g_path_get_basename (pika_file_get_utf8_name (file));
      g_object_unref (file);

      other = file_export_dialog_show (PIKA_FILE_DIALOG (file_dialog)->image->pika,
                                       PIKA_FILE_DIALOG (file_dialog)->image,
                                       GTK_WIDGET (parent), NULL);

      gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (other), folder);
      gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (other), basename);

      g_free (folder);
      g_free (basename);
    }
}

static GtkWidget *
file_export_dialog_show (Pika        *pika,
                         PikaImage   *image,
                         GtkWidget   *parent,
                         PikaDisplay *display)
{
  GtkWidget *dialog;

#define EXPORT_DIALOG_KEY "pika-file-export-dialog"

  dialog = dialogs_get_dialog (G_OBJECT (image), EXPORT_DIALOG_KEY);

  if (! dialog)
    {
      dialog = pika_dialog_factory_dialog_new (pika_dialog_factory_get_singleton (),
                                               pika_widget_get_monitor (parent),
                                               NULL /*ui_manager*/,
                                               parent,
                                               "pika-file-export-dialog",
                                               -1, FALSE);

      if (dialog)
        {
          gtk_window_set_transient_for (GTK_WINDOW (dialog),
                                        GTK_WINDOW (gtk_widget_get_toplevel (parent)));

          dialogs_attach_dialog (G_OBJECT (image), EXPORT_DIALOG_KEY, dialog);
          g_signal_connect_object (image, "disconnect",
                                   G_CALLBACK (gtk_widget_destroy),
                                   dialog, G_CONNECT_SWAPPED);

          g_signal_connect (dialog, "response",
                            G_CALLBACK (file_export_dialog_response),
                            image);
        }
    }

  if (dialog)
    {
      pika_export_dialog_set_image (PIKA_EXPORT_DIALOG (dialog), image,
                                    PIKA_OBJECT (display));

      gtk_window_present (GTK_WINDOW (dialog));
    }

  return dialog;
}

static void
file_export_dialog_response (GtkWidget *dialog,
                             gint       response_id,
                             gpointer   data)
{
  if (response_id == FILE_SAVE_RESPONSE_OTHER_DIALOG)
    {
      PikaFileDialog *file_dialog = PIKA_FILE_DIALOG (dialog);
      GtkWindow      *parent;
      GtkWidget      *other;
      GFile          *file;
      gchar          *folder;
      gchar          *basename;

      parent   = gtk_window_get_transient_for (GTK_WINDOW (dialog));
      file     = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
      folder   = g_path_get_dirname (pika_file_get_utf8_name (file));
      basename = g_path_get_basename (pika_file_get_utf8_name (file));
      g_object_unref (file);

      other = file_save_dialog_show (PIKA_FILE_DIALOG (file_dialog)->image->pika,
                                     PIKA_FILE_DIALOG (file_dialog)->image,
                                     GTK_WIDGET (parent),
                                     _("Save Image"),
                                     FALSE, FALSE, NULL);

      gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (other), folder);
      gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (other), basename);

      g_free (folder);
      g_free (basename);
    }
}

static void
file_new_template_callback (GtkWidget   *widget,
                            const gchar *name,
                            gpointer     data)
{
  PikaTemplate *template;
  PikaImage    *image;

  image = (PikaImage *) data;

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

  template = pika_template_new (name);
  pika_template_set_from_image (template, image);
  pika_container_add (image->pika->templates, PIKA_OBJECT (template));
  g_object_unref (template);
}

static void
file_revert_confirm_response (GtkWidget   *dialog,
                              gint         response_id,
                              PikaDisplay *display)
{
  PikaImage *old_image = pika_display_get_image (display);

  gtk_widget_destroy (dialog);

  if (response_id == GTK_RESPONSE_OK)
    {
      Pika              *pika = old_image->pika;
      PikaImage         *new_image;
      GFile             *file;
      PikaPDBStatusType  status;
      GError            *error = NULL;

      file = pika_image_get_file (old_image);

      if (! file)
        file = pika_image_get_imported_file (old_image);

      new_image = file_open_image (pika, pika_get_user_context (pika),
                                   PIKA_PROGRESS (display),
                                   file, FALSE, NULL,
                                   PIKA_RUN_INTERACTIVE,
                                   &status, NULL, &error);

      if (new_image)
        {
          pika_displays_reconnect (pika, old_image, new_image);
          pika_image_flush (new_image);

          /*  the displays own the image now  */
          g_object_unref (new_image);
        }
      else if (status != PIKA_PDB_CANCEL)
        {
          pika_message (pika, G_OBJECT (display), PIKA_MESSAGE_ERROR,
                        _("Reverting to '%s' failed:\n\n%s"),
                        pika_file_get_utf8_name (file), error->message);
          g_clear_error (&error);
        }
    }
}
