Sign in to follow this  
Followers 0
AvvA

Independant language file (not compiled into the .exe)

11 posts in this topic

Hello there :D

First, thanks a lot for this great software ^^

Second, to describe what I need, it's an independant language file for my future script's users to traduct it in their own -unknown for me- language, and without the need of recompiling the script or contact me, I love freedom (for them of course ! What are you thinking ;) ?).

For this kind of purpose, I must write a human-readable language file.

Here is what I tried to do first, which works, but embbed the file when compiling :

- I make a file filled with $variable = "content", one per line.

- I #include it at the begining of my AutoIt script, and all was rolling like a charm :D

Until I compiled the thing, and try again to substitute the language file :S

So, I remembered that one of AutoIt purpose was to make standalone executables... better late than never :D

I spent the morning searching the forum for what i'll explain there, but nobody makes a multi-lingual GUI with non-embended text ? Well...

That's not a problem since this let me discover a bunch of usefull tips, by reading out of "my" topic things ;)

I found the nearly solution in this post.

I would like to thanks YellowLab and Xenobiologist for their close answer to my problem, that put me on the way.

My problem was that I came from the php/js/sql world, and try to... kind of reproduce what I usually do, I was wrong, of course !

After trying the 2 veterans's solutions (after modifying the Xenobiologist one, as i didn't need to rewrite a file ^^), I was a bit disapointed, it works, i converted my file to an INI file (removing all $ and ", making a section...)

And I realised that in the operation, all the " & @CR & " stays litterals :S

I try to play with the Opt("ExpandVarStrings", 1), but nothing to do, it stays like text.

So I try to play with execute() and string(), but still nothing.

The problem came from the the IniReadSection(), I don't know why, but it doesn't interpret the string like I want.

So I try to make my own dirty code, here it is : (yes, it works)

$langfile = FileOpen(@ScriptDir & "\language.lng",0)
If $langfile = -1 Then
    MsgBox(0, "Error", "Please, copy a language.lng file at the same level as AIscript.exe :" & @CR & @ScriptDir & "\")
    Exit
EndIf
While 1
    $langline = FileReadLine($langfile) ; Read the file, line by line
    If @error = -1 Then ExitLoop ; means EOF, stop reading and exit the loop ^^

    $varr = StringSplit($langline, " = ", 1) ; split only if space=space is found (option 1)
    if $varr[0]=2 then Assign($varr[1],execute($varr[2])) ; test if the line grabbed is valid, as some lines are empty, others are comments.

Wend
FileClose($langfile)oÝ÷ Ù&¦¦W¥jx.jW­¢ÈhÃ*.¶«m³)íkhºÇºÚ"µÍØÙYXØ]B[×ÝXØÙYXØ]H ][ÝÐÙYXØ]I][ÝÂ[×ØÙÚ[ÈH   ][ÝÕÙH[ÜX][ÛÈÚ[HÚÝÛÈ[ÝÒÈÚ]HÚ]ÜËZ]Ú[XØÙ[ÈHÙYXØ]HÜHXZÚ[È[^Ù[ÛYÙYXØ]HÛÌÎNÝXÛÙÛ^HÈ[Y][ÝÈ   [ÈÔ   [È ][ÝÕHYY[[ÈXÚÝ[ÛÛZ[È[ÝTÜÜH[YHÙ[ÝÚ]HY[ÝHÜÈHH[ÈÙXÙKHÙXÜØ[ÈÙXÙKÜ]HYÚÝY[ÝT[HÛXZ[[YHÝÝË^Ú]KÛÛH][ÝÈ [ÈÔ   [È ][ÝÕÈY[ÚÝ[ÛÛZ[HYÜÈÈXXÚ[ÝÒÈÚ]KÚ]Ý]ÝØÛÛ
ËÈÜÎËÊK][ÝÂÈÛÛ[[Û[×ÛÚÈH ][ÝÛÚÉ][ÝÂ[×ÙÜH    ][ÝÑÜ][ÝÂ[×ÝØ[ÈH   ][ÝÕØ[È ÌÌÎÉ][ÝÂ[×Ù[WÛÝÜ]HH  ][ÝÕÛÝ[[ÝHZÙHÈÝÜ]HÈ[HÉ][Ý

This is : name_of_the_future_variable = "value of the variable"

As you can see, you can put blank lines, comments, as long as you don't use the separator in it. (and even if you do, you'll just create a useless variable.

I strongly recommand that you start all variable with a common exclusive prefix, to avoid overwriting an existing variable.

The big point in this is that languages are really differents, in french my file is 9Ko for 8Ko in english (for only 100 variable's line), this also means that @CR won't fit at the same place between two languages, most of the time. I couldn't take the Xenobiologist solution and force the break by making 3 variables, one per line...

Et voilà, the solution that leave your users free to translate yours scripts, without the assle of waiting for them to finish for you to recompile :P

I hope that can help some people out there ^^

So, by curiosity, there is no way to #include a file without embbeding it when compiling ? No similar thing ? I still like the first way i do, because it's operation free, just variable declaration, "too bad" it is automaticaly embbed ^^.

Share this post


Link to post
Share on other sites



Most applications keep the language files separate where the typical folder structure for English would be @ScriptDir& "\Lang\1033\1033.lng" or @ScriptDir & "\Lang\1033.lng" That way you can determine which file is used according to the users language settings. If that file doesn't exist then it would default to the English version or whatever you determine is the default language.


George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Share this post


Link to post
Share on other sites

Most applications keep the language files separate where the typical folder structure for English would be @ScriptDir& "\Lang\1033\1033.lng" or @ScriptDir & "\Lang\1033.lng" That way you can determine which file is used according to the users language settings. If that file doesn't exist then it would default to the English version or whatever you determine is the default language.

Do exactly as posted here. The lastthing to make this work effeciently is create an easy function...

$Lang = 'lang_ok =ok' & @CRLF & 'lang_error =Error' & @CRLF & 'lang_warning =Warning !' ; usually this would be a file loaded


MsgBox(0, "",  _GetText($lang, "lang_ok") & "|" & _GetText($lang, "lang_error"))

Func _GetText($lang, $str)
    $_SRE = StringRegExp($lang, $str & '\s?=(.*)', 1)
    If StringRight(StringToBinary($_SRE[0]), 2) = "0D" Then
        Return StringTrimRight($_SRE[0], 1)
    Else
        Return $_SRE[0]
    EndIf
EndFunc

Share this post


Link to post
Share on other sites

Thanks you :D

In fact I wasn't asking for help, instead I proposed a solution that I found funtionnal and didn't find in here (really, and I spent time on a lot of topics) :D

But, GEOSoft you answered a question I was asking myself, I'll use your solution, it seems appropriate to my needs.

Szhlopp, i'll try your function after dinner, but I can't figure out what's the interest of replacing my code by yours... (without any malicious meaning : i just don't understand what's better in your code or what is wrong in mine ^^)

And what is the msgbox for ?

Are regexp lighters than string expressions ?

Where do you assign the value to the variable ?

Do your code will interpret correctly the " & @CR & " so that linefeeds works ?

Well, i'll try it out, perhaps it will make me understand ;)

In all cases, thanks to have taken a bit of your time on this thing !

Share this post


Link to post
Share on other sites

Okay, I think I understood what you made Szhlopp :D

But it doesn't interpret correctly the @CR, I suppose I can put execute() somewhere to do the trick, but for now, i don't understand the benefit of using your function instead of my loop...

But I'm all hears opened, always ready to learn !

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Thanks you :D

In fact I wasn't asking for help, instead I proposed a solution that I found funtionnal and didn't find in here (really, and I spent time on a lot of topics) :D

But, GEOSoft you answered a question I was asking myself, I'll use your solution, it seems appropriate to my needs.

Szhlopp, i'll try your function after dinner, but I can't figure out what's the interest of replacing my code by yours... (without any malicious meaning : i just don't understand what's better in your code or what is wrong in mine ^^)

Maybe not anything. Just another way to do it. I think it may be easier but thats my opinion=)

And what is the msgbox for ?

Just showing it works.

The function grabs whatever paramater you give it(If you're using just a regular old text file)

Are regexp lighters than string expressions ?

Uhm?

Where do you assign the value to the variable ?

You don't. This was meant to work off of a txt file(Since you said INIread didn't work right for you)

-----------------------

$Text = Fileread(English.lng)

_GetText($Text, "lang_yes")

-----------------------

^^^ allows you to create a ton of different language files and always call the same function. The only difference is what "lang_yes" is in the file. It could return "Yes", "Si" or "Oui" depending on what file you read.

Do your code will interpret correctly the " & @CR & " so that linefeeds works ?

Will it? It should...

Well, i'll try it out, perhaps it will make me understand ;)

In all cases, thanks to have taken a bit of your time on this thing !

I did a quick sim through of the thread; I thought the way I proposed would make it easier to program with.

Hope that clears it up=)

Szh

Edited by Szhlopp

Share this post


Link to post
Share on other sites

I get it :D Okay, it's another way to do it, and I can feel that's better than my simple thing ^^

In fact, your function seems to balance the work during the loading of the controls where my loop do it all at the begining.

So, thanks for this function, I'll try to figure out a regexp to convert my variables into the call to _GetText ^^

about regexp/string thing, forget it, I was tired ^^

Share this post


Link to post
Share on other sites

Hello :D

Sorry to take all this time before feeding back here, I had to code others parts missing before arranging my language thing :D

So, after somes tries, a bit of regex, I managed to end with almost what you advice to me, I remove the language variable in the function call, and keep my initial structure for the translated string : Because I don't success with interpretation of @CR, or any other \N, @LF... I tried. It give me back the sting with @CR written in clear and with no Line feed. This is why I execute($str), to interpret the @CR correctly.

I'm interested in a way of doing this, even if it means to change @CR by something else, and remove " " delimiters ;)

But my principal problem for now is changing the language.

(I'll make the part that analyse the system language just after, i need to know if what I want is possible before, it will determine how I present the language choice, dialog before loading GUI, or instant changing buttons.)

So, I end up with this code :

$lang_def = FileRead(@ScriptDir & "\english.lng") ; loading of the default language

Func _GetText($str)
    If IsDeclared("lang_cur") Then             ; test if user has already click on a language button (that define $lang_cur)
        $lang_change = $lang_cur
    Else
        $lang_change = $lang_def           ; if not, keep default language
    EndIf
    $_SRE = StringRegExp($lang_change, $str & '\s?=(.*)', 1)          ; see explanations below **
    If @error = 1 Or @error = 2 Then $_SRE = StringRegExp($lang_def, $str & '\s?=(.*)', 1)
    If StringRight(StringToBinary($_SRE[0]), 2) = "0D" Then
        Return Execute(StringTrimRight($_SRE[0], 1))
    Else
        Return Execute($_SRE[0])
    EndIf
EndFunc   ;==>_GetText

$gui = GUICreate(_GetText("gui_title"), 330, 440) ; exemple of the calloÝ÷ Ù8b²«¶Ç­Èmë-®)à{ayÈh±éåjx.j¢~+j}ýµ·¢éÝÛj·!¶¬¶¸§)íç^}«­©à¹¨¶­Â)ejÊÈZ½ç¯z¼¬¶¸§ÀµêâµÈ^rGè­«)yÈÈZ­§-z¶­¶Ú¶«zÛ«çl¶¸§©Ý­é¨½è­úkzǧµ8^·­º¹íëkj{%jײÚâ-Â䲫}ç-+aÌÊ'íçëzw!~)^É¢²È§«-®)àÜ"VÞµ©úèØ^uçÚº[_W¦jH§§!j%x.jQ!»­!ø§v+[zÛ^®ØZ©Þr~'¥tÚ0#
.Ùbëh©Ù»­¶ìjëh×6Func _Change_lang($lang)
    $lang_cur = FileRead(@ScriptDir & "\" & $lang)

;; miss the refresh part

EndFunc   ;==>_Change_lang


$btn_lang_en = GUICtrlCreateButton("E", 290, 5, 16, 16)
$btn_lang_fr = GUICtrlCreateButton("F", 315, 5, 16, 16)


Do
  Switch $msg

     Case $btn_lang_fr
      _Change_lang("francais.lng")

     Case $btn_lang_en
      _Change_lang("english.lng")

  EndSwitch
Until $msg = $GUI_EVENT_CLOSE

The idea here is that a user click the button of his language, and the GUI load the appropriate file and apply the new strings. The thing is that I don't know, and didn't find any refresh, reload, switch, or similar function, that will do the trick instantly.

Is that a possible thing to do ?

Perhaps I miss a function or a macro, I don't know, I search a lot yesterday, with no luck at all ^^

Share this post


Link to post
Share on other sites

Thanks you for the quick answer :D

I deduct from you link that it's not possible to order the GUI to refresh his controls values, and that i have to pass thru a loop with GUICtrlSetData().

Ok, as I've no better idea, I will dig in this way.

Thanks again :D

Share this post


Link to post
Share on other sites

Thanks you for the quick answer :D

I deduct from you link that it's not possible to order the GUI to refresh his controls values, and that i have to pass thru a loop with GUICtrlSetData().

Ok, as I've no better idea, I will dig in this way.

Thanks again :D

Well you can re-update all of the controls. Store each control in an array and call it out one by one, GuiCtrlSetData($control[$i], iniread("my.ini", l"anguage", "1", $i)) or whatever.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0