[haiku-commits] r37517 - in haiku/trunk: headers/os/locale src/kits/locale src/preferences/time

  • From: pulkomandy@xxxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 14 Jul 2010 18:43:05 +0200 (CEST)

Author: pulkomandy
Date: 2010-07-14 18:43:04 +0200 (Wed, 14 Jul 2010)
New Revision: 37517
Changeset: http://dev.haiku-os.org/changeset/37517

Modified:
   haiku/trunk/headers/os/locale/Country.h
   haiku/trunk/src/kits/locale/Country.cpp
   haiku/trunk/src/preferences/time/DateTimeEdit.cpp
Log:
 * Allow use of unicode character in time view
 * Some support for languages having an order different than H:M:S:AM (like 
chinese). Does not seem to work too well, but I can't spot what I missed
 * API to get the infos about the type of each field in a time format


Modified: haiku/trunk/headers/os/locale/Country.h
===================================================================
--- haiku/trunk/headers/os/locale/Country.h     2010-07-14 15:32:00 UTC (rev 
37516)
+++ haiku/trunk/headers/os/locale/Country.h     2010-07-14 16:43:04 UTC (rev 
37517)
@@ -20,7 +20,15 @@
        B_US
 };
 
+typedef enum {
+       B_INVALID = B_BAD_DATA,
+       B_AM_PM = 0,
+       B_HOUR,
+       B_MINUTE,
+       B_SECOND
+} BDateField;
 
+
 class BCountry {
        public:
                BCountry(const char* languageCode, const char* countryCode);
@@ -44,7 +52,9 @@
                virtual void    FormatTime(BString* string, time_t time,
                        bool longFormat);
                status_t                FormatTime(BString* string, int*& 
fieldPositions,
-                       int& fieldCount, time_t time, bool LongFormat);
+                       int& fieldCount, time_t time, bool longFormat);
+               status_t                TimeFields(BDateField*& fields, int& 
fieldCount,
+                       bool longFormat);
 
                bool            DateFormat(BString&, bool longFormat) const;
                void            SetDateFormat(const char* formatString,

Modified: haiku/trunk/src/kits/locale/Country.cpp
===================================================================
--- haiku/trunk/src/kits/locale/Country.cpp     2010-07-14 15:32:00 UTC (rev 
37516)
+++ haiku/trunk/src/kits/locale/Country.cpp     2010-07-14 16:43:04 UTC (rev 
37517)
@@ -8,6 +8,7 @@
 #include <Country.h>
 
 #include <assert.h>
+#include <iostream>
 #include <stdlib.h>
 #include <vector>
 
@@ -239,6 +240,61 @@
 }
 
 
