示例#1
0
static void
gimp_thumb_box_create_thumbnail (GimpThumbBox      *box,
                                 const gchar       *uri,
                                 GimpThumbnailSize  size,
                                 gboolean           force,
                                 GimpProgress      *progress)
{
  gchar         *filename = file_utils_filename_from_uri (uri);
  GimpThumbnail *thumb;
  gchar         *basename;

  if (filename)
    {
      gboolean regular = g_file_test (filename, G_FILE_TEST_IS_REGULAR);

      g_free (filename);

      if (! regular)
        return;
    }

  thumb = gimp_imagefile_get_thumbnail (box->imagefile);

  basename = file_utils_uri_display_basename (uri);
  gtk_label_set_text (GTK_LABEL (box->filename), basename);
  g_free (basename);

  gimp_object_set_name (GIMP_OBJECT (box->imagefile), uri);

  if (force ||
      (gimp_thumbnail_peek_thumb (thumb, size) < GIMP_THUMB_STATE_FAILED &&
       ! gimp_thumbnail_has_failed (thumb)))
    {
      GError *error = NULL;

      if (! gimp_imagefile_create_thumbnail (box->imagefile, box->context,
                                             progress,
                                             size, ! force, &error))
        {
          gimp_message_literal (box->context->gimp,
				G_OBJECT (progress), GIMP_MESSAGE_ERROR,
				error->message);
          g_clear_error (&error);
        }
    }
}
示例#2
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);
}
示例#3
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);
}
示例#4
0
GList *
file_open_layers (Gimp                *gimp,
                  GimpContext         *context,
                  GimpProgress        *progress,
                  GimpImage           *dest_image,
                  gboolean             merge_visible,
                  const gchar         *uri,
                  GimpRunMode          run_mode,
                  GimpPlugInProcedure *file_proc,
                  GimpPDBStatusType   *status,
                  GError             **error)
{
    GimpImage   *new_image;
    GList       *layers    = NULL;
    const gchar *mime_type = NULL;

    g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
    g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
    g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), NULL);
    g_return_val_if_fail (GIMP_IS_IMAGE (dest_image), NULL);
    g_return_val_if_fail (uri != NULL, NULL);
    g_return_val_if_fail (status != NULL, NULL);
    g_return_val_if_fail (error == NULL || *error == NULL, NULL);

    new_image = file_open_image (gimp, context, progress,
                                 uri, uri, FALSE,
                                 file_proc,
                                 run_mode,
                                 status, &mime_type, error);

    if (new_image)
    {
        gint n_visible = 0;

        gimp_image_undo_disable (new_image);

        layers = file_open_get_layers (new_image, merge_visible, &n_visible);

        if (merge_visible && n_visible > 1)
        {
            GimpLayer *layer;

            g_list_free (layers);

            layer = gimp_image_merge_visible_layers (new_image, context,
                    GIMP_CLIP_TO_IMAGE,
                    FALSE, FALSE);

            layers = g_list_prepend (NULL, layer);
        }

        if (layers)
        {
            gchar *basename = file_utils_uri_display_basename (uri);

            file_open_convert_items (dest_image, basename, layers);
            g_free (basename);

            gimp_document_list_add_uri (GIMP_DOCUMENT_LIST (gimp->documents),
                                        uri, mime_type);
        }
        else
        {
            g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                                 _("Image doesn't contain any layers"));
            *status = GIMP_PDB_EXECUTION_ERROR;
        }

        g_object_unref (new_image);
    }

    return g_list_reverse (layers);
}
示例#5
0
GimpImage *
file_open_with_proc_and_display (Gimp                *gimp,
                                 GimpContext         *context,
                                 GimpProgress        *progress,
                                 const gchar         *uri,
                                 const gchar         *entered_filename,
                                 gboolean             as_new,
                                 GimpPlugInProcedure *file_proc,
                                 GimpPDBStatusType   *status,
                                 GError             **error)
{
    GimpImage   *image;
    const gchar *mime_type = NULL;

    g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
    g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
    g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), NULL);
    g_return_val_if_fail (status != NULL, NULL);

    image = file_open_image (gimp, context, progress,
                             uri,
                             entered_filename,
                             as_new,
                             file_proc,
                             GIMP_RUN_INTERACTIVE,
                             status,
                             &mime_type,
                             error);

    if (image)
    {
        /* If the file was imported we want to set the layer name to the
         * file name. For now, assume that multi-layered imported images
         * have named the layers already, so only rename the layer of
         * single-layered imported files. Note that this will also
         * rename already named layers from e.g. single-layered PSD
         * files. To solve this properly, we would need new file plug-in
         * API.
         */
        if (file_open_file_proc_is_import (file_proc) &&
                gimp_image_get_n_layers (image) == 1)
        {
            GimpObject *layer    = gimp_image_get_layer_iter (image)->data;
            gchar      *basename = file_utils_uri_display_basename (uri);

            gimp_item_rename (GIMP_ITEM (layer), basename, NULL);
            gimp_image_undo_free (image);
            gimp_image_clean_all (image);

            g_free (basename);
        }

        gimp_create_display (image->gimp, image, GIMP_UNIT_PIXEL, 1.0);

        if (! as_new)
        {
            GimpDocumentList *documents = GIMP_DOCUMENT_LIST (gimp->documents);
            GimpImagefile    *imagefile;

            imagefile = gimp_document_list_add_uri (documents, uri, mime_type);

            /*  can only create a thumbnail if the passed uri and the
             *  resulting image's uri match.
             */
            if (strcmp (uri, gimp_image_get_uri_or_untitled (image)) == 0)
            {
                /*  no need to save a thumbnail if there's a good one already  */
                if (! gimp_imagefile_check_thumbnail (imagefile))
                {
                    gimp_imagefile_save_thumbnail (imagefile, mime_type, image);
                }
            }
        }

        /*  the display owns the image now  */
        g_object_unref (image);

        /*  announce that we opened this image  */
        gimp_image_opened (image->gimp, uri);
    }

    return image;
}
示例#6
0
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 = display->image;

  uri = gimp_object_get_name (GIMP_OBJECT (image));

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

  if (! uri)
    {
      gimp_message (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 *basename;
      gchar *filename;

      dialog =
        gimp_message_dialog_new (_("Revert Image"), GTK_STOCK_REVERT_TO_SAVED,
                                 display->shell, 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);

      basename = file_utils_uri_display_basename (uri);
      filename = file_utils_uri_display_name (uri);

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

      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);
    }
}
示例#7
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';
}
示例#8
0
static void
gimp_file_dialog_proc_changed (GimpFileProcView *view,
                               GimpFileDialog   *dialog)
{
  GtkFileChooser *chooser = GTK_FILE_CHOOSER (dialog);
  gchar          *name;

  dialog->file_proc = gimp_file_proc_view_get_proc (view, &name);

  if (name)
    {
      gchar *label = g_strdup_printf (_("Select File _Type (%s)"), name);

      gtk_expander_set_label (GTK_EXPANDER (dialog->proc_expander), label);

      g_free (label);
      g_free (name);
    }

  if (gtk_file_chooser_get_action (chooser) == GTK_FILE_CHOOSER_ACTION_SAVE)
    {
      GimpPlugInProcedure *proc = dialog->file_proc;

      if (proc && proc->extensions_list)
        {
          gchar *uri = gtk_file_chooser_get_uri (chooser);

          if (uri && strlen (uri))
            {
              const gchar *last_dot = strrchr (uri, '.');

              /*  if the dot is before the last slash, ignore it  */
              if (last_dot && strrchr (uri, '/') > last_dot)
                last_dot = NULL;

              /*  check if the uri has a "meta extension" (e.g. foo.bar.gz)
               *  and try to truncate both extensions away.
               */
              if (last_dot && last_dot != uri)
                {
                  GList *list;

                  for (list = view->meta_extensions;
                       list;
                       list = g_list_next (list))
                    {
                      const gchar *ext = list->data;

                      if (! strcmp (ext, last_dot + 1))
                        {
                          const gchar *p = last_dot - 1;

                          while (p > uri && *p != '.')
                            p--;

                          if (p != uri && *p == '.')
                            {
                              last_dot = p;
                              break;
                            }
                        }
                    }
                }

              if (last_dot != uri)
                {
                  GString *s = g_string_new (uri);
                  gchar   *basename;

                  if (last_dot)
                    g_string_truncate (s, last_dot - uri);

                  g_string_append (s, ".");
                  g_string_append (s, (gchar *) proc->extensions_list->data);

                  gtk_file_chooser_set_uri (chooser, s->str);

                  basename = file_utils_uri_display_basename (s->str);
                  gtk_file_chooser_set_current_name (chooser, basename);
                  g_free (basename);

                  g_string_free (s, TRUE);
                }
            }

          g_free (uri);
        }
    }
}
示例#9
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);
}