• Jak zlokalizować program czyli locale.library w praktyce

25.07.2005 21:13, autor artykułu: Marcin Juszkiewicz
odsłon: 5634, powiększ obrazki, wersja do wydruku,

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.

    
komentarzy: 5ostatni: 08.08.2005 15:34
Na stronie www.PPA.pl, podobnie jak na wielu innych stronach internetowych, wykorzystywane są tzw. cookies (ciasteczka). Służą ona m.in. do tego, aby zalogować się na swoje konto, czy brać udział w ankietach. Ze względu na nowe regulacje prawne jesteśmy zobowiązani do poinformowania Cię o tym w wyraźniejszy niż dotychczas sposób. Dalsze korzystanie z naszej strony bez zmiany ustawień przeglądarki internetowej będzie oznaczać, że zgadzasz się na ich wykorzystywanie.
OK, rozumiem