Nothing was really clearly specified until now, which was kinda equivalent to
the string being in the OS encoding as used by GLib. Since this string will
usually be statically hardcoded in code (and not extracted from system), it's
just much easier to request UTF-8 for this specific case.
I hesitated a lot whether we should just drop the whole localization of
plug-ins' label and description (blurb) within the core. Actually the
commit messages I wrote a few days ago were moving towards this logic.
It really looks to me like plug-in localization can happen fully within
plug-in themselves. As far as I can see, the only advantage which the
current logic has theoretically is that if we needed, we have access to
both the original strings and their translations (e.g. it could be
useful for text search). Nevertheless I am not sure if we will ever make
use of this, and this is limited cases as all filters turned GEGL ops
don't have such ability anyway.
Nevertheless since previous contributors clearly put quite a lot of work
on this code of localizing the plug-in's label and description within
the main binary, I want to give myself a little more time to think and
study the whole thing because doing anything rash.
In the meantime, what changes is that by default now, a plug-in without
a local gettext catalog is simply not localized. In particular, the core
process doesn't try to localize it using the default catalog, a.k.a.
GETTEXT_PACKAGE"-std-plug-ins" ("gimp30-std-plug-ins"). It just doesn't
make sense and the worst which could happen would be to get unexpected
and wrong translations.
Now by default, plug-ins will try to find a catalog in their main
folder, named as this folder. If it fails to find it, a message is
printed to stderr and localization is disabled (rather than falling back
to a default catalog). It is up to plug-in developers to either install
a catalog, or implement set_i18n() to give the right catalog, folder, or
disable localization with gettext, as handled by libgimp.
Clearly the old logic for localizing plug-ins was "core plug-ins first":
* In particular, we were defaulting to the "gimp*-std-plugins" domain,
asking plug-ins to override it with libgimp function
gimp_plug_in_set_translation_domain(). Obviously any third-party
plug-in would have to call this function since their strings are most
likely not the same as GIMP core plug-ins.
* Moreover this was only for the localization of menu items, which means
we had to duplicate work anyway (simplified for core C plug-ins only
with the INIT_I18N macro).
* Also plug-ins had to manage the location of the Gettext catalogs,
which is simpler for core plug-ins with gimp_locale_directory(), but
more annoying for third-party plug-ins which can be installed
basically anywhere (assuming their message catalogs are in their
directory, not centrally installed on the system, especially for
non-UNIX-like packages, with relocatable GIMP, no central package
system and so on).
* Finally in this logic of centrally installed catalogs, we were
requesting that the domain name is unique, which makes sense in a
Linux world with well maintained packages to avoid name clashes, not
in a world with people making plug-ins without knowing too much what's
done by their neighbour.
So now the new logic is:
- By default, GIMP will search for a folder called locale/ on the same
level as the plug-in executable. The Gettext domain will be the name
of the executable folder (and it doesn't matter too much if it's not
unique in such configuration).
- This can be disabled by overriding set_i18n() to NULL or
reimplementing it. All our core plug-ins will do this since they will
continue to use the centrally installed "gimp*-std-plugins" domain (or
"gimp*-python" for Python plug-ins).
- When not disabled while the folder is not available, warning messages
will be outputted to stderr, so that plug-in developers can easily
detect what is missing and how to handle it (and how to easily support
internationalization of their plug-in).
- gimp_plug_in_set_translation_domain() is removed and a future commit
is going to get rid of _gimp_plug_in_domain_register() because we are
going to get rid of the core-side localization of menu items (with
logic explained in the upcoming commit).
The initial attempt of this commit was to remove the `GtkAction` usage,
but grew a bit wider than that. The following happened:
* The dialog became a proper GObject, rather than being a big chunk of
static variables that were hopefully initialized before you used them.
* The dialog now uses `GAction`s to implement actions, and converted
some signal handlers to actions as well.
* The plug-in run procedure now uses `GtkApplication`. This is one hand
necessary to be able to set accelerators for actions, but on the other
hand is more future-proof, as GTK4 removes `gtk_main()`
gtk-doc has been slowly dying for the past few years; with gi-docgen we
have a nice successor.
This also makes sure the C documentation also uses the GIR file, which
in turn means faster build times (since all the C code doesn't have to
be parsed and recompiled again), and has a clear dependency graph.
See the [gi-docgen tutorial] for more info on how the system works.
[gi-docgen tutorial]: https://gnome.pages.gitlab.gnome.org/gi-docgen/tutorial.html
We heavily rely on GError in libgimp to retrieve plug-in error messages.
In a lot of our code, we just use domain=0 for g_set_error*() functions
and alike, but this is actually forbidden and results in GLib warnings.
Some plug-ins instead create their own domain, other use G_FILE_ERROR
nearly everywhere, even in some cases where the choice is really
questionable. Since anyway this is mostly useful for passing the error
message through, it is much nicer to provide a generic domain
GIMP_PLUG_IN_ERROR, which can be used by all plug-ins when they don't
want to bother with the error domain.
Mention and guarantee the order of procedure registration (see
previous thumbnail loader commit). Remove duplicate docs from the
GimpPlugIn class comments that are needed for introspection, it's too
cumbersome to keep two identical texts in sync, and the removed text
is used nowhere.
GTK-docs needs the struct member documentations in the main struct
comment. So let's get this back, while keeping the proper GI
introspection for each method this time.
As discussed with Mitch.
Commit 005143a43e completely broke all the
introspected plug-ins, so I am reverting only the relevant changes.
If some things need to be improved in this part of the docs, let's do it
without breaking major stuff.
In particular: abstract methods must be properly documented (with
parameters, return values and annotations) like any function, and must
be named Class::method, e.g. GimpPlugInClass::query_procedures.
Other we break GObject Introspection, i.e. we break all plug-ins using
these.
Move the legacy loop code to gimplegacy.c. Also remove some more stuff
from gimp.c, old and new are now completely separate apart from one
glitch which wll go next...
The way currently implemented plug-ins are, they are already
NULL-terminating the returned arrays. Since a procedure name cannot be
NULL itself by definition, defining the array length by a terminal NULL
is enough. There is no need to also add a n_procedures parameters which
is just one more possible bug source, even more as we were already
expecting the NULL termination by using g_strfreev() to free the memory.
Anyway a length parameter does not bring any advantage since a plug-in
can still "lie" about its array size (just as it can forget to
NULL-terminate it) and when this happens, the plug-in will segfault.
That's it, it's just a plug-in programming error.
Last but not least, some binding seem to have issues with returned array
setting an (out) parameter as the length. In pygobject at least, the
length parameter doesn't disappear and we end up with this ugly
signature:
> In [3]: Gimp.PlugIn.do_query_procedures.__doc__
> Out[3]: 'query_procedures(self) -> list, n_procedures:int'
See bug report pygobject#352.
To avoid this, we should either set both the array and the length as
(out) parameters or just set the returned array as NULL-terminated
(which is the solution I chose).
Start copying all the actual wire communication to GimpPlugIn, and
move the legacy versions to gimplegacy.c.
This implies having the entire protocol code twice, but without any
if(PLUG_IN) { plug_in_stuff(); } else { legacy_stuff(); }
At the moment it is a wild mixture of old and new, but when finished
the wire code in gimplegacy.c will be entirely separate from the wire
code in GimpPlugIn, which will make it easy to g_assert() that only
one API is used by a plug-in.
The GimpPlugInClass:: prefix is important, otherwise GObject
Introspection tools don't take these docs/annotations into account (and
most methods ended up not introspected at all with annotations).
Also fix some typos/sillinesses (missing colon; useless (out) on Returns
value and useless (element-type) for easily scannable type).
- We were leaking the result of query_procedures(). At least as far as
the example port (help plug-in) shows, it returns a newly allocated
array of strings, NULL-terminated. This needs to be freed by the
calling code.
- Add documentations on GimpPlugIn virtual methods so that people know
what to do with them, and what kind of data to return (like
NULL-terminated array of procedure names for simple freeing).
- Fix _gimp_plug_in_init() which was registering the query procedures
instead of the init ones. For this, I added a `init` boolean parameter
to gimp_plug_in_register().
- Finally check the return value of gimp_plug_in_create_procedure(). It
is possible that a plug-in not properly implemented returns NULL and
we want to avoid the CRITICAL. Still output a warning as this is
likely a plug-in development bug.
- 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.
Mostly the same code as GimpProcedure in app/pdb/.
Move the "run" function to GimpProcedure. Add API to GimpPlugIn to
list and create procedures, and always keep a list of the plug-ins
procedures around. Still only using the old params and return_vals.
The new way of doing plug-ins:
- subclass GimpPlugIn in your plug-in
- implement its query() and run() methods, run() will move to a
new GimpProcedure class soon
- instead of MAIN(), say GIMP_MAIN(YOUR_PLUG_IN_TYPE)
Instead of keeping around a GimpPlugInInfo struct, libgimp will
create an instance of your plug-in class, keep it around during
the plug-in's lifetime, and call its virtual functions.
2009-01-17 Michael Natterer <mitch@gimp.org>
* all files with a GPL header and all COPYING files:
Change licence to GPLv3 (and to LGPLv3 for libgimp).
Cleaned up some copyright headers and regenerated the parsers in
the ImageMap plugin.
svn path=/trunk/; revision=27913
2004-05-19 Michael Natterer <mitch@gimp.org>
* tools/pdbgen/pdb/plug_in.pdb: made plugin_icon_register() an
underscore-prefixed function which needs to be wrapped.
* libgimp/gimpplugin_pdb.[ch]: regenerated.
* libgimp/Makefile.am
* libgimp/gimp.h
* libgimp/gimpplugin.[ch]: new files containing
gimp_plugin_icon_register() which has no "icon_data_length"
parameter and determines it from the passed icon data.
* libgimp/gimp.def: added gimp_plugin_icon_register.
* plug-ins/common/plugindetails.c
* plug-ins/common/screenshot.c
* plug-ins/common/uniteditor.c
* plug-ins/print/print.c: don't pass the icon_data_length.