第九篇:在SOUI中使用多語言翻譯


為UI在不同地區顯示不同的語言是產品國際化的一個重要要求。

在SOUI中實現了一套類似QT的多語言翻譯機制:布局XML不需要調整,程序代碼也不需要調整,只需要為不同地區的用戶提供不同的語言翻譯文件即可。

在SOUI中,我們實現了一個使用明文XML的語言翻譯模塊:translator.dll

為了使用多語言翻譯,首先需要准備一個語言翻譯的XML文件。demo中使用的翻譯文件如下:

<?xml version="1.0" encoding="utf-8"?>
<language name="ch" guid="{0DAEDE3C-6B94-4a81-9A55-C304FDD69D98}">
  <context>
    <!--沒有上下文的翻譯-->
  </context>
  <context name="editmenu">
    <message>
      <source>copy</source>
      <translation>復制</translation>
    </message>
    <message>
      <source>cut</source>
      <translation>剪切</translation>
    </message>
    <message>
      <source>paste</source>
      <translation>粘貼</translation>
    </message>
  </context>
  <context name="messagebox">
    <message>
      <source>ok</source>
      <translation>確定</translation>
    </message>
    <message>
      <source>cancel</source>
      <translation>取消</translation>
    </message>
    <message>
      <source>retry</source>
      <translation>重試</translation>
    </message>
  </context>
  <context name="dlg_main">
    <message>
      <source>close</source>
      <translation>關閉窗口</translation>
    </message>
  </context>
</language>

可以看到該XML中有一個language的根節點,該節點有兩個屬性:name和guid,這兩個屬性都是用來標識該翻譯文件的。

在language節點下,有多個context節點,每個context節點有一個name屬性(可以為空),對應一個翻譯上下文。

每一個context下有不同數量的message結點,每個message又有兩個子節點:source 和 translation。

source對應需要翻譯的文字,而translation則對應翻譯后的文字。

要使用這個語言翻譯文件,首先需要從translator.dll中創建一個SOUI::ITranslatorMgr對象,並將該對象交給SOUI::SApplication管理。

再從ItranslatorMgr對象創建SOUI::ITranslator對象,並將Itranslator對象添加到ItranslatorMgr管理的翻譯列表中。

最后還要為ITranslator對象加載翻譯數據源(也就是前面提供的XML文件)。

下面是demo中使用和語言翻譯相關的代碼(見_tWinMain函數)

        SApplication *theApp=new SApplication(pRenderFactory,hInstance);//SOUI APP
        CAutoRefPtr<ITranslatorMgr> transMgr; //多語言翻譯模塊,由translator.dll提供
        transLoader.CreateInstance("translator.dll",(IObjRef**)&transMgr);//
        if(trans)
        {//加載語言翻譯包
            theApp->SetTranslator(transMgr);
            pugi::xml_document xmlLang;
            if(theApp->LoadXmlDocment(xmlLang,_T("lang_cn"),_T("translator")))
            {
                CAutoRefPtr<ITranslator> langCN;
                transMgr->CreateTranslator(&langCN);
                langCN->Load(&xmlLang.child(L"language"),1);//1=LD_XML
                transMgr->InstallTranslator(langCN);
            }
        }

我們先看一下editmemu的XML:

<editmenu trCtx="editmenu" iconSkin="_skin.sys.icons" itemHeight="26" iconMargin="4" textMargin="8" >
  <item id="1" icon="3">cut</item>
  <item id="2" icon="4">copy</item>
  <item id="3" icon="5">paste</item>
  <item id="4" >delete</item>
  <sep/>
  <item id="5">select all</item>
</editmenu>

在這個XML中,根節點有一個屬性trCtx,代表翻譯上下文,對應語言翻譯文件中的context中的name屬性。

在這個menu定義中,所有的菜單項的文字全是英文。其中前面3項:cut, copy and paste在語言翻譯文件中有對應的翻譯項。

下圖為程序運行時edit的右鍵菜單顯示結果:

上面演示的是菜單資源的語言翻譯,布局XML中的文字的翻譯基本一樣,只需要為布局的根結點定義一個翻譯上下文(trCtx)(沒有定義時則從沒有指定name屬性的context里查找翻譯結果)。

可以參見demo的"close”按照的tooltip的翻譯。

不管是菜單XML還是布局XML,它們都是靜態的,經過設計需要使用代碼往UI添加新的文字,同樣也需要翻譯,這個時候如何處理?

其實看一下靜態資源翻譯的代碼就知道,要實現語言翻譯,需要為每一句待翻譯的文字調用一個函數:

SApplication::getSingleton().GetTranslator()->tr(const SStringW & strSrc,const SStringW & strCtx)

第一個參數是等翻譯字符串,第二個參數是翻譯上下文。

考慮到語句太長,系統提供了一個宏:

#define TR(p1,p2)       SApplication::getSingleton().GetTranslator()->tr(p1,p2)

這樣用TR就可以實現文字翻譯了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM