Page 1 of 2

FWH 18.10: Enhancements to strings.prg

PostPosted: Thu Nov 08, 2018 5:22 pm
by nageswaragunupudi
FWString( <english> ) translates the English string to the application's language. This feature is supported for 5 languages.
(1) English, (2) Spanish, (3) French, (4) Portuguese, (5) German and (6) Italian. This translation is based on the translated messages stored in a two dimensional array, "aStrings" in strings.prg. Each element of this array is an array of 6 strings in English, Spanish, etc.

Function FWAddString( aString ) is provided to add an additional translation. Now, this function can also be used to modify an existing entry.

Example usage:
Please see: viewtopic.php?f=18&t=36305
English "Move Down" is incorrectly translated as "Mover para cima" instead of "Mover para baixo".

This can be easily fixed by calling this function
Code: Select all  Expand view

FWAddString( { "Move Down", nil, nil, "Mover para baixo" } )
 

This modifies the Portuguese translation of "Move Down"
In a single call, we can add/modify multiple entries by using a two-dimensional array.

FWAddString( {{ <eng1>,,,<trans1> }, ... { <engN>,,,<transN> } } )


Adding a new language:

FWAddLanguage( [aLangArray] ) --> NewLanguageID
This function provides an additional column for the new language and return the ID (column number).
If aLangArray is specified, it should be a single dimensional array containing translates for all or some of the English words in the aStrings array in the same order. Where the translates are provided, FWString() returns the new translate and same English word in other cases. It is also possible to omit this array initially and later add translations using FWAddString().

FWMissingStrings() --> Writes missing strings (where translates are not available) to a file by name "missing.str". This can be used to add these translates and revise the program.

This is an example to add a new language and provide translates only to the required extent.

Add the beginning of the application call FWAddLanguage() and at the end call FWMissingStrings().

Code: Select all  Expand view

#include "fivewin.ch"

function Main()

   FW_SetUnicode( .t. )

   FWAddLanguage() // --> 7

   // Your entire application code
   XBROWSER "STATES.DBF"

   FWMissingStrings() // List missing strings

return nil
 


Run and close the application. This program creates "missing.str". Open the file with notepad which looks like this:
Code: Select all  Expand view

   FWAddString( { ;
   { "Add",,,,,, }, ;
      { "Bottom",,,,,, }, ;
      { "Close",,,,,, }, ;
      { "Delete",,,,,, }, ;
      { "Edit",,,,,, }, ;
      { "Move Down",,,,,, }, ;
      { "Move Up",,,,,, }, ;
      { "Print",,,,,, }, ;
      { "Top",,,,,, } ;
   } )
 

Now edit this file and add your translates after the last comma in each line. I have done this for an Indian language "Telugu". Like this:
Code: Select all  Expand view

   FWAddString( { ;
      { "Add",,,,,,"నూతన" }, ;
      { "Bottom",,,,,,"చివర"  }, ;
      { "Close",,,,,,"ముగించు" }, ;
      { "Delete",,,,,,"తొలగించు"  }, ;
      { "Edit",,,,,,"సవరింపు"  }, ;
      { "Move Down",,,,,,"తరువాత"  }, ;
      { "Move Up",,,,,,"వెనుక"  }, ;
      { "Print",,,,,,"ముద్రించు"  }, ;
      { "Top",,,,,,"మొదలు"  } ;
   } )
 


Now, copy this and paste into the application.
Code: Select all  Expand view

#include "fivewin.ch"

function Main()

   SetBalloon( .t. )
   FW_SetUnicode( .t. )

   FWAddLanguage()
   FWAddString( { ;
      { "Add",,,,,,"నూతన" }, ;
      { "Bottom",,,,,,"చివర"  }, ;
      { "Close",,,,,,"ముగించు" }, ;
      { "Delete",,,,,,"తొలగించు"  }, ;
      { "Edit",,,,,,"సవరింపు"  }, ;
      { "Move Down",,,,,,"తరువాత"  }, ;
      { "Move Up",,,,,,"వెనుక"  }, ;
      { "Print",,,,,,"ముద్రించు"  }, ;
      { "Top",,,,,,"మొదలు"  } ;
   } )

   XBROWSER "STATES.DBF"

return nil
 


Adding the new language, for the words used in the application, is complete now.

Image

Re: FWH 18.08: Enhancements to strings.prg

PostPosted: Fri Nov 09, 2018 11:40 am
by Horizon
Hi Mr. Rao,

I am confused about that.

There are 6 languages in builtin. And we add 7th one in it as a new language. Sometimes later if any languages add in built-in fwh. Our code is still use 7th. but it is occupied from new fwh version.

Is it true?

Re: FWH 18.08: Enhancements to strings.prg