+status_t
+BCountry::TimeFields(BDateField*& fields, int& fieldCount, bool longFormat)
+{
+       fields = NULL;
+       UErrorCode error = U_ZERO_ERROR;
+       ICU_VERSION::DateFormat* timeFormatter;
+       ICU_VERSION::FieldPositionIterator positionIterator;
+       timeFormatter = longFormat ? fICULongTimeFormatter : 
fICUShortTimeFormatter;
+       UnicodeString ICUString;
+       time_t now;
+       ICUString = timeFormatter->format((UDate)time(&now) * 1000, ICUString,
+               &positionIterator, error);
+
+       if (error != U_ZERO_ERROR)
+               return B_ERROR;
+
+       ICU_VERSION::FieldPosition field;
+       std::vector<int> fieldPosStorage;
+       fieldCount  = 0;
+       while (positionIterator.next(field)) {
+               fieldPosStorage.push_back(field.getField());
+               fieldCount ++;
+       }
+
+       fields = (BDateField*) malloc(fieldCount * sizeof(BDateField));
+
+       for (int i = 0 ; i < fieldCount ; i++ ) {
+               switch (fieldPosStorage[i]) {
+                       case UDAT_HOUR_OF_DAY1_FIELD:
+                       case UDAT_HOUR_OF_DAY0_FIELD:
+                       case UDAT_HOUR1_FIELD:
+                       case UDAT_HOUR0_FIELD:
+                               fields[i] = B_HOUR;
+                               break;
+                       case UDAT_MINUTE_FIELD:
+                               fields[i] = B_MINUTE;
+                               break;
+                       case UDAT_SECOND_FIELD:
+                               fields[i] = B_SECOND;
+                               break;
+                       case UDAT_AM_PM_FIELD:
+                               fields[i] = B_AM_PM;
+                               break;
+                       default:
+                               std::cout << "invalid field id " << 
fieldPosStorage[i] 
+                                       << std::endl;
+                               fields[i] = B_INVALID;
+                               break;
+               }
+       }
+
+       return B_OK;
+}
+
+
 bool
 BCountry::DateFormat(BString& format, bool longFormat) const
 {

Modified: haiku/trunk/src/preferences/time/DateTimeEdit.cpp
===================================================================
--- haiku/trunk/src/preferences/time/DateTimeEdit.cpp   2010-07-14 15:32:00 UTC 
(rev 37516)
+++ haiku/trunk/src/preferences/time/DateTimeEdit.cpp   2010-07-14 16:43:04 UTC 
(rev 37517)
@@ -115,15 +115,13 @@
        country->FormatTime(&text, fieldPositions, fieldCount, time, true);
                // TODO : this should be cached somehow to not redo it for each 
field
 
-       if (index * 2 + 1 > fieldCount) {
+       if (index * 2 + 1 >= fieldCount) {
                free(fieldPositions);
                return;
        }
 
        BString field;
-       // TODO : the following calculations assume chars are 8-bit. The
-       // fieldPositions are character index, not byte index.
-       field.SetTo(text.String()+fieldPositions[index * 2],
+       text.CopyCharsInto(field, fieldPositions[index * 2],
                fieldPositions[index * 2 + 1] - fieldPositions[index * 2]);
 
        free(fieldPositions);
@@ -136,8 +134,7 @@
 
        SetHighColor(0, 0, 0, 255);
        FillRect(bounds, B_SOLID_LOW);
-       DrawString(field.String(), bounds.LeftBottom() - offset);
-
+       DrawString(field, bounds.LeftBottom() - offset);
 }
 
 
@@ -169,9 +166,7 @@
        }
 
        BString field;
-       // TODO : the following calculations assume chars are 8-bit. The
-       // fieldPositions are character index, not byte index.
-       field.SetTo(text.String()+fieldPositions[index * 2  + 1],
+       text.CopyCharsInto(field, fieldPositions[index * 2 + 1],
                fieldPositions[index * 2 + 2] - fieldPositions[index * 2 + 1]);
 
        free(fieldPositions);
@@ -274,14 +269,27 @@
 
        message->AddBool("time", true);
 
+       BDateField* dateFormat;
+       int fieldCount;
+       BCountry* here;
+       be_locale_roster->GetDefaultCountry(&here);
+       here->TimeFields(dateFormat, fieldCount, true);
+       if (fFocus > fieldCount) {
+               free(dateFormat);
+               return;
+       }
+
        for (int32 index = 0; index < fSectionList->CountItems() -1; ++index) {
                uint32 data = _SectionValue(index);
 
                if (fFocus == index)
                        data = fHoldValue;
 
-               message->AddInt32(fields[index], data);
+               if (dateFormat[index] < 3)
+                       message->AddInt32(fields[dateFormat[index]], data);
        }
+
+       free(dateFormat);
 }
 
 
@@ -289,9 +297,17 @@
 TTimeEdit::_CheckRange()
 {
        int32 value = fHoldValue;
-       switch (fFocus) {
-               case 0:
-                       // hour
+       BDateField* fields;
+       int fieldCount;
+       BCountry* here;
+       be_locale_roster->GetDefaultCountry(&here);
+       here->TimeFields(fields, fieldCount, true);
+       if (fFocus > fieldCount) {
+               free(fields);
+               return;
+       }
+       switch (fields[fFocus]) {
+               case B_HOUR:
                        if (value > 23)
                                value = 0;
                        else if (value < 0)
@@ -300,8 +316,7 @@
                        fTime.SetTime(value, fTime.Minute(), fTime.Second());
                        break;
 
-               case 1:
-                       // minute
+               case B_MINUTE:
                        if (value> 59)
                                value = 0;
                        else if (value < 0)
@@ -310,8 +325,7 @@
                        fTime.SetTime(fTime.Hour(), value, fTime.Second());
                        break;
 
-               case 2:
-                       // second
+               case B_SECOND:
                        if (value > 59)
                                value = 0;
                        else if (value < 0)
@@ -320,8 +334,7 @@
                        fTime.SetTime(fTime.Hour(), fTime.Minute(), value);
                        break;
 
-               case 3:
-                       // AM/PM
+               case B_AM_PM:
                        value = fTime.Hour();
                        if (value < 13)
                                value += 12;
@@ -335,9 +348,12 @@
                        break;
 
                default:
+                       free(fields);
                        return;
        }
 
+       free(fields);
+
        fHoldValue = value;
        Invalidate(Bounds());
 }
@@ -347,29 +363,37 @@
 TTimeEdit::_IsValidDoubleDigi(int32 value)
 {
        bool isInRange = false;
-       switch (fFocus) {
-               case 0:
-                       // hour
+       BDateField* fields;
+       int fieldCount;
+       BCountry* here;
+       be_locale_roster->GetDefaultCountry(&here);
+       here->TimeFields(fields, fieldCount, true);
+       if (fFocus > fieldCount) {
+               free(fields);
+               return false;
+       }
+       switch (fields[fFocus]) {
+               case B_HOUR:
                        if (value <= 23)
                                isInRange = true;
                        break;
 
-               case 1:
-                       // minute
+               case B_MINUTE:
                        if (value <= 59)
                                isInRange = true;
                        break;
 
-               case 2:
-                       // second
+               case B_SECOND:
                        if (value <= 59)
                                isInRange = true;
                        break;
 
                default:
+                       free(fields);
                        return isInRange;
        }
 
+       free(fields);
        return isInRange;
 }
 
@@ -378,16 +402,25 @@
 TTimeEdit::_SectionValue(int32 index) const
 {
        int32 value;
-       switch (index) {
-               case 0:
+       BDateField* fields;
+       int fieldCount;
+       BCountry* here;
+       be_locale_roster->GetDefaultCountry(&here);
+       here->TimeFields(fields, fieldCount, true);
+       if (index > fieldCount) {
+               free(fields);
+               return 0;
+       }
+       switch (fields[index]) {
+               case B_HOUR:
                        value = fTime.Hour();
                        break;
 
-               case 1:
+               case B_MINUTE:
                        value = fTime.Minute();
                        break;
 
-               case 2:
+               case B_SECOND:
                        value = fTime.Second();
                        break;
 
@@ -396,6 +429,7 @@
                        break;
        }
 
+       free(fields);
        return value;
 }
 


Other related posts: