示例#1
0
static void
gimp_drawable_tree_view_new_dropped (GimpItemTreeView   *view,
                                     gint                x,
                                     gint                y,
                                     const GimpRGB      *color,
                                     GimpPattern        *pattern)
{
  GimpItem *item;

  gimp_image_undo_group_start (gimp_item_tree_view_get_image (view), GIMP_UNDO_GROUP_EDIT_PASTE,
                               _("New Layer"));

  item = GIMP_ITEM_TREE_VIEW_GET_CLASS (view)->new_item (gimp_item_tree_view_get_image (view));

  if (item)
    {
      gimp_edit_fill_full (gimp_item_get_image (item),
                           GIMP_DRAWABLE (item),
                           color, pattern,
                           GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE,
                           pattern ?
                           C_("undo-type", "Drop pattern to layer") :
                           C_("undo-type", "Drop color to layer"));
    }

  gimp_image_undo_group_end (gimp_item_tree_view_get_image (view));

  gimp_image_flush (gimp_item_tree_view_get_image (view));
}
示例#2
0
void
gimp_item_rotate (GimpItem         *item,
                  GimpContext      *context,
                  GimpRotationType  rotate_type,
                  gdouble           center_x,
                  gdouble           center_y,
                  gboolean          clip_result)
{
  GimpItemClass *item_class;
  GimpImage     *image;

  g_return_if_fail (GIMP_IS_ITEM (item));
  g_return_if_fail (gimp_item_is_attached (item));
  g_return_if_fail (GIMP_IS_CONTEXT (context));

  item_class = GIMP_ITEM_GET_CLASS (item);
  image = gimp_item_get_image (item);

  gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TRANSFORM,
                               item_class->rotate_desc);

  item_class->rotate (item, context, rotate_type, center_x, center_y,
                      clip_result);

  gimp_image_undo_group_end (image);
}
示例#3
0
static void
gimp_text_layer_set_buffer (GimpDrawable *drawable,
                            gboolean      push_undo,
                            const gchar  *undo_desc,
                            GeglBuffer   *buffer,
                            gint          offset_x,
                            gint          offset_y)
{
  GimpTextLayer *layer = GIMP_TEXT_LAYER (drawable);
  GimpImage     *image = gimp_item_get_image (GIMP_ITEM (layer));

  if (push_undo && ! layer->modified)
    gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_DRAWABLE_MOD,
                                 undo_desc);

  GIMP_DRAWABLE_CLASS (parent_class)->set_buffer (drawable,
                                                  push_undo, undo_desc,
                                                  buffer,
                                                  offset_x, offset_y);

  if (push_undo && ! layer->modified)
    {
      gimp_image_undo_push_text_layer_modified (image, NULL, layer);

      g_object_set (drawable, "modified", TRUE, NULL);

      gimp_image_undo_group_end (image);
    }
}
示例#4
0
/**
 * gimp_item_translate:
 * @item:      The #GimpItem to move.
 * @offset_x:  Increment to the X offset of the item.
 * @offset_y:  Increment to the Y offset of the item.
 * @push_undo: If #TRUE, create an entry in the image's undo stack
 *             for this action.
 *
 * Adds the specified increments to the X and Y offsets for the item.
 */