PostPosted: Fri Nov 09, 2018 12:10 pm
by AntoninoP
I agree, the list of commas is confusing and can carry into errors.
Maybe something like:
Code: Select all  Expand view
function Main()
   Local nLang
   FW_SetUnicode( .t. )
   nLang := FWAddLanguage()
   FWAddString(nLang, { ;
      { "Add","నూతన" }, ;
      { "Bottom","చివర"  }, ;
      { "Close","ముగించు" }, ;
      { "Delete","తొలగించు"  }, ;
      { "Edit","సవరింపు"  }, ;
      { "Move Down","తరువాత"  }, ;
      { "Move Up","వెనుక"  }, ;
      { "Print","ముద్రించు"  }, ;
      { "Top","మొదలు"  } ;
   } )
 

It is only a suggestion

Re: FWH 18.08: Enhancements to strings.prg

PostPosted: Fri Nov 09, 2018 12:32 pm
by nageswaragunupudi
Mr. Antonio and Mr. Hakan

Thank you both.
It appears Mr. Antonio's advice has a solution for Mr. Hakan's concern also.

We can not change FWAddString() because we need to keep the backward compatibility.
Syntax:
FWAddString( { en, es, fr, pt, de, it, ...... } )

We can have a new function:
FWSetString( nLang, { { en, <translate> }, .... } )

Even when FWH natively provides more languages, the logic will still work.

Code: Select all  Expand view

nLang := FWAddLanguage()
FWSetString( nLang, { { en, newlang }, .. } )
 


Any comments or suggestions please?

Re: FWH 18.08: Enhancements to strings.prg

PostPosted: Fri Nov 09, 2018 2:33 pm
by nageswaragunupudi
Added new function
FWSetString( nLang, aString )

Now, we can use
Code: Select all  Expand view

FWSetString( 4, { "Move Down", "Mover para baixo" } )
 

to modify the Portuguese translation of "Move Down" or to add a new translation.

In the example posted above, FWMissingStrings() now writes the following text to "missing.str" file.
Code: Select all  Expand view

   FWSetString( nLang, { ;
      { "Add", }, ;
      { "Bottom", }, ;
      { "Close", }, ;
      { "Delete", }, ;
      { "Edit", }, ;
      { "Move Down", }, ;
      { "Move Up", }, ;
      { "Print", }, ;
      { "Top", } ;
   } )
 

Modified program looks like this:
Code: Select all  Expand view

#include "fivewin.ch"

function Main()

   local nLang

   SetBalloon( .t. )
   FW_SetUnicode( .t. )

   nLang := FWAddLanguage()
   FWSetString( nLang, { ;
      { "Add","నూతన" }, ;
      { "Bottom","చివర"  }, ;
      { "Close","ముగించు" }, ;
      { "Delete","తొలగించు"  }, ;
      { "Edit","సవరింపు"  }, ;
      { "Move Down","తరువాత"  }, ;
      { "Move Up","వెనుక"  }, ;
      { "Print","ముద్రించు"  }, ;
      { "Top","మొదలు"  } ;
   } )

   XBROWSER "STATES.DBF"

return nil 
 


Thank you both.

Re: FWH 18.08: Enhancements to strings.prg

PostPosted: Fri Nov 09, 2018 8:16 pm
by TimStone
Interesting, but I did not know several languages were built in to FWH. This would be very useful for me.

Could you please point me to samples so I can see how this is setup ? Thank you.

Re: FWH 18.08: Enhancements to strings.prg

PostPosted: Sat Nov 10, 2018 7:59 am
by Antonio Linares
Tim,

Please review FWH\samples\fivedbu.prg

@ 5.0, 1.5 SAY FWString( "Language" ) OF oDlg // You use FWString( cText ) instead of cText

To retrieve the default language id:

nLanguage = FWSetLanguage()

To use a different language:
FWSetLanguage( nLanguageId )

where 1 is English, 2 is Spanish, 3 is French, 4 is Portuguese, 5 is German, 6 is Italian

when you use a text that it is not defined in FWH, FWH will let you know it and it will show you
the code to add to your app to support it :-)

Re: FWH 18.08: Enhancements to strings.prg

PostPosted: Sun Nov 11, 2018 5:11 pm
by Horizon
Hi,

Thank you very much for this feature. My clients were asking why there were foreign languages ​​in some places.



FWMissingStrings() function always gives same result like below.

Code: Select all  Expand view
0

Re: FWH 18.08: Enhancements to strings.prg

PostPosted: Sun Nov 11, 2018 5:19 pm
by nageswaragunupudi
Horizon wrote:My clients were asking why there were foreign languages ​in some places.

I could not understand. Can you explain in greater detail?

Horizon wrote:FWMissingStrings() function always gives same result like below.

Code: Select all  Expand view
0

"0" means there are no missing strings.
Are you trying to add Turkish Language?

