Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » U++ Library support » U++ Libraries and TheIDE: i18n, Unicode and Internationalization » Ctrl responds to Language-Setting event?
Ctrl responds to Language-Setting event? [message #35828] Tue, 27 March 2012 01:35 Go to next message
Lance is currently offline  Lance
Messages: 526
Registered: March 2007
Contributor

If I change language, the main menu reflects it immediately. Not other Ctrl-derivatives. Only Ctrls created afterwards will reflect the change in language setting. Is it a way to make Ctrls responds to change in language setting? For example, it is possible to defer language-translation to Paint() so that a call to Refresh() will do?


Another problem I encountered with changing language setting is with EditDate. Due to date scan format changing, it will not Accept() the date string it previously displayed.

Re: Ctrl responds to Language-Setting event? [message #35830 is a reply to message #35828] Tue, 27 March 2012 07:22 Go to previous messageGo to next message
dolik.rce is currently offline  dolik.rce
Messages: 1789
Registered: August 2008
Location: Czech Republic
Ultimate Contributor

Hi Lance Smile
Lance wrote on Tue, 27 March 2012 01:35


If I change language, the main menu reflects it immediately. Not other Ctrl-derivatives. Only Ctrls created afterwards will reflect the change in language setting. Is it a way to make Ctrls responds to change in language setting? For example, it is possible to defer language-translation to Paint() so that a call to Refresh() will do?

I was fighting the very same thing few weeks ago and the solution that seemed most elegant to me is this: For each GUI class I created a method Setup() which handled all the language dependent stuff - the layout initialization (CtrlLayout call) and all the code that used t_("") macro to assign translated strings to my Ctrls. If you call such function in constructor and also each time after the language changes, the labels will be translated correctly. The biggest problem I had was with GridCtrl, where I had to recreate all the contents because it contained some translated strings as well Smile.
Lance wrote on Tue, 27 March 2012 01:35

Another problem I encountered with changing language setting is with EditDate. Due to date scan format changing, it will not Accept() the date string it previously displayed.

I think simple workaround for this could be reading out the value to Date variable and assigning it back again after the change. Not tested, but should work Smile

In past I have also used slightly different approach, where I serialized the entire state of the application and then completely restarted the GUI. But that was way to crude, inefficient and involved a pointer Smile ... and on top of that it can't be done simply for every application.

Best regards,
Honza
Re: Ctrl responds to Language-Setting event? [message #35836 is a reply to message #35830] Tue, 27 March 2012 14:51 Go to previous messageGo to next message
Lance is currently offline  Lance
Messages: 526
Registered: March 2007
Contributor
Thank you for the suggestions, Honza! That's a lot of work though Smile



Re: Ctrl responds to Language-Setting event? [message #35842 is a reply to message #35836] Tue, 27 March 2012 18:43 Go to previous messageGo to next message
dolik.rce is currently offline  dolik.rce
Messages: 1789
Registered: August 2008
Location: Czech Republic
Ultimate Contributor

Lance wrote on Tue, 27 March 2012 14:51

Thank you for the suggestions, Honza! That's a lot of work though Smile

It is not that much work Smile Here is an example (from my not yet committed changes to HomeBudget example):
// this is a regular constructor:
HomeBudgetCategories::HomeBudgetCategories() {
	Add(spl.Horz(groups, categories));
	spl.SetPos(2000);

	groups.AddIndex(ID);
	groups.AddColumn(NAME, t_("Category")).Edit(eg);
	groups.Appending().Removing().Editing().Accepting().Canceling();
	groups.RejectNullRow();
	groups.SetToolBar();
	groups.WhenInsertRow = THISBACK(InsertGroup);
	groups.WhenUpdateRow = THISBACK(UpdateGroup);
	groups.WhenRemoveRow = THISBACK(RemoveGroup);
	groups.WhenChangeRow = THISBACK(ChangeGroup);

	categories.AddIndex(ID);
	categories.AddColumn(NAME, t_("Name")).Edit(ec);
	categories.AddColumn(DEFVALUE, t_("Default value")).Edit(defval).SetConvert(Single<ConvDouble>());
	categories.AddColumn(PM, t_("Plus / Minus")).Edit(dlpm).SetConvert(dlpm).Default(-1);
	categories.AddColumn(INNEWMONTH, t_("Default for a new month")).Edit(yesno).SetConvert(yesno).Default(0);
	categories.WhenInsertRow = THISBACK(InsertCategory);
	categories.WhenUpdateRow = THISBACK(UpdateCategory);
	categories.WhenRemoveRow = THISBACK(RemoveCategory);
	categories.WhenAcceptedRow = THISBACK(UpdateCategories);
	categories.Appending().Removing().Editing();
	categories.RejectNullRow();
	categories.SetToolBar();

	category.Resizeable(false).Header(false);
	category.AddPlus(THISBACK(NewCategory));
}

// ... and here is a function that (re)sets all the translated strings:
void HomeBudgetCategories::Setup() {
	// groups and categories are GridCtrls
	groups.GetColumn(1).Name(t_("Category"));

	categories.GetColumn(1).Name(t_("Name"));
	categories.GetColumn(2).Name(t_("Default value"));
	categories.GetColumn(3).Name(t_("Plus / Minus"));
	categories.GetColumn(4).Name(t_("Default for a new month"));
	//dlpm and yesno are DropGrid instances
	dlpm.Clear();
	dlpm.Add(-1, t_("Minus")).Add(1, t_("Plus"));
	yesno.Clear();
	yesno.Add(0, t_("No")).Add(1, t_("Yes"));

	LoadGroups();
	UpdateCategories();
	category <<= callback(expenses, &HomeBudgetExpenses::UpdateValue);
}

The Setup() method can be probably called from the constructor in most applications. In this example the HomeBudgetCategory is only one of three tabs more or less interconnected, so the Setup() is called from the main window constructor. Note that most of the code in Setup would be in constructor, so it is not that much more code, just some of it is moved to different place Wink

And here is a little example how the language changing code can look:
void HomeBudget::Options()
{
	WithOptionsLayout<TopWindow> dlg;
	CtrlLayoutOK(dlg, t_("Options"));
	Index<int> langs = GetLngSet(); // gets list of known languages
	for(int i = 0; i < langs.GetCount(); i++){
		// we iterate and search for translated strings - "Home budget" is a 
		// randomly chosen string that is probable to be translated 
		// in all languages (except English of course)
		String str = GetLngString(langs[i], "Home budget");
		if (i == 0 || str != "Home budget")
			// if the string is translated we add the language to the DropList
			dlg.lang.Add(langs[i], GetNativeLangName(langs[i]));
	}
	dlg.lang.SetIndex(max(dlg.lang.Find(GetCurrentLanguage()),0));
	dlg.clear <<= THISBACK(ClearAll);
	// check if the dialog was canceled or OKed
	if(dlg.Execute() != IDOK)
		return;
	// user clicked OK, lets change the language and reset all the strings
	SetLanguage(~dlg.lang);
	Setup();
}

The way I search for translations is not really great, but I didn't found anything that would work better without modifying U++ sources, so for now it has to work with this hack Smile

Best regards,
Honza

[Updated on: Tue, 27 March 2012 18:44]

Report message to a moderator

Re: Ctrl responds to Language-Setting event? [message #35850 is a reply to message #35842] Wed, 28 March 2012 05:38 Go to previous message
Lance is currently offline  Lance
Messages: 526
Registered: March 2007
Contributor
Very interesting. Thank you, Honza!
Previous Topic: Help for Indian Language Unicode display
Next Topic: How can I translate the controls for my app?
Goto Forum:
  


Current Time: Thu Mar 28 21:50:42 CET 2024

Total time taken to generate the page: 0.01853 seconds