As far as plug-in API is concerned, at least the calling API, order of arguments
when calling PDB procedures doesn't matter anymore.
Order still matters for creating procedures with standard arguments (for
instance, "run-mode" is first, then image, or file, drawables or whatnot,
depending on the subtype of procedure), but not for calling with libgimp.
Concretely in this commit:
- gimp_pdb_run_procedure_argv() was removed as it's intrinsically order-based.
- gimp_pdb_run_procedure() and gimp_pdb_run_procedure_valist() stay but their
semantic changes. Instead of an ordered list of (type, value) couple, it's now
an unordered list of (name, type, value) triplets. This way, you can also
ignore as many args as you want if you intend to keep them default. For
instance, say you have a procedure with 20 args and you only want to change
the last one and keep the 19 first with default values: while you used to have
to write down all 20 args annoyingly, now you can just list the only arg you
care about.
There are 2 important consequences here:
1. Calling PDB procedures becomes much more semantic, which means scripts with
PDB calls are simpler (smaller list of arguments) and easier to read (when
you had 5 int arguments in a row, you couldn't know what they refer to,
except by always checking the PDB source; now you'll have associated names,
such as "width", "height" and so on) hence maintain.
2. We will have the ability to add arguments and even order the new arguments in
middle of existing arguments without breaking compatibility. The only thing
which will matter will be that default values of new arguments will have to
behave like when the arg didn't exist. This way, existing scripts will not be
broken. This will avoid us having to always create variants of PDB procedure
(like original "file-bla-save", then variant "file-bla-save-2" and so on)
each time we add arguments.
Note: gimp_pdb_run_procedure_array() was not removed yet because it's currently
used by the PDB. To be followed.
Similar to commit 6905b0bbef for "file-pat-save-internal". For interactive
usage, nothing is changed, but for non-interactive ones, we can now choose a
list of drawables to export.
Pending more changes, relative to the discussion in #7370.
Since now the name of arguments will become more important, over order, let's
name the first parameter "run-mode" even in cases when this is a dummy argument
(most often the case when a procedure always acts the same, whether interactive
or not). I keep the mention of the parameter being useless in the nick and blurb
strings, as it's useful information. But let's keep using our "standard" arg
name "run-mode" for this first argument.
There were a lot of incertainty of what should happen when we copy layers being
descendant of each other (i.e. when you select a group layer and some of its
children), then when you paste such data. So we sat down with Aryeom and tried
to come up with some consistent behavior which is somewhat expectable, but also
which would allow the most use-case.
Otherwise it was making very weird result when pasting the data, duplicating
some layers and whatnot, which was obviously a buggy behavior and never the
expected result.
We decided that if you select one leaf item, then even if you also selected a
parent item, it would be as though the parent was not selected. This is very
often what you expect anyway when you select a whole bunch of layers and would
work well if, say, you shift-click over many layers in sub-groups. Then you
wouldn't have to manually ctrl-click to unselect every group.
Then what if you were instead expecting to copy many groups? Then you could
shift-click the group arrow, closing all same-level groups. Once they are all
closed, you can shift-click the groups to only select group layers, not their
contents.
This way, both use cases are still quite doable easily with this default choice.
There is not only the ARCHIVE_OK and ARCHIVE_FATAL cases. There are also
ARCHIVE_WARN cases which should not break the installation (I think?). Since I
still want to pass the warning over to extension developers, I am printing it to
stderr.
As an additional fix, prevent such a warning when installing an extension over
itself. In such case, it looks like the archive_entry_size() would be 0, which
was triggering some "Writing to Empty File" warning.
When we try to export a grayscale image with layers with negative offsets
to a GIH brush GIMP crashes without producing any crashlog.
Running in GDB showed us that there is heap corruption caused by incorrect
computation of buffer sizes because of the negative offsets.
In file_gih_image_to_pipe there is a comment that offsets are assumed
positive, but no checking is done whether that is correct.
Let's add some checks, set offset to 0 if negative and adjust width and
height accordingly.
… multiple drawables as parameter.
Previous commit 7bb892f3 was "making it work" by making the API
inconsistent and also only using the first drawable, which is making the
logics meaningless.
Instead accept multiple drawables, and export only the selected drawable
(when alone) or the merged-down image containing only the selected
drawables (when many).
Note that in current implementation, this is not useful from GUI calls
because the fully merged image is always exported when run interactively
or with last vals (i.e. from the GUI) because gimp_export_image()
flattens the image. So this change would only work when called
non-interactively from other plug-ins. In such a case, multi-layer
images do no longer return an error and whatever items are selected
would change the export result.
See also #7370 for a discussion about how to handle the selected items
during export (because currently the `drawables` parameter of
GimpSaveProcedure's run function is clearly a mostly bogus parameter).
This commit just changes our saving API (i.e. the GimpSaveProcedure
class) to take an array of drawables as argument instead of a single
drawable.
It actually doesn't matter much for exporting as the whole API seems
more or less bogus there and all formats plug-ins mostly care only
whether they will merge/flatten all visible layers (the selected ones
don't really matter) or if the format supports layers of some sort. It
may be worth later strengthening a bit this whole logics, and maybe
allow partial exports for instance.
As for saving, it was not even looking at the passed GimpDrawable either
and was simply re-querying the active layer anyway.
Note that I don't implement the multi-selection saving in XCF yet in
this commit. I only updated the API. The reason is that the current
commit won't be backportable to gimp-2-10 because it is an API break. On
the other hand, the code to save multi-selection can still be backported
even though the save() API will only pass a single drawable (as I said
anyway, this argument was mostly bogus until now, hence it doesn't
matter much for 2.10 logics).
and use the new feature of saving the last config in an image
parasite.
In app/file-data/fie-data-gbr.c, manually construct the same parasite
when loading a brush, so its spacing and description are stored in the
image.
This replaces the "gimp-brush-name" parasite which is now obsolete.
and in an attack of madness, changes almost all file plug-in
code to use GFile instead of filenames, which means passing
the GFile down to the bottom and get its filename at the very
end where it's actually needed.
It's an ancient concept from ancient times when we didn't have URIs
and only filenames (not to speak of GFile), and actually even from
before the ancient time before that ancient time when we first had
ones and zeros, and only had zeros.
and call it gimp_pdb_set_proc_icon(). Change icon registration code in
libgimp/ and app/ so it's now possible to register icons for temporary
procedures.
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/.
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.
on behalf of plug-in authors who have no style or can't type.
Instead, simply reject non-canonical procedure names and remove all
code that keeps aroud the original non-canonical shit just to pass it
back to the plug-in.
- Change the wire protocol's GPProcInstall to transmit the entire
information needed for constructing all GParamSpecs we use, don't
use GimpPDBArgType in GPProcInstall but an enum private to the wire
protocol plus the GParamSpec's GType name. Bump the wire protocol
version.
- Add gimpgpparamspecs.[ch] in both app/plug-in/ and libgimp/ which
take care of converting between GPParamDef and GParamSpec. They
share code as far as possible.
- Change pluginrc writing and parsing to re-use GPParamDef and the
utility functions from gimpgpparamspecs.
- Remove gimp_pdb_compat_param_spec() from app/pdb/gimp-pdb-compat.[ch],
the entire core uses proper GParamSpecs from the wire protocol now,
the whole file will follow down the drain once we use a GValue
representation on the wire too.
- In gimp_plug_in_handle_proc_install(), change the "run-mode"
parameter to a GParamSpecEnum(GIMP_TYPE_RUN_MODE) (if it is not
already an enum). and change all places in app/ to treat it as an
enum value.
- plug-ins: fix cml-explorer to register correctly, a typo in
"run-mode" was never noticed until now.
- Add gimpgpcompat.[ch] in libgimp to deal with all the transforms
between old-style wire communication and using GParamSpec and
GValue, it contains some functions that are subject to change or
even removal in the next steps.
- Change the libgimp GimpProcedure and GimpPlugIn in many ways to be
able to actually install procedures the new way.
- plug-ins: change goat-exercise to completely use the new GimpPlugIn
and GimpProcedure API, look here to see how plug-ins will look in
the future, of course subject to change until this is finished.
- Next: changing GPParam to transmit all information about a GValue.
Add "gboolean push_undo" parameters to gimp_image_parasite_attach()
and _detach() and use the API also from undo, instead of implementing
attaching/removing manually and forgetting about the signals.
Fixes updating of the image properties color profile page.
This completes my earlier commit 406279e4ef.
Extension installation is not about just decompressing a file in the
right folder. We must also make the extension manager and the GUI aware
of this newly available extension.
File extension (.gex) may still change if anything better is proposed.
This format is currently just a compressed archive containing the
extension data (plug-in, brushes or whatever) and the metadata file.
For now, opening such file will simply install it as a new extension,
keeping all file permissions and structure. Of course in the future, it
will have to trigger a confirmation dialog.
Currently the compression used is zip, which is just a first draft. This
is not a decisive choice as well. We could use some tarball compressed
in whatever other compression algorithm. I use libarchive as a new
dependency to support unarchiving as it seems to be a common library
(and since it is already used by AppStream-glib anyway, this doesn't add
any actual dependency, just make it direct).
but only the actual saving code, not the export magic and dialog.
Add new internal procedure file-pat-save-internal which is not
registered as a file procedure and always works non-interactively on
the passed arguments and only saves the passed drawable. Use the new
internal procedure from the file-pat-save code and remove all file
writing code from the plug-in.
This way all pattern file writing code duplication is killed, while
the whole export mechanism is completely unchanged.
We currently have brush and pattern I/O code in both the core and
plug-ins. This commit starts removing plug-in code in favor of having
one copy of the code in the core, much like XCF loading and saving is
implemented.
Add app/file-data/ module with file procedure registering code, for
now just with an implementation of file-gbr-load.
Remove the file-gbr-load code from the file-gbr plug-in.