It is a nearly full port. Some things would still need to be updated
(like deprecated use of GtkTable or gtk_range_set_update_policy()
removed), and other stuff need to be taken care of in GIMP API first.
But the core of the feature is there.
Maybe should we have IMAGE_ARRAY types as we still have to pass image
IDs when we pass more than one image between core and plug-in. And even
maybe have alternate LIST types to ARRAY ones, so that we can pass GList
through rather than one array parameter + one length parameter.
Anyway this port still return just old style array of image IDs + array
length as int32.
Turn all ID param specs into object param specs (e.g. GimpParamImageID
becomes GimpParamImage) and convert between IDs and objects in
gimpgpparams.c directly above the the wire protocol, so all of app/,
libgimp/ and plug-ins/ can deal directly with objects down to the
lowest level and not care about IDs.
Use the actual object param specs for procedure arguments and return
values again instead of a plain g_param_spec_object() and bring back
the none_ok parameter.
This implies changing the PDB type checking functions to work on pure
integers instead of IDs (one can't check whether object creation is
possible if performing that check requires the object to already
exist).
For example gimp_foo_is_valid() becomes gimp_foo_id_is_valid() and is
not involved in automatic object creation magic at the protocol
level. Added wrappers which still say gimp_foo_is_valid() and take the
respective objects.
Adapted all code, and it all becomes nicer and less convoluted, even
the generated PDB wrappers in app/ and libgimp/.
Note: there were 2 additional arguments which were totally unused in the
existing implementation. So I commented them out. Anyone is welcome to
actually implement their usage.
Remove the separate "advanced" procedure. With GParamSpec default
values the differance between normal and advanced is just
non-interactive vs. interactive.
There are 2 TODOs to take care of here. First, there is no GUI yet for
the interactive mode which will just use the default values.
Second, the color argument is not working yet because I had issues
passing a GimpRGB as argument (ideally I should create a GimpParamRGB
with gimp_param_spec_rgb(), but since we still have the pygobject bugs
about manipulating GParamSpec data directly, I can't).
Anyway it works with default values, which is already a good first step.
:-)
We now have both variants, one returning a GList, and another
returning an array. Turns out that while a list is often nicer,
sometimes a random-access array really keeps the code much simpler.
Adapt all plug-ins, and clean up a bit (like use g_list_reverse() once
instead of iterating the list reversed).
Apart from porting, only code logics change is the whole
encode()/decode() code because it created a string vs bytes mess and the
zipfile API apparently didn't like to deal with bytes, even though the
docs say otherwise.
It's hard to test on my UTF-8 system, so please anyone working with
non-UTF-8 paths, we welcome reports if ORA load/save does not work
properly.
Other than this, load, save and load_thumb were all tested and working
properly so far.
The JS and Python 3 had to be ported to the new GimpImageProcedure API.
The Lua one was still using the old ID API hence was broken. Also not
sure why run_mode enum has become a string in Lua with the new
GimpImageProcedure API (probably some automatic conversion happening
during the C to Lua binding?), but well… it works like that, so what.
Sync also the late changes from the C goat exercise, like for instance
not returning an error when selection is empty as well as keeping the
order of calls to be the same across the 4 supported demo scripts.
This fixes:
> warning: source file 'images/imagemap-icon-images.c' is in a subdirectory,
> but option 'subdir-objects' is disabled
And similar warnings.
This means that images' ownership is not given to caller in particular.
libgimp will now keep a reference of all GimpImage-s it creates and
return this same reference if called again. It also means that you can
now compare images by pointer comparison (as 2 GimpImage objects
representing the same image ID will be equal).
Obviously as a side effect, gimp_image_list() is changed to (transfer
container) as you must only free the container now, not the elements.
Also various other functions creating new images are now (transfer none)
too.
Long-time plug-ins will have to be taken in consideration in a further
step (we currently never free GimpImage for destroyed images in
particular).
PyGObject seems to have at least 3 syntaxes to create object properties.
Though the one I used previously was apparently the recommended syntax,
it was clearly a bit messy and not clear. This alternative syntax ends
up much more compact, really look alike the C-style, which is a good
thing and is very visual. From what I can see, we should also override
the get|set_property() methods, but since we are not going to actually
set any value (this is only a workaround to make a GParamSpec), it seems
to work fine without.
You'll notice that with the new class when used together with the new
GimpPlugIn API, it is not needed to allocate/destroy anymore the
GimpImage/GimpDrawable. These can be directly the parameters.
It's just too weird to be public. Remove its properties from the wire
protocol and from pluginrc. Instead, have all GParamSpecs' flags on
the wire and in pluginrc, so we can use stuff like
GIMP_PARAM_NO_VALIDATE.
Port the remaining few places to GIMP_PROC_ARG_STRING().
I'm sure something is broken now wrt UTF-8 validation,
will add tighter checks in the next commit.
And always pass URIs to all file procedures, the ones what didn't
register as "handles remove" will only ever get local file:// URIs.
Change all file plug-ins (also legacy ones) to expect URIs instead
of filenames, and convert to local paths in the plug-in.
The wire protocol should now be almost 100% clean of non-UTF-8 strings.
All the GimpImageProcedure must remap the order of their additional
arguments (i.e. subtracts 3).
This fixes the other plug-ins changed in commit 15019fef52 which had
such additional arguments.
I got a 'Invalid cross-device link' error (errno 18) on my system. Let's
add some redundancy and try g_file_move() if g_rename() failed.
This at least fixed my case.
This commit removes all save procedures except gimp-png-save with all
parameters, and kills the default value handling procedures.
Default handling is now broken for NONINTERACTIVE use, but we will
handle this much better and consistent for all save procedures inside
GimpSaveProcedure
So procedure:new_return_values() just seems broken with LGI. It doesn't
even look like it reaches the C code.
Anyway we can also just reconstruct the GimpValueArray, which works
fine. We now have official support for Lua plug-ins!
It is working fine except that it crashes at the end when running
procedure:new_return_values(). I have not understood why yet, but it may
be a bug in lua LGI. Maybe we'll have to create the returned
GimpValueArray by hand in Lua.
Also the dialog does not show the source yet.
This is not installed yet (and lua interpreter is not checked at
configure) because of these issues which I will have to figure out. In
the meantime, I commit this work-in-progress.
So it seems that whatever is in _SCRIPTS is not in the distribution by
default (I suppose the reason is that even scripts can be generated). So
let's add the non-generated scripts to EXTRA_DIST.
Something during the port to gimp-drawable-edit (commit
233ac80de1) broke add-bevel.scm when
the thickness is high enough for the selection to become empty.
Add an explicit check for a selection while constructing the bump-
map layer.
Implementing a shiny new GimpFileProcedure doesn't mean the libraries
we use to load/save files are automatically capable of handling remote
files, so we still need this flag.
As discussed on IRC, I am not sure if really this is needed, since
theoretically we now have support for a whole bunch of languages without
doing anything (languages supported by GObject Introspection) and we are
not going to check for all of them.
Yet since now we install one JS plug-in, let's still do a quick check.
We'll see later if we want to change how we handle supported script
languages.
The file path was already the same as ARGV first argument (i.e.
System.programInvocationName as I added this myself!). Why did I even
bothered with this annoying trick!
This makes the code much simpler, which is better for demo code.
Right now it is not working, always because of the same bug about not
being able to create GParamSpec (pygobject#227). As a consequence, I
tried a workaround by creating object properties and using their spec
instead. But it turns out that in pygobject, I cannot create random
properties for custom types (well I could for boxed types or GObject
subclasses, not for GimpImageID or GimpDrawableID). Cf. pygobject#357.
So I am stuck again.
Anyway I still push this demo file which would just work as it is, if we
coult at least got the image/drawable ID.
I comment out the Makefile.am part for now until we can get the issues
sorted out.
because they are deprecated.
Change GIMP_ICON_TYPE_INLINE_PIXBUF to GIMP_ICON_TYPE_PIXBUF and the
libgimp API to (icon-name, GdkPixbuf, GFile). Use the file's uri and a
PNG blob of the pixbuf to pass around on the wire and for storage in
pluginrc.
Only missing parts are:
- localization.
- help function and id unset.
- gimp_procedure_set_icon() should probably be reviewed for proper
introspection.
- Finally there is a String() conversion which raises a warning, but I
couldn't find the proper standard replacement code.
Other than this, the goat-exercise was totally reproduced in JavaScript.
This just adds a dialog before running the actual processing of data.
- it also shows what the run-mode is for;
- the purpose of the plug-in becomes explicit (plug-in creation
documentation);
- it shows some GTK+ code too.
- last but not least, the code is actually shown for people to study,
with a button to access the last version of the code on gitlab.
This makes the plug-in a lot more useful and understandable this way.
Other exercise plug-ins in other languages will have to do the same
thing.
It is not installed yet, I am just committing my first version. Further
version should look like goat-exercise as an example of what must be
done in javascript.
Also the plug-in stopped working with one of the recent libgimp commits,
without any change in the plug-in code. This will need to be
investigated before installing.
We will fill this up with more examples of plug-ins in other languages.
Also we will improve a bit the examples to redirect people to source
code so that they understand what these plug-ins are.
1/ First I realize we were still using AM_PATH_PYTHON() and not
AM_PATH_PYTHON3().
2/ We don't need to check anymore for pygtk, pycairo, nor do we need
Python headers. Everything is now taken care of by GObject
Introspection and we have nothing else to build GIMP-side.
3/ Change --enable-python into --with-python. We don't actually build
anything now. There is no Python support to enable or disable
anymore. We simply install Python plug-ins or not. The 3 values are
"yes" (default, configure breaks if a Python 3 interpreter is not
found), "no" (Python plug-ins are not installed, not recommended) and
"force" (install Python plug-ins anyway even if an interpreter is not
found; this can be useful especially for cross-compilation since
Python is not useful at build-time anymore).
Note that --with-python=force, if an interpreter is not found, the
file `pygimp.interp` won't be installed. This is not a problem at all
if the interpreter can be found at runtime the standard way.
Otherwise packagers should add themselves a pygimp.interp file with
the known interpreter path.
Oups, I left the plug-in as Python 2. This was still a good
proof-of-concept that GIMP 3 will support as well Python 2 and Python 3
(even though Python 2 is end-of-life soon anyway).
This first version will just offset by 1 in interactive mode, by
default. The GIMP 2 version used to have a GUI, but it was not created
by the plug-in itself. I am guessing that maybe our Python wrapper used
to create GUI by default.
If so, this will have to change. Python plug-ins will be responsible of
their own GUI, just like C plug-ins.
Older palette-to-gradient used to have a palette argument. Bring it
back. The logics is that if the string is empty or None, the procedure
will use the currently selected palette. Otherwise it will try to
transform the named palette into a gradient and will fail with an error
if this palette does not exist.
We have code for this in gimp_proc_browser_dialog_new(), but it cannot
be moved in the object init() because this is a construction-time only
property. So this needs to be passed from the python call too.
As mentioned in issue #1777, exporting non-animated WebP images was
only keeping the current layer.
Mimick file-gif-save.c: display the encoding settings pop-up earlier
so that gimp_export_image() can merge the layers unless "As Animation"
is enabled. Call gimp_image_get_layers() directly in save_image() in
case the layers were merged (for clarity because layers are used only
for animations).
Basically this commit makes sure that all return values that are marked
as "Returns:" also have a `(nullable)` annotation if it is mentioned on
the same line that NULL can also be returned.
This will prevent a few problems in GObject-introspection.