QDate, KCalendarSystem, KDatePicker, and some API change proposals (long)

John Layt johnlayt at yahoo.com.au
Thu Jul 12 19:01:36 BST 2007


On Thursday 12 Jul 2007, Thiago Macieira wrote:
> John Layt wrote:
> >As for the need for a different locale, the educational and religious
> > use cases would be prime examples, you may have an
> > English/German/Spanish desktop but want to see your religions calendar
> > in Arabic or Hebrew.  OK, so a limited use case, but the libs should be
> > able to provide for it.
>
> You're not getting the point.
>
> You have a German desktop and a Hebrew calendar. That means you're getting
> the Hebrew dates, but in German.
>
> There's no need to change the locale for that application.

Yes, but my point is that on your German desktop using the Gregorian calendar, 
you may want to see the Hebrew calendar displayed in a plasmoid in Hebrew and 
not German, which is why KCalendarSystem was originally designed and 
implemented to allow you to pass in a different locale to the constructor, as 
noted in the KCalendarSystem documentation:

  /**
   * Constructor of abstract calendar class. This will be called by the 
derived classes.
   *
   * @param locale It will use this locale for translations, 0 means global.
   */
  explicit KCalendarSystem(const KLocale * locale = 0);

In fact,things are worse than I first thought.  Even for the simple case of 
having a Hebrew date picker in German on your German/Gregorian desktop, you 
still can't do it.  The way KDatePicker, KDateTable, & KDateWidget are 
implemented is to not only call the global locale for the calendar system to 
be displayed, but also for some of the date formating and translations.  
What's the problem with that?  Well, look at the dateChangedSlot() method 
from KDatePicker for example:

void
KDatePicker::dateChangedSlot(const QDate &date)
{
//snip
    const KCalendarSystem * calendar = KGlobal::locale()->calendar();

    d->line->setText(KGlobal::locale()->formatDate(date, KLocale::ShortDate));
    d->selectMonth->setText(calendar->monthName(date, false));
//snip

    emit(dateChanged(date));
}

So, even if we replace the KGlobal call to fetch the calendar to use a locally 
held Hebrew calendar system you want displayed, it translates some strings 
using that chosen calendar system, but other strings using the _global_ 
calendar system.  So what you end up with displaying in KDatePicker is 
selectMonth showing the correct Hebrew month translated in German, but line 
will show a formatted date string for the Gregorian equivalent date 
translated into German.  The reverse also applies with it using the global 
readDate(): when you type a date into the picker, it will read it as a 
Gregorian date, not a Hebrew one.  Very wrong.

The only solution I can see is to have KDatePicker hold a KCalendarSystem 
pointer and allow KDatePicker to access the currently protected locale() 
method on KCalendarSystem to get the right translation (via friend or making 
it public, but both options may expose too much).

(I had thought of having KDatePicker hold a KLocale pointer and get both the 
right calendar and translation from that, but if it defaults to KGlobal and 
you call setCalendar() on it, you change your global calendar by mistake!).

The whole thing is a can of worms I wish I'd opened earlier to give time to 
work out a proper solution.  Unless there's an obvious solution I'm missing?  
Otherwise the widgets may just have to wait for 4.1.

John.

--

Send instant messages to your online friends http://au.messenger.yahoo.com 





More information about the kde-core-devel mailing list