mirror of https://github.com/GNOME/gimp.git
81b569cb8c
Plug-in localization was always partially plug-in side, especially for things like custom GUI. But labels or blurb in GIMP (such as in menus or action search) were localizing GIMP side. It had many drawbacks: - To get menu localization, a plug-in had to set up gettext, even though they might want to use something else for their GUI (after all, giving facilities for gettext is a good idea, but there is no reason to force using this system). - There was a complex internal system passing the localization domain name, as well as the catalog file system path to core, then through various classes which we can now get rid of. - There could be domain name clashes, if 2 plug-ins were to use the same i18n domain name. This was handled in now removed functions gimp_plug_in_manager_get_locale_domains() by simply keeping a unique one (and gimp_plug_in_manager_bind_text_domains() would just bind the domain to the kept directory). In other words, one of the duplicate plug-ins would use the wrong catalog. We could try to make the whole thing more complicated or try to forbid plug-ins to use any random name (in particular made easier with the new extension wrapper). But anyway this whole issue doesn't happen anymore if localization is fully made plug-in side, so why bother? I tried to evaluate the advantages of the core-side localization of plug-in labels/blurbs and could only find one theoretical: if we wanted to keep access to the original English text. This could be useful (theoretically) if we wanted to search (e.g. in the action search) in both localized and English text; or if we wanted to be able to swap easily en/l10n text in a UI without reload. But even if we were to ever do this, it would only be possible for plug-ins (GEGL operations in particular are localized GEGL-side), so it lacks consistency. And it's unsure why special-casing English should really make sense for other language natives who want text in their lang, and search in their lang. They don't necessarily care about original. So in the end, I decided to simplify the whole thing, make localization of plug-ins a plug-in side thing. Core will only receive translated text and that's it. It cuts a lot of code out of the core, simplify runtime processing and make plug-in creation simpler to understand. The only think I still want to look at is how exactly menu paths are translated right now. Note that it still works, but it's possible that some things may be worth improving/simplifying on this side too. |
||
---|---|---|
.. | ||
groups | ||
.gitignore | ||
Makefile.am | ||
README | ||
README_NEW_PDB_PROC | ||
app.pl | ||
enumcode.pl | ||
enumgen.pl | ||
enums-external.pl | ||
enums.pl | ||
groups.pl | ||
lib.pl | ||
meson-pdbgen.sh | ||
meson.build | ||
pdb.pl | ||
pdbgen.pl | ||
stddefs.pdb | ||
util.pl |
README
Some mostly unfinished docs are here. -Yosh This document describes the tool PDBGEN. If you added or modified .pdb files do not run this tool manually but run make instead! It will call pdbgen.pl then to generate the files into the right output directories. PDBGEN ------------------ What is this? PDBGEN is a tool to automate much of the drudge work of making PDB interfaces to GIMP internals. Right now, it generates PDB description records, argument marshallers (with sanity checking) for the app side, as well as libgimp wrappers for C plugins. It's written so that extending it to provide support for CORBA and other languages suited to static autogeneration. Invoking PDBGEN from the command line: 1. Change into the ./pdb directory. 2. $ ./pdbgen.pl DIRNAME where DIRNAME is either "lib" or "app", depending on which set of files you want to generate. The files are written into $destdir/app or $destdir/libgimp. $destdir is the environment variable destdir. If it's not set, then it's the ./pdb directory. Make sure the directories $destdir/app and $destdir/libgimp already exist and you have write permissions. Otherwise the code generator will fail and exit. It's up to you to diff the file you changed. When you're happy with the generated file, copy it into the actual ./app/ or ./libgimp/ directory where it finally gets built. Anatomy of a PDB descriptor: PDB descriptors are Perl code. You define a subroutine, which corresponds to the PDB function you want to create. You then fill certain special variables to fully describe all the information pdbgen needs to generate code. Since it's perl, you can do practically whatever perl lets you do to help you do this. However, at the simplest level, you don't need to know perl at all to make PDB descriptors. Annotated description: For example, we will look at gimp_display_new, specified in gdisplay.pdb. sub display_new { We start with the name of our PDB function (not including the "gimp_" prefix). $blurb = 'Create a new display for the specified image.'; This directly corresponds to the "blurb" field in the ProcRecord. $help = <<'HELP'; Creates a new display for the specified image. If the image already has a display, another is added. Multiple displays are handled transparently by the GIMP. The newly created display is returned and can be subsequently destroyed with a call to 'gimp-display-delete'. This procedure only makes sense for use with the GIMP UI. HELP This is the help field. Notice because it is a long string, we used HERE document syntax to split it over multiple lines. Any extra whitespace in $blurb or $help, including newlines, is automatically stripped, so you don't have to worry about that. &std_pdb_misc; This is the "author", "copyright", and "date" fields. Since S&P are quite common, they get a special shortcut which fills these in for you. Stuff like this is defined in stddefs.pdb. @inargs = ( &std_image_arg ); You specify arguments in a list. Again, your basic image is very common, so it gets a shortcut. @outargs = ( { name => 'display', type => 'display', desc => 'The new display', alias => 'gdisp', init => 1 } ); This is a real argument. It has a name, type, description at a minimum. "alias" lets you use the alias name in your invoker code, but the real name is still shown in the ProcRecord. This is useful not only as a shorthand, but for grabbing variables defined somewhere else (or constants), in conjunction with the "no_declare" flag. "init" simply says initialize this variable to a dummy value (in this case to placate gcc warnings) %invoke = ( headers => [ qw("gdisplay.h") ], These are the headers needed for the functions you call. vars => [ 'guint scale = 0x101' ], Extra variables can be put here for your invoker. code => <<'CODE' { if (gimage->layers == NULL) success = FALSE; else success = ((gdisp = gdisplay_new (gimage, scale)) != NULL); } CODE The actual invoker code. Since it's a multiline block, we put curly braces in the beginning.