]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/datetimefmt.cpp
set icons bundle, not single icon, for frames loaded from XRC
[wxWidgets.git] / src / common / datetimefmt.cpp
index ece5bff59f98882092c3bcb846fdc375b149d68f..91d64529812854cee56afa35f1837809d67531ae 100644 (file)
@@ -92,42 +92,6 @@ static const int MIN_PER_HOUR = 60;
 namespace
 {
 
-#ifdef HAVE_STRPTIME
-
-#if wxUSE_UNIX && !defined(HAVE_STRPTIME_DECL)
-    // configure detected that we had strptime() but not its declaration,
-    // provide it ourselves
-    extern "C" char *strptime(const char *, const char *, struct tm *);
-#endif
-
-// strptime() wrapper: call strptime() for the string starting at the given
-// iterator and fill output tm struct with the results and modify input to
-// point to the end of the string consumed by strptime() if successful,
-// otherwise return false and don't modify anything
-bool
-CallStrptime(const wxString& str,
-             wxString::const_iterator& p,
-             const char *fmt,
-             tm *tm)
-{
-    // convert from iterator to char pointer: this is simple as wxCStrData
-    // already supports this
-    const char * const start = str.c_str() + (p - str.begin());
-
-    const char * const end = strptime(start, fmt, tm);
-    if ( !end )
-        return false;
-
-    // convert back from char pointer to iterator: unfortunately we have no way
-    // to do it efficiently currently so create a temporary string just to
-    // compute the number of characters between start and end
-    p += wxString(start, end - start).length();
-
-    return true;
-}
-
-#endif // HAVE_STRPTIME
-
 enum
 {
     DateLang_English = 1,
@@ -281,15 +245,13 @@ ParseFormatAt(wxString::const_iterator& p,
               // FIXME-VC6: using wxString() instead of wxEmptyString in the
               //            line below results in error C2062: type 'class
               //            wxString (__cdecl *)(void)' unexpected
-              const wxString& fmtAlt = wxEmptyString,
-              const wxString& fmtAlt2 = wxString())
+              const wxString& fmtAlt = wxEmptyString)
 {
     const wxString str(p, end);
     wxString::const_iterator endParse;
     wxDateTime dt;
     if ( dt.ParseFormat(str, fmt, &endParse) ||
-            (!fmtAlt.empty() && dt.ParseFormat(str, fmtAlt, &endParse)) ||
-                (!fmtAlt2.empty() && dt.ParseFormat(str, fmtAlt2, &endParse)) )
+            (!fmtAlt.empty() && dt.ParseFormat(str, fmtAlt, &endParse)) )
     {
         p += endParse - str.begin();
     }
@@ -901,166 +863,6 @@ wxDateTime::ParseRfc822Date(const wxString& date, wxString::const_iterator *end)
     return true;
 }
 
