How to switch a language via switchLang without side effect of calling Initialize Scripts

Discussions about product bugs & problems!
Note: This is no replacement for the Official ETM Support!
15 posts • Page 1 of 2
flindecke
Posts:69
Joined: Wed Jun 24, 2015 1:54 pm

How to switch a language via switchLang without side effect of calling Initialize Scripts

Post by flindecke »

I have the problem to switch the language during runtime. This can be achieved by calling switchLang with a proper language index id.

My problem is, that every panel i already have created, must set the "LangChange redraw only" to true. Otherwise the initialize scripts will be called which results in bad behavior.
Furthermore whenever someone creates a new panel this person also has to set this flag to true.

My questions:
1) Is it possible to switch the language without this side effect and without setting above mentioned property for every panel?
2) When no, is it possible to set a default property for new panels?


Another problem is that sprintfPL uses the current WinCC OA language and it seems to be not possible to format a number using a specific language.
When i am not able to use switchLang due to above mentioned side effects, i need an API for formatting a number using a specific language and not with the side effect using current active one.
Does anybody knows a solution to this problem?

mkoller
Posts:741
Joined: Fri Sep 17, 2010 9:03 am

Re: How to switch a language via switchLang without side effect of calling Initialize Scripts

Post by mkoller »

Hi Frank,
> Furthermore whenever someone creates a new panel this person also has to set this flag to true.
only if there is code in the panel init script.

Answers:
ad 1) no
ad 2) no

> it seems to be not possible to format a number using a specific language.

This can only be done with a C++ Ctrl extension, since all our sprintf* CTRL functions already set the LC_NUMERIC locale
configuration to the requested language (sprintf -> always "C", sprintfPL - current project language, sprintfUL - user language from the OS)

flindecke
Posts:69
Joined: Wed Jun 24, 2015 1:54 pm

Re: How to switch a language via switchLang without side effect of calling Initialize Scripts

Post by flindecke »

Hello Martin,

thanks your reply. Due to your answers i wrote a control extension which formats a number based on a locale identifier like "de-DE" or "ru-RU" etc. using C++ standard functions.

I have learned some things about your WinCC OA API and my proposal for the Variable class API is:
A variable can be written to a string stream (std::stringstream) via "value->outToFile(stream)".
It would be nice also have an API for std::wstringstream (for using unicode characters) or better std::wostream.
Currently i have to check the VariableType by myself and cast each Variable instance to there corresponding class type.
This is error prone and bad to maintain.

The major problem of my solution is, that every base WinCC OA function which formats values, does not know by formatting function (e.g. any display or input fields).
So now i am trying to find another solution which validates the "LangChange redraw only" property of each panel.

My question is:
1) Is it possible to set the "LangChange redraw only" property via CTRL script, e.g. in an Initialize Script?
2) Does a GEDI hook exists when a file is saved? In such a case i could modify the file by myself and adding the desired property.

If no, than my last try is to modify the XML files directly afterwards.

All of these efforts has to be done, due to the side effect of switchLang and i must prevent people doing the wrong thing.

Gertjan van Schijndel
Posts:634
Joined: Mon Aug 02, 2010 10:37 am

Re: How to switch a language via switchLang without side effect of calling Initialize Scripts

Post by Gertjan van Schijndel »

What is the bad behavior that the second execution of the initialize script causes?
Perhaps it is easier to fix this bad behavior.

flindecke
Posts:69
Joined: Wed Jun 24, 2015 1:54 pm

Re: How to switch a language via switchLang without side effect of calling Initialize Scripts

Post by flindecke »

Hello Gertjan van Schijndel,

in my opinion and my assumption, an initialize handler of a panel should be called, when it is initialized. There exists a LangChanged handler, but initialize is called once more when "LangChange redraw only" is FALSE (and this is the default case!!!).

I understood the behavior of calling an initialize script once more, due to the evaluation of $-Parameters, but this seems to be a workaround to be "behavior conformant" to an old WinCC OA version.
It would be fine, when i will be able to set a default property value of "LangChange redraw only" which is the desired behavior for all panels in my project, or when i switch a language to decide if i want this side effect or not.

As long as this is not the case, all developers of new panels MUST know, that when a language is changed AND they have not set "LangChange redraw only" to true, their initialize script is might be called once more (without a call to terminate).
I bet on this case, that there will be a panel developer who forgets to set this property and some day later, the user will change the language and bam.... an initialize script is called once more which adds data to a combo box field, calls some functions on a library which changes a global state and everything gets weird. This failure is hard to find and debugging... do not ask.

The problem is, that you cannot prevent such a failure during panel development. People will call non-pure functions of a library (and these functions modify global state).
E.g. when you initalize the content elements of a combox in an initialize script and change the language during runtime, the content will be added once more. Without additional programming, you have no chance (with respect to "LangChange redraw only" property) to prevent this behavior. You do not even know in an initialize script, that it is called for panel initialization or because a language was changed.

Every single line you have write to prevent this behavior is a line too much, because it hides a side effect and will NOT FIX the root cause.

Furthermore i do not know how to set "LangChange redraw only" in Control. The only possibility to modify this property is to set it in GEDI or to modify the Panel XML file itself.

RudiKreiner
Posts:198
Joined: Mon May 16, 2011 2:10 pm

Re: How to switch a language via switchLang without side effect of calling Initialize Scripts

Post by RudiKreiner »

We have run into exactly the same problem as well and had to manually set "LangChange redraw only" in very many panels where we perform actions like those that Frank described.
But as Frank mentioned, when someone adds a new panel but doesn't test the change language feature or understand the problems that he sees there, the problem will appear again.

