diff --git a/docs/latex/wx/cmdlpars.tex b/docs/latex/wx/cmdlpars.tex index d9b3b8c378..5fe7725f15 100644 --- a/docs/latex/wx/cmdlpars.tex +++ b/docs/latex/wx/cmdlpars.tex @@ -85,7 +85,8 @@ enum wxCmdLineEntryType The field {\tt shortName} is the usual, short, name of the switch or the option. {\tt longName} is the corresponding long name or NULL if the option has no long -name. Both of these fields are unused for the parameters. +name. Both of these fields are unused for the parameters. Both the short and +long option names can contain only letters, digits and the underscores. {\tt description} is used by the \helpref{Usage()}{wxcmdlineparserusage} method to construct a help message explaining the syntax of the program. @@ -109,7 +110,8 @@ enum wxCMD\_LINE\_OPTION\_MANDATORY = 0x01, // this option must be given wxCMD\_LINE\_PARAM\_OPTIONAL = 0x02, // the parameter may be omitted wxCMD\_LINE\_PARAM\_MULTIPLE = 0x04, // the parameter may be repeated - wxCMD\_LINE\_OPTION\_HELP = 0x08 // this option is a help request + wxCMD\_LINE\_OPTION\_HELP = 0x08, // this option is a help request + wxCMD\_LINE\_NEEDS\_SEPARATOR = 0x10, // must have sep before the value } \end{verbatim}} @@ -125,6 +127,10 @@ use \helpref{GetParamCount}{wxcmdlineparsergetparamcount} to retrieve the number of parameters effectively specified after calling \helpref{Parse}{wxcmdlineparserparse}. +The last flag {\tt wxCMD\_LINE\_NEEDS\_SEPARATOR} can be specified to require a +separator (either a colon, an equal sign or white space) between the option +name and its value. By default, no separator is required. + \wxheading{See also} \helpref{wxApp::argc}{wxappargc} and \helpref{wxApp::argv}{wxappargv}\\ diff --git a/docs/latex/wx/datetime.tex b/docs/latex/wx/datetime.tex index 1d404695b3..01d8b9e54c 100644 --- a/docs/latex/wx/datetime.tex +++ b/docs/latex/wx/datetime.tex @@ -212,6 +212,7 @@ supported. Future versions will support other calendars. \helpref{GetBeginDST}{wxdatetimegetbegindst}\\ \helpref{GetEndDST}{wxdatetimegetenddst}\\ \helpref{Now}{wxdatetimenow}\\ +\helpref{UNow}{wxdatetimeunow}\\ \helpref{Today}{wxdatetimetoday} \membersection{Constructors, assignment operators and setters} @@ -562,6 +563,10 @@ Example: printf("Current time in Paris:\t%s\n", now.Format("%c", wxDateTime::CET).c_str()); \end{verbatim} +Note that this function is accurate up to second: +\helpref{wxDateTime::UNow}{wxdatetimeunow} should be used for better precision +(but it is less efficient and might not be availabel on all platforms). + \wxheading{See also} \helpref{Today}{wxdatetimetoday} @@ -591,6 +596,18 @@ same as \helpref{Now()}{wxdatetimenow}, but the time part is set to $0$). \helpref{Now}{wxdatetimenow} +\membersection{wxDateTime::UNow}\label{wxdatetimeunow} + +\func{static wxDateTime}{UNow}{\void} + +Returns the object corresopnding to the current time including the +milliseconds if a function to get time with such precision is available on the +current platform (supported under most Unices and Win32). + +\wxheading{See also} + +\helpref{Now}{wxdatetimenow} + %%%%%%%%%%%%%%%%%%%%%%%%%%% constructors &c %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \membersection{wxDateTime::wxDateTime}\label{wxdatetimewxdatetimedef} @@ -1069,6 +1086,10 @@ the character which stopped the scan. This function does the same as the standard ANSI C {\tt strftime(3)} function. Please see its description for the meaning of {\it format} parameter. +It also accepts a few wxWindows-specific extensions: you can optionally specify +the width of the field to follow using {\tt printf(3)}-like syntax and the +format specificator {\tt \%l} can be used to get the number of milliseconds. + \wxheading{See also} \helpref{ParseFormat}{wxdatetimeparseformat} diff --git a/docs/latex/wx/function.tex b/docs/latex/wx/function.tex index 5f1518a9bc..9df5c66f49 100644 --- a/docs/latex/wx/function.tex +++ b/docs/latex/wx/function.tex @@ -1459,21 +1459,6 @@ Return the (current) user's home directory. -\membersection{::wxGetElapsedTime}\label{wxgetelapsedtime} - -\func{long}{wxGetElapsedTime}{\param{bool}{ resetTimer = TRUE}} - -Gets the time in milliseconds since the last \helpref{::wxStartTimer}{wxstarttimer}. - -If {\it resetTimer} is TRUE (the default), the timer is reset to zero -by this call. - -See also \helpref{wxTimer}{wxtimer}. - -\wxheading{Include files} - - - \membersection{::wxGetFreeMemory}\label{wxgetfreememory} \func{long}{wxGetFreeMemory}{\void} @@ -1803,18 +1788,6 @@ as a keyboard shortkey in Windows and Motif) and $\backslash$t (tab in Windows). -\membersection{::wxStartTimer}\label{wxstarttimer} - -\func{void}{wxStartTimer}{\void} - -Starts a stopwatch; use \helpref{::wxGetElapsedTime}{wxgetelapsedtime} to get the elapsed time. - -See also \helpref{wxTimer}{wxtimer}. - -\wxheading{Include files} - - - \membersection{::wxToLower}\label{wxtolower} \func{char}{wxToLower}{\param{char }{ch}} @@ -2700,6 +2673,86 @@ Returns the error message corresponding to the given system error code. If \helpref{wxSysErrorCode}{wxsyserrorcode}, \helpref{wxLogSysError}{wxlogsyserror} +\section{Time functions}\label{timefunctions} + +The functions in this section deal with getting the current time and +starting/stopping the global timers. Please note that the timer functions are +deprecated because they work with one global timer only and +\helpref{wxTimer}{wxtimer} and/or \helpref{wxStopWatch}{wxstopwatch} classes +should be used instead. For retrieving the current time, you may also use +\helpref{wxDateTime::Now}{wxdatetimenow} or +\helpref{wxDateTime::UNow}{wxdatetimeunow} methods. + +\membersection{::wxGetElapsedTime}\label{wxgetelapsedtime} + +\func{long}{wxGetElapsedTime}{\param{bool}{ resetTimer = TRUE}} + +Gets the time in milliseconds since the last \helpref{::wxStartTimer}{wxstarttimer}. + +If {\it resetTimer} is TRUE (the default), the timer is reset to zero +by this call. + +See also \helpref{wxTimer}{wxtimer}. + +\wxheading{Include files} + + + +\membersection{::wxGetLocalTime}\label{wxgetlocaltime} + +\func{long}{wxGetLocalTime}{\void} + +Returns the number of seconds since local time 00:00:00 Jan 1st 1970. + +\wxheading{See also} + +\helpref{wxDateTime::Now}{wxdatetimenow} + +\wxheading{Include files} + + + +\membersection{::wxGetLocalTimeMillis}\label{wxgetlocaltimemillis} + +\func{wxLongLone}{wxGetLocalTimeMillis}{\void} + +Returns the number of milliseconds since local time 00:00:00 Jan 1st 1970. + +\wxheading{See also} + +\helpref{wxDateTime::Now}{wxdatetimenow},\\ +\helpref{wxLongLone}{wxlonglong} + +\wxheading{Include files} + + + +\membersection{::wxGetUTCTime}\label{wxgetutctime} + +\func{long}{wxGetUTCTime}{\void} + +Returns the number of seconds since GMT 00:00:00 Jan 1st 1970. + +\wxheading{See also} + +\helpref{wxDateTime::Now}{wxdatetimenow} + +\wxheading{Include files} + + + +\membersection{::wxStartTimer}\label{wxstarttimer} + +\func{void}{wxStartTimer}{\void} + +Starts a stopwatch; use \helpref{::wxGetElapsedTime}{wxgetelapsedtime} to get the elapsed time. + +See also \helpref{wxTimer}{wxtimer}. + +\wxheading{Include files} + + + \section{Debugging macros and functions}\label{debugmacros} Useful macros and functions for error checking and defensive programming. ASSERTs are only diff --git a/include/wx/cmdline.h b/include/wx/cmdline.h index c8bea6105f..7df010dbfc 100644 --- a/include/wx/cmdline.h +++ b/include/wx/cmdline.h @@ -32,7 +32,8 @@ enum wxCMD_LINE_OPTION_MANDATORY = 0x01, // this option must be given wxCMD_LINE_PARAM_OPTIONAL = 0x02, // the parameter may be omitted wxCMD_LINE_PARAM_MULTIPLE = 0x04, // the parameter may be repeated - wxCMD_LINE_OPTION_HELP = 0x08 // this option is a help request + wxCMD_LINE_OPTION_HELP = 0x08, // this option is a help request + wxCMD_LINE_NEEDS_SEPARATOR = 0x10, // must have sep before the value }; // an option value or parameter may be a string (the most common case), a diff --git a/include/wx/datetime.h b/include/wx/datetime.h index 1530d30657..688b2debf4 100644 --- a/include/wx/datetime.h +++ b/include/wx/datetime.h @@ -512,6 +512,10 @@ public: // return the wxDateTime object for the current time static inline wxDateTime Now(); + // return the wxDateTime object for the current time with millisecond + // precision (if available on this platform) + static wxDateTime UNow(); + // return the wxDateTime object for today midnight: i.e. as Now() but // with time set to 0 static inline wxDateTime Today(); @@ -1096,11 +1100,7 @@ public: // resulting text representation. Notice that only some of format // specifiers valid for wxDateTime are valid for wxTimeSpan: hours, // minutes and seconds make sense, but not "PM/AM" string for example. - wxString Format(const wxChar *format = _T("%c")) const; - // preferred date representation for the current locale - wxString FormatDate() const { return Format(_T("%x")); } - // preferred time representation for the current locale - wxString FormatTime() const { return Format(_T("%X")); } + wxString Format(const wxChar *format = _T("%H:%M:%S")) const; // implementation // ------------------------------------------------------------------------ diff --git a/include/wx/datetime.inl b/include/wx/datetime.inl index 65099bb35f..302d65c195 100644 --- a/include/wx/datetime.inl +++ b/include/wx/datetime.inl @@ -324,7 +324,7 @@ inline wxTimeSpan wxDateTime::Subtract(const wxDateTime& datetime) const { wxASSERT_MSG( IsValid() && datetime.IsValid(), _T("invalid wxDateTime")); - return wxTimeSpan(datetime.GetValue() - GetValue()); + return wxTimeSpan(GetValue() - datetime.GetValue()); } inline wxDateTime wxDateTime::Add(const wxDateSpan& diff) const diff --git a/include/wx/timer.h b/include/wx/timer.h index eddeb32d2c..7ea894d04a 100644 --- a/include/wx/timer.h +++ b/include/wx/timer.h @@ -222,10 +222,13 @@ long WXDLLEXPORT wxGetElapsedTime(bool resetTimer = TRUE); // ---------------------------------------------------------------------------- // Get number of seconds since local time 00:00:00 Jan 1st 1970. -long WXDLLEXPORT wxGetLocalTime(); +extern long WXDLLEXPORT wxGetLocalTime(); // Get number of seconds since GMT 00:00:00, Jan 1st 1970. -long WXDLLEXPORT wxGetUTCTime(); +extern long WXDLLEXPORT wxGetUTCTime(); + +// Get number of milliseconds since local time 00:00:00 Jan 1st 1970 +extern wxLongLong WXDLLEXPORT wxGetLocalTimeMillis(); #define wxGetCurrentTime() wxGetLocalTime() diff --git a/src/common/cmdline.cpp b/src/common/cmdline.cpp index ac13c84292..965d1143de 100644 --- a/src/common/cmdline.cpp +++ b/src/common/cmdline.cpp @@ -485,7 +485,7 @@ int wxCmdLineParser::Parse() isLong = TRUE; const wxChar *p = arg.c_str() + 2; - while ( wxIsalpha(*p) || (*p == _T('-')) ) + while ( wxIsalnum(*p) || (*p == _T('_')) || (*p == _T('-')) ) { name += *p++; } @@ -503,7 +503,7 @@ int wxCmdLineParser::Parse() // a short one: as they can be cumulated, we try to find the // longest substring which is a valid option const wxChar *p = arg.c_str() + 1; - while ( wxIsalpha(*p) ) + while ( wxIsalnum(*p) || (*p == _T('_')) ) { name += *p++; } @@ -596,6 +596,7 @@ int wxCmdLineParser::Parse() { switch ( *p ) { + case _T('='): case _T(':'): // the value follows p++; @@ -619,8 +620,15 @@ int wxCmdLineParser::Parse() break; default: - // the value is right here - ; + // the value is right here: this may be legal or + // not depending on the option style + if ( opt.flags & wxCMD_LINE_NEEDS_SEPARATOR ) + { + wxLogError(_("Separator expected after the option '%s'."), + name.c_str()); + + ok = FALSE; + } } } @@ -781,13 +789,18 @@ void wxCmdLineParser::Usage() wxStripExtension(appname); } - // we ocnstruct the brief cmd line desc on the fly, but not the detailed + // we construct the brief cmd line desc on the fly, but not the detailed // help message below because we want to align the options descriptions // and for this we must first know the longest one of them wxString brief; wxArrayString namesOptions, descOptions; brief.Printf(_("Usage: %s"), appname.c_str()); + // the switch char is usually '-' but this can be changed with + // SetSwitchChars() and then the first one of possible chars is used + wxChar chSwitch = !m_data->m_switchChars ? _T('-') + : m_data->m_switchChars[0u]; + size_t n, count = m_data->m_options.GetCount(); for ( n = 0; n < count; n++ ) { @@ -799,10 +812,10 @@ void wxCmdLineParser::Usage() brief << _T('['); } - brief << _T('-') << opt.shortName; + brief << chSwitch << opt.shortName; wxString option; - option << _T(" -") << opt.shortName; + option << _T(" ") << chSwitch << opt.shortName; if ( !!opt.longName ) { option << _T(" --") << opt.longName; diff --git a/src/common/datetime.cpp b/src/common/datetime.cpp index 765dc13d68..bc2c358e86 100644 --- a/src/common/datetime.cpp +++ b/src/common/datetime.cpp @@ -78,6 +78,7 @@ #include #include "wx/datetime.h" +#include "wx/timer.h" // for wxGetLocalTimeMillis() // ---------------------------------------------------------------------------- // conditional compilation @@ -98,8 +99,8 @@ #if defined(__BORLANDC__) || defined(__MINGW32__) || defined(__VISAGECPP__) #define WX_TIMEZONE _timezone #elif defined(__MWERKS__) - long wxmw_timezone = 28800; - #define WX_TIMEZONE wxmw_timezone ; + long wxmw_timezone = 28800; + #define WX_TIMEZONE wxmw_timezone; #else // unknown platform - try timezone #define WX_TIMEZONE timezone #endif @@ -1036,6 +1037,12 @@ wxDateTime wxDateTime::GetEndDST(int year, Country country) // constructors and assignment operators // ---------------------------------------------------------------------------- +// return the current time with ms precision +/* static */ wxDateTime wxDateTime::UNow() +{ + return wxDateTime(wxGetLocalTimeMillis()); +} + // the values in the tm structure contain the local time wxDateTime& wxDateTime::Set(const struct tm& tm) { @@ -1211,7 +1218,7 @@ wxDateTime::Tm wxDateTime::GetTm(const TimeZone& tz) const tm = localtime(&time); // should never happen - wxCHECK_MSG( tm, Tm(), _T("gmtime() failed") ); + wxCHECK_MSG( tm, Tm(), _T("localtime() failed") ); } else { @@ -1236,7 +1243,11 @@ wxDateTime::Tm wxDateTime::GetTm(const TimeZone& tz) const if ( tm ) { - return Tm(*tm, tz); + // adjust the milliseconds + Tm tm2(*tm, tz); + long timeOnly = (m_time % MILLISECONDS_PER_DAY).ToLong(); + tm2.msec = (wxDateTime_t)(timeOnly % 1000); + return tm2; } //else: use generic code below } @@ -1760,8 +1771,10 @@ wxString wxDateTime::Format(const wxChar *format, const TimeZone& tz) const { wxCHECK_MSG( format, _T(""), _T("NULL format in wxDateTime::Format") ); + // we have to use our own implementation if the date is out of range of + // strftime() or if we use non standard specificators time_t time = GetTicks(); - if ( time != (time_t)-1 ) + if ( (time != (time_t)-1) && !wxStrstr(format, _T("%l")) ) { // use strftime() tm *tm; @@ -1803,7 +1816,8 @@ wxString wxDateTime::Format(const wxChar *format, const TimeZone& tz) const } // we only parse ANSI C format specifications here, no POSIX 2 - // complications, no GNU extensions + // complications, no GNU extensions but we do add support for a "%l" format + // specifier allowing to get the number of milliseconds Tm tm = GetTm(tz); // used for calls to strftime() when we only deal with time @@ -2023,6 +2037,10 @@ wxString wxDateTime::Format(const wxChar *format, const TimeZone& tz) const res += wxString::Format(fmt, GetDayOfYear(tz)); break; + case _T('l'): // milliseconds (NOT STANDARD) + res += wxString::Format(fmt, GetMillisecond(tz)); + break; + case _T('m'): // month as a number (01-12) res += wxString::Format(fmt, tm.mon + 1); break; @@ -3452,46 +3470,46 @@ wxString wxTimeSpan::Format(const wxChar *format) const wxString str; str.Alloc(wxStrlen(format)); - for ( const wxChar *pch = format; pch; pch++ ) + for ( const wxChar *pch = format; *pch; pch++ ) { wxChar ch = *pch; - if ( ch == '%' ) + if ( ch == _T('%') ) { wxString tmp; - ch = *pch++; + ch = *++pch; // get the format spec char switch ( ch ) { default: wxFAIL_MSG( _T("invalid format character") ); // fall through - case '%': + case _T('%'): // will get to str << ch below break; - case 'D': + case _T('D'): tmp.Printf(_T("%d"), GetDays()); break; - case 'E': + case _T('E'): tmp.Printf(_T("%d"), GetWeeks()); break; - case 'H': + case _T('H'): tmp.Printf(_T("%02d"), GetHours()); break; - case 'l': + case _T('l'): tmp.Printf(_T("%03ld"), GetMilliseconds().ToLong()); break; - case 'M': + case _T('M'): tmp.Printf(_T("%02d"), GetMinutes()); break; - case 'S': + case _T('S'): tmp.Printf(_T("%02ld"), GetSeconds().ToLong()); break; } diff --git a/src/common/timercmn.cpp b/src/common/timercmn.cpp index 67cec8530c..95f42ef18d 100644 --- a/src/common/timercmn.cpp +++ b/src/common/timercmn.cpp @@ -88,12 +88,6 @@ #endif #endif // HAVE_GETTIMEOFDAY -// ---------------------------------------------------------------------------- -// prototypes -// ---------------------------------------------------------------------------- - -wxLongLong wxGetLocalTimeMillis(); - // ============================================================================ // implementation // ============================================================================ @@ -274,7 +268,7 @@ wxLongLong wxGetLocalTimeMillis() (void)ftime(&tp); val *= tp.time; return (val + tp.millitm); -#else +#else // no gettimeofday() nor ftime() // We use wxGetLocalTime() to get the seconds since // 00:00:00 Jan 1st 1970 and then whatever is available // to get millisecond resolution. @@ -290,17 +284,17 @@ wxLongLong wxGetLocalTimeMillis() ::DosGetDateTime(&dt); val += (dt.hundredths*10); #elif defined (__WIN32__) -#warning "Possible clock skew bug in wxStopWatch!" + #warning "Possible clock skew bug in wxGetLocalTimeMillis()!" SYSTEMTIME st; ::GetLocalTime(&st); val += st.wMilliseconds; -#else -#if !defined(__VISUALC__) && !defined(__BORLANDC__) -#warning "wxStopWatch will be up to second resolution!" -#endif +#else // !Win32 + #if !defined(__VISUALC__) && !defined(__BORLANDC__) + #warning "wxStopWatch will be up to second resolution!" + #endif #endif return val; -#endif +#endif // time functions } diff --git a/src/msw/menu.cpp b/src/msw/menu.cpp index 057cb1eac8..bf7b961b17 100644 --- a/src/msw/menu.cpp +++ b/src/msw/menu.cpp @@ -135,35 +135,50 @@ int wxMenu::FindAccel(int id) const void wxMenu::UpdateAccel(wxMenuItem *item) { - // find the (new) accel for this item - wxAcceleratorEntry *accel = wxGetAccelFromString(item->GetText()); - if ( accel ) - accel->m_command = item->GetId(); + if ( item->IsSubMenu() ) + { + wxMenu *submenu = item->GetSubMenu(); + wxMenuItemList::Node *node = submenu->GetMenuItems().GetFirst(); + while ( node ) + { + UpdateAccel(node->GetData()); - // find the old one - int n = FindAccel(item->GetId()); - if ( n == wxNOT_FOUND ) - { - // no old, add new if any - if ( accel ) - m_accels.Add(accel); - else - return; // skipping RebuildAccelTable() below + node = node->GetNext(); + } } - else + else if ( !item->IsSeparator() ) { - // replace old with new or just remove the old one if no new - delete m_accels[n]; + // find the (new) accel for this item + wxAcceleratorEntry *accel = wxGetAccelFromString(item->GetText()); if ( accel ) - m_accels[n] = accel; - else - m_accels.Remove(n); - } + accel->m_command = item->GetId(); - if ( IsAttached() ) - { - m_menuBar->RebuildAccelTable(); + // find the old one + int n = FindAccel(item->GetId()); + if ( n == wxNOT_FOUND ) + { + // no old, add new if any + if ( accel ) + m_accels.Add(accel); + else + return; // skipping RebuildAccelTable() below + } + else + { + // replace old with new or just remove the old one if no new + delete m_accels[n]; + if ( accel ) + m_accels[n] = accel; + else + m_accels.Remove(n); + } + + if ( IsAttached() ) + { + m_menuBar->RebuildAccelTable(); + } } + //else: it is a separator, they can't have accels, nothing to do } #endif // wxUSE_ACCEL