-#ifdef __WINDOWS__
-
-// returns the string containing strftime() format used for short dates in the
-// current locale or an empty string
-static wxString GetLocaleDateFormat()
-{
-    wxString fmtWX;
-
-    // there is no setlocale() under Windows CE, so just always query the
-    // system there
-#ifndef __WXWINCE__
-    if ( strcmp(setlocale(LC_ALL, NULL), "C") != 0 )
-#endif
-    {
-        // The locale was programatically set to non-C. We assume that this was
-        // done using wxLocale, in which case thread's current locale is also
-        // set to correct LCID value and we can use GetLocaleInfo to determine
-        // the correct formatting string:
-#ifdef __WXWINCE__
-        LCID lcid = LOCALE_USER_DEFAULT;
-#else
-        LCID lcid = GetThreadLocale();
-#endif
-        // according to MSDN 80 chars is max allowed for short date format
-        wxChar fmt[81];
-        if ( ::GetLocaleInfo(lcid, LOCALE_SSHORTDATE, fmt, WXSIZEOF(fmt)) )
-        {
-            wxChar chLast = _T('\0');
-            size_t lastCount = 0;
-            for ( const wxChar *p = fmt; /* NUL handled inside */; p++ )
-            {
-                if ( *p == chLast )
-                {
-                    lastCount++;
-                    continue;
-                }
-
-                switch ( *p )
-                {
-                    // these characters come in groups, start counting them
-                    case _T('d'):
-                    case _T('M'):
-                    case _T('y'):
-                    case _T('g'):
-                        chLast = *p;
-                        lastCount = 1;
-                        break;
-
-                    default:
-                        // first deal with any special characters we have had
-                        if ( lastCount )
-                        {
-                            switch ( chLast )
-                            {
-                                case _T('d'):
-                                    switch ( lastCount )
-                                    {
-                                        case 1: // d
-                                        case 2: // dd
-                                            // these two are the same as we
-                                            // don't distinguish between 1 and
-                                            // 2 digits for days
-                                            fmtWX += _T("%d");
-                                            break;
-
-                                        case 3: // ddd
-                                            fmtWX += _T("%a");
-                                            break;
-
-                                        case 4: // dddd
-                                            fmtWX += _T("%A");
-                                            break;
-
-                                        default:
-                                            wxFAIL_MSG( _T("too many 'd's") );
-                                    }
-                                    break;
-
-                                case _T('M'):
-                                    switch ( lastCount )
-                                    {
-                                        case 1: // M
-                                        case 2: // MM
-                                            // as for 'd' and 'dd' above
-                                            fmtWX += _T("%m");
-                                            break;
-
-                                        case 3:
-                                            fmtWX += _T("%b");
-                                            break;
-
-                                        case 4:
-                                            fmtWX += _T("%B");
-                                            break;
-
-                                        default:
-                                            wxFAIL_MSG( _T("too many 'M's") );
-                                    }
-                                    break;
-
-                                case _T('y'):
-                                    switch ( lastCount )
-                                    {
-                                        case 1: // y
-                                        case 2: // yy
-                                            fmtWX += _T("%y");
-                                            break;
-
-                                        case 4: // yyyy
-                                            fmtWX += _T("%Y");
-                                            break;
-
-                                        default:
-                                            wxFAIL_MSG( _T("wrong number of 'y's") );
-                                    }
-                                    break;
-
-                                case _T('g'):
-                                    // strftime() doesn't have era string,
-                                    // ignore this format
-                                    wxASSERT_MSG( lastCount <= 2,
-                                                  _T("too many 'g's") );
-                                    break;
-
-                                default:
-                                    wxFAIL_MSG( _T("unreachable") );
-                            }
-
-                            chLast = _T('\0');
-                            lastCount = 0;
-                        }
-
-                        // not a special character so must be just a separator,
-                        // treat as is
-                        if ( *p != _T('\0') )
-                        {
-                            if ( *p == _T('%') )
-                            {
-                                // this one needs to be escaped
-                                fmtWX += _T('%');
-                            }
-
-                            fmtWX += *p;
-                        }
-                }
-
-                if ( *p == _T('\0') )
-                    break;
-            }
-        }
-        //else: GetLocaleInfo() failed, leave fmtDate value unchanged and
-        //      try our luck with the default formats
-    }
-    //else: default C locale, default formats should work
-
-    return fmtWX;
-}
-
-#endif // __WINDOWS__
-
 bool
 wxDateTime::ParseFormat(const wxString& date,
                         const wxString& format,
@@ -1108,7 +910,7 @@ wxDateTime::ParseFormat(const wxString& date,
             {
                 // a white space in the format string matches 0 or more white
                 // spaces in the input
-                while ( wxIsspace(*input) )
+                while ( input != end && wxIsspace(*input) )
                 {
                     input++;
                 }
@@ -1117,7 +919,7 @@ wxDateTime::ParseFormat(const wxString& date,
             {
                 // any other character (not whitespace, not '%') must be
                 // matched by itself in the input
-                if ( *input++ != *fmt )
+                if ( input == end || *input++ != *fmt )
                 {
                     // no match
                     return false;
@@ -1203,49 +1005,38 @@ wxDateTime::ParseFormat(const wxString& date,
 
             case _T('c'):       // locale default date and time  representation
                 {
-#ifdef HAVE_STRPTIME
-                    struct tm tm;
+                    wxDateTime dt;
 
-                    // try using strptime() -- it may fail even if the input is
-                    // correct but the date is out of range, so we will fall back
-                    // to our generic code anyhow
-                    if ( CallStrptime(date, input, "%c", &tm) )
-                    {
-                        hour = tm.tm_hour;
-                        min = tm.tm_min;
-                        sec = tm.tm_sec;
+                    const wxString
+                        fmtDateTime = wxLocale::GetInfo(wxLOCALE_DATE_TIME_FMT);
+                    if ( !fmtDateTime.empty() )
+                        dt = ParseFormatAt(input, end, fmtDateTime);
 
-                        year = 1900 + tm.tm_year;
-                        mon = (Month)tm.tm_mon;
-                        mday = tm.tm_mday;
+                    if ( !dt.IsValid() )
+                    {
+                        // also try the format which corresponds to ctime()
+                        // output (i.e. the "C" locale default)
+                        dt = ParseFormatAt(input, end, wxS("%a %b %d %H:%M:%S %Y"));
                     }
-                    else // strptime() failed; try generic heuristic code
-#endif // HAVE_STRPTIME
+
+                    if ( !dt.IsValid() )
                     {
+                        // and finally also the two generic date/time formats
+                        dt = ParseFormatAt(input, end, wxS("%x %X"), wxS("%X %x"));
+                    }
 
-                        // try the format which corresponds to ctime() output
-                        // first, then the generic date/time formats
-                        const wxDateTime dt = ParseFormatAt
-                                              (
-                                                input,
-                                                end,
-                                                wxS("%a %b %d %H:%M:%S %Y"),
-                                                wxS("%x %X"),
-                                                wxS("%X %x")
-                                              );
-                        if ( !dt.IsValid() )
-                            return false;
+                    if ( !dt.IsValid() )
+                        return false;
 
-                        Tm tm = dt.GetTm();
+                    const Tm tm = dt.GetTm();
 
-                        hour = tm.hour;
-                        min = tm.min;
-                        sec = tm.sec;
+                    hour = tm.hour;
+                    min = tm.min;
+                    sec = tm.sec;
 
-                        year = tm.year;
-                        mon = tm.mon;
-                        mday = tm.mday;
-                    }
+                    year = tm.year;
+                    mon = tm.mon;
+                    mday = tm.mday;
 
                     haveDay = haveMon = haveYear =
                     haveHour = haveMin = haveSec = true;
@@ -1369,7 +1160,7 @@ wxDateTime::ParseFormat(const wxString& date,
 
                     haveHour = haveMin = haveSec = true;
 
-                    Tm tm = dt.GetTm();
+                    const Tm tm = dt.GetTm();
                     hour = tm.hour;
                     min = tm.min;
                     sec = tm.sec;
@@ -1386,7 +1177,7 @@ wxDateTime::ParseFormat(const wxString& date,
                     haveHour =
                     haveMin = true;
 
-                    Tm tm = dt.GetTm();
+                    const Tm tm = dt.GetTm();
                     hour = tm.hour;
                     min = tm.min;
                 }
@@ -1415,7 +1206,7 @@ wxDateTime::ParseFormat(const wxString& date,
                     haveMin =
                     haveSec = true;
 
-                    Tm tm = dt.GetTm();
+                    const Tm tm = dt.GetTm();
                     hour = tm.hour;
                     min = tm.min;
                     sec = tm.sec;
@@ -1435,57 +1226,41 @@ wxDateTime::ParseFormat(const wxString& date,
                 break;
 
             case _T('x'):       // locale default date representation
-#ifdef HAVE_STRPTIME
-                // try using strptime() -- it may fail even if the input is
-                // correct but the date is out of range, so we will fall back
-                // to our generic code anyhow
-                {
-                    struct tm tm;
-
-                    if ( CallStrptime(date, input, "%x", &tm) )
-                    {
-                        haveDay = haveMon = haveYear = true;
-
-                        year = 1900 + tm.tm_year;
-                        mon = (Month)tm.tm_mon;
-                        mday = tm.tm_mday;
-
-                        break;
-                    }
-                }
-#endif // HAVE_STRPTIME
-
                 {
-                    wxString fmtDate,
-                             fmtDateAlt;
+                    wxString
+                        fmtDate = wxLocale::GetInfo(wxLOCALE_SHORT_DATE_FMT),
+                        fmtDateAlt = wxLocale::GetInfo(wxLOCALE_LONG_DATE_FMT);
 
-#ifdef __WINDOWS__
-                    // The above doesn't work for all locales, try to query
-                    // Windows for the right way of formatting the date:
-                    fmtDate = GetLocaleDateFormat();
                     if ( fmtDate.empty() )
-#endif // __WINDOWS__
                     {
                         if ( IsWestEuropeanCountry(GetCountry()) ||
                              GetCountry() == Russia )
                         {
-                            fmtDate = _T("%d/%m/%y");
-                            fmtDateAlt = _T("%m/%d/%y");
-                        }
+                            fmtDate = wxS("%d/%m/%Y");
+                            fmtDateAlt = wxS("%m/%d/%Y");
+                         }
                         else // assume USA
                         {
-                            fmtDate = _T("%m/%d/%y");
-                            fmtDateAlt = _T("%d/%m/%y");
+                            fmtDate = wxS("%m/%d/%Y");
+                            fmtDateAlt = wxS("%d/%m/%Y");
                         }
                     }
 
-                    const wxDateTime
-                        dt = ParseFormatAt(input, end,
-                                           fmtDate, fmtDateAlt);
+                    wxDateTime
+                        dt = ParseFormatAt(input, end, fmtDate, fmtDateAlt);
+
                     if ( !dt.IsValid() )
-                        return false;
+                    {
+                        // try with short years too
+                        fmtDate.Replace("%Y","%y");
+                        fmtDateAlt.Replace("%Y","%y");
+                        dt = ParseFormatAt(input, end, fmtDate, fmtDateAlt);
+
+                        if ( !dt.IsValid() )
+                            return false;
+                    }
 
-                    Tm tm = dt.GetTm();
+                    const Tm tm = dt.GetTm();
 
                     haveDay =
                     haveMon =
@@ -1499,29 +1274,21 @@ wxDateTime::ParseFormat(const wxString& date,
                 break;
 
             case _T('X'):       // locale default time representation
-#ifdef HAVE_STRPTIME
                 {
-                    // use strptime() to do it for us (FIXME !Unicode friendly)
-                    struct tm tm;
-                    if ( !CallStrptime(date, input, "%X", &tm) )
-                        return false;
+                    wxString fmtTime = wxLocale::GetInfo(wxLOCALE_TIME_FMT),
+                             fmtTimeAlt;
 
-                    haveHour = haveMin = haveSec = true;
+                    if ( fmtTime.empty() )
+                    {
+                        // try to parse what follows as "%H:%M:%S" and, if this
+                        // fails, as "%I:%M:%S %p" - this should catch the most
+                        // common cases
+                        fmtTime = "%T";
+                        fmtTimeAlt = "%r";
+                    }
 
-                    hour = tm.tm_hour;
-                    min = tm.tm_min;
-                    sec = tm.tm_sec;
-                }
-#else // !HAVE_STRPTIME
-                // TODO under Win32 we can query the LOCALE_ITIME system
-                //      setting which says whether the default time format is
-                //      24 or 12 hour
-                {
-                    // try to parse what follows as "%H:%M:%S" and, if this
-                    // fails, as "%I:%M:%S %p" - this should catch the most
-                    // common cases
                     const wxDateTime
-                        dt = ParseFormatAt(input, end, "%T", "%r");
+                        dt = ParseFormatAt(input, end, fmtTime, fmtTimeAlt);
                     if ( !dt.IsValid() )
                         return false;
 
@@ -1529,12 +1296,11 @@ wxDateTime::ParseFormat(const wxString& date,
                     haveMin =
                     haveSec = true;
 
-                    Tm tm = dt.GetTm();
+                    const Tm tm = dt.GetTm();
                     hour = tm.hour;
                     min = tm.min;
                     sec = tm.sec;
                 }
-#endif // HAVE_STRPTIME/!HAVE_STRPTIME
                 break;
 
             case _T('y'):       // year without century (00-99)
@@ -1564,7 +1330,9 @@ wxDateTime::ParseFormat(const wxString& date,
                 break;
 
             case _T('Z'):       // timezone name
-                wxFAIL_MSG(_T("TODO"));
+                // FIXME: currently we just ignore everything that looks like a
+                //        time zone here
+                GetAlphaToken(input, end);
                 break;
 
             case _T('%'):       // a percent sign