From cd0b170911637899ac3c126367ee5821f357c185 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 21 Dec 1999 01:44:45 +0000 Subject: [PATCH] 1. wxLongLong and wxDateTime compilation fixed for the compilers without native "long long" type (and some code in timercmn.cpp too) 2. wxDate and wxTime reimplemented using wxDateTime (old versions tagged as OLD_DATE_AND_TIME) 3. wxString::To(U)Long and ToDouble added and documented 4. bug with combobox in toolbar (drop down list wasn't dismissed) fixed 5. several wxDateTime::Parse() functions implemented 6. added support for coloured buttons under MSW (not completely finished) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@5043 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 2 + docs/latex/wx/wxstring.tex | 35 ++ include/wx/date.h | 308 ++++++++++----- include/wx/datetime.h | 288 +++++++++++--- include/wx/datetime.inl | 89 +++-- include/wx/longlong.h | 49 ++- include/wx/msw/button.h | 11 + include/wx/string.h | 11 +- include/wx/time.h | 185 +++++---- src/common/cmndata.cpp | 219 +++++------ src/common/datetime.cpp | 762 ++++++++++++++++++++++++++++++++++++- src/common/longlong.cpp | 4 +- src/common/string.cpp | 43 +++ src/common/timercmn.cpp | 5 +- src/common/txtstrm.cpp | 2 +- src/common/variant.cpp | 6 + src/msw/button.cpp | 251 +++++++++++- src/msw/combobox.cpp | 44 ++- src/msw/window.cpp | 5 +- 19 files changed, 1884 insertions(+), 435 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index f1a903a382..8e3ead65dd 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -15,6 +15,7 @@ wxBase: - wxLog functions are now (more) MT-safe - wxStopWatch class, timer functions have more chances to return correct results for your platform (use ANSI functions where available) +- wxString::ToLong, ToULong, ToDouble methods added - buffer overflows in wxString and wxLog classes fixed (if snprintf() function is available) - wxArray::RemoveAt() replaces deprectaed wxArray::Remove(index) @@ -23,6 +24,7 @@ all (GUI): - wxMenu(Bar)::Insert() and Remove() functions for dynamic menu menagament - wxToolBar supports arbitrary controls (not only buttons) and can be dynamically changed (Delete/Insert functions) +- vertical toolbars supported by MSW and GTK native wxToolBar classes - wxTreeCtrl and wxListCtrl allow setting colour/fonts for individual items - "file open" dialog allows selecting multiple files at once (contributed by John Norris) diff --git a/docs/latex/wx/wxstring.tex b/docs/latex/wx/wxstring.tex index 5aa5d9d4a5..2427335159 100644 --- a/docs/latex/wx/wxstring.tex +++ b/docs/latex/wx/wxstring.tex @@ -138,6 +138,17 @@ functions. \helpref{Find}{wxstringfind}\\ \helpref{Replace}{wxstringreplace} +\membersection{Conversion to numbers} + +The string provides functions for conversion to signed and unsigned integer and +floating point numbers. All three functions take a pointer to the variable to +put the numeric value in and return TRUE if the {\bf entire} string could be +converted to a number. + +\helpref{ToLong}{wxstringtolong}\\ +\helpref{ToULong}{wxstringtoulong}\\ +\helpref{ToDouble}{wxstringtodouble} + \membersection{Writing values into the string} Both formatted versions (\helpref{Printf}{wxstringprintf}) and stream-like @@ -832,6 +843,30 @@ doesn't change this string. Same as \helpref{Mid}{wxstringmid}. +\membersection{wxString::ToDouble}\label{wxstringtodouble} + +\cosntfunc{bool}{To}{\param{double}{ *val}} + +Attempts to convert the string to a floating point number. Returns TRUE on +suceess (the number is stored in the location pointed to by {\it val}) or FALSE +if the string does not represent such number. + +\membersection{wxString::ToLong}\label{wxstringtolong} + +\cosntfunc{bool}{To}{\param{long}{ *val}} + +Attempts to convert the string to a signed integer. Returns TRUE on suceess +(the number is stored in the location pointed to by {\it val}) or FALSE if the +string does not represent such number. + +\membersection{wxString::ToULong}\label{wxstringtoulong} + +\cosntfunc{bool}{To}{\param{unsigned long}{ *val}} + +Attempts to convert the string to an unsigned integer. Returns TRUE on suceess +(the number is stored in the location pointed to by {\it val}) or FALSE if the +string does not represent such number. + \membersection{wxString::Trim}\label{wxstringtrim} \func{wxString\&}{Trim}{\param{bool}{ fromRight = TRUE}} diff --git a/include/wx/date.h b/include/wx/date.h index dc7c7b613a..43209e7f0d 100644 --- a/include/wx/date.h +++ b/include/wx/date.h @@ -1,146 +1,256 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: date.h -// Purpose: wxDate class +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/date.h +// Purpose: wxDate class: this class is deprecated, use wxDateTime instead! // Author: Julian Smart, Steve Marcus, Eric Simon, Chris Hill, // Charles D. Price -// Modified by: +// Modified by: 18.12.99 by VZ to use the new wxDateTime class // Created: 01/02/97 // RCS-ID: $Id$ -// Copyright: (c) +// Copyright:(c) // Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// #ifndef _WX_DATE_H_ #define _WX_DATE_H_ #ifdef __GNUG__ -#pragma interface "date.h" + #pragma interface "date.h" #endif -#include "wx/object.h" -#include "wx/string.h" +#include "wx/defs.h" #if wxUSE_TIMEDATE -// These lines necessary to stop VC++ 6 being confused about namespaces -class WXDLLEXPORT wxDate; -bool WXDLLEXPORT operator<(const wxDate &dt1, const wxDate &dt2); -bool WXDLLEXPORT operator<(const wxDate &dt1, const wxDate &dt2); -bool WXDLLEXPORT operator <= (const wxDate &dt1, const wxDate &dt2); -bool WXDLLEXPORT operator > (const wxDate &dt1, const wxDate &dt2); -bool WXDLLEXPORT operator >= (const wxDate &dt1, const wxDate &dt2); -bool WXDLLEXPORT operator == (const wxDate &dt1, const wxDate &dt2); -bool WXDLLEXPORT operator != (const wxDate &dt1, const wxDate &dt2); -enum wxdate_format_type {wxMDY, wxDAY, wxMONTH, wxFULL, wxEUROPEAN}; +#include "wx/object.h" +#include "wx/string.h" +#include "wx/datetime.h" -#define wxNO_CENTURY 0x02 -#define wxDATE_ABBR 0x04 +// ---------------------------------------------------------------------------- +// constants +// ---------------------------------------------------------------------------- -class WXDLLEXPORT wxDate : public wxObject +enum wxdate_format_type { -DECLARE_DYNAMIC_CLASS(wxDate) - -protected: - unsigned long julian; // see julDate(); days since 1/1/4713 B.C. - int month; // see NMonth() - int day; // see Day() - int year; // see NYear4() - int day_of_week; // see NDOW(); 1 = Sunday, ... 7 = Saturday + wxMDY, + wxDAY, + wxMONTH, + wxFULL, + wxEUROPEAN +}; -private: - int DisplayFormat; - unsigned char DisplayOptions; +enum // wxdate_format_flags +{ + wxNO_CENTURY = 0x02, + wxDATE_ABBR = 0x04 +}; - void julian_to_mdy (); // convert julian day to mdy - void julian_to_wday (); // convert julian day to day_of_week - void mdy_to_julian (); // convert mdy to julian day +// ---------------------------------------------------------------------------- +// wxDate +// ---------------------------------------------------------------------------- +class WXDLLEXPORT wxDate : public wxObject +{ public: - wxDate (); - wxDate (long j); - wxDate (int m, int d, int y); - wxDate (const wxString& dat); - wxDate (const wxDate &dt); + wxDate() { Init(); } + wxDate(long j) : m_date((double)(j + 0.5)) { Init(); } + wxDate(int m, int d, int y) : m_date(d, (wxDateTime::Month)m, y) { Init(); } + wxDate(const wxString& dat) { Init(); (void)m_date.ParseDate(dat); } + wxDate(const wxDate &date) { *this = date; } + + wxDate(const wxDateTime& dt) { Init(); m_date = dt; } #ifndef __SALFORDC__ - operator wxString (void); + operator wxString() const { return FormatDate(); } #endif - void operator = (const wxDate& date); - void operator = (const wxString& date); + void operator=(const wxDate& date) + { + m_date = date.m_date; + m_displayFormat = date.m_displayFormat; + m_displayOptions = date.m_displayOptions; + } - wxDate operator + (long i); - wxDate operator + (int i); + void operator=(const wxString& dat) { (void)m_date.ParseDate(dat); } - wxDate operator - (long i); - wxDate operator - (int i); + wxDate operator+(long i) { return wxDate(GetJulianDate() + i); } + wxDate operator+(int i) { return wxDate(GetJulianDate() + (long)i); } - long operator - (const wxDate &dt); + wxDate operator-(long i) { return wxDate(GetJulianDate() - i); } + wxDate operator-(int i) { return wxDate(GetJulianDate() - (long)i); } - wxDate &operator += (long i); - wxDate &operator -= (long i); + long operator-(const wxDate &dt) const + { return GetJulianDate() - dt.GetJulianDate(); } - wxDate &operator ++ (); // Prefix increment - wxDate &operator ++ (int); // Postfix increment - wxDate &operator -- (); // Prefix decrement - wxDate &operator -- (int); // Postfix decrement + wxDate &operator+=(long i) { m_date += wxTimeSpan::Days(i); return *this; } + wxDate &operator-=(long i) { m_date -= wxTimeSpan::Days(i); return *this; } - friend bool WXDLLEXPORT operator < (const wxDate &dt1, const wxDate &dt2); - friend bool WXDLLEXPORT operator <= (const wxDate &dt1, const wxDate &dt2); - friend bool WXDLLEXPORT operator > (const wxDate &dt1, const wxDate &dt2); - friend bool WXDLLEXPORT operator >= (const wxDate &dt1, const wxDate &dt2); - friend bool WXDLLEXPORT operator == (const wxDate &dt1, const wxDate &dt2); - friend bool WXDLLEXPORT operator != (const wxDate &dt1, const wxDate &dt2); + wxDate &operator++() { return *this += 1; } + wxDate &operator++(int) { return *this += 1; } + wxDate &operator--() { return *this -= 1; } + wxDate &operator--(int) { return *this -= 1; } #if wxUSE_STD_IOSTREAM - friend ostream WXDLLEXPORT & operator << (ostream &os, const wxDate &dt); + friend ostream WXDLLEXPORT & operator <<(ostream &os, const wxDate &dt) + { return os << dt.FormatDate().mb_str(); } #endif - wxString FormatDate (int type=-1) const; - void SetFormat (int format); - int SetOption (int option, bool enable=TRUE); - - long GetJulianDate() const; // returns julian date - int GetDayOfYear() const; // returns relative date since Jan. 1 - bool IsLeapYear() const; // returns TRUE if leap year, FALSE if not - - // Version 4.0 Extension to Public Interface - CDP - - // These 'Set's modify the date object and actually SET it - // They all return a reference to self (*this) + void SetFormat(int format) { m_displayFormat = format; } + int SetOption(int option, bool enable = TRUE) + { + if ( enable ) + m_displayOptions |= option; + else + m_displayOptions &= ~option; + + return 1; // (VZ: whatever it means) + } + + // returns julian date (VZ: the integral part of Julian Day Number) + long GetJulianDate() const + { return (long)(m_date.GetJulianDayNumber() - 0.5); } + + // returns relative date since Jan. 1 + int GetDayOfYear() const + { return m_date.GetDayOfYear(); } + + // returns TRUE if leap year, FALSE if not + bool IsLeapYear() const + { return wxDateTime::IsLeapYear(m_date.GetYear()); } + + // Sets to current system date + wxDate &Set() + { m_date = wxDateTime::Today(); return *this; } + wxDate &Set(long lJulian) + { m_date.Set((double)(lJulian + 0.5)); return *this; } + wxDate &Set(int nMonth, int nDay, int nYear) + { m_date.Set(nDay, (wxDateTime::Month)nMonth, nYear); } + + // May also pass neg# to decrement + wxDate &AddWeeks(int nCount = 1) + { m_date += wxDateSpan::Weeks(nCount); return *this; } + wxDate &AddMonths(int nCount = 1) + { m_date += wxDateSpan::Months(nCount); return *this; } + wxDate &AddYears(int nCount = 1) + { m_date += wxDateSpan::Years(nCount); return *this; } + + // Numeric Day of date object + int GetDay() const { return m_date.GetDay(); } + // Number of days in month(1..31) + int GetDaysInMonth() const + { + return wxDateTime::GetNumberOfDays((wxDateTime::Month)m_date.GetMonth(), + m_date.GetYear()); + } + + // First Day Of Month(1..7) + int GetFirstDayOfMonth() const + { return wxDate(GetMonth(), 1, GetYear()).GetDayOfWeek(); } + + // Character Day Of Week('Sunday'..'Saturday') + wxString GetDayOfWeekName() const { return FormatDate(wxDAY); } + int GetDayOfWeek() const { return (int)m_date.GetWeekDay() + 1; } + + // Numeric Week Of Month(1..6) (VZ: I'd love to see a month with 6 weeks) + int GetWeekOfMonth() const { return m_date.GetWeekOfMonth(); } + // Numeric Week Of Year(1..52) (VZ: but there are years with 53 weeks) + int GetWeekOfYear() const { return m_date.GetWeekOfYear(); } + + // Character Month name + wxString GetMonthName() { return FormatDate(wxMONTH); } + // Month Number(1..12) + int GetMonth() const { return m_date.GetMonth() + 1; } + + // First Date Of Month + wxDate GetMonthStart() const { return(wxDate(GetMonth(), 1, GetYear())); } + // Last Date Of Month + wxDate GetMonthEnd() const { return wxDate(GetMonth()+1, 1, GetYear())-1; } + + // eg. 1992 + int GetYear() const { return m_date.GetYear(); } + // First Date Of Year + wxDate GetYearStart() const { return wxDate(1, 1, GetYear()); } + // Last Date Of Year + wxDate GetYearEnd() const { return wxDate(1, 1, GetYear()+1) - 1; } + + bool IsBetween(const wxDate& first, const wxDate& second) const + { + return m_date.IsBetween(first.m_date, second.m_date); + } + + wxDate Previous(int dayOfWeek) const + { + int dow = GetDayOfWeek(); + if ( dayOfWeek <= dow ) + return *this - (dow - dayOfWeek); + else + return *this - 7 + (dayOfWeek - dow); + } + + wxString FormatDate(int type = -1) const + { + static const wxChar *formats[] = + { + // MDY (week)DAY MONTH FULL EUROPEAN + _T("%m/%d/%Y"), _T("%A"), _T("%B"), _T("%A, %B %d, %Y"), _T("%d %B %Y") + }; + + wxString fmt = formats[type == -1 ? m_displayFormat : type]; + + if ( m_displayOptions & wxDATE_ABBR ) + { + fmt.Replace(_T("A"), _T("a")); + fmt.Replace(_T("B"), _T("b")); + } + if ( m_displayOptions & wxNO_CENTURY ) + { + fmt.Replace(_T("Y"), _T("y")); + } + + return m_date.Format(fmt); + } - wxDate &Set(); // Sets to current system date - wxDate &Set(long lJulian); - wxDate &Set(int nMonth, int nDay, int nYear); - - wxDate &AddWeeks(int nCount = 1); // - wxDate &AddMonths(int nCount = 1); // May also pass neg# to decrement - wxDate &AddYears(int nCount = 1); // - - int GetDay() const; // Numeric Day of date object - int GetDaysInMonth(); // Number of days in month (1..31) - int GetFirstDayOfMonth() const; // First Day Of Month (1..7) - - wxString GetDayOfWeekName(); // Character Day Of Week ('Sunday'..'Saturday') - int GetDayOfWeek() const; // (1..7) +protected: + void Init() { m_displayFormat = wxMDY; m_displayOptions = 0; } - int GetWeekOfMonth(); // Numeric Week Of Month (1..6) - int GetWeekOfYear(); // Numeric Week Of Year (1..52) +#if 0 // the old wxDate members - unused any more + unsigned long julian; // see julDate(); days since 1/1/4713 B.C. + int month; // see NMonth() + int day; // see Day() + int year; // see NYear4() + int day_of_week; // see NDOW(); 1 = Sunday, ... 7 = Saturday - wxString GetMonthName(); // Character Month name - int GetMonth() const; // Month Number (1..12) - wxDate GetMonthStart(); // First Date Of Month - wxDate GetMonthEnd(); // Last Date Of Month + void julian_to_mdy(); // convert julian day to mdy + void julian_to_wday(); // convert julian day to day_of_week + void mdy_to_julian(); // convert mdy to julian day +#endif // 0 - int GetYear() const; // eg. 1992 - wxDate GetYearStart(); // First Date Of Year - wxDate GetYearEnd(); // Last Date Of Year +private: + wxDateTime m_date; - bool IsBetween(const wxDate& first, const wxDate& second) const; + int m_displayFormat; + int m_displayOptions; - wxDate Previous(int dayOfWeek) const; +private: + DECLARE_DYNAMIC_CLASS(wxDate) }; +// ---------------------------------------------------------------------------- +// global functions +// ---------------------------------------------------------------------------- + +inline bool WXDLLEXPORT operator <(const wxDate &dt1, const wxDate &dt2) + { return dt1.GetJulianDate() < dt2.GetJulianDate(); } +inline bool WXDLLEXPORT operator <=(const wxDate &dt1, const wxDate &dt2) + { return dt1.GetJulianDate() <= dt2.GetJulianDate(); } +inline bool WXDLLEXPORT operator >(const wxDate &dt1, const wxDate &dt2) + { return dt1.GetJulianDate() > dt2.GetJulianDate(); } +inline bool WXDLLEXPORT operator >=(const wxDate &dt1, const wxDate &dt2) + { return dt1.GetJulianDate() >= dt2.GetJulianDate(); } +inline bool WXDLLEXPORT operator ==(const wxDate &dt1, const wxDate &dt2) + { return dt1.GetJulianDate() == dt2.GetJulianDate(); } +inline bool WXDLLEXPORT operator !=(const wxDate &dt1, const wxDate &dt2) + { return dt1.GetJulianDate() != dt2.GetJulianDate(); } + #endif // wxUSE_TIMEDATE #endif // _WX_DATE_H_ diff --git a/include/wx/datetime.h b/include/wx/datetime.h index da7f5ee231..bbd8d833f6 100644 --- a/include/wx/datetime.h +++ b/include/wx/datetime.h @@ -65,22 +65,34 @@ class WXDLLEXPORT wxDateSpan; substraction ------------ wxDateTime - wxDateTime = wxTimeSpan + wxDateTime - wxTimeSpan = wxDateTime + wxDateTime - wxDateSpan = wxDateTime wxTimeSpan - wxTimeSpan = wxTimeSpan wxDateSpan - wxDateSpan = wxDateSpan multiplication -------------- wxTimeSpan * number = wxTimeSpan + number * wxTimeSpan = wxTimeSpan wxDateSpan * number = wxDateSpan + number * wxDateSpan = wxDateSpan unitary minus ------------- -wxTimeSpan = wxTimeSpan -wxDateSpan = wxDateSpan + + For each binary operation OP (+, -, *) we have the following operatorOP=() as + a method and the method with a symbolic name OPER (Add, Substract, Multiply) + as a synonym for it and another const method with the same name which returns + the changed copy of the object and operatorOP() as a global function which is + implemented in terms of the const version of OPEN. For the unary - we have + operator-() as a method, Neg() as synonym for it and Negate() which returns + the copy of the object with the changed sign. */ // ---------------------------------------------------------------------------- -// This class represents an absolute moment in the time +// wxDateTime represents an absolute moment in the time // ---------------------------------------------------------------------------- class WXDLLEXPORT wxDateTime @@ -89,11 +101,11 @@ public: // types // ------------------------------------------------------------------------ - // a small unsigned integer type for storing things like seconds, days - // of the week, &c. It should be at least short (i.e. not char) to - // contain the number of milliseconds - it may also be 'int' because - // there is no size penalty associated with it in our code, we don't - // store any data in this format + // a small unsigned integer type for storing things like minutes, + // seconds &c. It should be at least short (i.e. not char) to contain + // the number of milliseconds - it may also be 'int' because there is + // no size penalty associated with it in our code, we don't store any + // data in this format typedef unsigned short wxDateTime_t; // the timezones @@ -343,11 +355,11 @@ public: TimeZone(TZ tz); TimeZone(wxDateTime_t offset = 0) { m_offset = offset; } - int GetOffset() const { return m_offset; } + long GetOffset() const { return m_offset; } private: // offset for this timezone from GMT in seconds - int m_offset; + long m_offset; }; // standard struct tm is limited to the years from 1900 (because @@ -465,6 +477,10 @@ public: // return the wxDateTime object for the current time static inline wxDateTime Now(); + // return the wxDateTime object for today midnight: i.e. as Now() but + // with time set to 0 + static inline wxDateTime Today(); + // constructors: you should test whether the constructor succeeded with // IsValid() function. The values Inv_Month and Inv_Year for the // parameters mean take current month and/or year values. @@ -573,6 +589,15 @@ public: // unchanged, e.g. don't explictly zero it) // ------------------------------------------------------------------------ + // set to the given week day in the same week as this one + wxDateTime& SetToWeekDayInSameWeek(WeekDay weekday); + + // set to the next week day following this one + wxDateTime& SetToNextWeekDay(WeekDay weekday); + + // set to the previous week day following this one + wxDateTime& SetToPrevWeekDay(WeekDay weekday); + // set to Nth occurence of given weekday in the given month of the // given year (time is set to 0), return TRUE on success and FALSE on // failure. n may be positive (1..5) or negative to count from the end @@ -709,9 +734,12 @@ public: // get the day since the year start (1..366, 0 if date is invalid) wxDateTime_t GetDayOfYear(const TimeZone& tz = Local) const; - // get the week number since the year start (1..52, 0 if date is + // get the week number since the year start (1..52 or 53, 0 if date is // invalid) wxDateTime_t GetWeekOfYear(const TimeZone& tz = Local) const; + // get the week number since the month start (1..5, 0 if date is + // invalid) + wxDateTime_t GetWeekOfMonth(const TimeZone& tz = Local) const; // is this date a work day? This depends on a country, of course, // because the holidays are different in different countries @@ -732,12 +760,6 @@ public: // returns TRUE if the two moments are strictly identical inline bool IsEqualTo(const wxDateTime& datetime) const; - // returns TRUE if the two moments are identical - inline bool operator==(const wxDateTime& datetime) const; - - // returns TRUE if the two moments are different - inline bool operator!=(const wxDateTime& datetime) const; - // returns TRUE if the date is strictly earlier than the given one inline bool IsEarlierThan(const wxDateTime& datetime) const; @@ -751,48 +773,59 @@ public: // returns TRUE if the date is in the given range inline bool IsBetween(const wxDateTime& t1, const wxDateTime& t2) const; - // date operations: for the non-const methods, the return value is this - // object itself (see also functions below for operator versions) + // arithmetics with dates (see also below for more operators) // ------------------------------------------------------------------------ + // return the sum of the date with a time span (positive or negative) + inline wxDateTime Add(const wxTimeSpan& diff) const; // add a time span (positive or negative) inline wxDateTime& Add(const wxTimeSpan& diff); // add a time span (positive or negative) inline wxDateTime& operator+=(const wxTimeSpan& diff); + // return the difference of the date with a time span + inline wxDateTime Substract(const wxTimeSpan& diff) const; // substract a time span (positive or negative) inline wxDateTime& Substract(const wxTimeSpan& diff); // substract a time span (positive or negative) inline wxDateTime& operator-=(const wxTimeSpan& diff); + // return the sum of the date with a date span + inline wxDateTime Add(const wxDateSpan& diff) const; // add a date span (positive or negative) wxDateTime& Add(const wxDateSpan& diff); // add a date span (positive or negative) inline wxDateTime& operator+=(const wxDateSpan& diff); + // return the difference of the date with a date span + inline wxDateTime& Substract(const wxDateSpan& diff) const; // substract a date span (positive or negative) inline wxDateTime& Substract(const wxDateSpan& diff); // substract a date span (positive or negative) inline wxDateTime& operator-=(const wxDateSpan& diff); - // substract a date (may result in positive or negative time span) - inline wxTimeSpan Substract(const wxDateTime& datetime) const; - // substract a date (may result in positive or negative time span) - inline wxTimeSpan operator-(const wxDateTime& datetime) const; + // return the difference between two dates + inline wxTimeSpan Substract(const wxDateTime& dt) const; - // conversion to/from text: all conversions from text return TRUE on - // success or FALSE if the date is malformed/out of supported range + // conversion to/from text: all conversions from text return the pointer to + // the next character following the date specification (i.e. the one where + // the scan had to stop) or NULL on failure. // ------------------------------------------------------------------------ // parse a string in RFC 822 format (found e.g. in mail headers and // having the form "Wed, 10 Feb 1999 19:07:07 +0100") - bool ParseRfc822Date(const wxString& date); + const wxChar *ParseRfc822Date(const wxChar* date); // parse a date/time in the given format (see strptime(3)) - bool ParseFormat(const wxString& date, const char *format = "%c"); + const wxChar *ParseFormat(const wxChar *date, + const wxChar *format = _T("%c")); // parse a string containing the date/time in "free" format, this // function will try to make an educated guess at the string contents - // (and return FALSE if it fails) - bool ParseDateTime(const wxString& date); + const wxChar *ParseDateTime(const wxChar *datetime); + // parse a string containing the date only in "free" format (less + // flexible than ParseDateTime) + const wxChar *ParseDate(const wxChar *date); + // parse a string containing the time only in "free" format + const wxChar *ParseTime(const wxChar *time); // this function accepts strftime()-like format string (default // argument corresponds to the preferred date and time representation @@ -808,6 +841,9 @@ public: // implementation // ------------------------------------------------------------------------ + // construct from internal representation + wxDateTime(const wxLongLong& time) { m_time = time; } + // get the internal representation inline wxLongLong GetValue() const; @@ -830,7 +866,7 @@ private: // this constant is used to transform a time_t value to the internal // representation, as time_t is in seconds and we use milliseconds it's // fixed to 1000 - static const unsigned int TIME_T_FACTOR; + static const long TIME_T_FACTOR; // invalid wxDateTime object - returned by all functions which return // "wxDateTime &" on failure @@ -867,6 +903,12 @@ public: // return the timespan for the given number of hours static wxTimeSpan Hours(int hours) { return wxTimeSpan(hours, 0, 0); } + // return the timespan for the given number of days + static wxTimeSpan Days(int days) { return Hours(24 * days); } + + // return the timespan for the given number of weeks + static wxTimeSpan Weeks(int days) { return Days(7 * days); } + // default ctor constructs the 0 time span wxTimeSpan() { } @@ -878,32 +920,33 @@ public: int seconds = 0, int milliseconds = 0); - // from internal representation - wxTimeSpan(wxLongLong diff) : m_diff(diff) { } - // default copy ctor is ok // no dtor - // arithmetics with time spans + // arithmetics with time spans (see also below for more operators) // ------------------------------------------------------------------------ + // return the sum of two timespans + inline wxTimeSpan Add(const wxTimeSpan& diff) const; // add two timespans together inline wxTimeSpan& Add(const wxTimeSpan& diff); // add two timespans together wxTimeSpan& operator+=(const wxTimeSpan& diff) { return Add(diff); } + // return the difference of two timespans + inline wxTimeSpan Substract(const wxTimeSpan& diff) const; // substract another timespan inline wxTimeSpan& Substract(const wxTimeSpan& diff); // substract another timespan wxTimeSpan& operator-=(const wxTimeSpan& diff) { return Substract(diff); } + // multiply timespan by a scalar + inline wxTimeSpan Multiply(int n) const; // multiply timespan by a scalar inline wxTimeSpan& Multiply(int n); // multiply timespan by a scalar wxTimeSpan& operator*=(int n) { return Multiply(n); } - // multiply timespan by a scalar - inline wxTimeSpan operator*(int n) const; // return this timespan with inversed sign wxTimeSpan Negate() const { return wxTimeSpan(-GetValue()); } @@ -978,6 +1021,9 @@ public: // implementation // ------------------------------------------------------------------------ + // construct from internal representation + wxTimeSpan(const wxLongLong& diff) { m_diff = diff; } + // get the internal representation wxLongLong GetValue() const { return m_diff; } @@ -1064,14 +1110,18 @@ public: // returns 7*GetWeeks() + GetDays() int GetTotalDays() const { return 7*m_weeks + m_days; } - // arithmetics + // arithmetics with date spans (see also below for more operators) // ------------------------------------------------------------------------ + // return sum of two date spans + inline wxDateSpan Add(const wxDateSpan& other) const; // add another wxDateSpan to us inline wxDateSpan& Add(const wxDateSpan& other); // add another wxDateSpan to us inline wxDateSpan& operator+=(const wxDateSpan& other); + // return difference of two date spans + inline wxDateSpan Substract(const wxDateSpan& other) const; // substract another wxDateSpan from us inline wxDateSpan& Substract(const wxDateSpan& other); // substract another wxDateSpan from us @@ -1084,8 +1134,12 @@ public: // inverse the sign of this timespan wxDateSpan& operator-() { return Neg(); } + // return the date span proportional to this one with given factor + inline wxDateSpan Multiply(int factor) const; // multiply all components by a (signed) number - inline wxDateSpan& operator*=(int factor); + inline wxDateSpan& Multiply(int factor); + // multiply all components by a (signed) number + inline wxDateSpan& operator*=(int factor) { return Multiply(factor); } private: int m_years, @@ -1124,60 +1178,93 @@ WXDLLEXPORT_DATA(extern wxDateSpan) wxDay; // wxDateTime operators // ---------------------------------------------------------------------------- -inline bool WXDLLEXPORT operator<(const wxDateTime &t1, const wxDateTime &t2) +// arithmetics +// ----------- + +// no need to check for validity - the member functions we call will do it + +inline wxDateTime WXDLLEXPORT operator+(const wxDateTime& dt, + const wxTimeSpan& ts) { - wxASSERT_MSG( t1.IsValid() && t2.IsValid(), "invalid wxDateTime" ); + return dt.Add(ts); +} + +inline wxDateTime WXDLLEXPORT operator-(const wxDateTime& dt, + const wxTimeSpan& ts) +{ + return dt.Substract(ts); +} + +inline wxDateTime WXDLLEXPORT operator+(const wxDateTime& dt, + const wxDateSpan& ds) +{ + return dt.Add(ds); +} + +inline wxDateTime WXDLLEXPORT operator-(const wxDateTime& dt, + const wxDateSpan& ds) +{ + return dt.Substract(ds); +} + +inline wxTimeSpan WXDLLEXPORT operator-(const wxDateTime& dt1, + const wxDateTime& dt2) +{ + return dt1.Substract(dt2); +} + +// comparison +// ---------- + +inline bool WXDLLEXPORT operator<(const wxDateTime& t1, const wxDateTime& t2) +{ + wxASSERT_MSG( t1.IsValid() && t2.IsValid(), _T("invalid wxDateTime") ); return t1.GetValue() < t2.GetValue(); } -inline bool WXDLLEXPORT operator<=(const wxDateTime &t1, const wxDateTime &t2) +inline bool WXDLLEXPORT operator<=(const wxDateTime& t1, const wxDateTime& t2) { - wxASSERT_MSG( t1.IsValid() && t2.IsValid(), "invalid wxDateTime" ); + wxASSERT_MSG( t1.IsValid() && t2.IsValid(), _T("invalid wxDateTime") ); return t1.GetValue() <= t2.GetValue(); } -inline bool WXDLLEXPORT operator>(const wxDateTime &t1, const wxDateTime &t2) +inline bool WXDLLEXPORT operator>(const wxDateTime& t1, const wxDateTime& t2) { - wxASSERT_MSG( t1.IsValid() && t2.IsValid(), "invalid wxDateTime" ); + wxASSERT_MSG( t1.IsValid() && t2.IsValid(), _T("invalid wxDateTime") ); return t1.GetValue() > t2.GetValue(); } -inline bool WXDLLEXPORT operator>=(const wxDateTime &t1, const wxDateTime &t2) +inline bool WXDLLEXPORT operator>=(const wxDateTime& t1, const wxDateTime& t2) { - wxASSERT_MSG( t1.IsValid() && t2.IsValid(), "invalid wxDateTime" ); + wxASSERT_MSG( t1.IsValid() && t2.IsValid(), _T("invalid wxDateTime") ); return t1.GetValue() >= t2.GetValue(); } -inline bool WXDLLEXPORT operator==(const wxDateTime &t1, const wxDateTime &t2) +inline bool WXDLLEXPORT operator==(const wxDateTime& t1, const wxDateTime& t2) { - wxASSERT_MSG( t1.IsValid() && t2.IsValid(), "invalid wxDateTime" ); + wxASSERT_MSG( t1.IsValid() && t2.IsValid(), _T("invalid wxDateTime") ); return t1.GetValue() == t2.GetValue(); } -inline bool WXDLLEXPORT operator!=(const wxDateTime &t1, const wxDateTime &t2) +inline bool WXDLLEXPORT operator!=(const wxDateTime& t1, const wxDateTime& t2) { - wxASSERT_MSG( t1.IsValid() && t2.IsValid(), "invalid wxDateTime" ); + wxASSERT_MSG( t1.IsValid() && t2.IsValid(), _T("invalid wxDateTime") ); return t1.GetValue() != t2.GetValue(); } -inline wxTimeSpan WXDLLEXPORT operator-(const wxDateTime &t1, - const wxDateTime &t2) -{ - wxASSERT_MSG( t1.IsValid() && t2.IsValid(), "invalid wxDateTime" ); - - return wxTimeSpan(t1.GetValue() - t2.GetValue()); -} - // ---------------------------------------------------------------------------- // wxTimeSpan operators // ---------------------------------------------------------------------------- +// arithmetics +// ----------- + inline wxTimeSpan WXDLLEXPORT operator+(const wxTimeSpan& ts1, const wxTimeSpan& ts2) { @@ -1190,6 +1277,19 @@ inline wxTimeSpan WXDLLEXPORT operator-(const wxTimeSpan& ts1, return wxTimeSpan(ts1.GetValue() - ts2.GetValue()); } +inline wxTimeSpan WXDLLEXPORT operator*(const wxTimeSpan& ts, int n) +{ + return wxTimeSpan(ts).Multiply(n); +} + +inline wxTimeSpan WXDLLEXPORT operator*(int n, const wxTimeSpan& ts) +{ + return wxTimeSpan(ts).Multiply(n); +} + +// comparison +// ---------- + inline bool WXDLLEXPORT operator<(const wxTimeSpan &t1, const wxTimeSpan &t2) { return t1.GetValue() < t2.GetValue(); @@ -1224,13 +1324,77 @@ inline bool WXDLLEXPORT operator!=(const wxTimeSpan &t1, const wxTimeSpan &t2) // wxDateSpan // ---------------------------------------------------------------------------- -inline WXDLLEXPORT wxDateSpan operator+(const wxDateSpan& rt1, - const wxDateSpan& rt2) +// arithmetics +// ----------- + +inline WXDLLEXPORT wxDateSpan operator+(const wxDateSpan& ds1, + const wxDateSpan& ds2) +{ + return wxDateSpan(ds1.GetYears() + ds2.GetYears(), + ds1.GetMonths() + ds2.GetMonths(), + ds1.GetWeeks() + ds2.GetWeeks(), + ds1.GetDays() + ds2.GetDays()); +} + +inline WXDLLEXPORT wxDateSpan operator-(const wxDateSpan& ds1, + const wxDateSpan& ds2) +{ + return wxDateSpan(ds1.GetYears() - ds2.GetYears(), + ds1.GetMonths() - ds2.GetMonths(), + ds1.GetWeeks() - ds2.GetWeeks(), + ds1.GetDays() - ds2.GetDays()); +} + +inline WXDLLEXPORT wxDateSpan operator*(const wxDateSpan& ds, int n) +{ + return wxDateSpan(ds).Multiply(n); +} + +inline WXDLLEXPORT wxDateSpan operator*(int n, const wxDateSpan& ds) { - return wxDateSpan(rt1.GetYears() + rt2.GetYears(), - rt1.GetMonths() + rt2.GetMonths(), - rt1.GetWeeks() + rt2.GetWeeks(), - rt1.GetDays() + rt2.GetDays()); + return wxDateSpan(ds).Multiply(n); +} + +// ============================================================================ +// other helper functions +// ============================================================================ + +// ---------------------------------------------------------------------------- +// iteration helpers: can be used to write a for loop over enum variable like +// this: +// for ( m = wxDateTime::Jan; m < wxDateTime::Inv_Month; wxNextMonth(m) ) +// ---------------------------------------------------------------------------- + +inline WXDLLEXPORT void wxNextMonth(wxDateTime::Month& m) +{ + wxASSERT_MSG( m < wxDateTime::Inv_Month, _T("invalid month") ); + + // no wrapping or the for loop above would never end! + m = (wxDateTime::Month)(m + 1); +} + +inline WXDLLEXPORT void wxPrevMonth(wxDateTime::Month& m) +{ + wxASSERT_MSG( m < wxDateTime::Inv_Month, _T("invalid month") ); + + m = m == wxDateTime::Jan ? wxDateTime::Inv_Month + : (wxDateTime::Month)(m - 1); +} + +inline WXDLLEXPORT void wxNextWDay(wxDateTime::WeekDay& wd) +{ + wxASSERT_MSG( wd < wxDateTime::Inv_WeekDay, _T("invalid week day") ); + + // no wrapping or the for loop above would never end! + wd = (wxDateTime::WeekDay)(wd + 1); +} + +inline WXDLLEXPORT void wxPrevWDay(wxDateTime::WeekDay& wd) +{ + wxASSERT_MSG( wd < wxDateTime::Inv_WeekDay, _T("invalid week day") ); + + wd = wd == wxDateTime::Sun ? wxDateTime::Inv_WeekDay + : (wxDateTime::WeekDay)(wd - 1); } #endif // _WX_DATETIME_H diff --git a/include/wx/datetime.inl b/include/wx/datetime.inl index 0bfdb87fea..f96f06e806 100644 --- a/include/wx/datetime.inl +++ b/include/wx/datetime.inl @@ -22,12 +22,12 @@ // only define this once, when included from datetime.cpp #ifdef wxDEFINE_TIME_CONSTANTS - const unsigned int wxDateTime::TIME_T_FACTOR = 1000; + const long wxDateTime::TIME_T_FACTOR = 1000l; #endif // wxDEFINE_TIME_CONSTANTS bool wxDateTime::IsInStdRange() const { - return m_time >= 0l && (m_time / (long)TIME_T_FACTOR) < LONG_MAX; + return m_time >= 0l && (m_time / TIME_T_FACTOR) < LONG_MAX; } /* static */ @@ -36,6 +36,12 @@ wxDateTime wxDateTime::Now() return wxDateTime(GetTimeNow()); } +/* static */ +wxDateTime wxDateTime::Today() +{ + return wxDateTime((time_t)(86400*(GetTimeNow() / 86400))); +} + wxDateTime& wxDateTime::Set(time_t timet) { // assign first to avoid long multiplication overflow! @@ -102,14 +108,14 @@ wxDateTime::wxDateTime(wxDateTime_t day, wxLongLong wxDateTime::GetValue() const { - wxASSERT_MSG( IsValid(), "invalid wxDateTime"); + wxASSERT_MSG( IsValid(), _T("invalid wxDateTime")); return m_time; } time_t wxDateTime::GetTicks() const { - wxASSERT_MSG( IsValid(), "invalid wxDateTime"); + wxASSERT_MSG( IsValid(), _T("invalid wxDateTime")); if ( !IsInStdRange() ) { return (time_t)-1; @@ -131,31 +137,21 @@ bool wxDateTime::SetToLastWeekDay(WeekDay weekday, bool wxDateTime::IsEqualTo(const wxDateTime& datetime) const { - wxASSERT_MSG( IsValid() && datetime.IsValid(), "invalid wxDateTime"); + wxASSERT_MSG( IsValid() && datetime.IsValid(), _T("invalid wxDateTime")); return m_time == datetime.m_time; } -bool wxDateTime::operator==(const wxDateTime& datetime) const -{ - return IsEqualTo(datetime); -} - -bool wxDateTime::operator!=(const wxDateTime& datetime) const -{ - return !IsEqualTo(datetime); -} - bool wxDateTime::IsEarlierThan(const wxDateTime& datetime) const { - wxASSERT_MSG( IsValid() && datetime.IsValid(), "invalid wxDateTime"); + wxASSERT_MSG( IsValid() && datetime.IsValid(), _T("invalid wxDateTime")); return m_time < datetime.m_time; } bool wxDateTime::IsLaterThan(const wxDateTime& datetime) const { - wxASSERT_MSG( IsValid() && datetime.IsValid(), "invalid wxDateTime"); + wxASSERT_MSG( IsValid() && datetime.IsValid(), _T("invalid wxDateTime")); return m_time > datetime.m_time; } @@ -177,9 +173,16 @@ bool wxDateTime::IsBetween(const wxDateTime& t1, const wxDateTime& t2) const // wxDateTime arithmetics // ---------------------------------------------------------------------------- +wxDateTime wxDateTime::Add(const wxTimeSpan& diff) const +{ + wxASSERT_MSG( IsValid(), _T("invalid wxDateTime")); + + return wxDateTime(m_time + diff.GetValue()); +} + wxDateTime& wxDateTime::Add(const wxTimeSpan& diff) { - wxASSERT_MSG( IsValid(), "invalid wxDateTime"); + wxASSERT_MSG( IsValid(), _T("invalid wxDateTime")); m_time += diff.GetValue(); @@ -191,9 +194,16 @@ wxDateTime& wxDateTime::operator+=(const wxTimeSpan& diff) return Add(diff); } +wxDateTime wxDateTime::Substract(const wxTimeSpan& diff) const +{ + wxASSERT_MSG( IsValid(), _T("invalid wxDateTime")); + + return wxDateTime(m_time - diff.GetValue()); +} + wxDateTime& wxDateTime::Substract(const wxTimeSpan& diff) { - wxASSERT_MSG( IsValid(), "invalid wxDateTime"); + wxASSERT_MSG( IsValid(), _T("invalid wxDateTime")); m_time -= diff.GetValue(); @@ -207,16 +217,11 @@ wxDateTime& wxDateTime::operator-=(const wxTimeSpan& diff) wxTimeSpan wxDateTime::Substract(const wxDateTime& datetime) const { - wxASSERT_MSG( IsValid() && datetime.IsValid(), "invalid wxDateTime"); + wxASSERT_MSG( IsValid() && datetime.IsValid(), _T("invalid wxDateTime")); return wxTimeSpan(datetime.GetValue() - GetValue()); } -wxTimeSpan wxDateTime::operator-(const wxDateTime& datetime) const -{ - return Substract(datetime); -} - wxDateTime& wxDateTime::Substract(const wxDateSpan& diff) { return Add(diff.Negate()); @@ -248,12 +253,12 @@ wxDateTime wxDateTime::ToTimezone(const wxDateTime::TimeZone& tz) const wxTimeSpan::wxTimeSpan(int hours, int minutes, int seconds, int milliseconds) { // assign first to avoid precision loss - m_diff = hours; - m_diff *= 60; + m_diff = (long)hours; + m_diff *= 60l; m_diff += minutes; - m_diff *= 60; + m_diff *= 60l; m_diff += seconds; - m_diff *= 1000; + m_diff *= 1000l; m_diff += milliseconds; } @@ -290,6 +295,11 @@ int wxTimeSpan::GetWeeks() const // wxTimeSpan arithmetics // ---------------------------------------------------------------------------- +wxTimeSpan wxTimeSpan::Add(const wxTimeSpan& diff) const +{ + return wxTimeSpan(m_diff + diff.GetValue()); +} + wxTimeSpan& wxTimeSpan::Add(const wxTimeSpan& diff) { m_diff += diff.GetValue(); @@ -297,6 +307,11 @@ wxTimeSpan& wxTimeSpan::Add(const wxTimeSpan& diff) return *this; } +wxTimeSpan wxTimeSpan::Substract(const wxTimeSpan& diff) const +{ + return wxTimeSpan(m_diff - diff.GetValue()); +} + wxTimeSpan& wxTimeSpan::Substract(const wxTimeSpan& diff) { m_diff -= diff.GetValue(); @@ -306,17 +321,14 @@ wxTimeSpan& wxTimeSpan::Substract(const wxTimeSpan& diff) wxTimeSpan& wxTimeSpan::Multiply(int n) { - m_diff *= n; + m_diff *= (long)n; return *this; } -wxTimeSpan wxTimeSpan::operator*(int n) const +wxTimeSpan wxTimeSpan::Multiply(int n) const { - wxTimeSpan result(*this); - result.Multiply(n); - - return result; + return wxTimeSpan(m_diff * (long)n); } wxTimeSpan wxTimeSpan::Abs() const @@ -349,7 +361,7 @@ wxDateSpan::operator+=(const wxDateSpan& other) return *this; } -wxDateSpan& wxDateSpan::operator*=(int factor) +wxDateSpan& wxDateSpan::Multiply(int factor) { m_years *= m_years; m_months *= m_months; @@ -359,6 +371,11 @@ wxDateSpan& wxDateSpan::operator*=(int factor) return *this; } +wxDateSpan wxDateSpan::Multiply(int factor) const +{ + return wxDateSpan(*this).Multiply(factor); +} + wxDateSpan wxDateSpan::Negate() const { return wxDateSpan(-m_years, -m_months, -m_weeks, -m_days); diff --git a/include/wx/longlong.h b/include/wx/longlong.h index 02f7ded9ea..3a502e70d7 100644 --- a/include/wx/longlong.h +++ b/include/wx/longlong.h @@ -39,10 +39,7 @@ #if defined(SIZEOF_LONG) && (SIZEOF_LONG == 8) #define wxLongLong_t long #define wxLongLongIsLong -#elif defined(__WIN16__) - #define wxLongLong_t long - #define wxLongLongIsLong -#elif defined(__VISUALC__) || defined( __VMS__ ) +#elif (defined(__VISUALC__) && defined(__WIN32__)) || defined( __VMS__ ) #define wxLongLong_t __int64 #elif defined(__GNUG__) #define wxLongLong_t long long @@ -53,12 +50,14 @@ #error "The 64 bit integer support in CodeWarrior has been disabled." #error "See the documentation on the 'longlong' pragma." #endif -#else - #if !defined(__VISAGECPP__) - // Visualage does not support this pragma - #warning "Your compiler does not appear to support 64 bit integers, "\ - "using emulation class instead." - #endif +#else // no native long long type + // we don't give warnings for the compilers we know about that they don't + // have any 64 bit integer type + #if !defined(__VISAGECPP__) && !defined(__VISUALC__) + #warning "Your compiler does not appear to support 64 bit integers, "\ + "using emulation class instead." + #endif // known compilers without long long + #define wxUSE_LONGLONG_WX 1 #endif // compiler @@ -120,6 +119,12 @@ public: wxLongLongNative& operator=(wxLongLong_t ll) { m_ll = ll; return *this; } + // from double: this one has an explicit name because otherwise we + // would have ambiguity with "ll = int" and also because we don't want + // to have implicit conversions between doubles and wxLongLongs + wxLongLongNative& Assign(double d) + { m_ll = (wxLongLong_t)d; return *this; } + // assignment operators from wxLongLongNative is ok // accessors @@ -309,6 +314,8 @@ public: // from long wxLongLongWx& operator=(long l) { m_lo = l; m_hi = (l < 0 ? -1l : 0l); return *this; } + // from double + wxLongLongWx& Assign(double d); // can't have assignment operator from 2 longs // accessors @@ -317,6 +324,18 @@ public: // get low part unsigned long GetLo() const { return m_lo; } + // get absolute value + wxLongLongWx& Abs() { if ( m_hi < 0 ) m_hi = -m_hi; return *this; } + + // convert to long with range checking in the debug mode (only!) + long ToLong() const + { + wxASSERT_MSG( m_hi == 0l, + _T("wxLongLong to long conversion loss of precision") ); + + return (long)m_lo; + } + // operations // addition wxLongLongWx operator+(const wxLongLongWx& ll) const; @@ -372,18 +391,24 @@ public: // multiplication wxLongLongWx operator*(const wxLongLongWx& ll) const; wxLongLongWx& operator*=(const wxLongLongWx& ll); - void *asArray(void) const; // division + wxLongLongWx operator/(const wxLongLongWx& ll) const; + wxLongLongWx& operator/=(const wxLongLongWx& ll); + + wxLongLongWx operator%(const wxLongLongWx& ll) const; + void Divide(const wxLongLongWx& divisor, wxLongLongWx& quotient, wxLongLongWx& remainder) const; -#if wxUSE_STD_IOSTREAM // input/output +#if wxUSE_STD_IOSTREAM friend ostream& operator<<(ostream&, const wxLongLongWx&); #endif // wxUSE_STD_IOSTREAM + void *asArray(void) const; + private: // long is at least 32 bits, so represent our 64bit number as 2 longs diff --git a/include/wx/msw/button.h b/include/wx/msw/button.h index 8af354a03a..0b0476844e 100644 --- a/include/wx/msw/button.h +++ b/include/wx/msw/button.h @@ -56,6 +56,17 @@ public: virtual long MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam); virtual bool MSWCommand(WXUINT param, WXWORD id); +#ifdef __WIN32__ + // coloured buttons support + virtual bool SetBackgroundColour(const wxColour &colour); + virtual bool SetForegroundColour(const wxColour &colour); + + virtual bool MSWOnDraw(WXDRAWITEMSTRUCT *item); + +private: + void MakeOwnerDrawn(); +#endif // __WIN32__ + protected: // send a notification event, return TRUE if processed bool SendClickEvent(); diff --git a/include/wx/string.h b/include/wx/string.h index 1bd7e000b2..b0605d99a5 100644 --- a/include/wx/string.h +++ b/include/wx/string.h @@ -400,7 +400,7 @@ public: wxChar operator[](unsigned int n) const { ASSERT_VALID_INDEX( n ); return m_pchData[n]; } #endif - + // operator version of GetWriteableChar wxChar& operator[](size_t n) { ASSERT_VALID_INDEX( n ); CopyBeforeWrite(); return m_pchData[n]; } @@ -615,6 +615,15 @@ public: // check if the string contents matches a mask containing '*' and '?' bool Matches(const wxChar *szMask) const; + // conversion to numbers: all functions return TRUE only if the whole string + // is a number and put the value of this number into the pointer provided + // convert to a signed integer + bool ToLong(long *val) const; + // convert to an unsigned integer + bool ToULong(unsigned long *val) const; + // convert to a double + bool ToDouble(double *val) const; + // formated input/output // as sprintf(), returns the number of characters written or < 0 on error int Printf(const wxChar *pszFormat, ...); diff --git a/include/wx/time.h b/include/wx/time.h index 35cce7f686..f345d84994 100644 --- a/include/wx/time.h +++ b/include/wx/time.h @@ -1,23 +1,28 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: time.h -// Purpose: wxTime class, from NIHCL +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/time.h +// Purpose: wxTime class, from NIHCL: this class is deprecated, use +// wxDateTime instead // Author: Julian Smart, after K. E. Gorlen -// Modified by: +// Modified by: 18.12.99 by VZ to use the new wxDateTime class // Created: 01/02/97 // RCS-ID: $Id$ // Copyright: (c) Julian Smart and Markus Holzem // Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// #ifndef _WX_TIMEH__ #define _WX_TIMEH__ -#include "wx/object.h" +#include "wx/defs.h" #if wxUSE_TIMEDATE +#include "wx/object.h" +#include "wx/datetime.h" +#include "wx/date.h" + #ifdef __GNUG__ -#pragma interface "time.h" + #pragma interface "time.h" #endif class WXDLLEXPORT wxDate; @@ -27,82 +32,124 @@ typedef unsigned short minuteTy; typedef unsigned short secondTy; typedef unsigned long clockTy; -class WXDLLEXPORT wxTime: public wxObject +// seconds from 1/1/01 to 1/1/70 +#define wxTIME_EPOCH_DIFF 2177452800UL + +class WXDLLEXPORT wxTime : public wxObject { - DECLARE_DYNAMIC_CLASS(wxTime) - -public: // type definitions +public: + // type definitions enum tFormat { wx12h, wx24h }; enum tPrecision { wxStdMinSec, wxStdMin }; + +public: + // current time + wxTime() : m_time(wxDateTime::Now()) { } + wxTime(clockTy s) : m_time((time_t)(s - wxTIME_EPOCH_DIFF)) { } + void operator=(const wxTime& t) { m_time = t.m_time; } + wxTime(const wxTime& t) { *this = t; } + wxTime(hourTy h, minuteTy m, secondTy s = 0, bool WXUNUSED(dst) = FALSE) + : m_time(h, m, s) { } + + wxTime(const wxDate& d, hourTy h = 0, minuteTy m = 0, secondTy s = 0, + bool WXUNUSED(dst) = FALSE) + : m_time(d.GetDay(), (wxDateTime::Month)d.GetMonth(), d.GetYear(), + h, m, s) { } + + wxTime(const wxDateTime& time) : m_time(time) { } + + // Convert to string +#ifndef __SALFORDC__ + operator wxChar *() const { return FormatTime(); } + operator wxDate() const { return wxDate(m_time); } +#endif + + bool operator< (const wxTime& t) const { return m_time < t.m_time; } + bool operator<=(const wxTime& t) const { return m_time <= t.m_time; } + bool operator> (const wxTime& t) const { return m_time > t.m_time; } + bool operator>=(const wxTime& t) const { return m_time >= t.m_time; } + bool operator==(const wxTime& t) const { return m_time == t.m_time; } + bool operator!=(const wxTime& t) const { return m_time != t.m_time; } + + friend wxTime WXDLLEXPORT operator+(const wxTime& t, long s) + { return wxTime(t.m_time + wxTimeSpan::Seconds(s)); } + friend wxTime WXDLLEXPORT operator+(long s, const wxTime& t) + { return wxTime(t.m_time + wxTimeSpan::Seconds(s)); } + + long operator-(const wxTime& t) const + { return (m_time - t.m_time).GetValue().ToLong(); } + wxTime operator-(long s) const + { return wxTime(m_time - wxTimeSpan::Seconds(s)); } + void operator+=(long s) { m_time += wxTimeSpan::Seconds(s); } + void operator-=(long s) { m_time -= wxTimeSpan::Seconds(s); } + bool IsBetween(const wxTime& a, const wxTime& b) const + { return *this >= a && *this <= b; } + + // Get day + int GetDay() const { return m_time.GetDay(); } + // Get month + int GetMonth() const { return m_time.GetMonth(); } + // Get year + int GetYear() const { return m_time.GetYear(); } + // Get day of week (0=Sunday 6=Saturday) + int GetDayOfWeek() const { return m_time.GetWeekDay(); } + + hourTy GetHour() const { return (hourTy)m_time.GetHour(); } + hourTy GetHourGMT() const { return (hourTy)m_time.GetHour(wxDateTime::GMT0); } + minuteTy GetMinute() const { return (hourTy)m_time.GetMinute(); } + minuteTy GetMinuteGMT() const { return (hourTy)m_time.GetMinute(wxDateTime::GMT0); } + secondTy GetSecond() const { return (hourTy)m_time.GetSecond(); } + secondTy GetSecondGMT() const { return (hourTy)m_time.GetSecond(wxDateTime::GMT0); } + + clockTy GetSeconds() const { return (clockTy)m_time.GetValue().ToLong(); } + + wxTime Max(const wxTime& t) const { return (t < *this) ? *this : t; } + wxTime Min(const wxTime& t) const { return (t > *this) ? *this : t; } + + static void SetFormat(const tFormat lFormat = wx12h, + const tPrecision lPrecision = wxStdMinSec) + { + ms_Format = lFormat; + ms_Precision = lPrecision; + } + + // (VZ: DANGER: returns pointer to static buffer) + wxChar *FormatTime() const + { + static const wxChar *formats[2][2] = + { + // wxStdMinSec wxStdMin + { _T("%I:%M:%S %p"), _T("%I:%M %p") }, // wx12h + { _T("%H:%M:%S"), _T("%H:%M") } // wx24h + }; + + static wxChar s_bufTime[128]; + + wxStrncpy(s_bufTime, m_time.Format(formats[ms_Format][ms_Precision]), + WXSIZEOF(s_bufTime)); + + return s_bufTime; + } + private: - static tFormat Format; - static tPrecision Precision; + static tFormat ms_Format; + static tPrecision ms_Precision; +#if 0 // old wxTime members unused any more clockTy sec; /* seconds since 1/1/1901 */ bool IsDST() const; wxTime GetLocalTime() const; -private: // static member functions + + // static member functions static wxTime GetLocalTime(const wxDate& date, hourTy h=0, minuteTy m=0, secondTy s=0); static wxTime GetBeginDST(unsigned year); static wxTime GetEndDST(unsigned year); -public: - wxTime(); // current time - wxTime(clockTy s) { sec = s; } - void operator=(const wxTime& t) { sec = t.sec; } // Ordering required for some compilers - wxTime(const wxTime& t) { (*this) = t ; } - wxTime(hourTy h, minuteTy m, secondTy s =0, bool dst =FALSE); - wxTime(const wxDate&, hourTy h =0, minuteTy m =0, secondTy s=0, bool dst =FALSE); +#endif // 0 - // Convert to string -#ifndef __SALFORDC__ - operator wxChar * (void); - operator wxDate() const; -#endif + wxDateTime m_time; - bool operator<(const wxTime& t) const { return sec < t.sec; } - bool operator<=(const wxTime& t) const { return sec <= t.sec; } - bool operator>(const wxTime& t) const { return sec > t.sec; } - bool operator>=(const wxTime& t) const { return sec >= t.sec; } - bool operator==(const wxTime& t) const { return sec == t.sec; } - bool operator!=(const wxTime& t) const { return sec != t.sec; } - friend wxTime operator+(const wxTime& t, long s) { return wxTime(t.sec+s); } - friend wxTime operator+(long s, const wxTime& t) { return wxTime(t.sec+s); } - long operator-(const wxTime& t) const { return sec - t.sec; } - wxTime operator-(long s) const { return wxTime(sec-s); } - void operator+=(long s) { sec += s; } - void operator-=(long s) { sec -= s; } - bool IsBetween(const wxTime& a, const wxTime& b) const; - - /// Get day - int GetDay() const; - /// Get month - int GetMonth() const; - /// Get year - int GetYear() const; - /// Get day of week (0=Sunday 6=Saturday) - int GetDayOfWeek() const; - - hourTy GetHour() const; // hour in local time - hourTy GetHourGMT() const; // hour in GMT - minuteTy GetMinute() const; // minute in local time - minuteTy GetMinuteGMT() const; // minute in GMT - secondTy GetSecond() const; // second in local time or GMT - clockTy GetSeconds() const { return sec; } - secondTy GetSecondGMT() const ; - wxTime Max(const wxTime&) const; - wxTime Min(const wxTime&) const; - static void SetFormat(const tFormat lFormat = wx12h, - const tPrecision lPrecision = wxStdMinSec); - wxChar *FormatTime() const; -/* - virtual int compare(const Object&) const; - virtual void deepenShallowCopy(); // {} - virtual unsigned hash() const; - virtual bool isEqual(const Object&) const; - virtual void printOn(ostream& strm =cout) const; - virtual const Class* species() const; -*/ + DECLARE_DYNAMIC_CLASS(wxTime) }; #endif diff --git a/src/common/cmndata.cpp b/src/common/cmndata.cpp index 5353fe91cc..2e5cabad13 100644 --- a/src/common/cmndata.cpp +++ b/src/common/cmndata.cpp @@ -77,13 +77,14 @@ IMPLEMENT_DYNAMIC_CLASS(wxPrintDialogData, wxObject) IMPLEMENT_DYNAMIC_CLASS(wxPageSetupDialogData, wxObject) #endif // wxUSE_PRINTING_ARCHITECTURE + IMPLEMENT_DYNAMIC_CLASS(wxFontData, wxObject) IMPLEMENT_DYNAMIC_CLASS(wxColourData, wxObject) #ifdef __WXMAC__ -#define mm2pt 2.83464566929 -#define pt2mm 0.352777777778 -#endif + #define mm2pt 2.83464566929 + #define pt2mm 0.352777777778 +#endif // Mac // ============================================================================ // implementation @@ -170,7 +171,7 @@ wxPrintData::wxPrintData() #ifdef __WXMSW__ m_devMode = NULL; #elif defined( __WXMAC__ ) - m_macPrintInfo = NULL ; + m_macPrintInfo = NULL ; #endif m_printOrientation = wxPORTRAIT; m_printNoCopies = 1; @@ -202,7 +203,7 @@ wxPrintData::wxPrintData(const wxPrintData& printData) #ifdef __WXMSW__ m_devMode = NULL; #elif defined( __WXMAC__ ) - m_macPrintInfo = NULL ; + m_macPrintInfo = NULL ; #endif (*this) = printData; } @@ -214,8 +215,8 @@ wxPrintData::~wxPrintData() if (hDevMode ) GlobalFree(hDevMode); #elif defined(__WXMAC__) - if ( m_macPrintInfo ) - ::DisposeHandle( (Handle) m_macPrintInfo ) ; + if ( m_macPrintInfo ) + ::DisposeHandle( (Handle) m_macPrintInfo ) ; #endif } @@ -605,29 +606,29 @@ void wxPrintData::ConvertFromNative() #ifdef __WXMAC__ void wxPrintData::ConvertToNative() { - if ( !m_macPrintInfo ) - { - m_macPrintInfo = (THPrint) NewHandleClear( sizeof( TPrint ) ) ; - if ( m_macPrintInfo ) - { - ::PrintDefault( m_macPrintInfo ) ; - // todo setup the global pagesetup ? - } - } - if ( m_macPrintInfo ) - { - (**m_macPrintInfo).prJob.iCopies = m_printNoCopies ; - (**m_macPrintInfo).prJob.iFstPage = 0 ; - (**m_macPrintInfo).prJob.iLstPage = 0 ; - } + if ( !m_macPrintInfo ) + { + m_macPrintInfo = (THPrint) NewHandleClear( sizeof( TPrint ) ) ; + if ( m_macPrintInfo ) + { + ::PrintDefault( m_macPrintInfo ) ; + // todo setup the global pagesetup ? + } + } + if ( m_macPrintInfo ) + { + (**m_macPrintInfo).prJob.iCopies = m_printNoCopies ; + (**m_macPrintInfo).prJob.iFstPage = 0 ; + (**m_macPrintInfo).prJob.iLstPage = 0 ; + } } void wxPrintData::ConvertFromNative() { - if ( m_macPrintInfo ) - { - m_printNoCopies = (**m_macPrintInfo).prJob.iCopies ; - } + if ( m_macPrintInfo ) + { + m_printNoCopies = (**m_macPrintInfo).prJob.iCopies ; + } } #endif @@ -692,7 +693,7 @@ wxPrintDialogData::wxPrintDialogData() #ifdef __WXMSW__ m_printDlgData = NULL; #elif defined( __WXMAC__ ) - m_macPrintInfo = NULL ; + m_macPrintInfo = NULL ; #endif m_printFromPage = 0; m_printToPage = 0; @@ -715,7 +716,7 @@ wxPrintDialogData::wxPrintDialogData(const wxPrintDialogData& dialogData) #ifdef __WXMSW__ m_printDlgData = NULL; #elif defined( __WXMAC__ ) - m_macPrintInfo = NULL ; + m_macPrintInfo = NULL ; #endif (*this) = dialogData; } @@ -725,7 +726,7 @@ wxPrintDialogData::wxPrintDialogData(const wxPrintData& printData) #ifdef __WXMSW__ m_printDlgData = NULL; #elif defined( __WXMAC__ ) - m_macPrintInfo = NULL ; + m_macPrintInfo = NULL ; #endif m_printFromPage = 0; m_printToPage = 0; @@ -754,8 +755,8 @@ wxPrintDialogData::~wxPrintDialogData() if ( pd ) delete pd; #elif defined(__WXMAC__) - if ( m_macPrintInfo ) - ::DisposeHandle( (Handle) m_macPrintInfo ) ; + if ( m_macPrintInfo ) + ::DisposeHandle( (Handle) m_macPrintInfo ) ; #endif } @@ -914,31 +915,31 @@ void wxPrintDialogData::SetOwnerWindow(wxWindow* win) #ifdef __WXMAC__ void wxPrintDialogData::ConvertToNative() { - if ( !m_macPrintInfo ) - { - m_macPrintInfo = (THPrint) NewHandleClear( sizeof( TPrint ) ) ; - if ( m_macPrintInfo ) - { - ::PrintDefault( m_macPrintInfo ) ; - // todo setup the global pagesetup ? - } - } - if ( m_macPrintInfo ) - { - (**m_macPrintInfo).prJob.iCopies = m_printNoCopies ; - (**m_macPrintInfo).prJob.iFstPage = m_printFromPage ; - (**m_macPrintInfo).prJob.iLstPage = m_printToPage ; - } + if ( !m_macPrintInfo ) + { + m_macPrintInfo = (THPrint) NewHandleClear( sizeof( TPrint ) ) ; + if ( m_macPrintInfo ) + { + ::PrintDefault( m_macPrintInfo ) ; + // todo setup the global pagesetup ? + } + } + if ( m_macPrintInfo ) + { + (**m_macPrintInfo).prJob.iCopies = m_printNoCopies ; + (**m_macPrintInfo).prJob.iFstPage = m_printFromPage ; + (**m_macPrintInfo).prJob.iLstPage = m_printToPage ; + } } void wxPrintDialogData::ConvertFromNative() { - if ( m_macPrintInfo ) - { - m_printNoCopies = (**m_macPrintInfo).prJob.iCopies ; - m_printFromPage = (**m_macPrintInfo).prJob.iFstPage ; - m_printToPage = (**m_macPrintInfo).prJob.iLstPage ; - } + if ( m_macPrintInfo ) + { + m_printNoCopies = (**m_macPrintInfo).prJob.iCopies ; + m_printFromPage = (**m_macPrintInfo).prJob.iFstPage ; + m_printToPage = (**m_macPrintInfo).prJob.iLstPage ; + } } #endif @@ -977,7 +978,7 @@ wxPageSetupDialogData::wxPageSetupDialogData() #if defined(__WIN95__) m_pageSetupData = NULL; #elif defined( __WXMAC__ ) - m_macPageSetupInfo = NULL ; + m_macPageSetupInfo = NULL ; #endif m_paperSize = wxSize(0, 0); @@ -1003,7 +1004,7 @@ wxPageSetupDialogData::wxPageSetupDialogData(const wxPageSetupDialogData& dialog #if defined(__WIN95__) m_pageSetupData = NULL; #elif defined( __WXMAC__ ) - m_macPageSetupInfo = NULL ; + m_macPageSetupInfo = NULL ; #endif (*this) = dialogData; } @@ -1013,7 +1014,7 @@ wxPageSetupDialogData::wxPageSetupDialogData(const wxPrintData& printData) #if defined(__WIN95__) m_pageSetupData = NULL; #elif defined( __WXMAC__ ) - m_macPageSetupInfo = NULL ; + m_macPageSetupInfo = NULL ; #endif m_paperSize = wxSize(0, 0); m_minMarginTopLeft = wxPoint(0, 0); @@ -1046,8 +1047,8 @@ wxPageSetupDialogData::~wxPageSetupDialogData() if ( pd ) delete pd; #elif defined( __WXMAC__ ) - if( m_macPageSetupInfo ) - ::DisposeHandle( (Handle) m_macPageSetupInfo ) ; + if( m_macPageSetupInfo ) + ::DisposeHandle( (Handle) m_macPageSetupInfo ) ; #endif } @@ -1223,62 +1224,62 @@ void wxPageSetupDialogData::SetOwnerWindow(wxWindow* win) #ifdef __WXMAC__ void wxPageSetupDialogData::ConvertToNative() { - if ( !m_macPageSetupInfo ) - { - m_macPageSetupInfo = (THPrint) NewHandleClear( sizeof( TPrint ) ) ; - if ( m_macPageSetupInfo ) - { - ::PrintDefault( m_macPageSetupInfo ) ; - } - } - if ( m_macPageSetupInfo ) - { - // on mac the paper rect has a negative top left corner, because the page rect (printable area) is at 0,0 - (**m_macPageSetupInfo).rPaper.left = int( ((double) m_minMarginTopLeft.x)*mm2pt ) ; - (**m_macPageSetupInfo).rPaper.top = int( ((double) m_minMarginTopLeft.y)*mm2pt ) ; - - (**m_macPageSetupInfo).rPaper.right = int( ((double) m_paperSize.x - m_minMarginTopLeft.x)*mm2pt ) ; - (**m_macPageSetupInfo).rPaper.bottom = int( ((double) m_paperSize.y - m_minMarginTopLeft.y)*mm2pt ) ; - - (**m_macPageSetupInfo).prInfo.rPage.left = 0 ; - (**m_macPageSetupInfo).prInfo.rPage.top = 0 ; - (**m_macPageSetupInfo).prInfo.rPage.right = int( ((double) m_paperSize.x - m_minMarginTopLeft.x - m_minMarginBottomRight.x)*mm2pt ) ; - (**m_macPageSetupInfo).prInfo.rPage.bottom = int( ((double) m_paperSize.y - m_minMarginTopLeft.y - m_minMarginBottomRight.y)*mm2pt ) ; - - //TODO add custom fields in dialog for margins - - } + if ( !m_macPageSetupInfo ) + { + m_macPageSetupInfo = (THPrint) NewHandleClear( sizeof( TPrint ) ) ; + if ( m_macPageSetupInfo ) + { + ::PrintDefault( m_macPageSetupInfo ) ; + } + } + if ( m_macPageSetupInfo ) + { + // on mac the paper rect has a negative top left corner, because the page rect (printable area) is at 0,0 + (**m_macPageSetupInfo).rPaper.left = int( ((double) m_minMarginTopLeft.x)*mm2pt ) ; + (**m_macPageSetupInfo).rPaper.top = int( ((double) m_minMarginTopLeft.y)*mm2pt ) ; + + (**m_macPageSetupInfo).rPaper.right = int( ((double) m_paperSize.x - m_minMarginTopLeft.x)*mm2pt ) ; + (**m_macPageSetupInfo).rPaper.bottom = int( ((double) m_paperSize.y - m_minMarginTopLeft.y)*mm2pt ) ; + + (**m_macPageSetupInfo).prInfo.rPage.left = 0 ; + (**m_macPageSetupInfo).prInfo.rPage.top = 0 ; + (**m_macPageSetupInfo).prInfo.rPage.right = int( ((double) m_paperSize.x - m_minMarginTopLeft.x - m_minMarginBottomRight.x)*mm2pt ) ; + (**m_macPageSetupInfo).prInfo.rPage.bottom = int( ((double) m_paperSize.y - m_minMarginTopLeft.y - m_minMarginBottomRight.y)*mm2pt ) ; + + //TODO add custom fields in dialog for margins + + } } void wxPageSetupDialogData::ConvertFromNative() { - if ( m_macPageSetupInfo ) - { - m_paperSize.x = ((double) (**m_macPageSetupInfo).rPaper.right - (**m_macPageSetupInfo).rPaper.left ) * pt2mm ; - m_paperSize.y = ((double) (**m_macPageSetupInfo).rPaper.bottom - (**m_macPageSetupInfo).rPaper.top ) * pt2mm ; - - m_minMarginTopLeft.x = ((double) -(**m_macPageSetupInfo).rPaper.left ) * pt2mm ; - m_minMarginTopLeft.y = ((double) -(**m_macPageSetupInfo).rPaper.top ) * pt2mm ; - - m_minMarginBottomRight.x = ((double) (**m_macPageSetupInfo).rPaper.right - (**m_macPageSetupInfo).prInfo.rPage.right ) * pt2mm ; - m_minMarginBottomRight.y = ((double)(**m_macPageSetupInfo).rPaper.bottom - (**m_macPageSetupInfo).prInfo.rPage.bottom ) * pt2mm ; - - // adjust minimal values - //TODO add custom fields in dialog for margins - - if ( m_marginTopLeft.x < m_minMarginTopLeft.x ) - m_marginTopLeft.x = m_minMarginTopLeft.x ; - - if ( m_marginBottomRight.x < m_minMarginBottomRight.x ) - m_marginBottomRight.x = m_minMarginBottomRight.x ; - - if ( m_marginTopLeft.y < m_minMarginTopLeft.y ) - m_marginTopLeft.y = m_minMarginTopLeft.y ; - - if ( m_marginBottomRight.y < m_minMarginBottomRight.y ) - m_marginBottomRight.y = m_minMarginBottomRight.y ; - - } + if ( m_macPageSetupInfo ) + { + m_paperSize.x = ((double) (**m_macPageSetupInfo).rPaper.right - (**m_macPageSetupInfo).rPaper.left ) * pt2mm ; + m_paperSize.y = ((double) (**m_macPageSetupInfo).rPaper.bottom - (**m_macPageSetupInfo).rPaper.top ) * pt2mm ; + + m_minMarginTopLeft.x = ((double) -(**m_macPageSetupInfo).rPaper.left ) * pt2mm ; + m_minMarginTopLeft.y = ((double) -(**m_macPageSetupInfo).rPaper.top ) * pt2mm ; + + m_minMarginBottomRight.x = ((double) (**m_macPageSetupInfo).rPaper.right - (**m_macPageSetupInfo).prInfo.rPage.right ) * pt2mm ; + m_minMarginBottomRight.y = ((double)(**m_macPageSetupInfo).rPaper.bottom - (**m_macPageSetupInfo).prInfo.rPage.bottom ) * pt2mm ; + + // adjust minimal values + //TODO add custom fields in dialog for margins + + if ( m_marginTopLeft.x < m_minMarginTopLeft.x ) + m_marginTopLeft.x = m_minMarginTopLeft.x ; + + if ( m_marginBottomRight.x < m_minMarginBottomRight.x ) + m_marginBottomRight.x = m_minMarginBottomRight.x ; + + if ( m_marginTopLeft.y < m_minMarginTopLeft.y ) + m_marginTopLeft.y = m_minMarginTopLeft.y ; + + if ( m_marginBottomRight.y < m_minMarginBottomRight.y ) + m_marginBottomRight.y = m_minMarginBottomRight.y ; + + } } #endif diff --git a/src/common/datetime.cpp b/src/common/datetime.cpp index 00ccb08398..1e0991e496 100644 --- a/src/common/datetime.cpp +++ b/src/common/datetime.cpp @@ -70,6 +70,7 @@ #endif // WX_PRECOMP #include "wx/thread.h" +#include "wx/tokenzr.h" #define wxDEFINE_TIME_CONSTANTS @@ -99,7 +100,7 @@ static const long MILLISECONDS_PER_DAY = 86400000l; // this is the integral part of JDN of the midnight of Jan 1, 1970 // (i.e. JDN(Jan 1, 1970) = 2440587.5) -static const int EPOCH_JDN = 2440587; +static const long EPOCH_JDN = 2440587l; // the date of JDN -0.5 (as we don't work with fractional parts, this is the // reference date for us) is Nov 24, 4714BC @@ -108,10 +109,10 @@ static const int JDN_0_MONTH = wxDateTime::Nov; static const int JDN_0_DAY = 24; // the constants used for JDN calculations -static const int JDN_OFFSET = 32046; -static const int DAYS_PER_5_MONTHS = 153; -static const int DAYS_PER_4_YEARS = 1461; -static const int DAYS_PER_400_YEARS = 146097; +static const long JDN_OFFSET = 32046l; +static const long DAYS_PER_5_MONTHS = 153l; +static const long DAYS_PER_4_YEARS = 1461l; +static const long DAYS_PER_400_YEARS = 146097l; // ---------------------------------------------------------------------------- // globals @@ -123,6 +124,12 @@ static const int DAYS_PER_400_YEARS = 146097; wxCriticalSection gs_critsectTimezone; #endif // wxUSE_THREADS +// the symbolic names for date spans +wxDateSpan wxYear = wxDateSpan(1, 0, 0, 0); +wxDateSpan wxMonth = wxDateSpan(0, 1, 0, 0); +wxDateSpan wxWeek = wxDateSpan(0, 0, 1, 0); +wxDateSpan wxDay = wxDateSpan(0, 0, 0, 1); + // ---------------------------------------------------------------------------- // private functions // ---------------------------------------------------------------------------- @@ -238,6 +245,43 @@ static void ReplaceDefaultYearMonthWithCurrent(int *year, } } +// parsing helpers +// --------------- + +// return the month if the string is a month name or Inv_Month otherwise +static wxDateTime::Month GetMonthFromName(const wxString& name) +{ + wxDateTime::Month mon; + for ( mon = wxDateTime::Jan; mon < wxDateTime::Inv_Month; wxNextMonth(mon) ) + { + // case-insensitive comparison with both abbreviated and not versions + if ( name.CmpNoCase(wxDateTime::GetMonthName(mon, TRUE)) || + name.CmpNoCase(wxDateTime::GetMonthName(mon, FALSE)) ) + { + break; + } + } + + return mon; +} + +// return the weekday if the string is a weekday name or Inv_WeekDay otherwise +static wxDateTime::WeekDay GetWeekDayFromName(const wxString& name) +{ + wxDateTime::WeekDay wd; + for ( wd = wxDateTime::Sun; wd < wxDateTime::Inv_WeekDay; wxNextWDay(wd) ) + { + // case-insensitive comparison with both abbreviated and not versions + if ( name.IsSameAs(wxDateTime::GetWeekDayName(wd, TRUE), FALSE) || + name.IsSameAs(wxDateTime::GetWeekDayName(wd, FALSE), FALSE) ) + { + break; + } + } + + return wd; +} + // ============================================================================ // implementation of wxDateTime // ============================================================================ @@ -383,7 +427,7 @@ wxDateTime::TimeZone::TimeZone(wxDateTime::TZ tz) case wxDateTime::A_CST: // Central Standard Time in use in Australia = UTC + 9.5 - m_offset = 60*(9*60 + 30); + m_offset = 60l*(9*60 + 30); break; default: @@ -530,7 +574,13 @@ wxString wxDateTime::GetMonthName(wxDateTime::Month month, bool abbr) { wxCHECK_MSG( month != Inv_Month, _T(""), _T("invalid month") ); - tm tm = { 0, 0, 0, 1, month, 76 }; // any year will do + tm tm; + tm.tm_hour = + tm.tm_min = + tm.tm_sec = 0; + tm.tm_mday = 1; + tm.tm_mon = month; + tm.tm_year = 76; // any year will do return CallStrftime(abbr ? _T("%b") : _T("%B"), &tm); } @@ -965,8 +1015,9 @@ wxDateTime& wxDateTime::Set(double jdn) // EPOCH_JDN + 0.5 jdn -= EPOCH_JDN + 0.5; + jdn *= MILLISECONDS_PER_DAY; + m_time = jdn; - m_time *= MILLISECONDS_PER_DAY; return *this; } @@ -1203,6 +1254,74 @@ wxDateTime& wxDateTime::SetToLastMonthDay(Month month, return Set(GetNumOfDaysInMonth(year, month), month, year); } +wxDateTime& wxDateTime::SetToWeekDayInSameWeek(WeekDay weekday) +{ + wxCHECK_MSG( weekday != Inv_WeekDay, ms_InvDateTime, _T("invalid weekday") ); + + WeekDay wdayThis = GetWeekDay(); + if ( weekday == wdayThis ) + { + // nothing to do + return *this; + } + else if ( weekday < wdayThis ) + { + return Substract(wxTimeSpan::Days(wdayThis - weekday)); + } + else // weekday > wdayThis + { + return Add(wxTimeSpan::Days(weekday - wdayThis)); + } +} + +wxDateTime& wxDateTime::SetToNextWeekDay(WeekDay weekday) +{ + wxCHECK_MSG( weekday != Inv_WeekDay, ms_InvDateTime, _T("invalid weekday") ); + + int diff; + WeekDay wdayThis = GetWeekDay(); + if ( weekday == wdayThis ) + { + // nothing to do + return *this; + } + else if ( weekday < wdayThis ) + { + // need to advance a week + diff = 7 - (wdayThis - weekday); + } + else // weekday > wdayThis + { + diff = weekday - wdayThis; + } + + return Add(wxTimeSpan::Days(diff)); +} + +wxDateTime& wxDateTime::SetToPrevWeekDay(WeekDay weekday) +{ + wxCHECK_MSG( weekday != Inv_WeekDay, ms_InvDateTime, _T("invalid weekday") ); + + int diff; + WeekDay wdayThis = GetWeekDay(); + if ( weekday == wdayThis ) + { + // nothing to do + return *this; + } + else if ( weekday > wdayThis ) + { + // need to go to previous week + diff = 7 - (weekday - wdayThis); + } + else // weekday < wdayThis + { + diff = wdayThis - weekday; + } + + return Substract(wxTimeSpan::Days(diff)); +} + bool wxDateTime::SetToWeekDay(WeekDay weekday, int n, Month month, @@ -1506,6 +1625,629 @@ wxString wxDateTime::Format(const wxChar *format, const TimeZone& tz) const return str; } +// this function parses a string in (strict) RFC 822 format: see the section 5 +// of the RFC for the detailed description, but briefly it's something of the +// form "Sat, 18 Dec 1999 00:48:30 +0100" +// +// this function is "strict" by design - it must reject anything except true +// RFC822 time specs. +// +// TODO a great candidate for using reg exps +const wxChar *wxDateTime::ParseRfc822Date(const wxChar* date) +{ + wxCHECK_MSG( date, (wxChar *)NULL, _T("NULL pointer in wxDateTime::Parse") ); + + const wxChar *p = date; + const wxChar *comma = wxStrchr(p, _T(',')); + if ( comma ) + { + // the part before comma is the weekday + + // skip it for now - we don't use but might check that it really + // corresponds to the specfied date + p = comma + 1; + + if ( *p != _T(' ') ) + { + wxLogDebug(_T("no space after weekday in RFC822 time spec")); + + return (wxChar *)NULL; + } + + p++; // skip space + } + + // the following 1 or 2 digits are the day number + if ( !wxIsdigit(*p) ) + { + wxLogDebug(_T("day number expected in RFC822 time spec, none found")); + + return (wxChar *)NULL; + } + + wxDateTime_t day = *p++ - _T('0'); + if ( wxIsdigit(*p) ) + { + day *= 10; + day += *p++ - _T('0'); + } + + if ( *p++ != _T(' ') ) + { + return (wxChar *)NULL; + } + + // the following 3 letters specify the month + wxString monName(p, 3); + Month mon; + if ( monName == _T("Jan") ) + mon = Jan; + else if ( monName == _T("Feb") ) + mon = Feb; + else if ( monName == _T("Mar") ) + mon = Mar; + else if ( monName == _T("Apr") ) + mon = Apr; + else if ( monName == _T("May") ) + mon = May; + else if ( monName == _T("Jun") ) + mon = Jun; + else if ( monName == _T("Jul") ) + mon = Jul; + else if ( monName == _T("Aug") ) + mon = Aug; + else if ( monName == _T("Sep") ) + mon = Sep; + else if ( monName == _T("Oct") ) + mon = Oct; + else if ( monName == _T("Nov") ) + mon = Nov; + else if ( monName == _T("Dec") ) + mon = Dec; + else + { + wxLogDebug(_T("Invalid RFC 822 month name '%s'"), monName.c_str()); + + return (wxChar *)NULL; + } + + p += 3; + + if ( *p++ != _T(' ') ) + { + return (wxChar *)NULL; + } + + // next is the year + if ( !wxIsdigit(*p) ) + { + // no year? + return (wxChar *)NULL; + } + + int year = *p++ - _T('0'); + + if ( !wxIsdigit(*p) ) + { + // should have at least 2 digits in the year + return (wxChar *)NULL; + } + + year *= 10; + year += *p++ - _T('0'); + + // is it a 2 digit year (as per original RFC 822) or a 4 digit one? + if ( wxIsdigit(*p) ) + { + year *= 10; + year += *p++ - _T('0'); + + if ( !wxIsdigit(*p) ) + { + // no 3 digit years please + return (wxChar *)NULL; + } + + year *= 10; + year += *p++ - _T('0'); + } + + if ( *p++ != _T(' ') ) + { + return (wxChar *)NULL; + } + + // time is in the format hh:mm:ss and seconds are optional + if ( !wxIsdigit(*p) ) + { + return (wxChar *)NULL; + } + + wxDateTime_t hour = *p++ - _T('0'); + + if ( !wxIsdigit(*p) ) + { + return (wxChar *)NULL; + } + + hour *= 10; + hour += *p++ - _T('0'); + + if ( *p++ != _T(':') ) + { + return (wxChar *)NULL; + } + + if ( !wxIsdigit(*p) ) + { + return (wxChar *)NULL; + } + + wxDateTime_t min = *p++ - _T('0'); + + if ( !wxIsdigit(*p) ) + { + return (wxChar *)NULL; + } + + min *= 10; + min += *p++ - _T('0'); + + wxDateTime_t sec = 0; + if ( *p++ == _T(':') ) + { + if ( !wxIsdigit(*p) ) + { + return (wxChar *)NULL; + } + + sec = *p++ - _T('0'); + + if ( !wxIsdigit(*p) ) + { + return (wxChar *)NULL; + } + + sec *= 10; + sec += *p++ - _T('0'); + } + + if ( *p++ != _T(' ') ) + { + return (wxChar *)NULL; + } + + // and now the interesting part: the timezone + int offset; + if ( *p == _T('-') || *p == _T('+') ) + { + // the explicit offset given: it has the form of hhmm + bool plus = *p++ == _T('+'); + + if ( !wxIsdigit(*p) || !wxIsdigit(*(p + 1)) ) + { + return (wxChar *)NULL; + } + + // hours + offset = 60*(10*(*p - _T('0')) + (*(p + 1) - _T('0'))); + + p += 2; + + if ( !wxIsdigit(*p) || !wxIsdigit(*(p + 1)) ) + { + return (wxChar *)NULL; + } + + // minutes + offset += 10*(*p - _T('0')) + (*(p + 1) - _T('0')); + + if ( !plus ) + { + offset = -offset; + } + + p += 2; + } + else + { + // the symbolic timezone given: may be either military timezone or one + // of standard abbreviations + if ( !*(p + 1) ) + { + // military: Z = UTC, J unused, A = -1, ..., Y = +12 + static const int offsets[26] = + { + //A B C D E F G H I J K L M + -1, -2, -3, -4, -5, -6, -7, -8, -9, 0, -10, -11, -12, + //N O P R Q S T U V W Z Y Z + +1, +2, +3, +4, +5, +6, +7, +8, +9, +10, +11, +12, 0 + }; + + if ( *p < _T('A') || *p > _T('Z') || *p == _T('J') ) + { + wxLogDebug(_T("Invalid militaty timezone '%c'"), *p); + + return (wxChar *)NULL; + } + + offset = offsets[*p++ - _T('A')]; + } + else + { + // abbreviation + wxString tz = p; + if ( tz == _T("UT") || tz == _T("UTC") || tz == _T("GMT") ) + offset = 0; + else if ( tz == _T("AST") ) + offset = AST - GMT0; + else if ( tz == _T("ADT") ) + offset = ADT - GMT0; + else if ( tz == _T("EST") ) + offset = EST - GMT0; + else if ( tz == _T("EDT") ) + offset = EDT - GMT0; + else if ( tz == _T("CST") ) + offset = CST - GMT0; + else if ( tz == _T("CDT") ) + offset = CDT - GMT0; + else if ( tz == _T("MST") ) + offset = MST - GMT0; + else if ( tz == _T("MDT") ) + offset = MDT - GMT0; + else if ( tz == _T("PST") ) + offset = PST - GMT0; + else if ( tz == _T("PDT") ) + offset = PDT - GMT0; + else + { + wxLogDebug(_T("Unknown RFC 822 timezone '%s'"), p); + + return (wxChar *)NULL; + } + + p += tz.length(); + } + + // make it minutes + offset *= 60; + } + + // the spec was correct + Set(day, mon, year, hour, min, sec); + MakeTimezone(60*offset); + + return p; +} + +const wxChar *wxDateTime::ParseFormat(const wxChar *date, const wxChar *format) +{ + wxCHECK_MSG( date && format, (wxChar *)NULL, + _T("NULL pointer in wxDateTime::Parse") ); + + // there is a public domain version of getdate.y, but it only works for + // English... + wxFAIL_MSG(_T("TODO")); + + return (wxChar *)NULL; +} + +const wxChar *wxDateTime::ParseDateTime(const wxChar *date) +{ + wxCHECK_MSG( date, (wxChar *)NULL, _T("NULL pointer in wxDateTime::Parse") ); + + // find a public domain version of strptime() somewhere? + wxFAIL_MSG(_T("TODO")); + + return (wxChar *)NULL; +} + +const wxChar *wxDateTime::ParseDate(const wxChar *date) +{ + // this is a simplified version of ParseDateTime() which understands only + // "today" (for wxDate compatibility) and digits only otherwise (and not + // all esoteric constructions ParseDateTime() knows about) + + wxCHECK_MSG( date, (wxChar *)NULL, _T("NULL pointer in wxDateTime::Parse") ); + + const wxChar *p = date; + while ( wxIsspace(*p) ) + p++; + + wxString today = _T("today"); + size_t len = today.length(); + if ( wxString(p, len).CmpNoCase(today) == 0 ) + { + // nothing can follow this, so stop here + p += len; + + *this = Today(); + + return p; + } + + // what do we have? + bool haveDay = FALSE, // the months day? + haveWDay = FALSE, // the day of week? + haveMon = FALSE, // the month? + haveYear = FALSE; // the year? + + // and the value of the items we have (init them to get rid of warnings) + WeekDay wday = Inv_WeekDay; + wxDateTime_t day = 0; + wxDateTime::Month mon = Inv_Month; + int year = 0; + + // tokenize the string + wxStringTokenizer tok(p, _T(",/-\t ")); + while ( tok.HasMoreTokens() ) + { + wxString token = tok.GetNextToken(); + + // is it a number? + unsigned long val; + if ( token.ToULong(&val) ) + { + // guess what this number is + + bool isDay = FALSE, + isMonth = FALSE, + // only years are counted from 0 + isYear = (val == 0) || (val > 31); + if ( !isYear ) + { + // may be the month or month day or the year, assume the + // month day by default and fallback to month if the range + // allow it or to the year if our assumption doesn't work + if ( haveDay ) + { + // we already have the day, so may only be a month or year + if ( val > 12 ) + { + isYear = TRUE; + } + else + { + isMonth = TRUE; + } + } + else // it may be day + { + isDay = TRUE; + + // check the range + if ( haveMon ) + { + if ( val > GetNumOfDaysInMonth(haveYear ? year + : Inv_Year, + mon) ) + { + // oops, it can't be a day finally + isDay = FALSE; + + if ( val > 12 ) + { + isYear = TRUE; + } + else + { + isMonth = TRUE; + } + } + } + } + } + + // remember that we have this and stop the scan if it's the second + // time we find this, except for the day logic (see there) + if ( isYear ) + { + if ( haveYear ) + { + break; + } + + haveYear = TRUE; + + // no roll over - 99 means 99, not 1999 for us + year = val; + } + else if ( isMonth ) + { + if ( haveMon ) + { + break; + } + + haveMon = TRUE; + + mon = (wxDateTime::Month)val; + } + else + { + wxASSERT_MSG( isDay, _T("logic error") ); + + if ( haveDay ) + { + // may be were mistaken when we found it for the first + // time? may be it was a month or year instead? + // + // this ability to "backtrack" allows us to correctly parse + // both things like 01/13 and 13/01 - but, of course, we + // still can't resolve the ambiguity in 01/02 (it will be + // Feb 1 for us, not Jan 2 as americans might expect!) + if ( (day <= 12) && !haveMon ) + { + // exchange day and month + mon = (wxDateTime::Month)day; + + haveMon = TRUE; + } + else if ( !haveYear ) + { + // exchange day and year + year = day; + + haveYear = TRUE; + } + } + + haveDay = TRUE; + + day = val; + } + } + else // not a number + { + mon = GetMonthFromName(token); + if ( mon != Inv_Month ) + { + // it's a month + if ( haveMon ) + { + break; + } + + haveMon = TRUE; + } + else + { + wday = GetWeekDayFromName(token); + if ( wday != Inv_WeekDay ) + { + // a week day + if ( haveWDay ) + { + break; + } + + haveWDay = TRUE; + } + else + { + // try the ordinals + static const wxChar *ordinals[] = + { + wxTRANSLATE("first"), + wxTRANSLATE("second"), + wxTRANSLATE("third"), + wxTRANSLATE("fourth"), + wxTRANSLATE("fifth"), + wxTRANSLATE("sixth"), + wxTRANSLATE("seventh"), + wxTRANSLATE("eighth"), + wxTRANSLATE("ninth"), + wxTRANSLATE("tenth"), + wxTRANSLATE("eleventh"), + wxTRANSLATE("twelfth"), + wxTRANSLATE("thirteenth"), + wxTRANSLATE("fourteenth"), + wxTRANSLATE("fifteenth"), + wxTRANSLATE("sixteenth"), + wxTRANSLATE("seventeenth"), + wxTRANSLATE("eighteenth"), + wxTRANSLATE("nineteenth"), + wxTRANSLATE("twentieth"), + // that's enough - otherwise we'd have problems with + // composite (or not) ordinals otherwise + }; + + size_t n; + for ( n = 0; n < WXSIZEOF(ordinals); n++ ) + { + if ( token.CmpNoCase(ordinals[n]) == 0 ) + { + break; + } + } + + if ( n == WXSIZEOF(ordinals) ) + { + // stop here - something unknown + break; + } + + // it's a day + if ( haveDay ) + { + // don't try anything here (as in case of numeric day + // above) - the symbolic day spec should always + // precede the month/year + break; + } + + haveDay = TRUE; + + day = n + 1; + } + } + } + } + + // either no more tokens or the scan was stopped by something we couldn't + // parse - in any case, see if we can construct a date from what we have + if ( !haveDay && !haveWDay ) + { + wxLogDebug(_T("no day, no weekday hence no date.")); + + return (wxChar *)NULL; + } + + if ( haveWDay && (haveMon || haveYear || haveDay) && + !(haveMon && haveMon && haveYear) ) + { + // without adjectives (which we don't support here) the week day only + // makes sense completely separately or with the full date + // specification (what would "Wed 1999" mean?) + return (wxChar *)NULL; + } + + if ( !haveMon ) + { + mon = GetCurrentMonth(); + } + + if ( !haveYear ) + { + year = GetCurrentYear(); + } + + if ( haveDay ) + { + Set(day, mon, year); + + if ( haveWDay ) + { + // check that it is really the same + if ( GetWeekDay() != wday ) + { + // inconsistency detected + return (wxChar *)NULL; + } + } + } + else // haveWDay + { + *this = Today(); + + SetToWeekDayInSameWeek(wday); + } + + // return the pointer to the next char + return p + wxStrlen(p) - wxStrlen(tok.GetString()); +} + +const wxChar *wxDateTime::ParseTime(const wxChar *time) +{ + wxCHECK_MSG( time, (wxChar *)NULL, _T("NULL pointer in wxDateTime::Parse") ); + + // this function should be able to parse different time formats as well as + // timezones (take the code out from ParseRfc822Date()) and AM/PM. + wxFAIL_MSG(_T("TODO")); + + return (wxChar *)NULL; +} + // ============================================================================ // wxTimeSpan // ============================================================================ @@ -1565,7 +2307,7 @@ wxString wxTimeSpan::Format(const wxChar *format) const break; case 'l': - tmp.Printf(_T("%03d"), GetMilliseconds().GetValue()); + tmp.Printf(_T("%03ld"), GetMilliseconds().ToLong()); break; case 'M': @@ -1573,7 +2315,7 @@ wxString wxTimeSpan::Format(const wxChar *format) const break; case 'S': - tmp.Printf(_T("%02d"), GetSeconds().GetValue()); + tmp.Printf(_T("%02ld"), GetSeconds().ToLong()); break; } diff --git a/src/common/longlong.cpp b/src/common/longlong.cpp index 29a4f867b9..5493e0bfca 100644 --- a/src/common/longlong.cpp +++ b/src/common/longlong.cpp @@ -423,7 +423,9 @@ wxLongLongWx& wxLongLongWx::operator*=(const wxLongLongWx& ll) // division -void wxLongLongWx::Divide(const wxLongLongWx& divisor, wxLongLongWx& quotient, wxLongLongWx& remainder) const +void wxLongLongWx::Divide(const wxLongLongWx& divisor, + wxLongLongWx& quotient, + wxLongLongWx& remainder) const { if ((divisor.m_lo == 0) && (divisor.m_hi == 0)) { diff --git a/src/common/string.cpp b/src/common/string.cpp index 8b83cf17fc..917e979231 100644 --- a/src/common/string.cpp +++ b/src/common/string.cpp @@ -1028,6 +1028,49 @@ int wxString::Find(const wxChar *pszSub) const return (psz == NULL) ? wxNOT_FOUND : psz - (const wxChar*) m_pchData; } +// ---------------------------------------------------------------------------- +// conversion to numbers +// ---------------------------------------------------------------------------- + +bool wxString::ToLong(long *val) const +{ + wxCHECK_MSG( val, FALSE, _T("NULL pointer in wxString::ToLong") ); + + const wxChar *start = c_str(); + wxChar *end; + *val = wxStrtol(start, &end, 10); + + // return TRUE only if scan was stopped by the terminating NUL and if the + // string was not empty to start with + return !*end && (end != start); +} + +bool wxString::ToULong(unsigned long *val) const +{ + wxCHECK_MSG( val, FALSE, _T("NULL pointer in wxString::ToULong") ); + + const wxChar *start = c_str(); + wxChar *end; + *val = wxStrtoul(start, &end, 10); + + // return TRUE only if scan was stopped by the terminating NUL and if the + // string was not empty to start with + return !*end && (end != start); +} + +bool wxString::ToDouble(double *val) const +{ + wxCHECK_MSG( val, FALSE, _T("NULL pointer in wxString::ToDouble") ); + + const wxChar *start = c_str(); + wxChar *end; + *val = wxStrtod(start, &end); + + // return TRUE only if scan was stopped by the terminating NUL and if the + // string was not empty to start with + return !*end && (end != start); +} + // --------------------------------------------------------------------------- // stream-like operators // --------------------------------------------------------------------------- diff --git a/src/common/timercmn.cpp b/src/common/timercmn.cpp index 6409e809e7..64dbb0aac2 100644 --- a/src/common/timercmn.cpp +++ b/src/common/timercmn.cpp @@ -103,7 +103,7 @@ long wxStopWatch::GetElapsedTime() const // old timer functions superceded by wxStopWatch // ---------------------------------------------------------------------------- -static wxLongLong wxStartTime = 0; +static wxLongLong wxStartTime = 0l; // starts the global timer void wxStartTimer() @@ -211,7 +211,8 @@ wxLongLong wxGetLocalTimeMillis() // 00:00:00 Jan 1st 1970 and then whatever is available // to get millisecond resolution. // - wxLongLong val = 1000 * wxGetLocalTime(); + wxLongLong val = 1000l; + val *= wxGetLocalTime(); // If we got here, do not fail even if we can't get // millisecond resolution. diff --git a/src/common/txtstrm.cpp b/src/common/txtstrm.cpp index 4e8dae20ac..cd0300b42d 100644 --- a/src/common/txtstrm.cpp +++ b/src/common/txtstrm.cpp @@ -343,7 +343,7 @@ wxTextOutputStream::~wxTextOutputStream() { } -void wxTextOutputStream::SetMode( wxEOL mode = wxEOL_NATIVE ) +void wxTextOutputStream::SetMode(wxEOL mode) { m_mode = mode; if (m_mode == wxEOL_NATIVE) diff --git a/src/common/variant.cpp b/src/common/variant.cpp index 3acdd76f4f..ccc6b92526 100644 --- a/src/common/variant.cpp +++ b/src/common/variant.cpp @@ -36,6 +36,12 @@ #include "wx/string.h" #include "wx/variant.h" +IMPLEMENT_DYNAMIC_CLASS(wxDate, wxObject) +IMPLEMENT_DYNAMIC_CLASS(wxTime, wxObject) + +wxTime::tFormat wxTime::ms_Format = wxTime::wx12h; +wxTime::tPrecision wxTime::ms_Precision = wxTime::wxStdMinSec; + IMPLEMENT_ABSTRACT_CLASS(wxVariantData, wxObject) wxVariant WXDLLEXPORT wxNullVariant; diff --git a/src/msw/button.cpp b/src/msw/button.cpp index cce54d6389..e913563260 100644 --- a/src/msw/button.cpp +++ b/src/msw/button.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: button.cpp +// Name: msw/button.cpp // Purpose: wxButton // Author: Julian Smart // Modified by: @@ -16,6 +16,7 @@ // ---------------------------------------------------------------------------- // headers // ---------------------------------------------------------------------------- + #ifdef __GNUG__ #pragma implementation "button.h" #endif @@ -42,7 +43,7 @@ // macros // ---------------------------------------------------------------------------- - IMPLEMENT_DYNAMIC_CLASS(wxButton, wxControl) +IMPLEMENT_DYNAMIC_CLASS(wxButton, wxControl) // this macro tries to adjust the default button height to a reasonable value // using the char height as the base @@ -70,8 +71,9 @@ bool wxButton::Create(wxWindow *parent, parent->AddChild((wxButton *)this); - m_backgroundColour = parent->GetBackgroundColour() ; - m_foregroundColour = parent->GetForegroundColour() ; + m_backgroundColour = parent->GetBackgroundColour(); + m_foregroundColour = parent->GetForegroundColour(); + m_hWnd = (WXHWND)CreateWindowEx ( @@ -189,14 +191,18 @@ void wxButton::SetDefault() SendMessage(GetWinHwnd(parent), DM_SETDEFID, m_windowId, 0L); } - // this doesn't work with bitmap buttons because it also removes the - // "ownerdrawn" style... - if ( btnOldDefault && !wxDynamicCast(btnOldDefault, wxBitmapButton) ) + if ( btnOldDefault ) { // remove the BS_DEFPUSHBUTTON style from the other button long style = GetWindowLong(GetHwndOf(btnOldDefault), GWL_STYLE); - style &= ~BS_DEFPUSHBUTTON; - SendMessage(GetHwndOf(btnOldDefault), BM_SETSTYLE, style, 1L); + + // don't do it with the owner drawn buttons because it will reset + // BS_OWNERDRAW style bit too (BS_OWNERDRAW & BS_DEFPUSHBUTTON != 0)! + if ( !(style & BS_OWNERDRAW) ) + { + style &= ~BS_DEFPUSHBUTTON; + SendMessage(GetHwndOf(btnOldDefault), BM_SETSTYLE, style, 1L); + } } // set this button as the default @@ -265,3 +271,230 @@ long wxButton::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) // let the base class do all real processing return wxControl::MSWWindowProc(nMsg, wParam, lParam); } + +// ---------------------------------------------------------------------------- +// owner-drawn buttons support +// ---------------------------------------------------------------------------- + +#ifdef __WIN32__ + +// drawing helpers + +static void DrawButtonText(HDC hdc, + RECT *pRect, + const wxString& text, + COLORREF col) +{ + COLORREF colOld = SetTextColor(hdc, col); + int modeOld = SetBkMode(hdc, TRANSPARENT); + + DrawText(hdc, text, text.length(), pRect, + DT_CENTER | DT_VCENTER | DT_SINGLELINE); + + SetBkMode(hdc, modeOld); + SetTextColor(hdc, colOld); +} + +static void DrawRect(HDC hdc, const RECT& r) +{ + MoveToEx(hdc, r.left, r.top, NULL); + LineTo(hdc, r.right, r.top); + LineTo(hdc, r.right, r.bottom); + LineTo(hdc, r.left, r.bottom); + LineTo(hdc, r.left, r.top); +} + +void wxButton::MakeOwnerDrawn() +{ + long style = GetWindowLong(GetHwnd(), GWL_STYLE); + if ( !(style & BS_OWNERDRAW) ) + { + // make it so + style |= BS_OWNERDRAW; + SetWindowLong(GetHwnd(), GWL_STYLE, style); + } +} + +bool wxButton::SetBackgroundColour(const wxColour &colour) +{ + if ( !wxControl::SetBackgroundColour(colour) ) + { + // nothing to do + return FALSE; + } + + MakeOwnerDrawn(); + + Refresh(); + + return TRUE; +} + +bool wxButton::SetForegroundColour(const wxColour &colour) +{ + if ( !wxControl::SetForegroundColour(colour) ) + { + // nothing to do + return FALSE; + } + + MakeOwnerDrawn(); + + Refresh(); + + return TRUE; +} + +/* + The button frame looks like this normally: + + WWWWWWWWWWWWWWWWWWB + W GB + W GB + W GB where W, G, B are white, grey and black pixels + W GB + WGGGGGGGGGGGGGGGGGB + BBBBBBBBBBBBBBBBBBB + + When the button is selected, the button becomes like this (the total button + size doesn't change): + + BBBBBBBBBBBBBBBBBBB + BWWWWWWWWWWWWWWWWBB + BW GBB + BW GBB + BWGGGGGGGGGGGGGGGBB + BBBBBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBB + + When the button is pushed (while selected) it is like: + + BBBBBBBBBBBBBBBBBBB + BGGGGGGGGGGGGGGGGGB + BG GB + BG GB + BG GB + BGGGGGGGGGGGGGGGGGB + BBBBBBBBBBBBBBBBBBB +*/ + +static void DrawButtonFrame(HDC hdc, const RECT& rectBtn, + bool selected, bool pushed) +{ + RECT r; + CopyRect(&r, &rectBtn); + + HPEN hpenBlack = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DDKSHADOW)), + hpenGrey = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DSHADOW)), + hpenWhite = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DHILIGHT)); + + HPEN hpenOld = (HPEN)SelectObject(hdc, hpenBlack); + + r.right--; + r.bottom--; + + if ( pushed ) + { + DrawRect(hdc, r); + + (void)SelectObject(hdc, hpenGrey); + InflateRect(&r, -1, -1); + + DrawRect(hdc, r); + } + else // !pushed + { + if ( selected ) + { + DrawRect(hdc, r); + + InflateRect(&r, -1, -1); + } + + MoveToEx(hdc, r.left, r.bottom, NULL); + LineTo(hdc, r.right, r.bottom); + LineTo(hdc, r.right, r.top - 1); + + (void)SelectObject(hdc, hpenWhite); + MoveToEx(hdc, r.left, r.bottom - 1, NULL); + LineTo(hdc, r.left, r.top); + LineTo(hdc, r.right, r.top); + + (void)SelectObject(hdc, hpenGrey); + MoveToEx(hdc, r.left + 1, r.bottom - 1, NULL); + LineTo(hdc, r.right - 1, r.bottom - 1); + LineTo(hdc, r.right - 1, r.top); + } + + (void)SelectObject(hdc, hpenOld); + DeleteObject(hpenWhite); + DeleteObject(hpenGrey); + DeleteObject(hpenBlack); +} + +bool wxButton::MSWOnDraw(WXDRAWITEMSTRUCT *wxdis) +{ + LPDRAWITEMSTRUCT lpDIS = (LPDRAWITEMSTRUCT)wxdis; + + RECT rectBtn; + CopyRect(&rectBtn, &lpDIS->rcItem); + + COLORREF colBg = wxColourToRGB(GetBackgroundColour()), + colFg = wxColourToRGB(GetForegroundColour()); + + HDC hdc = lpDIS->hDC; + UINT state = lpDIS->itemState; + + // first, draw the background + HBRUSH hbrushBackground = ::CreateSolidBrush(colBg); + + FillRect(hdc, &rectBtn, hbrushBackground); + + // draw the border for the current state + bool selected = (state & ODS_SELECTED) != 0; + if ( !selected ) + { + wxPanel *panel = wxDynamicCast(GetParent(), wxPanel); + if ( panel ) + { + selected = panel->GetDefaultItem() == this; + } + } + bool pushed = (SendMessage(GetHwnd(), BM_GETSTATE, 0, 0) & BST_PUSHED) != 0; + + DrawButtonFrame(hdc, rectBtn, selected, pushed); + + // draw the focus rect if needed + if ( state & ODS_FOCUS ) + { + RECT rectFocus; + CopyRect(&rectFocus, &rectBtn); + + // I don't know where does this constant come from, but this is how + // Windows draws them + InflateRect(&rectFocus, -4, -4); + + DrawFocusRect(hdc, &rectFocus); + } + + DrawButtonText(hdc, &rectBtn, GetLabel(), + state & ODS_DISABLED ? GetSysColor(COLOR_GRAYTEXT) + : colFg); + + ::DeleteObject(hbrushBackground); + +#if 0 + wxString s = "button state: "; + if ( selected ) + s += "selected "; + if ( pushed ) + s += "pushed "; + if ( state & ODS_FOCUS ) + s += "focused "; + wxLogStatus(s); +#endif + + return TRUE; +} + +#endif // __WIN32__ diff --git a/src/msw/combobox.cpp b/src/msw/combobox.cpp index dd0de6353c..d4ec3f017a 100644 --- a/src/msw/combobox.cpp +++ b/src/msw/combobox.cpp @@ -34,30 +34,32 @@ IMPLEMENT_DYNAMIC_CLASS(wxComboBox, wxControl) bool wxComboBox::MSWCommand(WXUINT param, WXWORD WXUNUSED(id)) { - if (param == CBN_SELCHANGE) - { - if (GetSelection() > -1) + switch ( param ) { - wxCommandEvent event(wxEVT_COMMAND_COMBOBOX_SELECTED, m_windowId); - event.SetInt(GetSelection()); - event.SetEventObject(this); - event.SetString(GetStringSelection()); - ProcessCommand(event); + case CBN_SELCHANGE: + if (GetSelection() > -1) + { + wxCommandEvent event(wxEVT_COMMAND_COMBOBOX_SELECTED, GetId()); + event.SetInt(GetSelection()); + event.SetEventObject(this); + event.SetString(GetStringSelection()); + ProcessCommand(event); + } + break; + + case CBN_EDITCHANGE: + { + wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, GetId()); + event.SetString(GetValue()); + event.SetEventObject(this); + ProcessCommand(event); + } + break; } - return TRUE; - } - else if (param == CBN_EDITCHANGE) - { - wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, m_windowId); - event.SetString(GetValue()); - event.SetEventObject(this); - ProcessCommand(event); - - return TRUE; - } - else - return FALSE; + // there is no return value for the CBN_ notifications, so always return + // FALSE from here to pass the message to DefWindowProc() + return FALSE; } bool wxComboBox::Create(wxWindow *parent, wxWindowID id, diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 96ab891d7b..eefebd74d7 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -2670,10 +2670,9 @@ bool wxWindow::MSWOnDrawItem(int id, WXDRAWITEMSTRUCT *itemStruct) { return ((wxControl *)item)->MSWOnDraw(itemStruct); } - else -#endif - return FALSE; +#endif // USE_OWNER_DRAWN + return FALSE; } bool wxWindow::MSWOnMeasureItem(int id, WXMEASUREITEMSTRUCT *itemStruct) -- 2.45.2