Page 1 of 1

Changing labels on Mac menu bar

Posted: Wed Oct 24, 2012 1:36 pm
by stegemma
I have to translate label in standard application menu bar, on MAC OS X. Using FindItem doesn't works, because menu items are in different menu than those of main wxMenuBar of my frame. The menu items are added by wxMenuBar::Init() function (in wxWidgets sources). I don't want to subclass just to change labels but they are added "by code" and are not good for internationalization. Here's the wxWidgets code:

Code: Select all

    hideLabel = wxString::Format(_("Hide %s"), wxTheApp ? wxTheApp->GetAppDisplayName() : _("Application"));
    m_appleMenu->Append( wxID_OSX_HIDE, hideLabel + "\tCtrl+H" );    
    m_appleMenu->Append( wxID_OSX_HIDEOTHERS, _("Hide Others")+"\tAlt+Ctrl+H" );    
    m_appleMenu->Append( wxID_OSX_SHOWALL, _("Show All") );   
In Italy, we need the word "Nascondi" instead of "Hide", "Nascondi tutte" instead of "Hide others" and so on. I think in other countries they have the same problem.

So, it would be good to change this fixed strings ("Hide" etc) in wxWidgets sources to use something like string resources that can be internationalized. For now i've patched somehow the code, this way:

Code: Select all

void MainDialog::OnActivate( wxActivateEvent& event )
{
#if defined(__WXMAC__) && !wxOSX_USE_CARBON
	if(wxMenu * pAppleMenu=GetMenuBar()->m_rootMenu)
	{
		typedef struct
		{
			int idItem;
			const wxChar *newText;
		} tagTranslateMenuItem;

		tagTranslateMenuItem aryTranslate[] = { { wxID_OSX_HIDE, wxT("Nascondi Ammortamenti\tCtrl+H") },
			{ wxID_OSX_HIDEOTHERS, wxT("Nascondi altre\tAlt+Ctrl+H")} ,
			{ wxID_OSX_SHOWALL, wxT("Mostra tutte") },
			{ wxApp::s_macExitMenuItemId, wxT("Esci da Ammortamenti\tCtrl+Q") }
		};
		for(size_t i=0; i<ARRAY_COUNT(aryTranslate); i++)
		{
			// GetMenuBar()->SetLabel(aryTranslate[i].idItem, aryTranslate[i].newText);
			if(wxMenuItem *pMenuItem = pAppleMenu->FindItem(aryTranslate[i].idItem))
			{
				pMenuItem->SetItemLabel(aryTranslate[i].newText);
			}
		}

	}
#endif
	event.Skip();
}
This is a very bad solution... but it works. It requires to change menu.h header, to make m_rootMenu a public member... and this is the worst working solution that i've found in all my life :)

Re: Changing labels on Mac menu bar

Posted: Wed Oct 24, 2012 3:43 pm
by stegemma
Sorry, missed information:

wxWidgets 2.9.4 - static build release unicode
compiler GCC/G++ 4.2.1
CodeLite / wxFormBuilder
MAC OS X 10.7.5

Re: Changing labels on Mac menu bar

Posted: Wed Oct 24, 2012 4:10 pm
by doublemax
These strings are marked for translation and they exist in the italian .po file. Is your system set to Italian?

If not, try adding this to your wxApp::OnInit():

Code: Select all

wxLocale my_locale( wxLANGUAGE_ITALIAN );

Re: Changing labels on Mac menu bar

Posted: Wed Oct 24, 2012 4:52 pm
by stegemma
I'm trying internationalization using wxLocale but it is not clear how to get a .mo file from it.po

Re: Changing labels on Mac menu bar

Posted: Wed Oct 24, 2012 6:18 pm
by PB
When I needed a compiled message catalog, I opened the .po file in POEdit and just saved it, having "Automatically compile .mo file on save" checked in File/Preferences Editor Tab.

Re: Changing labels on Mac menu bar

Posted: Wed Oct 24, 2012 8:49 pm
by stegemma
PB wrote:When I needed a compiled message catalog, I opened the .po file in POEdit and just saved it, having "Automatically compile .mo file on save" checked in File/Preferences Editor Tab.
Many thanks to PB and doublemax. It works!

I've sligtly changed the code in:

http://wiki.wxwidgets.org/Internationalization

so that it compiles without warnings:

Code: Select all


wxLocale* locale;

bool InitLanguage(const wxString &ApplicationName, long Language)
{
	bool bOk = false;

	// load language if possible, fall back to english otherwise
	if(wxLocale::IsAvailable(Language))
	{
		locale = new wxLocale( Language ); // , wxLOCALE_CONV_ENCODING );

#ifdef __WXGTK__
		// add locale search paths
		locale->AddCatalogLookupPathPrefix(wxT("/usr"));
		locale->AddCatalogLookupPathPrefix(wxT("/usr/local"));
		wxStandardPaths* paths = (wxStandardPaths*) &wxStandardPaths::Get();
		wxString prefix = paths->GetInstallPrefix();
		locale->AddCatalogLookupPathPrefix( prefix );
#endif
		locale->AddCatalog(ApplicationName);

		bOk = locale->IsOk();
		if(!bOk)
		{
			delete locale;
		}
	}
	if(!bOk)
	{
		locale = new wxLocale( wxLANGUAGE_ENGLISH );
		// language = wxLANGUAGE_ENGLISH;
	}
	return bOk;
}