mkoller
Posts:741
Joined: Fri Sep 17, 2010 9:03 am

Re: How to switch a language via switchLang without side effect of calling Initialize Scripts

Post by mkoller »

> It would be nice also have an API for std::wstringstream (for using unicode characters) or better std::wostream.
Why would you need that ? In WinCC_OA we don't use wchar_t and deal always with multibyte encoded strings.
Also, outToFile() is not meant for formatting the values. Therefore you have Variable::formatValue().

To your questions:
ad 1) no
ad 2) yes. The script function pt_updateSumAlertPanel() is called (from pt.ctl). Not really meant for your purpose but you can use it for it. Just
make sure you overload the pt.ctl and change this function.
As an alternative, you could also use uiConnect() with the global "fileAdded" event which is also triggered (but is triggered not only for the just saved panel)

kilianvp
Posts:443
Joined: Fri Jan 16, 2015 10:29 am

Re: How to switch a language via switchLang without side effect of calling Initialize Scripts

Post by kilianvp »

if you call pt_updateSumAlertPanel() from ctrl you have to modify the original function first

flindecke
Posts:69
Joined: Wed Jun 24, 2015 1:54 pm

Re: How to switch a language via switchLang without side effect of calling Initialize Scripts

Post by flindecke »

Martin Koller wrote:
> It would be nice also have an API for std::wstringstream (for using unicode characters) or better std::wostream.
Why would you need that ? In WinCC_OA we don't use wchar_t and deal always with multibyte encoded strings.
Also, outToFile() is not meant for formatting the values. Therefore you have Variable::formatValue().

To your questions:
ad 1) no
ad 2) yes. The script function pt_updateSumAlertPanel() is called (from pt.ctl). Not really meant for your purpose but you can use it for it. Just
make sure you overload the pt.ctl and change this function.
As an alternative, you could also use uiConnect() with the global "fileAdded" event which is also triggered (but is triggered not only for the just saved panel)
Some thoughts about your answers...

I need to use w_char, because WinCC OA has the above mentioned side effect when calling switchLang and i need a way to format numbers.
Though i cannot use switchLang (or changeLang which i have found and which is not mentioned in section Multilinguage Help documentation).

My own API provides a locale parameter, which is routed through the C++ locale API. WinCC OA API depends on side effect variable returned by getActiveLang().
Furthermore Variable::formatValue works only when getActiveLang is choosen properly (which is currently not the case due to the side effect in the panels). It is not possible to format a value for another language. So i was not able to use this function either.
I decided to use a c++ unicode stream and configure it properly depending on the format (not the best way, but it works perfect) and a locale.

My goal is to format a number 123456.789 in german like "123.456,789", in english "123,456.789" and in russian like "123 456,789" where the space is NOT a 0x20 char but 0xc2 (in UTF-8; seems to be a half wide space).


My lessons learned so far in WinCC OA ...
1) ... switching the language without reloading all panels is not possible by default in CTRL; every(!) user has to be aware of this case and SHOULD NEVER EVER FORGET TO SET "LangChange redraw only" properly in GEDI for every panel(!!!)
2) ... formatting a value for another language is not possible by default in CTRL
3) ... WinCC OA CharString handles unicode (nice), but there exists no API for formatting it (e.g. via Variable::formatValue) using a specific locale; the implementation seems to use the current active language (given by getActiveLang() in CTRL)
4) ... it is not possible to change the property "LangChange redraw only" programmatically
5) ... there exists no default property setting in a project for "LangChagne redraw only"
6) ... it is not possible to check "LangChagne redraw only" in CTRL (so i cannot check it during runtime, when panels are loaded)
7) ... in CTRL it is not possible in an Initialize Script to check if Initialize is called for initializing the panel or caused by a language change and "LangChange redraw only" is at the default value (with respect to 4, 5 and 6)

All of my efforts were driven by getting rid of the side effect of "switchLang" which crash by UI totally. In any way i have to deal with some drawbacks (sometimes behavior, sometimes maintenance of code).
I want to make it hard for the panel developer to make it wrong and easy to make it right and NOT VICE VERSA.

So i will try to write a script which changes the panel files directly by setting the switchLang property in these files (which can be called before committing a file).
My hope is, that i can use switchLang afterwards and format values via sprintf CTRL function which should be formatted like the C++ std library API.


Final thoughts on pt_updateSumAlertPanel() in pt.ctl or uiConnect and global event "fileAdded":
As you mentioned, there exists no CTRL API to check or modify "LangChange redraw only" property. So changing the property has to be done outside of CTRL.
Perhaps i can use global event "fileAdded" to add the property my selfs after file is created and before file is presented to the user.
I will give it a try when i finished the above mentioned modify panel script.

With kind regards,
Frank

fmulder
Posts:330
Joined: Wed Feb 03, 2010 9:46 am

Re: How to switch a language via switchLang without side effect of calling Initialize Scripts

Post by fmulder »

I had a similar problems years ago which we solved quite simple.

* The basepanel would react to the language change event. We would then do some work, updating some global variables and then do a dpSet() to our own datapoint. something called "LanguagehasChangedAndGlobalshaveBeenUpdated"
* The relevant graphics symbols, that have a dpConnect() on some proces data, would include the element "LanguagehasChangedAndGlobalshaveBeenUpdated"

I would not make your own sprintf(). Instead I would do the formatting in scripting which seems fairly simple. Just strreplace the "." by a " ".
Making a control DLL has the disadvantage that you'll need to recompile with every new version

Share the fun
Frenk Mulder

15 posts • Page 1 of 2