void
gimp_item_translate (GimpItem *item,
                     gint      offset_x,
                     gint      offset_y,
                     gboolean  push_undo)
{
  GimpItemClass *item_class;
  GimpImage     *image;

  g_return_if_fail (GIMP_IS_ITEM (item));

  item_class = GIMP_ITEM_GET_CLASS (item);
  image = gimp_item_get_image (item);

  if (! gimp_item_is_attached (item))
    push_undo = FALSE;

  if (push_undo)
    gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_ITEM_DISPLACE,
                                 item_class->translate_desc);

  item_class->translate (item, offset_x, offset_y, push_undo);

  if (push_undo)
    gimp_image_undo_group_end (image);
}
示例#5
0
void
floating_sel_remove (GimpLayer *layer)
{
  GimpImage *image;

  g_return_if_fail (GIMP_IS_LAYER (layer));
  g_return_if_fail (gimp_layer_is_floating_sel (layer));

  image = gimp_item_get_image (GIMP_ITEM (layer->fs.drawable));

  gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_FS_REMOVE,
                               _("Remove Floating Selection"));

  /*  store the affected area from the drawable in the backing store  */
  floating_sel_relax (layer, TRUE);

  /*  Invalidate the preview of the obscured drawable.  We do this here
   *  because it will not be done until the floating selection is removed,
   *  at which point the obscured drawable's preview will not be declared
   *  invalid.
   */
  gimp_viewable_invalidate_preview (GIMP_VIEWABLE (layer));

  /*  remove the layer from the image  */
  gimp_image_remove_layer (image, layer);

  gimp_image_undo_group_end (image);
}
示例#6
0
void
gimp_item_transform (GimpItem               *item,
                     GimpContext            *context,
                     const GimpMatrix3      *matrix,
                     GimpTransformDirection  direction,
                     GimpInterpolationType   interpolation,
                     gint                    recursion_level,
                     GimpTransformResize     clip_result,
                     GimpProgress           *progress)
{
  GimpItemClass *item_class;
  GimpImage     *image;

  g_return_if_fail (GIMP_IS_ITEM (item));
  g_return_if_fail (gimp_item_is_attached (item));
  g_return_if_fail (GIMP_IS_CONTEXT (context));
  g_return_if_fail (matrix != NULL);
  g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress));

  item_class = GIMP_ITEM_GET_CLASS (item);
  image = gimp_item_get_image (item);

  gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TRANSFORM,
                               item_class->transform_desc);

  item_class->transform (item, context, matrix, direction, interpolation,
                         recursion_level, clip_result, progress);

  gimp_image_undo_group_end (image);
}
示例#7
0
void
gimp_image_item_list_transform (GimpImage              *image,
                                GList                  *list,
                                GimpContext            *context,
                                const GimpMatrix3      *matrix,
                                GimpTransformDirection  direction,
                                GimpInterpolationType   interpolation_type,
                                GimpTransformResize     clip_result,
                                GimpProgress           *progress)
{
  g_return_if_fail (GIMP_IS_IMAGE (image));
  g_return_if_fail (GIMP_IS_CONTEXT (context));
  g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress));

  if (list)
    {
      GList *l;

      if (list->next)
        gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TRANSFORM,
                                     C_("undo-type", "Transform Items"));

      for (l = list; l; l = g_list_next (l))
        gimp_item_transform (GIMP_ITEM (l->data), context,
                             matrix, direction,
                             interpolation_type,
                             clip_result, progress);

      if (list->next)
        gimp_image_undo_group_end (image);
    }
}
示例#8
0
void
gimp_image_item_list_translate (GimpImage *image,
                                GList     *list,
                                gint       offset_x,
                                gint       offset_y,
                                gboolean   push_undo)
{
  g_return_if_fail (GIMP_IS_IMAGE (image));

  if (list)
    {
      GList *l;

      if (push_undo && list->next)
        gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_ITEM_DISPLACE,
                                     C_("undo-type", "Translate Items"));

      for (l = list; l; l = g_list_next (l))
        gimp_item_translate (GIMP_ITEM (l->data),
                             offset_x, offset_y, push_undo);

      if (push_undo && list->next)
        gimp_image_undo_group_end (image);
    }
}
示例#9
0
GimpLayer *
gimp_image_merge_group_layer (GimpImage      *image,
                              GimpGroupLayer *group)
{
  GimpLayer *parent;
  GimpLayer *layer;
  gint       index;

  g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
  g_return_val_if_fail (GIMP_IS_GROUP_LAYER (group), NULL);
  g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (group)), NULL);
  g_return_val_if_fail (gimp_item_get_image (GIMP_ITEM (group)) == image, NULL);

  gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_LAYERS_MERGE,
                               C_("undo-type", "Merge Layer Group"));

  parent = gimp_layer_get_parent (GIMP_LAYER (group));
  index  = gimp_item_get_index (GIMP_ITEM (group));

  layer = GIMP_LAYER (gimp_item_duplicate (GIMP_ITEM (group),
                                           GIMP_TYPE_LAYER));

  gimp_object_set_name (GIMP_OBJECT (layer), gimp_object_get_name (group));

  gimp_image_remove_layer (image, GIMP_LAYER (group), TRUE, NULL);
  gimp_image_add_layer (image, layer, parent, index, TRUE);

  gimp_image_undo_group_end (image);

  return layer;
}
示例#10
0
void
gimp_item_scale (GimpItem              *item,
                 gint                   new_width,
                 gint                   new_height,
                 gint                   new_offset_x,
                 gint                   new_offset_y,
                 GimpInterpolationType  interpolation,
                 GimpProgress          *progress)
{
  GimpItemClass *item_class;
  GimpImage     *image;

  g_return_if_fail (GIMP_IS_ITEM (item));
  g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress));

  if (new_width < 1 || new_height < 1)
    return;

  item_class = GIMP_ITEM_GET_CLASS (item);
  image = gimp_item_get_image (item);

  if (gimp_item_is_attached (item))
    gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_ITEM_SCALE,
                                 item_class->scale_desc);

  item_class->scale (item, new_width, new_height, new_offset_x, new_offset_y,
                     interpolation, progress);

  if (gimp_item_is_attached (item))
    gimp_image_undo_group_end (image);
}
示例#11
0
void
gimp_item_resize (GimpItem    *item,
                  GimpContext *context,
                  gint         new_width,
                  gint         new_height,
                  gint         offset_x,
                  gint         offset_y)
{
  GimpItemClass *item_class;
  GimpImage     *image;

  g_return_if_fail (GIMP_IS_ITEM (item));
  g_return_if_fail (GIMP_IS_CONTEXT (context));

  if (new_width < 1 || new_height < 1)
    return;

  item_class = GIMP_ITEM_GET_CLASS (item);
  image = gimp_item_get_image (item);

  if (gimp_item_is_attached (item))
    gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_ITEM_RESIZE,
                                 item_class->resize_desc);

  item_class->resize (item, context, new_width, new_height, offset_x, offset_y);

  if (gimp_item_is_attached (item))
    gimp_image_undo_group_end (image);
}
示例#12
0
static void
gimp_text_layer_push_undo (GimpDrawable *drawable,
                           const gchar  *undo_desc,
                           GeglBuffer   *buffer,
                           gint          x,
                           gint          y,
                           gint          width,
                           gint          height)
{
  GimpTextLayer *layer = GIMP_TEXT_LAYER (drawable);
  GimpImage     *image = gimp_item_get_image (GIMP_ITEM (layer));

  if (! layer->modified)
    gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_DRAWABLE, undo_desc);

  GIMP_DRAWABLE_CLASS (parent_class)->push_undo (drawable, undo_desc,
                                                 buffer,
                                                 x, y, width, height);

  if (! layer->modified)
    {
      gimp_image_undo_push_text_layer_modified (image, NULL, layer);

      g_object_set (drawable, "modified", TRUE, NULL);

      gimp_image_undo_group_end (image);
    }
}
示例#13
0
void
callback_edit_mask_button (GtkWidget * button, gpointer data)
{
  NewLayerData *nl_data = NEW_LAYER_DATA (data);
  PreviewData *p_data = nl_data->preview_data;
  gint32 layer_ID = *(nl_data->layer_ID);

  IMAGE_CHECK_ACTION(p_data->image_ID, gtk_dialog_response (GTK_DIALOG (dlg), RESPONSE_FATAL), );
  LAYER_CHECK_ACTION(layer_ID, gtk_dialog_response (GTK_DIALOG (dlg), RESPONSE_REFRESH), );
  if (*(nl_data->status) != TRUE)
    {
      g_message ("You just found a bug!");
      return;
    }

  gimp_image_undo_group_start (p_data->image_ID);
  gimp_image_set_active_layer(p_data->image_ID, layer_ID);
  gimp_image_undo_group_end (p_data->image_ID);

  nl_data->preview_data->ui_vals->layer_on_edit_ID = layer_ID;
  nl_data->preview_data->ui_vals->layer_on_edit_type = nl_data->layer_type;
  nl_data->preview_data->ui_vals->layer_on_edit_is_new = FALSE;

  gtk_dialog_response (GTK_DIALOG(dlg), RESPONSE_WORK_ON_AUX_LAYER);
}
示例#14
0
static GValueArray *
image_undo_group_start_invoker (GimpProcedure      *procedure,
                                Gimp               *gimp,
                                GimpContext        *context,
                                GimpProgress       *progress,
                                const GValueArray  *args,
                                GError            **error)
{
  gboolean success = TRUE;
  GimpImage *image;

  image = gimp_value_get_image (&args->values[0], gimp);

  if (success)
    {
      GimpPlugIn  *plug_in   = gimp->plug_in_manager->current_plug_in;
      const gchar *undo_desc = NULL;

      if (plug_in)
        {
          success = gimp_plug_in_cleanup_undo_group_start (plug_in, image);

          if (success)
            undo_desc = gimp_plug_in_get_undo_desc (plug_in);
        }

      if (success)
        gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_MISC, undo_desc);
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}
static void
callback_alarm_triggered (GtkWidget * size_entry, gpointer data)
{
    gint new_width, new_height;
    gboolean render_success;
    InterfaceIData *p_data = INTERFACE_I_DATA (data);
    CarverData *c_data = p_data->carver_data;
    //gtk_widget_set_sensitive (p_data->size_frame, FALSE);

    new_width =
        ROUND (alt_size_entry_get_refval (ALT_SIZE_ENTRY (size_entry), 0));
    new_height =
        ROUND (alt_size_entry_get_refval (ALT_SIZE_ENTRY (size_entry), 1));
    state->new_width = new_width;
    state->new_height = new_height;
    gimp_image_undo_group_start (c_data->image_ID);
    render_success = render_interactive (state, p_data->carver_data);
    gimp_image_undo_group_end (c_data->image_ID);
    /* p_data->drawable_vals->layer_ID = c_data->layer_ID; */
    if (!render_success)
    {
        dialog_I_response = RESPONSE_FATAL;
        gtk_main_quit();
    }
    gimp_displays_flush();

    set_info_label_text (p_data);
    //set_info_label_text (p_data->info_label, c_data->ref_w, c_data->ref_h, c_data->orientation, c_data->depth, c_data->enl_step);
    //gtk_widget_set_sensitive (p_data->dump_button, (c_data->depth != 0));
    //gtk_widget_set_sensitive (p_data->size_frame, TRUE);

}
示例#16
0
static void
image_scale_callback (GtkWidget              *dialog,
                      GimpViewable           *viewable,
                      gint                    width,
                      gint                    height,
                      GimpUnit                unit,
                      GimpInterpolationType   interpolation,
                      gdouble                 xresolution,
                      gdouble                 yresolution,
                      GimpUnit                resolution_unit,
                      gpointer                user_data)
{
  GimpImage *image = GIMP_IMAGE (viewable);
  gdouble    xres;
  gdouble    yres;

  image_scale_unit   = unit;
  image_scale_interp = interpolation;

  gimp_image_get_resolution (image, &xres, &yres);

  if (width > 0 && height > 0)
    {
      if (width           == gimp_image_get_width  (image) &&
          height          == gimp_image_get_height (image) &&
          xresolution     == xres                          &&
          yresolution     == yres                          &&
          resolution_unit == gimp_image_get_unit (image))
        return;

      gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_SCALE,
                                   _("Scale Image"));

      gimp_image_set_resolution (image, xresolution, yresolution);
      gimp_image_set_unit (image, resolution_unit);

      if (width  != gimp_image_get_width  (image) ||
          height != gimp_image_get_height (image))
        {
          GimpProgress *progress;

          progress = gimp_progress_start (GIMP_PROGRESS (user_data),
                                          _("Scaling"), FALSE);

          gimp_image_scale (image, width, height, interpolation, progress);

          if (progress)
            gimp_progress_end (progress);
        }

      gimp_image_undo_group_end (image);

      gimp_image_flush (image);
    }
  else
    {
      g_warning ("Scale Error: "
                 "Both width and height must be greater than zero.");
    }
}
示例#17
0
static void
image_print_size_callback (GtkWidget *dialog,
                           GimpImage *image,
                           gdouble    xresolution,
                           gdouble    yresolution,
                           GimpUnit   resolution_unit,
                           gpointer   data)
{
  gdouble xres;
  gdouble yres;

  gtk_widget_destroy (dialog);

  gimp_image_get_resolution (image, &xres, &yres);

  if (xresolution     == xres &&
      yresolution     == yres &&
      resolution_unit == gimp_image_get_unit (image))
    return;

  gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_SCALE,
                               _("Change Print Size"));

  gimp_image_set_resolution (image, xresolution, yresolution);
  gimp_image_set_unit (image, resolution_unit);

  gimp_image_undo_group_end (image);

  gimp_image_flush (image);
}
示例#18
0
void
gimp_image_item_list_rotate (GimpImage        *image,
                             GList            *list,
                             GimpContext      *context,
                             GimpRotationType  rotate_type,
                             gdouble           center_x,
                             gdouble           center_y,
                             gboolean          clip_result)
{
  g_return_if_fail (GIMP_IS_IMAGE (image));
  g_return_if_fail (GIMP_IS_CONTEXT (context));

  if (list)
    {
      GList *l;

      if (list->next)
        gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TRANSFORM,
                                     C_("undo-type", "Rotate Items"));

      for (l = list; l; l = g_list_next (l))
        gimp_item_rotate (GIMP_ITEM (l->data), context,
                          rotate_type, center_x, center_y, clip_result);

      if (list->next)
        gimp_image_undo_group_end (image);
    }
}
示例#19
0
static void
gimp_display_shell_drop_component (GtkWidget       *widget,
                                   gint             x,
                                   gint             y,
                                   GimpImage       *image,
                                   GimpChannelType  component,
                                   gpointer         data)
{
  GimpDisplayShell *shell      = GIMP_DISPLAY_SHELL (data);
  GimpImage        *dest_image = gimp_display_get_image (shell->display);
  GimpChannel      *channel;
  GimpItem         *new_item;
  const gchar      *desc;

  GIMP_LOG (DND, NULL);

  if (shell->display->gimp->busy)
    return;

  if (! dest_image)
    {
      dest_image = gimp_image_new_from_component (image->gimp,
                                                  image, component);
      gimp_create_display (dest_image->gimp, dest_image, GIMP_UNIT_PIXEL, 1.0,
                           G_OBJECT (gtk_widget_get_screen (widget)),
                           gimp_widget_get_monitor (widget));
      g_object_unref (dest_image);

      return;
    }

  channel = gimp_channel_new_from_component (image, component, NULL, NULL);

  new_item = gimp_item_convert (GIMP_ITEM (channel),
                                dest_image, GIMP_TYPE_LAYER);
  g_object_unref (channel);

  if (new_item)
    {
      GimpLayer *new_layer = GIMP_LAYER (new_item);

      gimp_enum_get_value (GIMP_TYPE_CHANNEL_TYPE, component,
                           NULL, NULL, &desc, NULL);
      gimp_object_take_name (GIMP_OBJECT (new_layer),
                             g_strdup_printf (_("%s Channel Copy"), desc));

      gimp_image_undo_group_start (dest_image, GIMP_UNDO_GROUP_EDIT_PASTE,
                                   _("Drop New Layer"));

      gimp_display_shell_dnd_position_item (shell, image, new_item);

      gimp_image_add_layer (dest_image, new_layer,
                            GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE);

      gimp_image_undo_group_end (dest_image);

      gimp_display_shell_dnd_flush (shell, dest_image);
    }
}
示例#20
0
void
gimp_image_item_list_transform (GimpImage              *image,
                                GList                  *list,
                                GimpContext            *context,
                                const GimpMatrix3      *matrix,
                                GimpTransformDirection  direction,
                                GimpInterpolationType   interpolation_type,
                                GimpTransformResize     clip_result,
                                GimpProgress           *progress)
{
  g_return_if_fail (GIMP_IS_IMAGE (image));
  g_return_if_fail (GIMP_IS_CONTEXT (context));
  g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress));

  if (list)
    {
      GimpObjectQueue *queue = NULL;
      GList           *l;

      if (progress)
        {
          queue    = gimp_object_queue_new (progress);
          progress = GIMP_PROGRESS (queue);

          gimp_object_queue_push_list (queue, list);
        }

      if (list->next)
        {
          gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TRANSFORM,
                                       C_("undo-type", "Transform Items"));

          for (l = list; l; l = g_list_next (l))
            gimp_item_start_transform (GIMP_ITEM (l->data), TRUE);
        }

      for (l = list; l; l = g_list_next (l))
        {
          if (queue)
            gimp_object_queue_pop (queue);

          gimp_item_transform (GIMP_ITEM (l->data), context,
                               matrix, direction,
                               interpolation_type,
                               clip_result, progress);
        }

      if (list->next)
        {
          for (l = list; l; l = g_list_next (l))
            gimp_item_end_transform (GIMP_ITEM (l->data), TRUE);

          gimp_image_undo_group_end (image);
        }

      g_clear_object (&queue);
    }
}
示例#21
0
static void
gimp_display_shell_drop_pixbuf (GtkWidget *widget,
                                gint       x,
                                gint       y,
                                GdkPixbuf *pixbuf,
                                gpointer   data)
{
  GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (data);
  GimpImage        *image = gimp_display_get_image (shell->display);
  GimpLayer        *new_layer;
  gboolean          has_alpha = FALSE;

  GIMP_LOG (DND, NULL);

  if (shell->display->gimp->busy)
    return;

  if (! image)
    {
      image = gimp_image_new_from_pixbuf (shell->display->gimp, pixbuf,
                                          _("Dropped Buffer"));
      gimp_create_display (image->gimp, image, GIMP_UNIT_PIXEL, 1.0,
                           G_OBJECT (gtk_widget_get_screen (widget)),
                           gimp_widget_get_monitor (widget));
      g_object_unref (image);

      return;
    }

  if (gdk_pixbuf_get_n_channels (pixbuf) == 2 ||
      gdk_pixbuf_get_n_channels (pixbuf) == 4)
    {
      has_alpha = TRUE;
    }

  new_layer =
    gimp_layer_new_from_pixbuf (pixbuf, image,
                                gimp_image_get_layer_format (image, has_alpha),
                                _("Dropped Buffer"),
                                GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE);

  if (new_layer)
    {
      GimpItem *new_item = GIMP_ITEM (new_layer);

      gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_PASTE,
                                   _("Drop New Layer"));

      gimp_display_shell_dnd_position_item (shell, image, new_item);

      gimp_image_add_layer (image, new_layer,
                            GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE);

      gimp_image_undo_group_end (image);

      gimp_display_shell_dnd_flush (shell, image);
    }
}
示例#22
0
void
gimp_item_parasite_attach (GimpItem           *item,
                           const GimpParasite *parasite)
{
  GimpParasite  copy;

  g_return_if_fail (GIMP_IS_ITEM (item));
  g_return_if_fail (parasite != NULL);

  /*  make a temporary copy of the GimpParasite struct because
   *  gimp_parasite_shift_parent() changes it
   */
  copy = *parasite;

  if (gimp_item_is_attached (item))
    {
      /*  only set the dirty bit manually if we can be saved and the new
       *  parasite differs from the current one and we aren't undoable
       */
      if (gimp_parasite_is_undoable (&copy))
        {
          /* do a group in case we have attach_parent set */
          gimp_image_undo_group_start (item->image,
                                       GIMP_UNDO_GROUP_PARASITE_ATTACH,
                                       _("Attach Parasite"));

          gimp_image_undo_push_item_parasite (item->image, NULL, item, &copy);
        }
      else if (gimp_parasite_is_persistent (&copy) &&
               ! gimp_parasite_compare (&copy,
                                        gimp_item_parasite_find
                                        (item, gimp_parasite_name (&copy))))
        {
          gimp_image_undo_push_cantundo (item->image,
                                         _("Attach Parasite to Item"));
        }
    }

  gimp_parasite_list_add (item->parasites, &copy);

  if (gimp_parasite_has_flag (&copy, GIMP_PARASITE_ATTACH_PARENT))
    {
      gimp_parasite_shift_parent (&copy);
      gimp_image_parasite_attach (item->image, &copy);
    }
  else if (gimp_parasite_has_flag (&copy, GIMP_PARASITE_ATTACH_GRANDPARENT))
    {
      gimp_parasite_shift_parent (&copy);
      gimp_parasite_shift_parent (&copy);
      gimp_parasite_attach (item->image->gimp, &copy);
    }

  if (gimp_item_is_attached (item) &&
      gimp_parasite_is_undoable (&copy))
    {
      gimp_image_undo_group_end (item->image);
    }
}
示例#23
0
GimpLayer *
gimp_image_flatten (GimpImage    *image,
                    GimpContext  *context,
                    GError      **error)
{
  GList     *list;
  GSList    *merge_list = NULL;
  GimpLayer *layer;

  g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
  g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);

  for (list = gimp_image_get_layer_iter (image);
       list;
       list = g_list_next (list))
    {
      layer = list->data;

      if (gimp_layer_is_floating_sel (layer))
        continue;

      if (gimp_item_get_visible (GIMP_ITEM (layer)))
        merge_list = g_slist_append (merge_list, layer);
    }

  if (merge_list)
    {
      gimp_set_busy (image->gimp);

      gimp_image_undo_group_start (image,
                                   GIMP_UNDO_GROUP_IMAGE_LAYERS_MERGE,
                                   C_("undo-type", "Flatten Image"));

      /* if there's a floating selection, anchor it */
      if (gimp_image_get_floating_selection (image))
        floating_sel_anchor (gimp_image_get_floating_selection (image));

      layer = gimp_image_merge_layers (image,
                                       gimp_image_get_layers (image),
                                       merge_list, context,
                                       GIMP_FLATTEN_IMAGE);
      g_slist_free (merge_list);

      gimp_image_alpha_changed (image);

      gimp_image_undo_group_end (image);

      gimp_unset_busy (image->gimp);

      return layer;
    }

  g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED,
                       _("Cannot flatten an image without any visible layer."));
  return NULL;
}
示例#24
0
static void
gimp_display_shell_drop_drawable (GtkWidget    *widget,
                                  gint          x,
                                  gint          y,
                                  GimpViewable *viewable,
                                  gpointer      data)
{
  GimpDisplayShell *shell     = GIMP_DISPLAY_SHELL (data);
  GimpImage        *image     = gimp_display_get_image (shell->display);
  GType             new_type;
  GimpItem         *new_item;

  GIMP_LOG (DND, NULL);

  if (shell->display->gimp->busy)
    return;

  if (! image)
    {
      image = gimp_image_new_from_drawable (shell->display->gimp,
                                            GIMP_DRAWABLE (viewable));
      gimp_create_display (shell->display->gimp, image, GIMP_UNIT_PIXEL, 1.0,
                           G_OBJECT (gtk_widget_get_screen (widget)),
                           gimp_widget_get_monitor (widget));
      g_object_unref (image);

      return;
    }

  if (GIMP_IS_LAYER (viewable))
    new_type = G_TYPE_FROM_INSTANCE (viewable);
  else
    new_type = GIMP_TYPE_LAYER;

  new_item = gimp_item_convert (GIMP_ITEM (viewable), image, new_type);

  if (new_item)
    {
      GimpLayer *new_layer = GIMP_LAYER (new_item);

      gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_PASTE,
                                   _("Drop New Layer"));

      gimp_display_shell_dnd_position_item (shell, image, new_item);

      gimp_item_set_visible (new_item, TRUE, FALSE);
      gimp_item_set_linked (new_item, FALSE, FALSE);

      gimp_image_add_layer (image, new_layer,
                            GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE);

      gimp_image_undo_group_end (image);

      gimp_display_shell_dnd_flush (shell, image);
    }
}
示例#25
0
GimpDrawable *
gimp_drawable_transform_paste (GimpDrawable     *drawable,
                               GeglBuffer       *buffer,
                               GimpColorProfile *buffer_profile,
                               gint              offset_x,
                               gint              offset_y,
                               gboolean          new_layer)
{
  GimpImage   *image;
  GimpLayer   *layer     = NULL;
  const gchar *undo_desc = NULL;

  g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
  g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)), NULL);
  g_return_val_if_fail (GEGL_IS_BUFFER (buffer), NULL);
  g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (buffer_profile), NULL);

  image = gimp_item_get_image (GIMP_ITEM (drawable));

  if (GIMP_IS_LAYER (drawable))
    undo_desc = C_("undo-type", "Transform Layer");
  else if (GIMP_IS_CHANNEL (drawable))
    undo_desc = C_("undo-type", "Transform Channel");
  else
    return NULL;

  gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_PASTE, undo_desc);

  if (new_layer)
    {
      layer =
        gimp_layer_new_from_gegl_buffer (buffer, image,
                                         gimp_drawable_get_format_with_alpha (drawable),
                                         _("Transformation"),
                                         GIMP_OPACITY_OPAQUE,
                                         gimp_image_get_default_new_layer_mode (image),
                                         buffer_profile);

      gimp_item_set_offset (GIMP_ITEM (layer), offset_x, offset_y);

      floating_sel_attach (layer, drawable);

      drawable = GIMP_DRAWABLE (layer);
    }
  else
    {
      gimp_drawable_set_buffer_full (drawable, TRUE, NULL,
                                     buffer,
                                     offset_x, offset_y,
                                     TRUE);
    }

  gimp_image_undo_group_end (image);

  return drawable;
}
void
floating_sel_anchor (GimpLayer *layer)
{
  GimpImage    *image;
  GimpDrawable *drawable;
  GimpFilter   *filter = NULL;
  gint          off_x, off_y;
  gint          dr_off_x, dr_off_y;

  g_return_if_fail (GIMP_IS_LAYER (layer));
  g_return_if_fail (gimp_layer_is_floating_sel (layer));

  /* Don't let gimp_image_remove_layer free the layer while we still need it */
  g_object_ref (layer);

  image = gimp_item_get_image (GIMP_ITEM (layer));

  gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_FS_ANCHOR,
                               C_("undo-type", "Anchor Floating Selection"));

  drawable = gimp_layer_get_floating_sel_drawable (layer);

  gimp_item_get_offset (GIMP_ITEM (layer), &off_x, &off_y);
  gimp_item_get_offset (GIMP_ITEM (drawable), &dr_off_x, &dr_off_y);

  if (gimp_item_get_visible (GIMP_ITEM (layer)) &&
      gimp_rectangle_intersect (off_x, off_y,
                                gimp_item_get_width  (GIMP_ITEM (layer)),
                                gimp_item_get_height (GIMP_ITEM (layer)),
                                dr_off_x, dr_off_y,
                                gimp_item_get_width  (GIMP_ITEM (drawable)),
                                gimp_item_get_height (GIMP_ITEM (drawable)),
                                NULL, NULL, NULL, NULL))
    {
      filter = gimp_drawable_get_floating_sel_filter (drawable);
      g_object_ref (filter);
    }

  /*  first remove the filter, then merge it, or we will get warnings
   *  about already connected nodes
   */
  gimp_image_remove_layer (image, layer, TRUE, NULL);

  if (filter)
    {
      gimp_drawable_merge_filter (drawable, filter, NULL, NULL);
      g_object_unref (filter);
    }

  gimp_image_undo_group_end (image);

  /*  invalidate the boundaries  */
  gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (gimp_image_get_mask (image)));

  g_object_unref (layer);
}
示例#27
0
void
floating_sel_to_layer (GimpLayer *layer)
{
  GimpItem  *item;
  GimpImage *image;

  g_return_if_fail (GIMP_IS_LAYER (layer));
  g_return_if_fail (gimp_layer_is_floating_sel (layer));

  item = GIMP_ITEM (layer);

  if (! (image = gimp_item_get_image (item)))
    return;

  /*  Check if the floating layer belongs to a channel...  */
  if (GIMP_IS_CHANNEL (layer->fs.drawable))
    {
      gimp_message (image->gimp, NULL, GIMP_MESSAGE_WARNING,
                    _("Cannot create a new layer from the floating selection "
                      "because it belongs to a layer mask or channel."));
      return;
    }

  gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_FS_TO_LAYER,
                               _("Floating Selection to Layer"));

  /*  restore the contents of the drawable  */
  floating_sel_restore (layer,
                        item->offset_x,
                        item->offset_y,
                        item->width,
                        item->height);

  gimp_image_undo_push_fs_to_layer (image, NULL, layer);

  /*  clear the selection  */
  gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (layer));

  /*  Set pointers  */
  layer->fs.drawable   = NULL;
  image->floating_sel = NULL;

  gimp_item_set_visible (GIMP_ITEM (layer), TRUE, TRUE);
  gimp_layer_set_lock_alpha (layer, FALSE, TRUE);

  gimp_image_undo_group_end (image);

  gimp_object_name_changed (GIMP_OBJECT (layer));

  gimp_drawable_update (GIMP_DRAWABLE (layer),
                        0, 0,
                        GIMP_ITEM (layer)->width,
                        GIMP_ITEM (layer)->height);

  gimp_image_floating_selection_changed (image);
}
示例#28
0
void
gimp_paint_core_finish (GimpPaintCore *core,
                        GimpDrawable  *drawable,
                        gboolean       push_undo)
{
  GimpImage *image;

  g_return_if_fail (GIMP_IS_PAINT_CORE (core));
  g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
  g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)));

  if (core->stroke_buffer)
    {
      g_array_free (core->stroke_buffer, TRUE);
      core->stroke_buffer = NULL;
    }

  image = gimp_item_get_image (GIMP_ITEM (drawable));

  /*  Determine if any part of the image has been altered--
   *  if nothing has, then just return...
   */
  if ((core->x2 == core->x1) || (core->y2 == core->y1))
    {
      gimp_viewable_preview_thaw (GIMP_VIEWABLE (drawable));
      return;
    }

  if (push_undo)
    {
      gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_PAINT,
                                   core->undo_desc);

      GIMP_PAINT_CORE_GET_CLASS (core)->push_undo (core, image, NULL);

      gimp_drawable_push_undo (drawable, NULL,
                               core->x1, core->y1,
                               core->x2 - core->x1, core->y2 - core->y1,
                               core->undo_tiles,
                               TRUE);

      gimp_image_undo_group_end (image);
    }

  tile_manager_unref (core->undo_tiles);
  core->undo_tiles = NULL;

  if (core->saved_proj_tiles)
    {
      tile_manager_unref (core->saved_proj_tiles);
      core->saved_proj_tiles = NULL;
    }

  gimp_viewable_preview_thaw (GIMP_VIEWABLE (drawable));
}
示例#29
0
void
gimp_text_layer_set (GimpTextLayer *layer,
                     const gchar   *undo_desc,
                     const gchar   *first_property_name,
                     ...)
{
  GimpImage *image;
  GimpText  *text;
  va_list    var_args;

  g_return_if_fail (gimp_item_is_text_layer (GIMP_ITEM (layer)));
  g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (layer)));

  text = gimp_text_layer_get_text (layer);
  if (! text)
    return;

  image = gimp_item_get_image (GIMP_ITEM (layer));

  gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TEXT, undo_desc);

  g_object_freeze_notify (G_OBJECT (layer));

  if (layer->modified)
    {
      gimp_image_undo_push_text_layer_modified (image, NULL, layer);

      /*  pass copy_tiles = TRUE so we not only ref the tiles; after
       *  being a text layer again, undo doesn't care about the
       *  layer's pixels any longer because they are generated, so
       *  changing the text would happily overwrite the layer's
       *  pixels, changing the pixels on the undo stack too without
       *  any chance to ever undo again.
       */
      gimp_image_undo_push_drawable_mod (image, NULL,
                                         GIMP_DRAWABLE (layer), TRUE);
    }

  gimp_image_undo_push_text_layer (image, undo_desc, layer, NULL);

  va_start (var_args, first_property_name);

  g_object_set_valist (G_OBJECT (text), first_property_name, var_args);

  va_end (var_args);

  g_object_set (layer, "modified", FALSE, NULL);

  g_object_thaw_notify (G_OBJECT (layer));

  gimp_image_undo_group_end (image);
}
示例#30
0
static GimpBuffer *
gimp_edit_extract (GimpImage     *image,
                   GimpPickable  *pickable,
                   GimpContext   *context,
                   gboolean       cut_pixels,
                   GError       **error)
{
  GeglBuffer *buffer;
  gint        offset_x;
  gint        offset_y;

  if (cut_pixels)
    gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_CUT,
                                 C_("undo-type", "Cut"));

  /*  Cut/copy the mask portion from the image  */
  buffer = gimp_selection_extract (GIMP_SELECTION (gimp_image_get_mask (image)),
                                   pickable, context,
                                   cut_pixels, FALSE,
                                   &offset_x, &offset_y, error);

  if (cut_pixels)
    gimp_image_undo_group_end (image);

  if (buffer)
    {
      GimpBuffer *gimp_buffer;
      gdouble     res_x;
      gdouble     res_y;

      gimp_buffer = gimp_buffer_new (buffer, _("Global Buffer"),
                                     offset_x, offset_y, FALSE);
      g_object_unref (buffer);

      gimp_image_get_resolution (image, &res_x, &res_y);
      gimp_buffer_set_resolution (gimp_buffer, res_x, res_y);
      gimp_buffer_set_unit (gimp_buffer, gimp_image_get_unit (image));

      if (GIMP_IS_COLOR_MANAGED (pickable))
        {
          GimpColorProfile *profile =
            gimp_color_managed_get_color_profile (GIMP_COLOR_MANAGED (pickable));

          if (profile)
            gimp_buffer_set_color_profile (gimp_buffer, profile);
        }

      return gimp_buffer;
    }

  return NULL;
}