Date format in wxLocale Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
maxbld
Earned some good credits
Earned some good credits
Posts: 113
Joined: Wed Jan 30, 2013 10:49 pm

Date format in wxLocale

Post by maxbld »

Dear all,

when I call wxDateTime.Format I always get back a date written in English, even though my win OS is set to another language. If I set say wxLocale locale(wxLANGUAGE_ITALIAN); then the date is formatted in Italian, but ONLY locally in the wxLocale locale object scope.

How can I make the settings global to my whole application, please?

BR,
Max.
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4193
Joined: Sun Jan 03, 2010 5:45 pm

Re: Date format in wxLocale

Post by PB »

You answered your own question already. In order to preserve the set locale, its instance can not go out of scope. If your locale is supposed to be application-wide, set it e.g. in the OnInit() method of your wxApp instance. You can take a look at the code in the internat sample (located in %WXWIN%\samples\internat folder).
maxbld
Earned some good credits
Earned some good credits
Posts: 113
Joined: Wed Jan 30, 2013 10:49 pm

Re: Date format in wxLocale

Post by maxbld »

PB wrote:You answered your own question already. In order to preserve the set locale, its instance can not go out of scope. If your locale is supposed to be application-wide, set it e.g. in the OnInit() method of your wxApp instance. You can take a look at the code in the internat sample (located in %WXWIN%\samples\internat folder).
OK. And that way I get a m_locale member of the mainframe of my app which I can use app-spread. But what if I have e.g. a wxGrid and i set a cell renderer for the date:

Code: Select all

		wxGridCellDateTimeRenderer *dateRenderer = new wxGridCellDateTimeRenderer(wxLocale::GetInfo(wxLOCALE_LONG_DATE_FMT), wxLocale::GetInfo(wxLOCALE_DATE_TIME_FMT));
		Grid->SetCellRenderer(row, (*mapArray)[col].pos, dateRenderer);
Here I set the format of the date, but not the language in which a long date will be written in the cell. Actually that choice is made inside the wxWidgets dll for the wxGridCellDateTimeRenderer::Draw, when it calls wxGridCellDateTimeRenderer::GetString. Down there my m_locale doesn't exist, but I would have expected the format would have been retrieved based on the regional settings of the OS. Please don't tell me I have to override wxGridCellDateTimeRenderer, I'm too lazy for that and I would have expected it work on its own by getting the OS settings. It's quite surprising to me to see that OS regional settings are ignored...

Thanks a lot, BR,
Max.
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4193
Joined: Sun Jan 03, 2010 5:45 pm

Re: Date format in wxLocale

Post by PB »

Sorry, I have no experience whatsoever with wxGridCellDateTimeRenderer, so I just ask again: Is the locale you set earlier still in effect during the lifetime of your Grid? In another words, set your locale before you create the grid and ensure its instance doesn't get destroyed before the grid/frame does, e.g. the locale is a member variable of the class you derived from wxApp or wxFrame.
maxbld
Earned some good credits
Earned some good credits
Posts: 113
Joined: Wed Jan 30, 2013 10:49 pm

Re: Date format in wxLocale

Post by maxbld »

Well, here is happening something I don't understand: all my app has the locale I initialize in wxApp::OnInit() and I pass to wxLocale wxFrame::m_locale of my app.

But the wxGrid, which I create in the constructor of wxFrame has a different wxLocale. Actually the wxGrid is child of a wxAuiNotebook object which is a child of the wxFrame of the app, and is a pane to a wxAuiManager that manages the wxFrame itself. I wonder if in one of these passages there is a new wxLocale getting focus over the subsequent childs...
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Date format in wxLocale

Post by doublemax »

all my app has the locale I initialize in wxApp::OnInit() and I pass to wxLocale wxFrame::m_locale of my app.
I'm not quite sure what you mean here.

Anyway, it's pretty simple in principle: The locale settings is always application-wide. You only need one active wxLocale instance, usually as member variable of wxApp and initialize it in wxApp::OnInit(). After that you don't have to touch it any more and you don't have to pass the object around to other classes.

