Debugging

You will typically experience two types of errors:

The first item often happens because the translation files (.mo files) are not present for the current language, not placed where they are expected to be etc. The second occurs because a property of some component should not be translated. When possible, you should get an Exception that is easy to understand, but sometimes you don't. This section is about finding the error anyway.

The gnugettext.pas file has a logging system for debugging built-in. You activate it by defining the conditional define DXGETTEXTDEBUG. You can also find the first occurence of this string in gnugettext.pas - here you will find the following code:

// DEBUGGING stuff. If the conditional define DXGETTEXTDEBUG is defined, it is activated.
{ $define DXGETTEXTDEBUG}
{$ifdef DXGETTEXTDEBUG}
const
  DebugLogFilename='c:\dxgettext-log.txt';
{$endif}

One way to activate the debugging log is to change

{ $define DXGETTEXTDEBUG}
to
{$define DXGETTEXTDEBUG}
by removing the space. As you can see, you can also here modify the location where the log-file is written to.

The log-file contains a lot of information. At the beginning, you will find very useful information about what settings the system uses:

Debug log started 21-08-2003 10:32:08

UseLanguage(''); called
LANG env variable is ''.
Found Windows language code to be 'da_DK'.
Language code that will be set is 'da_DK'.
Plural form for the language was not found. English plurality system assumed.

Text domain "default" is now located at "C:\source\sf\dxgettext-devel\dxgettext\sample\locale\"
Changed text domain to "default"
Globally, the NAME property of class TComponent is being ignored.
Globally, the PROPNAME property of class TCollection is being ignored.
Extra domain for resourcestring: delphi
Globally, class TFont is being ignored.

In this example, we can see that the program was running on a Danish language Windows, which uses the same plurality system as English. It also tells us where it will look for .mo files, and what ignore settings were specified. When TranslateComponent() is used, it looks like this:

======================================================================
TranslateComponent() was called for a component with name FormMain.
A retranslator was created.
----------------------------------------------------------------------
TranslateProperties() was called for an object of class TFormMain with domain "".
Reading .mo data from file 'C:\source\sf\dxgettext-devel\dxgettext\sample\locale\da_DK\LC_MESSAGES\default.mo'
Found in .mo (default): ""->"Project-Id-Version: PACKAGE VERSIONPOT-Creation-Date: 2003-02-16 21:36PO-Revision-Date: 2003-02-17 23:01+0100Last-Translator: Lars B. Dybdahl <lars@dybdahl.dk>Language-Team:  <>MIME-Version: 1.0Content-Type: text/plain; charset=UTF-8Content-Transfer-Encoding: 8bit"
GetTranslationProperty(CONTENT-TYPE: ) returns 'text/plain; charset=UTF-8'.
Found in .mo (default): "GNU gettext sample application"->"GNU gettext eksempel"
Found in .mo (default): "Click me"->"Klik mig"
Found in .mo (default): "Click me"->"Klik mig"
----------------------------------------------------------------------
This is the first time, that this component has been translated. A retranslator component has been created for this component.
======================================================================

The log simply specifies exactly the filename from which translations are fetched, and it also specifies exactly, which strings are translated to what using which text domain. The "retranslator component" is a component that is added to the form to make it remember the untranslated properties, in case you want to do a language switch at runtime.

The first time that the application wants to translate an "OK" button, it looks like this:

Loaded resourcestring: OK
Translation not found in .mo file (default) : "OK"
Reading .mo data from file 'C:\source\sf\dxgettext-devel\dxgettext\sample\locale\da_DK\LC_MESSAGES\delphi.mo'
Found in .mo (delphi): ""->"Project-Id-Version: Delphi 7 RTLPOT-Creation-Date: 2003-03-02 18:54PO-Revision-Date: 2003-03-03 00:31+0100Last-Translator: Lars B. Dybdahl >lars@dybdahl.dk<Language-Team: Dansk >da@li.org<MIME-Version: 1.0Content-Type: text/plain; charset=UTF-8Content-Transfer-Encoding: 8bit"
GetTranslationProperty(CONTENT-TYPE: ) returns 'text/plain; charset=UTF-8'.
Found in .mo (delphi): "OK"->"O.k."

Here you can see, that it first searches default.mo for a translation, but doesn't find one. Because it's a resourcestring translation, and because we specified the "delphi" textdomain to be searched for resourcestrings, it decides to try out delphi.mo. This file has not been opened, yet, and therefore the file is opened at this point, and the full filename is written to the log file. The first action when opening a new .mo file is to check wether the Content-Type is set to use utf-8. Once it found out that this is the case, it looks up "OK" in the delphi.mo file, and finds the Danish "O.k." translation.

Log-files can be huge if your program runs for a long time. If that happens, load the logfile into an editor that is capable of handling huge files, and search for the keywords that you saw in this section.

If your program breaks because a string property is translated that shouldn't, try to search for the Exception error message in the log file (error messages are translated, too, and are also mentioned in the log file). The last translation mentioned before that error mesage is probably the one that made your program fail.

When you have identified a property that should not be translated, you can either specify it globally that it should not be translated, by calling TP_GlobalIgnoreClassProperty(), or you can disable it only for the next call to TranslateComponent() using TP_Ignore.