예제 #1
0
파일: file-commands.c 프로젝트: 1ynx/gimp
static void
file_open_dialog_show (Gimp        *gimp,
                       GtkWidget   *parent,
                       const gchar *title,
                       GimpImage   *image,
                       const gchar *uri,
                       gboolean     open_as_layers)
{
  GtkWidget *dialog;

  dialog = gimp_dialog_factory_dialog_new (gimp_dialog_factory_get_singleton (),
                                           gtk_widget_get_screen (parent),
                                           NULL /*ui_manager*/,
                                           "gimp-file-open-dialog", -1, FALSE);

  if (dialog)
    {
      if (! uri && image)
        uri = gimp_image_get_uri (image);

      if (! uri)
        uri = g_object_get_data (G_OBJECT (gimp), GIMP_FILE_OPEN_LAST_URI_KEY);

      if (uri)
        gtk_file_chooser_set_uri (GTK_FILE_CHOOSER (dialog), uri);

      gimp_file_dialog_set_open_image (GIMP_FILE_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));
    }
}
예제 #2
0
파일: file-utils.c 프로젝트: bklynate/gimp
gboolean
file_utils_save_thumbnail (GimpImage   *image,
                           const gchar *filename)
{
    const gchar *image_uri;
    gboolean     success = FALSE;

    g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
    g_return_val_if_fail (filename != NULL, FALSE);

    image_uri = gimp_image_get_uri (image);

    if (image_uri)
    {
        gchar *uri = g_filename_to_uri (filename, NULL, NULL);

        if (uri)
        {
            if ( ! strcmp (uri, image_uri))
            {
                GimpImagefile *imagefile;

                imagefile = gimp_imagefile_new (image->gimp, uri);
                success = gimp_imagefile_save_thumbnail (imagefile, NULL, image);
                g_object_unref (imagefile);
            }

            g_free (uri);
        }
    }

    return success;
}
예제 #3
0
static void
gimp_image_duplicate_save_source_uri (GimpImage *image,
                                      GimpImage *new_image)
{
  g_object_set_data_full (G_OBJECT (new_image), "gimp-image-source-uri",
                          g_strdup (gimp_image_get_uri (image)),
                          (GDestroyNotify) g_free);
}
예제 #4
0
static void
gimp_image_prop_view_label_set_filename (GtkWidget *label,
                                         GimpImage *image)
{
  const gchar *uri = gimp_image_get_uri (image);

  if (uri)
    {
      gchar *name = file_utils_uri_display_name (uri);

      gtk_label_set_text (GTK_LABEL (label), name);
      g_free (name);
    }
  else
    {
      gtk_label_set_text (GTK_LABEL (label), NULL);
      gimp_help_set_help_data (gtk_widget_get_parent (label), NULL, NULL);
    }
}
예제 #5
0
static void
gimp_display_shell_close_name_changed (GimpImage      *image,
                                       GimpMessageBox *box)
{
  GtkWidget *window = gtk_widget_get_toplevel (GTK_WIDGET (box));
  gchar     *name;

  name = file_utils_uri_display_basename (gimp_image_get_uri (image));

  if (window)
    {
      gchar *title = g_strdup_printf (_("Close %s"), name);

      gtk_window_set_title (GTK_WINDOW (window), title);
      g_free (title);
    }

  gimp_message_box_set_primary_text (box,
                                     _("Save the changes to image '%s' "
                                       "before closing?"),
                                     name);
  g_free (name);
}
예제 #6
0
static void
gimp_display_shell_close_dialog (GimpDisplayShell *shell,
                                 GimpImage        *image)
{
  GtkWidget      *dialog;
  GtkWidget      *button;
  GimpMessageBox *box;
  GClosure       *closure;
  GSource        *source;
  gchar          *name;
  gchar          *title;

  if (shell->close_dialog)
    {
      gtk_window_present (GTK_WINDOW (shell->close_dialog));
      return;
    }

  name = file_utils_uri_display_basename (gimp_image_get_uri (image));

  title = g_strdup_printf (_("Close %s"), name);
  g_free (name);

  shell->close_dialog =
    dialog = gimp_message_dialog_new (title, GTK_STOCK_SAVE,
                                      GTK_WIDGET (shell),
                                      GTK_DIALOG_DESTROY_WITH_PARENT,
                                      gimp_standard_help_func, NULL,
                                      NULL);
  g_free (title);

  button = gtk_dialog_add_button (GTK_DIALOG (dialog),
                                  _("Do_n't Save"), GTK_RESPONSE_CLOSE);
  gtk_button_set_image (GTK_BUTTON (button),
                        gtk_image_new_from_stock (GTK_STOCK_DELETE,
                                                  GTK_ICON_SIZE_BUTTON));

  gtk_dialog_add_buttons (GTK_DIALOG (dialog),
                          GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                          GTK_STOCK_SAVE,   RESPONSE_SAVE,
                          NULL);

  gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL);

  gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
                                           RESPONSE_SAVE,
                                           GTK_RESPONSE_CLOSE,
                                           GTK_RESPONSE_CANCEL,
                                           -1);

  g_signal_connect (dialog, "destroy",
                    G_CALLBACK (gtk_widget_destroyed),
                    &shell->close_dialog);

  g_signal_connect (dialog, "response",
                    G_CALLBACK (gimp_display_shell_close_response),
                    shell);

  box = GIMP_MESSAGE_DIALOG (dialog)->box;

  g_signal_connect_object (image, "name-changed",
                           G_CALLBACK (gimp_display_shell_close_name_changed),
                           box, 0);

  gimp_display_shell_close_name_changed (image, box);

  closure =
    g_cclosure_new_object (G_CALLBACK (gimp_display_shell_close_time_changed),
                           G_OBJECT (box));

  /*  update every 10 seconds  */
  source = g_timeout_source_new (10 * 1000);
  g_source_set_closure (source, closure);
  g_source_attach (source, NULL);
  g_source_unref (source);

  /*  The dialog is destroyed with the shell, so it should be safe
   *  to hold an image pointer for the lifetime of the dialog.
   */
  g_object_set_data (G_OBJECT (box), "gimp-image", image);

  gimp_display_shell_close_time_changed (box);

  gtk_widget_show (dialog);
}
예제 #7
0
파일: file-commands.c 프로젝트: 1ynx/gimp
void
file_revert_cmd_callback (GtkAction *action,
                          gpointer   data)
{
  GimpDisplay *display;
  GimpImage   *image;
  GtkWidget   *dialog;
  const gchar *uri;
  return_if_no_display (display, data);

  image = gimp_display_get_image (display);

  uri = gimp_image_get_uri (image);

  if (! uri)
    uri = gimp_image_get_imported_uri (image);

  dialog = g_object_get_data (G_OBJECT (image), REVERT_DATA_KEY);

  if (! uri)
    {
      gimp_message_literal (image->gimp,
			    G_OBJECT (display), GIMP_MESSAGE_ERROR,
			    _("Revert failed. "
			      "No file name associated with this image."));
    }
  else if (dialog)
    {
      gtk_window_present (GTK_WINDOW (dialog));
    }
  else
    {
      gchar *filename;

      dialog =
        gimp_message_dialog_new (_("Revert Image"), GTK_STOCK_REVERT_TO_SAVED,
                                 GTK_WIDGET (gimp_display_get_shell (display)),
                                 0,
                                 gimp_standard_help_func, GIMP_HELP_FILE_REVERT,

                                 GTK_STOCK_CANCEL,          GTK_RESPONSE_CANCEL,
                                 GTK_STOCK_REVERT_TO_SAVED, GTK_RESPONSE_OK,

                                 NULL);

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

      filename = file_utils_uri_display_name (uri);

      gimp_message_box_set_primary_text (GIMP_MESSAGE_DIALOG (dialog)->box,
                                         _("Revert '%s' to '%s'?"),
                                         gimp_image_get_display_name (image),
                                         filename);
      g_free (filename);

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

      g_object_set_data (G_OBJECT (image), REVERT_DATA_KEY, dialog);

      gtk_widget_show (dialog);
    }
}
예제 #8
0
파일: file-commands.c 프로젝트: 1ynx/gimp
void
file_save_cmd_callback (GtkAction *action,
                        gint       value,
                        gpointer   data)
{
  Gimp         *gimp;
  GimpDisplay  *display;
  GimpImage    *image;
  GtkWidget    *widget;
  GimpSaveMode  save_mode;
  const gchar  *uri;
  gboolean      saved = FALSE;
  return_if_no_gimp (gimp, data);
  return_if_no_display (display, data);
  return_if_no_widget (widget, data);

  image = gimp_display_get_image (display);

  save_mode = (GimpSaveMode) value;

  if (! gimp_image_get_active_drawable (image))
    return;

  uri = gimp_image_get_uri (image);

  switch (save_mode)
    {
    case GIMP_SAVE_MODE_SAVE:
    case GIMP_SAVE_MODE_SAVE_AND_CLOSE:
      /*  Only save if the image has been modified, or if it is new.  */
      if ((gimp_image_is_dirty (image) ||
           ! GIMP_GUI_CONFIG (image->gimp->config)->trust_dirty_flag) ||
          uri == NULL)
        {
          GimpPlugInProcedure *save_proc = gimp_image_get_save_proc (image);

          if (uri && ! save_proc)
            {
              save_proc =
                file_procedure_find (image->gimp->plug_in_manager->save_procs,
                                     uri, NULL);
            }

          if (uri && save_proc)
            {
              saved = file_save_dialog_save_image (GIMP_PROGRESS (display),
                                                   gimp, image, uri,
                                                   save_proc,
                                                   GIMP_RUN_WITH_LAST_VALS,
                                                   TRUE, FALSE, FALSE, TRUE);
              break;
            }

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

    case GIMP_SAVE_MODE_SAVE_AS:
      file_save_dialog_show (gimp, image, widget,
                             _("Save Image"), FALSE,
                             save_mode == GIMP_SAVE_MODE_SAVE_AND_CLOSE, display);
      break;

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

    case GIMP_SAVE_MODE_EXPORT:
      file_export_dialog_show (gimp, image, widget);
      break;

    case GIMP_SAVE_MODE_EXPORT_TO:
    case GIMP_SAVE_MODE_OVERWRITE:
      {
        const gchar         *uri = NULL;
        GimpPlugInProcedure *export_proc;
        gboolean             overwrite;

        if (save_mode == GIMP_SAVE_MODE_EXPORT_TO)
          {
            uri = gimp_image_get_exported_uri (image);

            if (! uri)
              {
                /* Behave as if Export... was invoked */
                file_export_dialog_show (gimp, image, widget);
                break;
              }

            overwrite = FALSE;
          }
        else if (save_mode == GIMP_SAVE_MODE_OVERWRITE)
          {
            uri = gimp_image_get_imported_uri (image);

            overwrite = TRUE;
          }

        if (uri)
          {
            export_proc =
              file_procedure_find (image->gimp->plug_in_manager->export_procs,
                                   uri, NULL);
          }

        if (uri && export_proc)
          {
            char *uri_copy;

            /* The memory that 'uri' points to can be freed by
               file_save_dialog_save_image(), when it eventually calls
               gimp_image_set_imported_uri() to reset the imported uri,
               resulting in garbage. So make a duplicate of it here. */

            uri_copy = g_strdup (uri);

            saved = file_save_dialog_save_image (GIMP_PROGRESS (display),
                                                 gimp, image, uri_copy,
                                                 export_proc,
                                                 GIMP_RUN_WITH_LAST_VALS,
                                                 FALSE,
                                                 overwrite, ! overwrite,
                                                 TRUE);
            g_free (uri_copy);
          }
      }
      break;
    }

  if (save_mode == GIMP_SAVE_MODE_SAVE_AND_CLOSE &&
      saved &&
      ! gimp_image_is_dirty (image))
    {
      gimp_display_close (display);
    }
}
예제 #9
0
static void
gimp_display_shell_format_title (GimpDisplayShell *shell,
                                 gchar            *title,
                                 gint              title_len,
                                 const gchar      *format)
{
  Gimp      *gimp;
  GimpImage *image;
  gint       num, denom;
  gint       i = 0;

  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));

  image = shell->display->image;
  gimp  = image->gimp;

  gimp_zoom_model_get_fraction (shell->zoom, &num, &denom);

  while (i < title_len && *format)
    {
      switch (*format)
        {
        case '%':
          format++;
          switch (*format)
            {
            case 0:
              /* format string ends within %-sequence, print literal '%' */

            case '%':
              title[i++] = '%';
              break;

            case 'f': /* pruned filename */
              {
                const gchar *uri = gimp_image_get_uri (image);
                gchar       *basename;

                basename = file_utils_uri_display_basename (uri);

                i += print (title, title_len, i, "%s", basename);

                g_free (basename);
              }
              break;

            case 'F': /* full filename */
              {
                gchar *filename;
                const gchar *uri = gimp_image_get_uri (image);

                filename = file_utils_uri_display_name (uri);

                i += print (title, title_len, i, "%s", filename);

                g_free (filename);
              }
              break;

            case 'p': /* PDB id */
              i += print (title, title_len, i, "%d", gimp_image_get_ID (image));
              break;

            case 'i': /* instance */
              i += print (title, title_len, i, "%d", shell->display->instance);
              break;

            case 't': /* type */
              {
                const gchar *image_type_str = NULL;
                gboolean     empty          = gimp_image_is_empty (image);

                switch (gimp_image_base_type (image))
                  {
                  case GIMP_RGB:
                    image_type_str = empty ? _("RGB-empty") : _("RGB");
                    break;
                  case GIMP_GRAY:
                    image_type_str = empty ? _("grayscale-empty") : _("grayscale");
                    break;
                  case GIMP_INDEXED:
                    image_type_str = empty ? _("indexed-empty") : _("indexed");
                    break;
                  default:
                    g_assert_not_reached ();
                    break;
                  }

                i += print (title, title_len, i, "%s", image_type_str);
              }
              break;

            case 's': /* user source zoom factor */
              i += print (title, title_len, i, "%d", denom);
              break;

            case 'd': /* user destination zoom factor */
              i += print (title, title_len, i, "%d", num);
              break;

            case 'z': /* user zoom factor (percentage) */
              {
                gdouble  scale = gimp_zoom_model_get_factor (shell->zoom);

                i += print (title, title_len, i,
                            scale >= 0.15 ? "%.0f" : "%.2f", 100.0 * scale);
              }
              break;

            case 'D': /* dirty flag */
              if (format[1] == 0)
                {
                  /* format string ends within %D-sequence, print literal '%D' */
                  i += print (title, title_len, i, "%%D");
                  break;
                }
              if (image->dirty)
                title[i++] = format[1];
              format++;
              break;

            case 'C': /* clean flag */
              if (format[1] == 0)
                {
                  /* format string ends within %C-sequence, print literal '%C' */
                  i += print (title, title_len, i, "%%C");
                  break;
                }
              if (! image->dirty)
                title[i++] = format[1];
              format++;
              break;

            case 'B': /* dirty flag (long) */
              if (image->dirty)
                i += print (title, title_len, i, "%s", _("(modified)"));
              break;

            case 'A': /* clean flag (long) */
              if (! image->dirty)
                i += print (title, title_len, i, "%s", _("(clean)"));
              break;

            case 'm': /* memory used by image */
              {
                GimpObject *object = GIMP_OBJECT (image);
                gchar      *str;

                str = gimp_memsize_to_string (gimp_object_get_memsize (object,
                                                                       NULL));

                i += print (title, title_len, i, "%s", str);

                g_free (str);
              }
              break;

            case 'l': /* number of layers */
              i += print (title, title_len, i, "%d",
                          gimp_container_num_children (image->layers));
              break;

            case 'L': /* number of layers (long) */
              {
                gint num = gimp_container_num_children (image->layers);

                i += print (title, title_len, i,
                            ngettext ("%d layer", "%d layers", num), num);
              }
              break;

            case 'n': /* active drawable name */
              {
                GimpDrawable *drawable = gimp_image_get_active_drawable (image);

                if (drawable)
                  i += print (title, title_len, i, "%s",
                              gimp_object_get_name (GIMP_OBJECT (drawable)));
                else
                  i += print (title, title_len, i, "%s", _("(none)"));
              }
              break;

            case 'P': /* active drawable PDB id */
              {
                GimpDrawable *drawable = gimp_image_get_active_drawable (image);

                if (drawable)
                  i += print (title, title_len, i, "%d",
                              gimp_item_get_ID (GIMP_ITEM (drawable)));
                else
                  i += print (title, title_len, i, "%s", _("(none)"));
              }
              break;

            case 'W': /* width in real-world units */
              if (shell->unit != GIMP_UNIT_PIXEL)
                {
                  gchar unit_format[8];

                  g_snprintf (unit_format, sizeof (unit_format), "%%.%df",
                              _gimp_unit_get_digits (gimp, shell->unit) + 1);
                  i += print (title, title_len, i, unit_format,
                              (image->width *
                               _gimp_unit_get_factor (gimp, shell->unit) /
                               image->xresolution));
                  break;
                }
              /* else fallthru */
            case 'w': /* width in pixels */
              i += print (title, title_len, i, "%d", image->width);
              break;

            case 'H': /* height in real-world units */
              if (shell->unit != GIMP_UNIT_PIXEL)
                {
                  gchar unit_format[8];

                  g_snprintf (unit_format, sizeof (unit_format), "%%.%df",
                              _gimp_unit_get_digits (gimp, shell->unit) + 1);
                  i += print (title, title_len, i, unit_format,
                              (image->height *
                               _gimp_unit_get_factor (gimp, shell->unit) /
                               image->yresolution));
                  break;
                }
              /* else fallthru */
            case 'h': /* height in pixels */
              i += print (title, title_len, i, "%d", image->height);
              break;

            case 'u': /* unit symbol */
              i += print (title, title_len, i, "%s",
                          _gimp_unit_get_symbol (gimp, shell->unit));
              break;

            case 'U': /* unit abbreviation */
              i += print (title, title_len, i, "%s",
                          _gimp_unit_get_abbreviation (gimp, shell->unit));
              break;

              /* Other cool things to be added:
               * %r = xresolution
               * %R = yresolution
               * %ø = image's fractal dimension
               * %þ = the answer to everything
               */

            default:
              /* format string contains unknown %-sequence, print it literally */
              i += print (title, title_len, i, "%%%c", *format);
              break;
            }
          break;

        default:
          title[i++] = *format;
          break;
        }

      format++;
    }

  title[MIN (i, title_len - 1)] = '\0';
}
예제 #10
0
GimpPDBStatusType
file_save (GimpImage           *image,
           GimpContext         *context,
           GimpProgress        *progress,
           const gchar         *uri,
           GimpPlugInProcedure *file_proc,
           GimpRunMode          run_mode,
           gboolean             save_a_copy,
           GError             **error)
{
  GimpDrawable      *drawable;
  GValueArray       *return_vals;
  GimpPDBStatusType  status;
  gchar             *filename;
  gint32             image_ID;
  gint32             drawable_ID;

  g_return_val_if_fail (GIMP_IS_IMAGE (image), GIMP_PDB_CALLING_ERROR);
  g_return_val_if_fail (GIMP_IS_CONTEXT (context), GIMP_PDB_CALLING_ERROR);
  g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress),
                        GIMP_PDB_CALLING_ERROR);
  g_return_val_if_fail (uri != NULL, GIMP_PDB_CALLING_ERROR);
  g_return_val_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (file_proc),
                        GIMP_PDB_CALLING_ERROR);
  g_return_val_if_fail (error == NULL || *error == NULL,
                        GIMP_PDB_CALLING_ERROR);

  drawable = gimp_image_get_active_drawable (image);

  if (! drawable)
    return GIMP_PDB_EXECUTION_ERROR;

  filename = file_utils_filename_from_uri (uri);

  if (filename)
    {
      /* check if we are saving to a file */
      if (g_file_test (filename, G_FILE_TEST_EXISTS))
        {
          if (! g_file_test (filename, G_FILE_TEST_IS_REGULAR))
            {
              g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                           "%s", _("Not a regular file"));
              status = GIMP_PDB_EXECUTION_ERROR;
              goto out;
            }

          if (g_access (filename, W_OK) != 0)
            {
              g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_ACCES,
                           "%s", g_strerror (errno));
              status = GIMP_PDB_EXECUTION_ERROR;
              goto out;
            }
        }
    }
  else
    {
      filename = g_strdup (uri);
    }

  /* ref the image, so it can't get deleted during save */
  g_object_ref (image);

  image_ID    = gimp_image_get_ID (image);
  drawable_ID = gimp_item_get_ID (GIMP_ITEM (drawable));

  return_vals =
    gimp_pdb_execute_procedure_by_name (image->gimp->pdb,
                                        context, progress, error,
                                        GIMP_OBJECT (file_proc)->name,
                                        GIMP_TYPE_INT32,       run_mode,
                                        GIMP_TYPE_IMAGE_ID,    image_ID,
                                        GIMP_TYPE_DRAWABLE_ID, drawable_ID,
                                        G_TYPE_STRING,         filename,
                                        G_TYPE_STRING,         uri,
                                        G_TYPE_NONE);

  status = g_value_get_enum (&return_vals->values[0]);

  g_value_array_free (return_vals);

  if (status == GIMP_PDB_SUCCESS)
    {
      GimpDocumentList *documents;
      GimpImagefile    *imagefile;

      if (save_a_copy)
        {
          /*  remember the "save-a-copy" filename for the next invocation  */
          g_object_set_data_full (G_OBJECT (image), "gimp-image-save-a-copy",
                                  g_strdup (uri),
                                  (GDestroyNotify) g_free);
        }
      else
        {
          /*  reset the "save-a-copy" filename when the image URI changes  */
          if (strcmp (uri, gimp_image_get_uri (image)))
            g_object_set_data (G_OBJECT (image),
                               "gimp-image-save-a-copy", NULL);

          gimp_image_set_uri (image, uri);
          gimp_image_set_save_proc (image, file_proc);

          gimp_image_clean_all (image);
        }

      gimp_image_saved (image, uri);

      documents = GIMP_DOCUMENT_LIST (image->gimp->documents);
      imagefile = gimp_document_list_add_uri (documents,
                                              uri,
                                              file_proc->mime_type);

      /* only save a thumbnail if we are saving as XCF, see bug #25272 */
      if (GIMP_PROCEDURE (file_proc)->proc_type == GIMP_INTERNAL)
        gimp_imagefile_save_thumbnail (imagefile, file_proc->mime_type, image);
    }
  else if (status != GIMP_PDB_CANCEL)
    {
      if (error && *error == NULL)
        {
          g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                       _("%s plug-in could not save image"),
                       gimp_plug_in_procedure_get_label (file_proc));
        }
    }

  gimp_image_flush (image);

  g_object_unref (image);

 out:
  g_free (filename);

  return status;
}
예제 #11
0
static void
gimp_display_shell_close_dialog (GimpDisplayShell *shell,
                                 GimpImage        *image)
{
  GtkWidget       *dialog;
  GimpMessageBox  *box;
  GtkWidget       *label;
  GtkAccelGroup   *accel_group;
  GClosure        *closure;
  GSource         *source;
  guint            accel_key;
  GdkModifierType  accel_mods;
  gchar           *title;
  gchar           *accel_string;
  gchar           *hint;
  gchar           *markup;
  const gchar     *uri;

  if (shell->close_dialog)
    {
      gtk_window_present (GTK_WINDOW (shell->close_dialog));
      return;
    }

  uri = gimp_image_get_uri (image);

  title = g_strdup_printf (_("Close %s"), gimp_image_get_display_name (image));

  shell->close_dialog =
    dialog = gimp_message_dialog_new (title, "document-save",
                                      GTK_WIDGET (shell),
                                      GTK_DIALOG_DESTROY_WITH_PARENT,
                                      gimp_standard_help_func, NULL,
                                      NULL);
  g_free (title);

  gtk_dialog_add_buttons (GTK_DIALOG (dialog),
                          _("_Discard Changes"), GTK_RESPONSE_CLOSE,
                          GTK_STOCK_CANCEL,      GTK_RESPONSE_CANCEL,
                          (uri ?
                           GTK_STOCK_SAVE :
                           GTK_STOCK_SAVE_AS),   RESPONSE_SAVE,
                          NULL);

  gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL);

  gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
                                           RESPONSE_SAVE,
                                           GTK_RESPONSE_CLOSE,
                                           GTK_RESPONSE_CANCEL,
                                           -1);

  g_signal_connect (dialog, "destroy",
                    G_CALLBACK (gtk_widget_destroyed),
                    &shell->close_dialog);

  g_signal_connect (dialog, "response",
                    G_CALLBACK (gimp_display_shell_close_response),
                    shell);

  /* connect <Primary>D to the quit/close button */
  accel_group = gtk_accel_group_new ();
  gtk_window_add_accel_group (GTK_WINDOW (shell->close_dialog), accel_group);
  g_object_unref (accel_group);

  closure = g_closure_new_object (sizeof (GClosure),
                                  G_OBJECT (shell->close_dialog));
  g_closure_set_marshal (closure, gimp_display_shell_close_accel_marshal);
  gtk_accelerator_parse ("<Primary>D", &accel_key, &accel_mods);
  gtk_accel_group_connect (accel_group, accel_key, accel_mods, 0, closure);

  box = GIMP_MESSAGE_DIALOG (dialog)->box;

  accel_string = gtk_accelerator_get_label (accel_key, accel_mods);
  hint = g_strdup_printf (_("Press %s to discard all changes and close the image."),
                          accel_string);
  markup = g_strdup_printf ("<i><small>%s</small></i>", hint);

  label = gtk_label_new (NULL);
  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
  gtk_label_set_markup (GTK_LABEL (label), markup);
  gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
  gtk_widget_show (label);

  g_free (markup);
  g_free (hint);
  g_free (accel_string);

  g_signal_connect_object (image, "name-changed",
                           G_CALLBACK (gimp_display_shell_close_name_changed),
                           box, 0);
  g_signal_connect_object (image, "exported",
                           G_CALLBACK (gimp_display_shell_close_exported),
                           box, 0);

  gimp_display_shell_close_name_changed (image, box);

  closure =
    g_cclosure_new_object (G_CALLBACK (gimp_display_shell_close_time_changed),
                           G_OBJECT (box));

  /*  update every 10 seconds  */
  source = g_timeout_source_new_seconds (10);
  g_source_set_closure (source, closure);
  g_source_attach (source, NULL);
  g_source_unref (source);

  /*  The dialog is destroyed with the shell, so it should be safe
   *  to hold an image pointer for the lifetime of the dialog.
   */
  g_object_set_data (G_OBJECT (box), "gimp-image", image);

  gimp_display_shell_close_time_changed (box);

  gtk_widget_show (dialog);
}
예제 #12
0
void
gimp_file_dialog_set_image (GimpFileDialog *dialog,
                            GimpImage      *image,
                            gboolean        save_a_copy,
                            gboolean        close_after_saving)
{
  const gchar *uri = NULL;
  gchar       *dirname;
  gchar       *basename;

  g_return_if_fail (GIMP_IS_FILE_DIALOG (dialog));
  g_return_if_fail (GIMP_IS_IMAGE (image));

  dialog->image              = image;
  dialog->save_a_copy        = save_a_copy;
  dialog->close_after_saving = close_after_saving;

  if (save_a_copy)
    uri = g_object_get_data (G_OBJECT (image), "gimp-image-save-a-copy");

  if (! uri)
    uri = gimp_image_get_uri (image);

  gimp_file_dialog_set_file_proc (dialog, NULL);

#ifndef G_OS_WIN32
  dirname  = g_path_get_dirname (uri);
#else
  /* g_path_get_dirname() is supposed to work on pathnames, not URIs.
   *
   * If uri points to a file on the root of a drive
   * "file:///d:/foo.png", g_path_get_dirname() would return
   * "file:///d:". (What we really would want is "file:///d:/".) When
   * this then is passed inside gtk+ to g_filename_from_uri() we get
   * "d:" which is not an absolute pathname. This currently causes an
   * assertion failure in gtk+. This scenario occurs if we have opened
   * an image from the root of a drive and then do Save As.
   *
   * Of course, gtk+ shouldn't assert even if we feed it slighly bogus
   * data, and that problem should be fixed, too. But to get the
   * correct default current folder in the filechooser combo box, we
   * need to pass it the proper URI for an absolute path anyway. So
   * don't use g_path_get_dirname() on file: URIs.
   */
  if (g_str_has_prefix (uri, "file:///"))
    {
      gchar *filepath = g_filename_from_uri (uri, NULL, NULL);
      gchar *dirpath  = NULL;

      if (filepath != NULL)
	{
	  dirpath = g_path_get_dirname (filepath);
	  g_free (filepath);
	}

      if (dirpath != NULL)
	{
	  dirname = g_filename_to_uri (dirpath, NULL, NULL);
	  g_free (dirpath);
	}
      else
        {
          dirname = NULL;
        }
    }
  else
    {
      dirname = g_path_get_dirname (uri);
    }
#endif

  if (dirname && strlen (dirname) && strcmp (dirname, "."))
    {
      gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dialog),
                                               dirname);
    }
  else
    {
      const gchar *folder;

      folder = g_object_get_data (G_OBJECT (image), "gimp-image-dirname");

      if (folder)
        gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), folder);
    }

  g_free (dirname);

  basename = file_utils_uri_display_basename (uri);
  gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), basename);
  g_free (basename);
}
예제 #13
0
    }

    show_overwrite =
        (source &&
         gimp_plug_in_manager_uri_has_exporter (gimp->plug_in_manager,
                 source));

#define SET_VISIBLE(action,condition) \
        gimp_action_group_set_action_visible (group, action, (condition) != 0)
#define SET_SENSITIVE(action,condition) \
        gimp_action_group_set_action_sensitive (group, action, (condition) != 0)

    SET_SENSITIVE ("file-save",            drawable);
    SET_SENSITIVE ("file-save-as",         drawable);
    SET_SENSITIVE ("file-save-a-copy",     drawable);
    SET_SENSITIVE ("file-revert",          image && (gimp_image_get_uri (image) || source));
    SET_SENSITIVE ("file-export-to",       drawable);
    SET_VISIBLE   ("file-export-to",       ! show_overwrite);
    SET_SENSITIVE ("file-overwrite",       show_overwrite);
    SET_VISIBLE   ("file-overwrite",       show_overwrite);
    SET_SENSITIVE ("file-export",          drawable);
    SET_SENSITIVE ("file-create-template", image);

    if (export)
    {
        gchar *label = file_actions_create_label (_("Export to %s"), export);
        gimp_action_group_set_action_label (group, "file-export-to", label);
        g_free (label);
    }
    else if (show_overwrite)
    {