章 18. 本地化

在 GNUstep 中, 本地化 (Localization) 非常簡單, 分成程式碼內字串的本地化及 Gorm 檔案的本地化. 在這裡製做一個無用的程式來介紹本地化的方法.

使用 Gorm 製做以下的使用者介面:

圖形 18.1. 使用者介面

使用者介面

繼承自 NSObject, 產生一個 AppDelegate 類別, 要做為 NSApp 的代理者. 在 AppDelegate 中加入一個 "window" outlet, 連結至視窗上. 在這裡不打算使用這個 Gorm 介面做為主介面, 因此設定 NSOwner 為 AppDelegate 類別. 在程式碼中會手動載入這個使用者介面.

將使用者介面存檔成 "Localization.gorm". 以下是 AppDelegate 的程式碼.

AppDelegate.h

#ifndef _AppDelegate_
#define _AppDelegate_

#include <Foundation/NSObject.h>

@interface AppDelegate: NSObject
{
  id window;
}
@end

#endif /* _AppDelegate */

AppDelegate.m

#include "AppDelegate.h"
#include <AppKit/AppKit.h>

@implementation AppDelegate

- (void) applicationWillFinishLaunching: (NSNotification *) not
{
  NSMenu *menu;

程式碼內字串的本地化基本上是使用 bundle. 但是 GNUstep 提供了很方便的巨集, _(). 將要本地化的字串都用 _() 包起來即可.

  menu = [[NSMenu alloc] initWithTitle: _(@"Main Menu")];

  [menu addItemWithTitle: _(@"Hide")
                  action: @selector(hide:)
           keyEquivalent: @"h"];
  [menu addItemWithTitle: _(@"Quit")
                  action: @selector(terminate:)
           keyEquivalent: @"q"];

  [NSApp setMainMenu: menu];

  RELEASE(menu);
}

- (void) applicationDidFinishLaunching: (NSNotification *) not
{

在這裡手動載入 Gorm 使用者介面.

  [NSBundle loadNibNamed: @"Localization.gorm" owner: self];
  [window makeKeyAndOrderFront: self];
}

@end

因為 main() 很簡單, 寫在同一個檔案中.

int main(int argc, const char **argv)
{
   NSAutoreleasePool *pool = [NSAutoreleasePool new];

   [NSApplication sharedApplication];

   [NSApp setDelegate: [AppDelegate new]];

   NSApplicationMain(argc, argv);

   RELEASE(pool);

   return 0;
}

GNUmakefile

include $(GNUSTEP_MAKEFILES)/common.make

APP_NAME = Localization

Localization_OBJC_FILES = AppDelegate.m

Localization_HEADERS = AppDelegate.h

Localization_LANGUAGES = English TraditionalChinese

Localization_LOCALIZED_RESOURCE_FILES = \
        Localizable.strings \
        Localization.gorm

include $(GNUSTEP_MAKEFILES)/application.make

在 GNUmakefile 中, 最重要的是指定 Localization_LANGUAGES 及 Localization_LOCALIZED_RESOURCE_FILES. _LANGUAGES 指定所支援的語言, 在此是 English 及 TraditionalChinese, 相對應到 English.lproj/ 及 TraditionalChinese.lproj/ 目錄. _LOCALIZED_RESOURCE_FILES 則指定在這些目錄中本地化的檔案. Localizable.strings 是固定檔名, 用來放置程式碼中字串本地化所用的翻譯. Localization.gorm 則是剛製做的使用者介面.

以下是 English.lproj/Localizable.strings 的寫法:

Localizable.strings

"Main Menu" = "Main Menu";

"Hide" = "Hide";

"Quit" = "Quit";

左邊是程式碼中的字串, 即 _() 包含的字串, 右邊是其翻譯. 因為這是英文, 所以兩邊相同. 可以試著修變右邊的字串看看結果.

對於正體中文的部份, 只要將 Localizable.strings 及 Localization.gorm 複製到 TraditionalChinese.lproj/ 即可. 改寫 Localizable.strings 右邊的部份成正體中文. . 使用 Gorm 將 Localization.gorm 的字串都改成正體中文. 這個程式便可支援英文及正體中文了.

應用程式會根據使用者設定中的 NSLanguages 來決定要使用那個語言的翻譯. 可以參考 "語言設定" 章節.

程式碼在此: Localization-src.tar.gz. 有興趣可以試著增加其他語言的支援.

有些人不喜歡針對每一個語言製做一個 Gorm 使用者介面. Gorm 使用這個方法的原因是各國語言的字串長短不同, 針對每個語言製做一個使用者介面才能達到最好的視覺效果. 這也是 Gorm 使用絕對位置來安排圖形元件的原因. 如果偏好使用相對位置來按排圖形元件, 可以試試 Renaissance.

總結來說, 在程式碼中使用 _() 來包含要本地化的字串. 製做本地化語言的 language.lproj/ 目錄, 並在 GNUmakefile 中指定該語言. 將 language.lproj/ 中的 "Localizable.strings" 翻譯程式碼中被 -() 包起來的字串. 使有 Gorm 將所有 Gorm 使用者介面翻譯成該語言. 如此便大功告成.