W Magazynie Amiga pojawiło się już kilka artykułów na temat locale.library, jednakże żaden z nich nie opisywał dokładnie jak w prosty sposób użyć tej biblioteki do zlokalizowania swego programu.
W MA 5/98 ukazał się artykuł, w którym Łukasz Jodłowski opisał jak użyć FlexCata do wygenerowania catalogu i fragmentu kodu źródłowego odpowiedzialnego za użycie locale.library. Po obejrzeniu utworzonego w ten sposób kodu uznałem, że jest to metoda bardzo nieczytelna i niepotrzebne utrudnianie sobie życia, gdyż istnieje o wiele prostsza metoda na zlokalizowanie programu.
Idea stosowanej przeze mnie metody polega na jednorazowym odczycie listy tłumaczeń i stosowaniu jej zamiast każdorazowego odczytywania tłumaczenia z katalogu. Zaprezentuję to na przykładzie w AmigaE, zaadaptowanym z mojego MultiViewa.
Na początku programu należy dołączyć moduły od locale.library i
zdefiniować stałe numery tekstów pobieranych z katalogu. Osobiście używam
tych samych nazw w programie i w plikach .cd .ct - ułatwia to tłumaczenie.
Nie należy używać nazw zbyt skrótowych, gdyż w końcu sami możecie zapomnieć
co jest od czego. Następnie definiujemy listę, w której przechowywać
będziemy wszystkie teksty:
DEF textlist[12] : LIST
Odczytywanie katalogu proponuję zrobić w oddzielnej procedurze - w
przykładzie jest to get_locale(). Odczyt katalogu zacząć należy od
zdefiniowania wskaźnika na strukturę catalog:
DEF catalog : PTR TO catalog
Następnie wypełniamy listę tekstami własnymi, które będą użyte w razie
braku katalogu w języku wybranym przez użytkownika. Po czym możemy
przystąpić do zmieniania własnych tekstów na teksty w innych językach.
W tym celu otwieramy bibliotekę locale.library w wersji 38 (pierwsza
publiczna wersja). Jeśli nam się to nie uda to nie musimy rozpaczać - po
prostu użyjemy tekstów wpisanych przed chwilą do listy textlist. Jednak
biblioteka została otwarta więc przystępujemy do dzieła.
Otwieramy katalog funkcją OpenCatalogA(locale,name,tagList). Poszczególne
pola to:
locale - w jakim języku chcemy katalog - powinno być NIL, czyli język wybrany jako systemowy
name - nazwa katalogu np. 'MultiView.catalog'
taglist - lista tagów
Rozpoznawane tagi to:
OC_BuiltInLanguage - w jakim języku mamy wbudowane teksty - jeśli NIL, to w angielskim
OC_Language - w jakim języku chcemy katalog - podobny do parametru locale - nie należy go używać bez wyraźnej potrzeby
OC_Version - wersja katalogu. Inaczej niż przy OpenLibrary() wersja MUSI się zgadzać.
Osobiście proponuję użyć składni:
catalog := OpenCatalogA(NIL,'MultiView.catalog',NIL)
co oznacza, że program chce katalog w języku systemowym, a wbudowany ma
angielski. Jeśli system nie znajdzie żądanego przez nas katalogu, zmienna
catalog będzie miała wartość NIL.
Do odczytywania tekstu z katalogu służy funkcja
GetCatalogStr(catalog,id,defaultstring). Poszczególne pola to:
catalog - wskaźnik na wcześniej otwarty katalog (może być NIL)
id - numer tekstu do odczytania
defaultstring - tekst do wstawienia, w razie braku tekstu w katalogu
Tak więc, jeśli wcześniej utworzyliśmy listę tekstów, to teraz wystarczy w
pętli odczytywać teksty z katalogu i wstawiać je do własnej listy.
FOR a := 1 TO 18 textlist[a] := GetCatalogStr(catalog,a,textlist[a]) ENDFOR
Mamy już listę tłumaczeń, więc możemy zamknąć katalog i bibliotekę.
IF catalog THEN CloseCatalog(catalog) CloseLibrary(localebase)
Teraz zostało nam już tylko używać właśnie odczytane teksty. Jest to
bardzo proste, gdyż wszędzie tam, gdzie wcześniej używaliśmy stringów, teraz
wstawiamy textlist[etykieta] i mamy właściwy tekst. Na przykład, jeśli obsługę
wypisania komunikatu o braku biblioteki mieliśmy w takiej postaci:
WriteF('Error : Cannot open FileID.library !n')
to teraz wyglądać to powinno tak:
WriteF('Error : s !n',textlist[ERR_NO_FILEID])
Stosując tę metodę możemy łatwo i szybko zlokalizować każdy program w dość krótkim czasie, chociaż najlepiej od razu pisać program zlokalizowany. Wbrew pozorom nie jest to trudne, a korzyści są wielkie - przykładowo mój MultiView jest standardowo w języku angielskim, ale dzięki ludziom z ATO i innym, można używać go w 11 innych językach. Bez użycia locale.library byłoby to znacznie trudniejsze do uzyskania, a kompilacja tylu wersji językowych byłaby tylko niepotrzebną stratą czasu.
MODULE 'locale', 'libraries/locale' /* identyfikatory tekstów w katalogu */ ENUM ERR_NOICON = 1, ERR_CHECK, ERR_ALLOC, ERR_NO_FILEID, MSG_INFO_TITLE, MSG_INFO_FILE, MSG_INFO_TYPE, MSG_ASL_FR, ERR_NO_ASL, ERR_NO_AGUIDE DEF textlist[12] : LIST /* lista z textami */ PROC main() DEF a get_locale() -> Pobranie catalogu /* Poniższa pętla wypisuje teksty z listy */ WriteF('Catalog viewer n') FOR a := 1 TO 18 WriteF('String rzd[2] = sn',a,textlist[a]) ENDFOR CleanUp(NIL) ENDPROC PROC get_locale() DEF catalog : PTR TO catalog, a /* inicjacja listy tłumaczeń */ textlist := ['$VER: MultiView 3.8 (10.05.98) by Szczepan/BlaBla', 'No program icon !', 'Error during checking file : ', 'Cannot allocate structure !', 'Cannot open FileID.library !', 'Information', 'File :', 'Type :', 'Select file', 'Cannot open Asl.library !', 'Cannot open AmigaGuide.library !nUsing DEFAULT instead.', 'Cannot open XFDMaster.library !nUsing DEFAULT instead.', 'Cannot unpack file !', 'Unsupported. Requires password OR key.', 'Unknown error.', 'Cannot open file.', 'Not enough memory.', 'Cannot save temporary file.', 'Cannot use datatypes.nUsing C:More instead.'] localebase := OpenLibrary('locale.library',38) IF localebase catalog := OpenCatalogA(NIL,'MultiView.catalog',NIL) FOR a := 1 TO 18 textlist[a] := GetCatalogStr(catalog,a,textlist[a]) ENDFOR IF catalog THEN CloseCatalog(catalog) CloseLibrary(localebase) ENDIF ENDPROC
Artykuł opublikowany za zgodą autora. Pierwotnie ukazał się w Magazynie Amiga 7/98.