706 lines
19 KiB
Plaintext
706 lines
19 KiB
Plaintext
# PIKA - Photo and Image Kooker Application
|
|
# Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
|
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
|
|
|
|
sub edit_cut {
|
|
$blurb = 'Cut from the specified drawables.';
|
|
|
|
$help = <<'HELP';
|
|
If there is a selection in the image, then the area specified by the
|
|
selection is cut from the specified drawables and placed in an internal
|
|
PIKA edit buffer. It can subsequently be retrieved using the
|
|
pika_edit_paste() command. If there is no selection and only one
|
|
specified drawable, then the specified drawable will be removed and its
|
|
contents stored in the internal PIKA edit buffer.
|
|
This procedure will fail if the selected area lies completely outside
|
|
the bounds of the current drawables and there is nothing to cut from.
|
|
HELP
|
|
|
|
&std_pdb_misc;
|
|
|
|
@inargs = (
|
|
{ name => 'drawables', type => 'itemarray',
|
|
desc => 'The drawables to cut from',
|
|
no_validate => 1,
|
|
array => { name => 'num_drawables',
|
|
type => '1 <= int32',
|
|
desc => "The number of drawables" } }
|
|
);
|
|
|
|
@outargs = (
|
|
{ name => 'non_empty', type => 'boolean',
|
|
desc => 'TRUE if the cut was successful,
|
|
FALSE if there was nothing to copy from' }
|
|
);
|
|
|
|
%invoke = (
|
|
code => <<CODE
|
|
{
|
|
PikaImage *image = NULL;
|
|
GList *drawable_list = NULL;
|
|
gint i;
|
|
|
|
for (i = 0; i < num_drawables; i++)
|
|
{
|
|
if (! pika_pdb_item_is_attached (PIKA_ITEM (drawables[i]), NULL,
|
|
PIKA_PDB_ITEM_CONTENT, error) ||
|
|
pika_pdb_item_is_group (PIKA_ITEM (drawables[i]), error))
|
|
{
|
|
success = FALSE;
|
|
break;
|
|
}
|
|
|
|
if (! image)
|
|
{
|
|
image = pika_item_get_image (PIKA_ITEM (drawables[i]));
|
|
}
|
|
else if (image != pika_item_get_image (PIKA_ITEM (drawables[i])))
|
|
{
|
|
success = FALSE;
|
|
pika_message_literal (pika,
|
|
G_OBJECT (progress), PIKA_MESSAGE_WARNING,
|
|
_("All specified drawables must belong to the same image."));
|
|
break;
|
|
}
|
|
|
|
drawable_list = g_list_prepend (drawable_list, (gpointer) drawables[i]);
|
|
}
|
|
|
|
if (success && image)
|
|
{
|
|
GError *my_error = NULL;
|
|
|
|
non_empty = pika_edit_cut (image, drawable_list, context, &my_error) != NULL;
|
|
|
|
if (! non_empty)
|
|
{
|
|
pika_message_literal (pika,
|
|
G_OBJECT (progress), PIKA_MESSAGE_WARNING,
|
|
my_error->message);
|
|
g_clear_error (&my_error);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
success = FALSE;
|
|
}
|
|
g_list_free (drawable_list);
|
|
}
|
|
CODE
|
|
);
|
|
}
|
|
|
|
sub edit_copy {
|
|
$blurb = 'Copy from the specified drawables.';
|
|
|
|
$help = <<'HELP';
|
|
If there is a selection in the image, then the area specified by the
|
|
selection is copied from the specified drawables and placed in an
|
|
internal PIKA edit buffer. It can subsequently be retrieved using the
|
|
pika_edit_paste() command. If there is no selection, then the
|
|
specified drawables' contents will be stored in the internal PIKA edit
|
|
buffer. This procedure will fail if the selected area lies completely
|
|
outside the bounds of the current drawables and there is nothing to
|
|
copy from.
|
|
All the drawables must belong to the same image.
|
|
HELP
|
|
|
|
&std_pdb_misc;
|
|
|
|
@inargs = (
|
|
{ name => 'drawables', type => 'itemarray',
|
|
desc => 'Drawables to copy from',
|
|
no_validate => 1,
|
|
array => { name => 'num_drawables',
|
|
type => '1 <= int32',
|
|
desc => "The number of drawables to save" } },
|
|
);
|
|
|
|
@outargs = (
|
|
{ name => 'non_empty', type => 'boolean',
|
|
desc => 'TRUE if the cut was successful,
|
|
FALSE if there was nothing to copy from' }
|
|
);
|
|
|
|
%invoke = (
|
|
code => <<CODE
|
|
{
|
|
PikaImage *image = NULL;
|
|
GList *drawables_list = NULL;
|
|
gint i;
|
|
|
|
for (i = 0; i < num_drawables; i++)
|
|
{
|
|
if (! pika_pdb_item_is_attached (PIKA_ITEM (drawables[i]), NULL, 0, error))
|
|
{
|
|
success = FALSE;
|
|
break;
|
|
}
|
|
if (image == NULL)
|
|
{
|
|
image = pika_item_get_image (PIKA_ITEM (drawables[i]));
|
|
}
|
|
else if (image != pika_item_get_image (PIKA_ITEM (drawables[i])))
|
|
{
|
|
success = FALSE;
|
|
break;
|
|
}
|
|
drawables_list = g_list_prepend (drawables_list, (gpointer) drawables[i]);
|
|
}
|
|
|
|
if (success && num_drawables > 0)
|
|
{
|
|
GError *my_error = NULL;
|
|
|
|
non_empty = pika_edit_copy (image, drawables_list, context, &my_error) != NULL;
|
|
|
|
if (! non_empty)
|
|
{
|
|
pika_message_literal (pika,
|
|
G_OBJECT (progress), PIKA_MESSAGE_WARNING,
|
|
my_error->message);
|
|
g_clear_error (&my_error);
|
|
}
|
|
}
|
|
else
|
|
success = FALSE;
|
|
|
|
g_list_free (drawables_list);
|
|
}
|
|
CODE
|
|
);
|
|
}
|
|
|
|
sub edit_copy_visible {
|
|
$blurb = 'Copy from the projection.';
|
|
|
|
$help = <<'HELP';
|
|
If there is a selection in the image, then the area specified by the
|
|
selection is copied from the projection and placed in an internal PIKA
|
|
edit buffer. It can subsequently be retrieved using the
|
|
pika_edit_paste() command. If there is no selection, then the
|
|
projection's contents will be stored in the internal PIKA edit buffer.
|
|
HELP
|
|
|
|
&mitch_pdb_misc('2004', '2.2');
|
|
|
|
@inargs = (
|
|
{ name => 'image', type => 'image',
|
|
desc => "The image to copy from" }
|
|
);
|
|
|
|
@outargs = (
|
|
{ name => 'non_empty', type => 'boolean',
|
|
desc => 'TRUE if the copy was successful' }
|
|
);
|
|
|
|
%invoke = (
|
|
code => <<CODE
|
|
{
|
|
GError *my_error = NULL;
|
|
|
|
non_empty = pika_edit_copy_visible (image, context, &my_error) != NULL;
|
|
|
|
if (! non_empty)
|
|
{
|
|
pika_message_literal (pika,
|
|
G_OBJECT (progress), PIKA_MESSAGE_WARNING,
|
|
my_error->message);
|
|
g_clear_error (&my_error);
|
|
}
|
|
}
|
|
CODE
|
|
);
|
|
}
|
|
|
|
sub edit_paste {
|
|
$blurb = 'Paste buffer to the specified drawable.';
|
|
|
|
$help = <<'HELP';
|
|
This procedure pastes a copy of the internal PIKA edit buffer to the
|
|
specified drawable. The PIKA edit buffer will be empty unless a call
|
|
was previously made to either pika_edit_cut() or pika_edit_copy(). The
|
|
"paste_into" option specifies whether to clear the current image
|
|
selection, or to paste the buffer "behind" the selection. This allows
|
|
the selection to act as a mask for the pasted buffer. Anywhere that
|
|
the selection mask is non-zero, the pasted buffer will show
|
|
through.
|
|
The pasted data may be a floating selection when relevant, layers otherwise.
|
|
If the image has a floating selection at the time of pasting, the old
|
|
floating selection will be anchored to its drawable before the new
|
|
floating selection is added.
|
|
|
|
This procedure returns the new layers (floating or not). If the result
|
|
is a floating selection, it will already be attached to the specified
|
|
drawable, and a subsequent call to floating_sel_attach is not needed.
|
|
HELP
|
|
|
|
&std_pdb_misc;
|
|
|
|
@inargs = (
|
|
{ name => 'drawable', type => 'drawable',
|
|
desc => 'The drawable to paste to' },
|
|
{ name => 'paste_into', type => 'boolean',
|
|
desc => 'Clear selection, or paste behind it?' }
|
|
);
|
|
|
|
@outargs = (
|
|
{ name => 'layers', type => 'layerarray',
|
|
desc => 'The list of pasted layers.',
|
|
array => { name => 'num_layers',
|
|
desc => 'The newly pasted layers' } }
|
|
);
|
|
|
|
%invoke = (
|
|
code => <<CODE
|
|
{
|
|
PikaObject *paste = pika_get_clipboard_object (pika);
|
|
|
|
if (paste &&
|
|
pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
|
|
PIKA_PDB_ITEM_CONTENT, error) &&
|
|
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
|
|
{
|
|
GList *drawables = NULL;
|
|
GList *list;
|
|
gint i;
|
|
|
|
if (drawable != NULL)
|
|
drawables = g_list_prepend (drawables, drawable);
|
|
|
|
list = pika_edit_paste (pika_item_get_image (PIKA_ITEM (drawable)),
|
|
drawables, paste,
|
|
paste_into ?
|
|
PIKA_PASTE_TYPE_FLOATING_INTO :
|
|
PIKA_PASTE_TYPE_FLOATING,
|
|
context, FALSE,
|
|
-1, -1, -1, -1);
|
|
g_list_free (drawables);
|
|
|
|
if (! list)
|
|
success = FALSE;
|
|
|
|
num_layers = g_list_length (list);
|
|
layers = g_new (PikaLayer *, num_layers);
|
|
|
|
for (i = 0; i < num_layers; i++, list = g_list_next (list))
|
|
layers[i] = g_object_ref (list->data);
|
|
|
|
g_list_free (list);
|
|
}
|
|
else
|
|
success = FALSE;
|
|
}
|
|
CODE
|
|
);
|
|
}
|
|
|
|
sub edit_paste_as_new_image {
|
|
$blurb = 'Paste buffer to a new image.';
|
|
|
|
$help = <<'HELP';
|
|
This procedure pastes a copy of the internal PIKA edit buffer to a new
|
|
image. The PIKA edit buffer will be empty unless a call was
|
|
previously made to either pika_edit_cut() or pika_edit_copy(). This
|
|
procedure returns the new image or -1 if the edit buffer was empty.
|
|
HELP
|
|
|
|
&mitch_pdb_misc('2005', '2.10');
|
|
|
|
@outargs = (
|
|
{ name => 'image', type => 'image',
|
|
desc => 'The new image' }
|
|
);
|
|
%invoke = (
|
|
code => <<CODE
|
|
{
|
|
PikaObject *paste = pika_get_clipboard_object (pika);
|
|
|
|
if (paste)
|
|
{
|
|
image = pika_edit_paste_as_new_image (pika, paste, context);
|
|
|
|
if (! image)
|
|
success = FALSE;
|
|
}
|
|
}
|
|
CODE
|
|
);
|
|
}
|
|
|
|
sub edit_named_cut {
|
|
$blurb = 'Cut into a named buffer.';
|
|
|
|
$help = <<'HELP';
|
|
This procedure works like pika_edit_cut(), but additionally stores the
|
|
cut buffer into a named buffer that will stay available for later
|
|
pasting, regardless of any intermediate copy or cut operations.
|
|
HELP
|
|
|
|
&mitch_pdb_misc('2005', '2.4');
|
|
|
|
@inargs = (
|
|
{ name => 'drawables', type => 'itemarray',
|
|
desc => 'The drawables to cut from',
|
|
no_validate => 1,
|
|
array => { name => 'num_drawables',
|
|
type => '1 <= int32',
|
|
desc => "The number of drawables" } },
|
|
{ name => 'buffer_name', type => 'string', non_empty => 1,
|
|
desc => 'The name of the buffer to create' }
|
|
);
|
|
|
|
@outargs = (
|
|
{ name => 'real_name', type => 'string',
|
|
desc => 'The real name given to the buffer, or NULL if the
|
|
cut failed' }
|
|
);
|
|
|
|
%invoke = (
|
|
code => <<CODE
|
|
{
|
|
PikaImage *image = NULL;
|
|
GList *drawable_list = NULL;
|
|
gint i;
|
|
|
|
for (i = 0; i < num_drawables; i++)
|
|
{
|
|
if (! pika_pdb_item_is_attached (PIKA_ITEM (drawables[i]), NULL,
|
|
PIKA_PDB_ITEM_CONTENT, error) ||
|
|
pika_pdb_item_is_group (PIKA_ITEM (drawables[i]), error))
|
|
{
|
|
success = FALSE;
|
|
break;
|
|
}
|
|
|
|
if (! image)
|
|
{
|
|
image = pika_item_get_image (PIKA_ITEM (drawables[i]));
|
|
}
|
|
else if (image != pika_item_get_image (PIKA_ITEM (drawables[i])))
|
|
{
|
|
success = FALSE;
|
|
pika_message_literal (pika,
|
|
G_OBJECT (progress), PIKA_MESSAGE_WARNING,
|
|
_("All specified drawables must belong to the same image."));
|
|
break;
|
|
}
|
|
|
|
drawable_list = g_list_prepend (drawable_list, (gpointer) drawables[i]);
|
|
}
|
|
|
|
if (success && image)
|
|
{
|
|
GError *my_error = NULL;
|
|
|
|
real_name = (gchar *) pika_edit_named_cut (image, buffer_name,
|
|
drawable_list, context, &my_error);
|
|
|
|
if (real_name)
|
|
{
|
|
real_name = g_strdup (real_name);
|
|
}
|
|
else
|
|
{
|
|
pika_message_literal (pika,
|
|
G_OBJECT (progress), PIKA_MESSAGE_WARNING,
|
|
my_error->message);
|
|
g_clear_error (&my_error);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
success = FALSE;
|
|
}
|
|
g_list_free (drawable_list);
|
|
}
|
|
CODE
|
|
);
|
|
}
|
|
|
|
sub edit_named_copy {
|
|
$blurb = 'Copy into a named buffer.';
|
|
|
|
$help = <<'HELP';
|
|
This procedure works like pika_edit_copy(), but additionally stores the
|
|
copied buffer into a named buffer that will stay available for later
|
|
pasting, regardless of any intermediate copy or cut operations.
|
|
HELP
|
|
|
|
&mitch_pdb_misc('2005', '2.4');
|
|
|
|
@inargs = (
|
|
{ name => 'drawables', type => 'itemarray',
|
|
desc => 'The drawables to copy from',
|
|
no_validate => 1,
|
|
array => { name => 'num_drawables',
|
|
type => '1 <= int32',
|
|
desc => "The number of drawables" } },
|
|
{ name => 'buffer_name', type => 'string', non_empty => 1,
|
|
desc => 'The name of the buffer to create' }
|
|
);
|
|
|
|
@outargs = (
|
|
{ name => 'real_name', type => 'string',
|
|
desc => 'The real name given to the buffer, or NULL if the
|
|
copy failed' }
|
|
);
|
|
|
|
%invoke = (
|
|
code => <<CODE
|
|
{
|
|
PikaImage *image = NULL;
|
|
GList *drawable_list = NULL;
|
|
gint i;
|
|
|
|
for (i = 0; i < num_drawables; i++)
|
|
{
|
|
if (! pika_pdb_item_is_attached (PIKA_ITEM (drawables[i]), NULL,
|
|
0, error))
|
|
{
|
|
success = FALSE;
|
|
break;
|
|
}
|
|
|
|
if (! image)
|
|
{
|
|
image = pika_item_get_image (PIKA_ITEM (drawables[i]));
|
|
}
|
|
else if (image != pika_item_get_image (PIKA_ITEM (drawables[i])))
|
|
{
|
|
success = FALSE;
|
|
pika_message_literal (pika,
|
|
G_OBJECT (progress), PIKA_MESSAGE_WARNING,
|
|
_("All specified drawables must belong to the same image."));
|
|
break;
|
|
}
|
|
|
|
drawable_list = g_list_prepend (drawable_list, (gpointer) drawables[i]);
|
|
}
|
|
|
|
if (success && image)
|
|
{
|
|
GError *my_error = NULL;
|
|
|
|
real_name = (gchar *) pika_edit_named_copy (image, buffer_name,
|
|
drawable_list, context, &my_error);
|
|
|
|
if (real_name)
|
|
{
|
|
real_name = g_strdup (real_name);
|
|
}
|
|
else
|
|
{
|
|
pika_message_literal (pika,
|
|
G_OBJECT (progress), PIKA_MESSAGE_WARNING,
|
|
my_error->message);
|
|
g_clear_error (&my_error);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
success = FALSE;
|
|
}
|
|
g_list_free (drawable_list);
|
|
}
|
|
CODE
|
|
);
|
|
}
|
|
|
|
sub edit_named_copy_visible {
|
|
$blurb = 'Copy from the projection into a named buffer.';
|
|
|
|
$help = <<'HELP';
|
|
This procedure works like pika_edit_copy_visible(), but additionally
|
|
stores the copied buffer into a named buffer that will stay available
|
|
for later pasting, regardless of any intermediate copy or cut
|
|
operations.
|
|
HELP
|
|
|
|
&mitch_pdb_misc('2005', '2.4');
|
|
|
|
@inargs = (
|
|
{ name => 'image', type => 'image',
|
|
desc => "The image to copy from" },
|
|
{ name => 'buffer_name', type => 'string', non_empty => 1,
|
|
desc => 'The name of the buffer to create' }
|
|
);
|
|
|
|
@outargs = (
|
|
{ name => 'real_name', type => 'string',
|
|
desc => 'The real name given to the buffer, or NULL if the
|
|
copy failed' }
|
|
);
|
|
|
|
%invoke = (
|
|
code => <<CODE
|
|
{
|
|
GError *my_error = NULL;
|
|
|
|
real_name = (gchar *) pika_edit_named_copy_visible (image, buffer_name,
|
|
context, &my_error);
|
|
|
|
if (real_name)
|
|
{
|
|
real_name = g_strdup (real_name);
|
|
}
|
|
else
|
|
{
|
|
pika_message_literal (pika,
|
|
G_OBJECT (progress), PIKA_MESSAGE_WARNING,
|
|
my_error->message);
|
|
g_clear_error (&my_error);
|
|
}
|
|
}
|
|
CODE
|
|
);
|
|
}
|
|
|
|
sub edit_named_paste {
|
|
$blurb = 'Paste named buffer to the specified drawable.';
|
|
|
|
$help = <<'HELP';
|
|
This procedure works like pika_edit_paste() but pastes a named buffer
|
|
instead of the global buffer.
|
|
HELP
|
|
|
|
&mitch_pdb_misc('2005', '2.4');
|
|
|
|
@inargs = (
|
|
{ name => 'drawable', type => 'drawable',
|
|
desc => 'The drawable to paste to' },
|
|
{ name => 'buffer_name', type => 'string',
|
|
desc => 'The name of the buffer to paste' },
|
|
{ name => 'paste_into', type => 'boolean',
|
|
desc => 'Clear selection, or paste behind it?' }
|
|
);
|
|
|
|
@outargs = (
|
|
{ name => 'floating_sel', type => 'layer',
|
|
desc => 'The new floating selection' }
|
|
);
|
|
|
|
%invoke = (
|
|
code => <<CODE
|
|
{
|
|
PikaBuffer *buffer = pika_pdb_get_buffer (pika, buffer_name, error);
|
|
|
|
if (buffer &&
|
|
pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
|
|
PIKA_PDB_ITEM_CONTENT, error) &&
|
|
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
|
|
{
|
|
GList *drawables = NULL;
|
|
GList *layers;
|
|
|
|
if (drawable != NULL)
|
|
drawables = g_list_prepend (drawables, drawable);
|
|
|
|
layers = pika_edit_paste (pika_item_get_image (PIKA_ITEM (drawable)),
|
|
drawables, PIKA_OBJECT (buffer),
|
|
paste_into ?
|
|
PIKA_PASTE_TYPE_FLOATING_INTO :
|
|
PIKA_PASTE_TYPE_FLOATING,
|
|
context, FALSE,
|
|
-1, -1, -1, -1);
|
|
g_list_free (drawables);
|
|
|
|
if (! layers)
|
|
success = FALSE;
|
|
else
|
|
floating_sel = layers->data;
|
|
|
|
g_list_free (layers);
|
|
}
|
|
else
|
|
success = FALSE;
|
|
}
|
|
CODE
|
|
)
|
|
}
|
|
|
|
sub edit_named_paste_as_new_image {
|
|
$blurb = 'Paste named buffer to a new image.';
|
|
|
|
$help = <<'HELP';
|
|
This procedure works like pika_edit_paste_as_new_image() but pastes a
|
|
named buffer instead of the global buffer.
|
|
HELP
|
|
|
|
&mitch_pdb_misc('2005', '2.10');
|
|
|
|
@inargs = (
|
|
{ name => 'buffer_name', type => 'string',
|
|
desc => 'The name of the buffer to paste' }
|
|
);
|
|
|
|
@outargs = (
|
|
{ name => 'image', type => 'image',
|
|
desc => 'The new image' }
|
|
);
|
|
|
|
%invoke = (
|
|
code => <<CODE
|
|
{
|
|
PikaBuffer *buffer = pika_pdb_get_buffer (pika, buffer_name, error);
|
|
|
|
if (buffer)
|
|
{
|
|
image = pika_edit_paste_as_new_image (pika, PIKA_OBJECT (buffer), context);
|
|
|
|
if (! image)
|
|
success = FALSE;
|
|
}
|
|
else
|
|
success = FALSE;
|
|
}
|
|
CODE
|
|
);
|
|
}
|
|
|
|
|
|
@headers = qw("libpikaconfig/pikaconfig.h"
|
|
"core/pika.h"
|
|
"core/pika-edit.h"
|
|
"core/pikadrawable-edit.h"
|
|
"core/pikabuffer.h"
|
|
"core/pikaimage.h"
|
|
"core/pikaprogress.h"
|
|
"pikapdb-utils.h"
|
|
"pikapdbcontext.h"
|
|
"pika-intl.h");
|
|
|
|
@procs = qw(edit_cut
|
|
edit_copy
|
|
edit_copy_visible
|
|
edit_paste
|
|
edit_paste_as_new_image
|
|
edit_named_cut
|
|
edit_named_copy
|
|
edit_named_copy_visible
|
|
edit_named_paste
|
|
edit_named_paste_as_new_image);
|
|
|
|
%exports = (app => [@procs], lib => [@procs]);
|
|
|
|
$desc = 'Edit procedures';
|
|
$doc_title = 'pikaedit';
|
|
$doc_short_desc = 'Edit menu functions (cut, copy, paste, clear, etc.)';
|
|
$doc_long_desc = 'Edit menu functions (cut, copy, paste, clear, etc.)';
|
|
|
|
1;
|