Alternatively, calling wxApp::SetCLocale() should also work.
Use the source, Luke!
maxbld
Earned some good credits
Earned some good credits
Posts: 113
Joined: Wed Jan 30, 2013 10:49 pm

Re: Date format in wxLocale

Post by maxbld »

doublemax wrote:
all my app has the locale I initialize in wxApp::OnInit() and I pass to wxLocale wxFrame::m_locale of my app.
I'm not quite sure what you mean here.
what I mean is if I put a piece of code like

Code: Select all

	wxString str;
	str.Printf(wxT("current date: %s"), wxDateTime::Now().Format("%A %d %B %Y"));
	wxMessageBox( str );
wherever in my app, I get the expected result: the date is written in the language I set. BUT, the date written in a cell of the wxGrid i istantiated as described above (so inside wxFrame), is always in English, regardless what did I set in wxApp::OnInit(). And that's against the documented behavior. So, since the wxGrid is inside an AUI Manager, I was wondering if something is creating a sub-domain for wxLocale in the panes of the wxAuiManager object?

So wxDateTime::Format works anywhere in my app, but in the wxWidgets standard code that actually writes the date in the wxGrid cell the wxLocale settings seem to be ignored:

Code: Select all

wxString wxGridCellDateTimeRenderer::GetString(const wxGrid& grid, int row, int col)
{
    wxGridTableBase *table = grid.GetTable();

    bool hasDatetime = false;
    wxDateTime val;
    wxString text;
    if ( table->CanGetValueAs(row, col, wxGRID_VALUE_DATETIME) )
    {
        void * tempval = table->GetValueAsCustom(row, col,wxGRID_VALUE_DATETIME);

        if (tempval)
        {
            val = *((wxDateTime *)tempval);
            hasDatetime = true;
            delete (wxDateTime *)tempval;
        }

    }

    if (!hasDatetime )
    {
        text = table->GetValue(row, col);
        const char * const end = val.ParseFormat(text, m_iformat, m_dateDef);
        hasDatetime = end && !*end;
    }

    if ( hasDatetime )
        text = val.Format(m_oformat, m_tz );

    // If we failed to parse string just show what we where given?
    return text;
}
Having m_oformat = "%A %d %B %Y", the value of text = val.Format(m_oformat, m_tz ); is a string written in English, even though the wxLocale was constructed with another language and elsewhere in my app it did write it in the right language.

If I derive my own renderer and override the Draw function so that it calls my own version of GetString, I should have solved the issue, but it's really crappy... How comes the standard GetString doesn't work?? Is it a bug?
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Date format in wxLocale

Post by doublemax »

The code in wxGridCellDateTimeRenderer looks ok. But as the "grid" sample doesn't use this class, i can't test this easily.

So if you want someone to look into this, you'll have to create a patch to the grid sample that shows the problem.
Use the source, Luke!
maxbld
Earned some good credits
Earned some good credits
Posts: 113
Joined: Wed Jan 30, 2013 10:49 pm

Re: Date format in wxLocale

Post by maxbld »

Dear all,

I've been misled by the internat sample: There wxLocale::Init is used, which in my project didn't work well (I got asserts in intl.cpp ln 1445 of method wxLocale::GetInfo) I don't know what was I doing wrong, but for the moment I don't care much, since I've no internationalization nor dictionary files. I guess something in wxLocale::Init or in m_locale.AddCatalog("wxstd"); was messing it up... Anyway after that, I ended up with a wxLocale object local to wxApp::OnInit(). So it was alive until the end of the wxFrame::wxFrame c'tor, then it was deleted. By declaring it as wxLocale *wxApp::m_locale, everything works well, the wxGrid too. Actually even though the wxGrid was instantiated by the wxFrame::wxFrame c'tor, then the wxGridCellDateTimeRenderer::Draw was called on mouse event when the part of the grid containing the date had to be drawn, and that was in the eventloop, outside the wxFrame::wxFrame c'tor.

So sorry for wasting your time, hope somebody finds this post useful in case he does my same mistake.

BR,
Max.
Post Reply