Re: FWH 18.08: Enhancements to strings.prg

PostPosted: Mon Nov 12, 2018 9:13 am
by Silvio.Falconi
Question

When I compile An Application and I used fwstring function for all strings

is there a function to save all strings into an array to insert the strings ?

on xharbour the compilar created a file I18n extern

Re: FWH 18.08: Enhancements to strings.prg

PostPosted: Tue Nov 13, 2018 1:43 am
by nageswaragunupudi
Adding a new language:

If you want to add a new language, here is a proposal for consideration. This proposal uses
Code: Select all  Expand view

nLang := FWAddLanguage( aTranslates )
 

to add a new language, where aTranslates is a single dimensional array consisting of a list of translates corresponding to the English string constants in the aStrings array in strings.prg. Though it is possible to build such an array manually, it is very tedious, time-consuming, error-prone and very difficult to maintain.

We propose a tool (a program) that makes the process much easier and safer. This program can be customized to individual needs.
Code: Select all  Expand view

#include "fivewin.ch"

function Main()

   local aStrings, a

   // IF UNICODE LANGUAGE, SET UNICODE
   //---------------------------------
   FW_SetUnicode( .t. )

   // OTHERWISE, SET THE CODEPAGE HERE
   // SETTINGS SHOULD EXACTLY MATCH THE MAIN PROJECT
   //---------------------------------


   // Create or read DBF
   //
   if !File( "TRANSLATE.DBF" )
      aStrings := FWAddString()
      DBCREATE( "TRANSLATE.DBF", { { "ENGLISH",   "C",  80, 0 },   ;
                                   { "TRANSLATE", "C", 100, 0 } }, ;
                                 nil, .T., "TRN" )

      AEval( aStrings, { |a| DBAPPEND(), TRN->ENGLISH := a[ 1 ] } )
      GO TOP
   else
      USE TRANSLATE NEW ALIAS TRN
   endif

   // Enter / Edit Translates
   //
   XBROWSER "TRN" FASTEDIT SHOW RECID ;
      SETUP ( oBrw:aCols[ 1 ]:nEditType := 0, ;
              oBrw:nWidths := 400 )

   if MsgYesNo( "Generate Program?" )
      GeneratePRG()
   endif

return nil

