static gint
gimp_plug_in_manager_file_proc_compare (gconstpointer a,
                                        gconstpointer b,
                                        gpointer      data)
{
  GimpPlugInProcedure *proc_a = GIMP_PLUG_IN_PROCEDURE (a);
  GimpPlugInProcedure *proc_b = GIMP_PLUG_IN_PROCEDURE (b);
  const gchar         *label_a;
  const gchar         *label_b;
  gint                 retval = 0;

  if (g_str_has_prefix (proc_a->prog, "gimp-xcf"))
    return -1;

  if (g_str_has_prefix (proc_b->prog, "gimp-xcf"))
    return 1;

  label_a = gimp_plug_in_procedure_get_label (proc_a);
  label_b = gimp_plug_in_procedure_get_label (proc_b);

  if (label_a && label_b)
    retval = g_utf8_collate (label_a, label_b);

  return retval;
}
static void
gimp_image_prop_view_label_set_filetype (GtkWidget *label,
                                         GimpImage *image)
{
  GimpPlugInManager   *manager = image->gimp->plug_in_manager;
  GimpPlugInProcedure *proc;

  proc = gimp_image_get_save_proc (image);

  if (! proc)
    proc = gimp_image_get_load_proc (image);

  if (! proc)
    {
      gchar *filename = gimp_image_get_filename (image);

      if (filename)
        {
          proc = file_procedure_find (manager->load_procs, filename, NULL);
          g_free (filename);
        }
    }

  gtk_label_set_text (GTK_LABEL (label),
                      proc ? gimp_plug_in_procedure_get_label (proc) : NULL);
}
void
gimp_plug_in_procedure_handle_return_values (GimpPlugInProcedure *proc,
                                             Gimp                *gimp,
                                             GimpProgress        *progress,
                                             GimpValueArray      *return_vals)
{
  g_return_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc));
  g_return_if_fail (return_vals != NULL);

  if (! gimp_value_array_length (return_vals) > 0 ||
      G_VALUE_TYPE (gimp_value_array_index (return_vals, 0)) !=
      GIMP_TYPE_PDB_STATUS_TYPE)
    {
      return;
    }

  switch (g_value_get_enum (gimp_value_array_index (return_vals, 0)))
    {
    case GIMP_PDB_SUCCESS:
      break;

    case GIMP_PDB_CALLING_ERROR:
      if (gimp_value_array_length (return_vals) > 1 &&
          G_VALUE_HOLDS_STRING (gimp_value_array_index (return_vals, 1)))
        {
          gimp_message (gimp, G_OBJECT (progress), GIMP_MESSAGE_ERROR,
                        _("Calling error for '%s':\n"
                          "%s"),
                        gimp_plug_in_procedure_get_label (proc),
                        g_value_get_string (gimp_value_array_index (return_vals, 1)));
        }
      break;

    case GIMP_PDB_EXECUTION_ERROR:
      if (gimp_value_array_length (return_vals) > 1 &&
          G_VALUE_HOLDS_STRING (gimp_value_array_index (return_vals, 1)))
        {
          gimp_message (gimp, G_OBJECT (progress), GIMP_MESSAGE_ERROR,
                        _("Execution error for '%s':\n"
                          "%s"),
                        gimp_plug_in_procedure_get_label (proc),
                        g_value_get_string (gimp_value_array_index (return_vals, 1)));
        }
      break;
    }
}
static void
gimp_plug_in_cleanup_item (GimpPlugInProcFrame   *proc_frame,
                           GimpPlugInCleanupItem *cleanup)
{
  GimpItem *item = cleanup->item;

  if (cleanup->shadow_buffer)
    {
      GimpProcedure *proc = proc_frame->procedure;

      GIMP_LOG (SHADOW_TILES,
                "Freeing shadow buffer of drawable '%s' on behalf of '%s'.",
                gimp_object_get_name (item),
                gimp_plug_in_procedure_get_label (GIMP_PLUG_IN_PROCEDURE (proc)));

      gimp_drawable_free_shadow_buffer (GIMP_DRAWABLE (item));
    }
}
void
gimp_plug_in_cleanup (GimpPlugIn          *plug_in,
                      GimpPlugInProcFrame *proc_frame)
{
  GList *list;

  g_return_if_fail (GIMP_IS_PLUG_IN (plug_in));
  g_return_if_fail (proc_frame != NULL);

  for (list = proc_frame->cleanups; list; list = g_list_next (list))
    {
      GimpPlugInCleanupImage *cleanup = list->data;
      GimpImage              *image   = cleanup->image;

      if (! gimp_container_have (plug_in->manager->gimp->images,
                                 (GimpObject *) image))
        continue;

      if (image->pushing_undo_group == GIMP_UNDO_GROUP_NONE)
        continue;

      if (cleanup->undo_group_count != image->group_count)
        {
          GimpProcedure *proc = proc_frame->procedure;

          g_message ("Plug-In '%s' left image undo in inconsistent state, "
                     "closing open undo groups.",
                     gimp_plug_in_procedure_get_label (GIMP_PLUG_IN_PROCEDURE (proc)));

          while (image->pushing_undo_group != GIMP_UNDO_GROUP_NONE &&
                 cleanup->undo_group_count < image->group_count)
            {
              if (! gimp_image_undo_group_end (image))
                break;
            }
        }

      g_slice_free (GimpPlugInCleanupImage, cleanup);
    }

  g_list_free (proc_frame->cleanups);
  proc_frame->cleanups = NULL;
}
Exemple #6
0
const gchar *
gimp_plug_in_get_undo_desc (GimpPlugIn *plug_in)
{
  GimpPlugInProcFrame *proc_frame;
  const gchar         *undo_desc = NULL;

  g_return_val_if_fail (GIMP_IS_PLUG_IN (plug_in), NULL);

  proc_frame = gimp_plug_in_get_proc_frame (plug_in);

  if (proc_frame)
    {
      GimpPlugInProcedure *proc;

      proc = GIMP_PLUG_IN_PROCEDURE (proc_frame->procedure);

      if (proc)
        undo_desc = gimp_plug_in_procedure_get_label (proc);
    }

  return undo_desc ? undo_desc : gimp_object_get_name (plug_in);
}
static void
gimp_plug_in_cleanup_image (GimpPlugInProcFrame    *proc_frame,
                            GimpPlugInCleanupImage *cleanup)
{
  GimpImage *image = cleanup->image;

  if (gimp_image_get_undo_group_count (image) == 0)
    return;

  if (cleanup->undo_group_count != gimp_image_get_undo_group_count (image))
    {
      GimpProcedure *proc = proc_frame->procedure;

      g_message ("Plug-In '%s' left image undo in inconsistent state, "
                 "closing open undo groups.",
                 gimp_plug_in_procedure_get_label (GIMP_PLUG_IN_PROCEDURE (proc)));

      while (cleanup->undo_group_count < gimp_image_get_undo_group_count (image))
        {
          if (! gimp_image_undo_group_end (image))
            break;
        }
    }
}
Exemple #8
0
GimpPDBStatusType
file_save (Gimp                *gimp,
           GimpImage           *image,
           GimpProgress        *progress,
           const gchar         *uri,
           GimpPlugInProcedure *file_proc,
           GimpRunMode          run_mode,
           gboolean             change_saved_state,
           gboolean             export_backward,
           gboolean             export_forward,
           GError             **error)
{
  GimpDrawable      *drawable;
  GimpValueArray    *return_vals;
  GimpPDBStatusType  status;
  gchar             *filename;
  gint32             image_ID;
  gint32             drawable_ID;

  g_return_val_if_fail (GIMP_IS_GIMP (gimp), GIMP_PDB_CALLING_ERROR);
  g_return_val_if_fail (GIMP_IS_IMAGE (image), 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 ((export_backward && export_forward) == FALSE,
                        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_literal (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
				   _("Not a regular file"));
              status = GIMP_PDB_EXECUTION_ERROR;
              goto out;
            }

          if (g_access (filename, W_OK) != 0)
            {
              g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_ACCES,
                                   g_strerror (errno));
              status = GIMP_PDB_EXECUTION_ERROR;
              goto out;
            }
        }

      if (file_proc->handles_uri)
        {
          g_free (filename);
          filename = g_strdup (uri);
        }
    }
  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,
                                        gimp_get_user_context (gimp),
                                        progress, error,
                                        gimp_object_get_name (file_proc),
                                        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 (gimp_value_array_index (return_vals, 0));

  gimp_value_array_unref (return_vals);

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

      if (change_saved_state)
        {
          gimp_image_set_uri (image, uri);
          gimp_image_set_save_proc (image, file_proc);

          /* Forget the import source when we save. We interpret a
           * save as that the user is not interested in being able
           * to quickly export back to the original any longer
           */
          gimp_image_set_imported_uri (image, NULL);

          gimp_image_clean_all (image);
        }
      else if (export_backward)
        {
          /* We exported the image back to its imported source,
           * change nothing about export/import flags, only set
           * the export state to clean
           */
          gimp_image_export_clean_all (image);

          gimp_object_name_changed (GIMP_OBJECT (image));
        }
      else if (export_forward)
        {
          /* Remember the last entered Export URI for the image. We
           * only need to do this explicitly when exporting. It
           * happens implicitly when saving since the GimpObject name
           * of a GimpImage is the last-save URI
           */
          gimp_image_set_exported_uri (image, uri);

          /* An image can not be considered both exported and imported
           * at the same time, so stop consider it as imported now
           * that we consider it exported.
           */
          gimp_image_set_imported_uri (image, NULL);

          gimp_image_export_clean_all (image);
        }

      if (export_backward || export_forward)
        gimp_image_exported (image, uri);
      else
        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;
}
Exemple #9
0
static void
plug_in_actions_history_changed (GimpPlugInManager *manager,
                                 GimpActionGroup   *group)
{
    GimpPlugInProcedure *proc;
    gint                 i;

    proc = gimp_plug_in_manager_history_nth (manager, 0);

    if (proc)
    {
        GtkAction   *actual_action;
        const gchar *label;
        gchar       *repeat;
        gchar       *reshow;
        gboolean     sensitive = FALSE;

        /*  copy the sensitivity of the plug-in procedure's actual action
         *  instead of calling plug_in_actions_update() because doing the
         *  latter would set the sensitivity of this image's action on
         *  all images' actions. See bug #517683.
         */
        actual_action = gtk_action_group_get_action (GTK_ACTION_GROUP (group),
                        GIMP_OBJECT (proc)->name);
        if (actual_action)
            sensitive = gtk_action_get_sensitive (actual_action);

        label = gimp_plug_in_procedure_get_label (proc);

        repeat = g_strdup_printf (_("Re_peat \"%s\""),  label);
        reshow = g_strdup_printf (_("R_e-Show \"%s\""), label);

        gimp_action_group_set_action_label (group, "plug-in-repeat", repeat);
        gimp_action_group_set_action_label (group, "plug-in-reshow", reshow);

        gimp_action_group_set_action_sensitive (group, "plug-in-repeat", sensitive);
        gimp_action_group_set_action_sensitive (group, "plug-in-reshow", sensitive);

        g_free (repeat);
        g_free (reshow);
    }
    else
    {
        gimp_action_group_set_action_label (group, "plug-in-repeat",
                                            _("Repeat Last"));
        gimp_action_group_set_action_label (group, "plug-in-reshow",
                                            _("Re-Show Last"));

        gimp_action_group_set_action_sensitive (group, "plug-in-repeat", FALSE);
        gimp_action_group_set_action_sensitive (group, "plug-in-reshow", FALSE);
    }

    for (i = 0; i < gimp_plug_in_manager_history_length (manager); i++)
    {
        GtkAction *action;
        GtkAction *actual_action;
        gchar     *name      = g_strdup_printf ("plug-in-recent-%02d", i + 1);
        gboolean   sensitive = FALSE;

        action = gtk_action_group_get_action (GTK_ACTION_GROUP (group), name);
        g_free (name);

        proc = gimp_plug_in_manager_history_nth (manager, i);

        /*  see comment above  */
        actual_action = gtk_action_group_get_action (GTK_ACTION_GROUP (group),
                        GIMP_OBJECT (proc)->name);
        if (actual_action)
            sensitive = gtk_action_get_sensitive (actual_action);

        g_object_set (action,
                      "visible",   TRUE,
                      "sensitive", sensitive,
                      "procedure", proc,
                      "label",     gimp_plug_in_procedure_get_label (proc),
                      "stock-id",  gimp_plug_in_procedure_get_stock_id (proc),
                      "tooltip",   gimp_plug_in_procedure_get_blurb (proc),
                      NULL);
    }

    for (; i < gimp_plug_in_manager_history_size (manager); i++)
    {
        GtkAction *action;
        gchar     *name = g_strdup_printf ("plug-in-recent-%02d", i + 1);

        action = gtk_action_group_get_action (GTK_ACTION_GROUP (group), name);
        g_free (name);

        g_object_set (action,
                      "visible",   FALSE,
                      "procedure", NULL,
                      NULL);
    }
}
Exemple #10
0
GimpPDBStatusType
file_save (Gimp                *gimp,
           GimpImage           *image,
           GimpProgress        *progress,
           GFile               *file,
           GimpPlugInProcedure *file_proc,
           GimpRunMode          run_mode,
           gboolean             change_saved_state,
           gboolean             export_backward,
           gboolean             export_forward,
           GError             **error)
{
  GimpDrawable      *drawable;
  GimpValueArray    *return_vals;
  GimpPDBStatusType  status     = GIMP_PDB_EXECUTION_ERROR;
  GFile             *local_file = NULL;
  gchar             *path       = NULL;
  gchar             *uri        = NULL;
  gint32             image_ID;
  gint32             drawable_ID;
  GError            *my_error   = NULL;

  g_return_val_if_fail (GIMP_IS_GIMP (gimp), GIMP_PDB_CALLING_ERROR);
  g_return_val_if_fail (GIMP_IS_IMAGE (image), GIMP_PDB_CALLING_ERROR);
  g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress),
                        GIMP_PDB_CALLING_ERROR);
  g_return_val_if_fail (G_IS_FILE (file), 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 ((export_backward && export_forward) == FALSE,
                        GIMP_PDB_CALLING_ERROR);
  g_return_val_if_fail (error == NULL || *error == NULL,
                        GIMP_PDB_CALLING_ERROR);

  /*  ref image and file, so they can't get deleted during save  */
  g_object_ref (image);
  g_object_ref (file);

  drawable = gimp_image_get_active_drawable (image);

  if (! drawable)
    goto out;

  /* FIXME enable these tests for remote files again, needs testing */
  if (g_file_is_native (file) &&
      g_file_query_exists (file, NULL))
    {
      GFileInfo *info;

      info = g_file_query_info (file,
                                G_FILE_ATTRIBUTE_STANDARD_TYPE ","
                                G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE,
                                G_FILE_QUERY_INFO_NONE,
                                NULL, error);
      if (! info)
        goto out;

      if (g_file_info_get_file_type (info) != G_FILE_TYPE_REGULAR)
        {
          g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                               _("Not a regular file"));
          g_object_unref (info);
          goto out;
        }

      if (! g_file_info_get_attribute_boolean (info,
                                               G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE))
        {
          g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                               _("Permission denied"));
          g_object_unref (info);
          goto out;
        }

      g_object_unref (info);
    }

  if (! g_file_is_native (file) &&
      ! file_remote_mount_file (gimp, file, progress, &my_error))
    {
      if (my_error)
        g_propagate_error (error, my_error);
      else
        status = GIMP_PDB_CANCEL;

      goto out;
    }

  if (! file_proc->handles_uri)
    {
      path = g_file_get_path (file);

      if (! path)
        {
          local_file = file_remote_upload_image_prepare (gimp, file, progress,
                                                         &my_error);

          if (! local_file)
            {
              if (my_error)
                g_propagate_error (error, my_error);
              else
                status = GIMP_PDB_CANCEL;

              goto out;
            }

          path = g_file_get_path (local_file);
        }
    }

  if (! path)
    path = g_file_get_uri (file);

  uri = g_file_get_uri (file);

  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,
                                        gimp_get_user_context (gimp),
                                        progress, error,
                                        gimp_object_get_name (file_proc),
                                        GIMP_TYPE_INT32,       run_mode,
                                        GIMP_TYPE_IMAGE_ID,    image_ID,
                                        GIMP_TYPE_DRAWABLE_ID, drawable_ID,
                                        G_TYPE_STRING,         path,
                                        G_TYPE_STRING,         uri,
                                        G_TYPE_NONE);

  status = g_value_get_enum (gimp_value_array_index (return_vals, 0));

  gimp_value_array_unref (return_vals);

  if (local_file)
    {
      if (status == GIMP_PDB_SUCCESS)
        {
          GError *my_error = NULL;

          if (! file_remote_upload_image_finish (gimp, file, local_file,
                                                 progress, &my_error))
            {
              status = GIMP_PDB_EXECUTION_ERROR;

              if (my_error)
                g_propagate_error (error, my_error);
              else
                status = GIMP_PDB_CANCEL;
            }
        }

      g_file_delete (local_file, NULL, NULL);
      g_object_unref (local_file);
    }

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

      if (change_saved_state)
        {
          gimp_image_set_file (image, file);
          gimp_image_set_save_proc (image, file_proc);

          /* Forget the import source when we save. We interpret a
           * save as that the user is not interested in being able
           * to quickly export back to the original any longer
           */
          gimp_image_set_imported_file (image, NULL);

          gimp_image_clean_all (image);
        }
      else if (export_backward)
        {
          /* We exported the image back to its imported source,
           * change nothing about export/import flags, only set
           * the export state to clean
           */
          gimp_image_export_clean_all (image);

          gimp_object_name_changed (GIMP_OBJECT (image));
        }
      else if (export_forward)
        {
          /* Remember the last entered Export URI for the image. We
           * only need to do this explicitly when exporting. It
           * happens implicitly when saving since the GimpObject name
           * of a GimpImage is the last-save URI
           */
          gimp_image_set_exported_file (image, file);
          gimp_image_set_export_proc (image, file_proc);

          /* An image can not be considered both exported and imported
           * at the same time, so stop consider it as imported now
           * that we consider it exported.
           */
          gimp_image_set_imported_file (image, NULL);

          gimp_image_export_clean_all (image);
        }

      if (export_backward || export_forward)
        gimp_image_exported (image, file);
      else
        gimp_image_saved (image, file);

      documents = GIMP_DOCUMENT_LIST (image->gimp->documents);

      imagefile = gimp_document_list_add_file (documents, file,
                                               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,
                                       NULL);
    }
  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);

 out:
  g_object_unref (file);
  g_object_unref (image);

  g_free (path);
  g_free (uri);

  return status;
}
Exemple #11
0
GimpImage *
file_open_image (Gimp                *gimp,
                 GimpContext         *context,
                 GimpProgress        *progress,
                 GFile               *file,
                 GFile               *entered_file,
                 gboolean             as_new,
                 GimpPlugInProcedure *file_proc,
                 GimpRunMode          run_mode,
                 GimpPDBStatusType   *status,
                 const gchar        **mime_type,
                 GError             **error)
{
  GimpValueArray *return_vals;
  GimpImage      *image       = NULL;
  GFile          *local_file  = NULL;
  gchar          *path        = NULL;
  gchar          *entered_uri = NULL;
  GError         *my_error    = 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 (G_IS_FILE (file), NULL);
  g_return_val_if_fail (G_IS_FILE (entered_file), NULL);
  g_return_val_if_fail (status != NULL, NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);

  *status = GIMP_PDB_EXECUTION_ERROR;

  /* FIXME enable these tests for remote files again, needs testing */
  if (g_file_is_native (file) &&
      g_file_query_exists (file, NULL))
    {
      GFileInfo *info;

      info = g_file_query_info (file,
                                G_FILE_ATTRIBUTE_STANDARD_TYPE ","
                                G_FILE_ATTRIBUTE_ACCESS_CAN_READ,
                                G_FILE_QUERY_INFO_NONE,
                                NULL, error);
      if (! info)
        return NULL;

      if (g_file_info_get_file_type (info) != G_FILE_TYPE_REGULAR)
        {
          g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                               _("Not a regular file"));
          g_object_unref (info);
          return NULL;
        }

      if (! g_file_info_get_attribute_boolean (info,
                                               G_FILE_ATTRIBUTE_ACCESS_CAN_READ))
        {
          g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                               _("Permission denied"));
          g_object_unref (info);
          return NULL;
        }

      g_object_unref (info);
    }

  if (! file_proc)
    file_proc = file_procedure_find (gimp->plug_in_manager->load_procs, file,
                                     error);

  if (! file_proc)
    return NULL;

  if (! g_file_is_native (file) &&
      ! file_remote_mount_file (gimp, file, progress, &my_error))
    {
      if (my_error)
        g_propagate_error (error, my_error);
      else
        *status = GIMP_PDB_CANCEL;

      return NULL;
    }

  if (! file_proc->handles_uri)
    {
      path = g_file_get_path (file);

      if (! path)
        {
          local_file = file_remote_download_image (gimp, file, progress,
                                                   &my_error);

          if (! local_file)
            {
              if (my_error)
                g_propagate_error (error, my_error);
              else
                *status = GIMP_PDB_CANCEL;

              return NULL;
            }

          path = g_file_get_path (local_file);
        }
    }

  if (! path)
    path = g_file_get_uri (file);

  entered_uri = g_file_get_uri (entered_file);

  if (! entered_uri)
    entered_uri = g_strdup (path);

  return_vals =
    gimp_pdb_execute_procedure_by_name (gimp->pdb,
                                        context, progress, error,
                                        gimp_object_get_name (file_proc),
                                        GIMP_TYPE_INT32, run_mode,
                                        G_TYPE_STRING,   path,
                                        G_TYPE_STRING,   entered_uri,
                                        G_TYPE_NONE);

  g_free (path);
  g_free (entered_uri);

  *status = g_value_get_enum (gimp_value_array_index (return_vals, 0));

  if (*status == GIMP_PDB_SUCCESS)
    image = gimp_value_get_image (gimp_value_array_index (return_vals, 1),
                                  gimp);

  if (local_file)
    {
      if (image)
        gimp_image_set_file (image, file);

      g_file_delete (local_file, NULL, NULL);
      g_object_unref (local_file);
    }

  if (*status == GIMP_PDB_SUCCESS)
    {
      if (image)
        {
          file_open_sanitize_image (image, as_new);

          /* Only set the load procedure if it hasn't already been set. */
          if (! gimp_image_get_load_proc (image))
            gimp_image_set_load_proc (image, file_proc);

          file_proc = gimp_image_get_load_proc (image);

          if (mime_type)
            *mime_type = file_proc->mime_type;
        }
      else
        {
          if (error && ! *error)
            g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                         _("%s plug-in returned SUCCESS but did not "
                           "return an image"),
                         gimp_plug_in_procedure_get_label (file_proc));

          *status = GIMP_PDB_EXECUTION_ERROR;
        }
    }
  else if (*status != GIMP_PDB_CANCEL)
    {
      if (error && ! *error)
        g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                     _("%s plug-In could not open image"),
                     gimp_plug_in_procedure_get_label (file_proc));
    }

  gimp_value_array_unref (return_vals);

  if (image)
    {
      file_open_handle_color_profile (image, context, progress, run_mode);

      if (file_open_file_proc_is_import (file_proc))
        {
          /* Remember the import source */
          gimp_image_set_imported_file (image, file);

          /* We shall treat this file as an Untitled file */
          gimp_image_set_file (image, NULL);
        }
    }

  return image;
}
GimpImage *
file_open_image (Gimp                *gimp,
                 GimpContext         *context,
                 GimpProgress        *progress,
                 const gchar         *uri,
                 const gchar         *entered_filename,
                 gboolean             as_new,
                 GimpPlugInProcedure *file_proc,
                 GimpRunMode          run_mode,
                 GimpPDBStatusType   *status,
                 const gchar        **mime_type,
                 GError             **error)
{
    GValueArray *return_vals;
    gchar       *filename;
    GimpImage   *image = 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);
    g_return_val_if_fail (error == NULL || *error == NULL, NULL);

    *status = GIMP_PDB_EXECUTION_ERROR;

    if (! file_proc)
        file_proc = file_procedure_find (gimp->plug_in_manager->load_procs, uri,
                                         error);

    if (! file_proc)
        return NULL;

    filename = file_utils_filename_from_uri (uri);

    if (filename)
    {
        /* check if we are opening a file */
        if (g_file_test (filename, G_FILE_TEST_EXISTS))
        {
            if (! g_file_test (filename, G_FILE_TEST_IS_REGULAR))
            {
                g_free (filename);
                g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                                     _("Not a regular file"));
                return NULL;
            }

            if (g_access (filename, R_OK) != 0)
            {
                g_free (filename);
                g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_ACCES,
                                     g_strerror (errno));
                return NULL;
            }
        }
    }
    else
    {
        filename = g_strdup (uri);
    }

    return_vals =
        gimp_pdb_execute_procedure_by_name (gimp->pdb,
                                            context, progress, error,
                                            gimp_object_get_name (file_proc),
                                            GIMP_TYPE_INT32, run_mode,
                                            G_TYPE_STRING,   filename,
                                            G_TYPE_STRING,   entered_filename,
                                            G_TYPE_NONE);

    g_free (filename);

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

    if (*status == GIMP_PDB_SUCCESS)
    {
        image = gimp_value_get_image (&return_vals->values[1], gimp);

        if (image)
        {
            file_open_sanitize_image (image, as_new);

            /* Only set the load procedure if it hasn't already been set. */
            if (! gimp_image_get_load_proc (image))
                gimp_image_set_load_proc (image, file_proc);

            file_proc = gimp_image_get_load_proc (image);

            if (mime_type)
                *mime_type = file_proc->mime_type;
        }
        else
        {
            if (error && ! *error)
                g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                             _("%s plug-in returned SUCCESS but did not "
                               "return an image"),
                             gimp_plug_in_procedure_get_label (file_proc));

            *status = GIMP_PDB_EXECUTION_ERROR;
        }
    }
    else if (*status != GIMP_PDB_CANCEL)
    {
        if (error && ! *error)
            g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                         _("%s plug-In could not open image"),
                         gimp_plug_in_procedure_get_label (file_proc));
    }

    g_value_array_free (return_vals);

    if (image)
    {
        file_open_handle_color_profile (image, context, progress, run_mode);

        if (file_open_file_proc_is_import (file_proc))
        {
            /* Remember the import source */
            gimp_image_set_imported_uri (image, uri);

            /* We shall treat this file as an Untitled file */
            gimp_image_set_uri (image, NULL);
        }
    }

    return image;
}
Exemple #13
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;
}
Exemple #14
0
GtkWidget *
gimp_file_proc_view_new (Gimp        *gimp,
                         GSList      *procedures,
                         const gchar *automatic,
                         const gchar *automatic_help_id)
{
  GtkTreeView       *view;
  GtkTreeViewColumn *column;
  GtkCellRenderer   *cell;
  GtkListStore      *store;
  GSList            *list;
  GtkTreeIter        iter;

  g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);

  store = gtk_list_store_new (NUM_COLUMNS,
                              GIMP_TYPE_PLUG_IN_PROCEDURE, /*  COLUMN_PROC   */
                              G_TYPE_STRING,          /*  COLUMN_LABEL       */
                              G_TYPE_STRING,          /*  COLUMN_EXTENSIONS  */
                              G_TYPE_STRING);         /*  COLUMN_HELP_ID     */

  view = g_object_new (GIMP_TYPE_FILE_PROC_VIEW,
                       "model",      store,
                       "rules-hint", TRUE,
                       NULL);

  g_object_unref (store);

  for (list = procedures; list; list = g_slist_next (list))
    {
      GimpPlugInProcedure *proc = list->data;

      if (! proc->prefixes_list) /*  skip URL loaders  */
        {
          const gchar *label   = gimp_plug_in_procedure_get_label (proc);
          gchar       *help_id = gimp_plug_in_procedure_get_help_id (proc);
          GSList      *list2;

          if (label)
            {
              gtk_list_store_append (store, &iter);
              gtk_list_store_set (store, &iter,
                                  COLUMN_PROC,       proc,
                                  COLUMN_LABEL,      label,
                                  COLUMN_EXTENSIONS, proc->extensions,
                                  COLUMN_HELP_ID,    help_id,
                                  -1);
            }

          g_free (help_id);

          for (list2 = proc->extensions_list;
               list2;
               list2 = g_slist_next (list2))
            {
              GimpFileProcView *proc_view = GIMP_FILE_PROC_VIEW (view);
              const gchar      *ext       = list2->data;
              const gchar      *dot       = strchr (ext, '.');

              if (dot && dot != ext)
                proc_view->meta_extensions =
                  g_list_append (proc_view->meta_extensions,
                                 g_strdup (dot + 1));
            }
        }
    }

  if (automatic)
    {
      gtk_list_store_prepend (store, &iter);

      gtk_list_store_set (store, &iter,
                          COLUMN_PROC,    NULL,
                          COLUMN_LABEL,   automatic,
                          COLUMN_HELP_ID, automatic_help_id,
                          -1);
    }

  column = gtk_tree_view_column_new ();
  gtk_tree_view_column_set_title (column, _("File Type"));
  gtk_tree_view_column_set_expand (column, TRUE);

  cell = gtk_cell_renderer_text_new ();
  gtk_tree_view_column_pack_start (column, cell, TRUE);
  gtk_tree_view_column_set_attributes (column, cell,
                                       "text", COLUMN_LABEL,
                                       NULL);

  gtk_tree_view_append_column (view, column);

  column = gtk_tree_view_column_new ();
  gtk_tree_view_column_set_title (column, _("Extensions"));

  cell = gtk_cell_renderer_text_new ();
  gtk_tree_view_column_pack_start (column, cell, TRUE);
  gtk_tree_view_column_set_attributes (column, cell,
                                       "text", COLUMN_EXTENSIONS,
                                       NULL);

  gtk_tree_view_append_column (view, column);

  g_signal_connect (gtk_tree_view_get_selection (view), "changed",
                    G_CALLBACK (gimp_file_proc_view_selection_changed),
                    view);

  return GTK_WIDGET (view);
}
Exemple #15
0
static void
gimp_file_dialog_add_filters (GimpFileDialog *dialog,
                              Gimp           *gimp,
                              GSList         *file_procs)
{
  GtkFileFilter *all;
  GSList        *list;

  all = gtk_file_filter_new ();
  gtk_file_filter_set_name (all, _("All files"));
  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), all);
  gtk_file_filter_add_pattern (all, "*");

  all = gtk_file_filter_new ();
  gtk_file_filter_set_name (all, _("All images"));
  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), all);

  for (list = file_procs; list; list = g_slist_next (list))
    {
      GimpPlugInProcedure *file_proc = list->data;

      if (file_proc->extensions_list)
        {
          GtkFileFilter *filter = gtk_file_filter_new ();
          GString       *str;
          GSList        *ext;
          gint           i;

          str = g_string_new (gimp_plug_in_procedure_get_label (file_proc));

/*  an arbitrary limit to keep the file dialog from becoming too wide  */
#define MAX_EXTENSIONS  4

          for (ext = file_proc->extensions_list, i = 0;
               ext;
               ext = g_slist_next (ext), i++)
            {
              const gchar *extension = ext->data;
              gchar       *pattern;

              pattern = gimp_file_dialog_pattern_from_extension (extension);
              gtk_file_filter_add_pattern (filter, pattern);
              gtk_file_filter_add_pattern (all, pattern);
              g_free (pattern);

              if (i == 0)
                {
                  g_string_append (str, " (");
                }
              else if (i <= MAX_EXTENSIONS)
                {
                  g_string_append (str, ", ");
                }

              if (i < MAX_EXTENSIONS)
                {
                  g_string_append (str, "*.");
                  g_string_append (str, extension);
                }
              else if (i == MAX_EXTENSIONS)
                {
                  g_string_append (str, "...");
                }

              if (! ext->next)
                {
                  g_string_append (str, ")");
                }
            }

          gtk_file_filter_set_name (filter, str->str);
          g_string_free (str, TRUE);

          gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
        }
    }

  gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), all);
}