Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Translation of forms labels etc. 1

Status
Not open for further replies.

SMCmtg

Programmer
Mar 27, 2000
90
US
Requesting Ideas/Guidance/Recommendations/Thoughts!
Project is built in English with labels etc. in English.
On the homepage we have the ability to choose different languages. We have set up a public variable "Language" and can be set to English, Spanish, Quechua, Aymara, etc. and on activate of the various forms, reports, etc. can change the label.captions etc. to the appropiate language. This works. . .but is massive and a bit ugly! I keep thinking there might be a better mouse trap! Any feedback would deeply appreciated. Bill
 
We use the following system:
All strings have assigned a unique ID (ID's & strings stored in a table)
Introduced a general funcion Translate(<ID>, <default string>)
This function looks up the ID in the table and if a string for the current language is found, this translation is returned, otherwise the default string.

Now the big work:
All our (base)classes/controls have an additional property ID and additional code in the INIT(): if the ID is filled AND a caption is provided, the caption is replaced by the translation.

Once that is done, implementation or the translations is quite simple. Either set the ID of call the Translate function.

Eh, this is a bit simplified, but you get the drift.
Diederik Vermeeren
verm1864@exact.nl
 
IF you wish to have your forms etc. translated while they are openend, so they are translated when you switch languages you could introduce a function f.i. set_trans().

In this function on each object that can have strings the strings are translated runtime (using Diederiks method).

So you will have to use a drill down structure to accomplish this.

To give you an example:

LOCAL lnCounter

WITH _SCREEN
IF .FORMCOUNT > 0
FOR lnCounter = 1 TO .FORMCOUNT
IF PEMSTATUS(.FORMS[lnCounter], &quot;Set_Trans&quot;, 5)
.FORMS[lnCounter].Set_Trans()
ENDIF
ENDFOR
ENDIF
*- this is my main menu that has to be translated as well.
DO std_men
ENDWITH

So for a label the set_trans() method would do something like this.

THIS.CAPTION = txt_msg(<unique ID>, THIS.CAPTION)

I call for every active form its set_trans() method. This method does the same for all its contained objects, using the Controls[] array of the objects.

In this way all strings are translated immediately when you switch language. Otherwise you will have to implement a check that doesn't allow you to switch language when forms are open.
It would look silly if you have a form openend in English and you switch to Spanish, and have you menu translated and your from still in English.

HTH,
Weedz (The Grassman)
veld4663@exact.nl

They cling emotionally to code and fix development rather than choosing practices based on analytical assesments of what works best.

After the GoldRush - Steve McConnell
 
Hello.

Very nice. How about the menus?

How can they be translated on the fly? (I'm not thinking about generating a menu for each language...)

Thanks
Grigore Dolghin
 
Same approach.
However, you'll have to code your menu. Or adapt the menu-designer...
Somehow, you'll need to replace fixed strings by (function)calls to the string-handler.
Diederik Vermeeren
verm1864@exact.nl
 
How about making a coded menu iso using the menugenerator ??

In this way you can make something like:

DEFINE BAR 3901 OF POPUP_OPTIONS PROMPT txt_msg(&quot;1011&quot;, &quot;Visual FoxPro \<command window&quot;) ;
KEY CTRL+F2, &quot;CTRL+F2&quot;
ON SELECTION BAR 3901 OF POPUP_OPTIONS do std_susp

HTH,
Weedz (The Grassman)
veld4663@exact.nl

They cling emotionally to code and fix development rather than choosing practices based on analytical assesments of what works best.

After the GoldRush - Steve McConnell
 
Diederik, you wrote:
&quot;All strings have assigned a unique ID (ID's &amp; strings stored in a table)Introduced a general funcion Translate(<ID>, <default string>)This function looks up the ID in the table and if a string for the current language is found, this translation is returned, otherwise the default string.&quot;

Could you paste a &quot;sample&quot; of this function?

Appreciate everbody's feedback. . .

 
SMCmtg,

A very basic example:
Somewhere in a procedure file, define a function Translate():
Code:
FUNCTION Translate( tcID, tcDefaultString )
LOCAL lcResultString, lnCurrentArea

*- set the default (and add a visible clue..)
lcResultString = &quot;*&quot; + ALLTRIM( tcDefaultString ) + &quot;*&quot;

IF USED(&quot;translations&quot;)
   lnCurrentArea = SELECT(0)
   SELECT translations

   LOCATE FOR .T.       &amp;&amp; = GO TOP
   LOCATE FOR ID = tcID
   IF FOUND()
      lcResultString = ALLTRIM( translations.TEXTMSG )
   ENDIF
   SELECT( lnCurrentArea )
ENDIF

RETURN lcResultString

This code assumes that you have a table with the fields ID (= the unique ID) and TEXTMSG (= the translation).

The only thing left, is to make sure that the correct table is opened (eg. the table with the translations in the &quot;current&quot; language), and that this table has a fixed alias &quot;translations&quot;

Additional, the controls need some coding.
An example:
- create control cLabel, based on the label-base class
- add property
Code:
cTransID
- put the following in the INIT:
Code:
LOCAL llRetVal

llRetVal = DODEFAULT()

WITH THIS
   IF llRetVal AND !EMPTY( .cTransID )
      .CAPTION = Translate( .cTransID, .CAPTION )
   ENDIF
ENDWITH

RETURN llRetVal


Hope this gives you the idea.
Do note that this is just the basic layout; in real life you'll have to adapt the translation function to match the actual table (or tables), you'll have to think about the language table setup, put all handling in an object which is runtime general available etc etc.
Diederik Vermeeren
verm1864@exact.nl
 
This is an example of the function I use.

FUNCTION txt_msg
LPARAMETERS tcCode, tcString
LOCAL lcTranslation
lcTransaltion = tcString
lcTranslation = TRANS_MNGR.Get_msg(tcCode, tcString)
RETURN lcTranslation
ENDFUNC

This procedure beneath (TRANS_MNGR.Get_msg()) is actually a method of my translation manager (TRANS_MNGR).
My manager is an invisible toolbar with a private datasession, so I have to open the translation table only once.
My manager (TRANS_MNGR) is a public object.

The property lng_set is the field from which the string is to be returned (i.e. English = msg_ae, Spanish is: msg_es etc.)

PROCEDURE TRANS_MNGR.Get_Msg
LPARAMETERS tcCode, tcString
LOCAL lcCode, lcString, lcLanguage, lcTranslation

lcLanguage = THIS.lng_set
lcCode = ALLTRIM(IIF(VARTYPE(tcCode) == 'C', tcCode, SPACE(0)))
lcString = IIF(VARTYPE(tcString) == 'C', tcString, &quot;Wrong parameter&quot;)

IF !EMPTY(lcCode)
GO TOP
LOCATE FOR ALLTRIM(tran_code) == lcCode
IF FOUND()
lcTranslation = &amp;lcLanguage
IF !EMPTY(lcTranslation)
lcString = lcTranslation
ENDIF
ENDIF
ENDIF

RETURn lcString

HTH,
Weedz (Wietze Veld)
veld4663@exact.nl

They cling emotionally to code and fix development rather than choosing practices based on analytical assesments of what works best.

After the GoldRush - Steve McConnell
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top