function GeneratePRG()

   local cPrgFolder := ""  // Folder to save the program
   local cFunc
   local cList    := ""
   local cLine    := ""

   OrdSetFocus( 0 )
   GO TOP
   do while !Eof()

      if Len( cLine ) == 0
         cLine    := Chr( 9 )
      else
         cLine    += ","
      endif

      if !Empty( FIELD->TRANSLATE )
         cLine    += '"' + AllTrim( FIELD->TRANSLATE ) + '"'
      endif

      if RECNO() < LASTREC()
         if HB_UTF8LEN( cLine ) > 100
            cList += cLine + ", ;" + CRLF
            cLine := ""
         endif
      else
         cList    += cLine
         cLine    := ""
      endif

      SKIP
   enddo

   cFunc    := [#include "fivewin.ch"] + CRLF + CRLF
   cFunc    += "function AddLanguge()" + CRLF + CRLF
   cFunc    += Chr( 9) + "local aLang := { ;" + CRLF + cList + " }" + CRLF + CRLF
   cFunc    += "return FWAddLanguage( aLang )" + CRLF

   MEMOWRIT( cPrgFolder + "addlang.prg", cFunc )
   MEMOEDIT( cFunc )

return cFunc
 


Description:

Initially, the program reads all English string constants from 'strings.prg' and creates "translate.dbf" with two fields "ENGLISH" and "TRANSLATE" in the exe folder and displays the same in XBrowse for entering the translates.

Image

Provide translates to as many messages as necessary/possible. Other messages will be displayed in English during runtime. It is possible to revise and update the translates later also.

After editing and closing the browse, the program generates "addlang.prg", saves it in the specified programs folder and also displays it. The gerated program typically looks like:
Code: Select all  Expand view

#include "fivewin.ch"

function AddLanguge()

    local aLang := { ;
    "గమనిక","పిడిఎఫ్ ప్లగిన్ లోపం",,,,,,"కనిపించలేదు","ముద్రణ లోపం","దృశ్యం","ఎక్సెల్ లేదు","కాగితం వెడల్పు తక్కువ", ;
    ,,"ముద్రణ వీక్షణ","ఫైలు","ముద్రణ","ప్రస్తుత పుట ముద్రించు","విరమణ",,"పుట","మొదలు","మొదటి పుట","వెనుకకు", ;
    "వెనుక పుట","తరువాత","తరువాతి పుటట","చివర","చివరి పుట","పెద్దగా","పుట పెద్దగా",,,,,,"రెండు పుటలు",,"ఒక పుట", ;
    ,"పుట సంఖ్య",,,,,"వెనుక","తరువాత","చివరి",,,,,,,,,,,"విరమణ",,,,,,,,"అన్ని",,,,,,,,,,,,,,,,,"ఎడమ",,,,, ;
    ,,,,,,,,,,,,,"నూతన","సవరణ","తొలగించు",,,,,,,,,,,,,,,,"సవరణ",,,"విలువ",,,"అవునా కాదా",,,,,,,,,,,,,,,"పేరు", ;
    "రకము","నిడివి","అంకము",,,"క్రమము",,,,,,"సహాయము",,,,"హెచ్చరిక",,,"నిలువుగా",,"అడ్డంగా",,,,,,,,,,,,,,, ;
    ,,,,,"గురించి",,,,,,,,,,,,,,,,,,,,,,,,"భాష","ఆంగ్లము",,,,,,,"ప్రశ్న","ప్రశ్న నిర్మాణము",,"సమానము","వేరు", ;
    ,,,,,,,,,,,,,"వరుస",,,,,,,,,,,,,,,,"ఎంపిక",,,,,,,,,,,,,,,,,,,,,,,,,,,,,"కనుగొనుము",,"మరల వెతుకుము",,, ;
    ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,"సాధారణము",,,,,,,,"ఇది",,,,,"సంఖ్య",,,,,,,,,,,,,,,,,,,,,,,"మొత్తము", ;
    "విలువ",,,"తేదీ",,,,"పూర్తి","క్లిప్ బోర్డు లేదు" }

return FWAddLanguage( aLang )
 

Link this program with the main project, call the function "AddLanguage" in main function and build the main project.
Code: Select all  Expand view

   nLang := AddLanguage()
 


Steps:

1. Run the program
2. Edit translates in the browse
3. Generate "addlang.prg"
4. Include this program in the project
5. Call "nLang := AddLanguage()" in the main project
6. Build the main project.
Done

Preserve this program and "translate.dbf". We can use them for maintenance for updating the translations at a later stage, if and when required.

Maintenance (Updating translations):

1. Run the program and edit the translates
2. Generate the program
3. Rebuild the project
Done.

Re: FWH 18.08: Enhancements to strings.prg

PostPosted: Tue Nov 13, 2018 1:50 am
by nageswaragunupudi
Silvio.Falconi wrote:Question

When I compile An Application and I used fwstring function for all strings

is there a function to save all strings into an array to insert the strings ?

on xharbour the compilar created a file I18n extern


If you are programming for Italian language only, then I think there is no need to use FWString() function. You can as well directly code the string constants in Italian language.

Re: FWH 18.08: Enhancements to strings.prg

PostPosted: Tue Nov 13, 2018 10:20 am
by Silvio.Falconi
Of Course,

Dear Master Rao
Code: Select all  Expand view
Application
===========
   Path and name: C:\Work\Errori\Lingue\test.Exe (32 bits)
   Size: 3,596,288 bytes
   Compiler version: Harbour 3.2.0dev (r1712141320)
   FiveWin  version: FWH 17.12
   C compiler version: Borland/Embarcadero C++ 7.3 (32-bit)
   Windows version: 6.1, Build 7601 Service Pack 1

   Time from start: 0 hours 0 mins 0 secs
   Error occurred at: 11/13/18, 11:24:21
   Error description: Error BASE/2017  Argument error: AEVAL
   Args:
     [   1] = U  
     [   2] = B   {|| ... }

Stack Calls
===========
   Called from:  => AEVAL( 0 )
   Called from: test.prg => MAIN( 24 )

but if I should create an application in different languages (English, French, Spanish, German) I would have to spend many days writing strings.

Instead on Xhabour it was automatically (with / j Main.hil) the compiler automatically saved the strings it encountered with the i18n () function in a hit or hil file, we could use a hbdict to translate the sentences into different languages.
In Harbor this is not possible and Linares created the system with the fwstring () function.

It would be nice if there was a function that scans every prg used in our application (.prg) that saved in a strings.prg file all the strings found in the prg files with the function fwstring ().

and then we can use your utility (translate.dbf)

Re: FWH 18.08: Enhancements to strings.prg

PostPosted: Tue Nov 13, 2018 1:14 pm
by nageswaragunupudi
Mr. Silvio

You get the runtime error with any version prior to FWH1810.

Re: FWH 18.08: Enhancements to strings.prg

PostPosted: Tue Nov 13, 2018 1:20 pm
by nageswaragunupudi
but if I should create an application in different languages (English, French, Spanish, German) I would have to spend many days writing strings.


You need to use this function for each word:
Code: Select all  Expand view

FWAddString( { "englishStr", "SpanishStr", "FrenchStr", nil, "GermalStr", "ItalianStr" } )
 

This works in all versions.