diff options
Diffstat (limited to 'svtools/source/control/calendar.cxx')
-rw-r--r-- | svtools/source/control/calendar.cxx | 3037 |
1 files changed, 3037 insertions, 0 deletions
diff --git a/svtools/source/control/calendar.cxx b/svtools/source/control/calendar.cxx new file mode 100644 index 000000000000..4a0bc4112264 --- /dev/null +++ b/svtools/source/control/calendar.cxx @@ -0,0 +1,3037 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svtools.hxx" + +#include <vcl/svapp.hxx> +#include <tools/table.hxx> +#include <vcl/help.hxx> +#include <vcl/menu.hxx> +#include <vcl/decoview.hxx> +#include <vcl/floatwin.hxx> +#include <vcl/button.hxx> +#include <vcl/fixed.hxx> +#include <unotools/calendarwrapper.hxx> +#include <unotools/localedatawrapper.hxx> +#include <com/sun/star/i18n/Weekdays.hpp> +#include <com/sun/star/i18n/CalendarDisplayIndex.hpp> +#include <com/sun/star/i18n/CalendarFieldIndex.hpp> + +#define _SV_CALENDAR_CXX +#include <svtools/svtools.hrc> +#include <svtools/svtdata.hxx> +#include <svtools/calendar.hxx> + +// ======================================================================= + +#define DAY_OFFX 4 +#define DAY_OFFY 2 +#define MONTH_BORDERX 4 +#define MONTH_OFFY 3 +#define WEEKNUMBER_OFFX 4 +#define WEEKDAY_OFFY 3 +#define TITLE_OFFY 3 +#define TITLE_BORDERY 2 +#define SPIN_OFFX 4 +#define SPIN_OFFY TITLE_BORDERY + +#define WEEKNUMBER_HEIGHT 85 + +#define CALENDAR_HITTEST_DAY ((sal_uInt16)0x0001) +#define CALENDAR_HITTEST_WEEK ((sal_uInt16)0x0002) +#define CALENDAR_HITTEST_MONTHTITLE ((sal_uInt16)0x0004) +#define CALENDAR_HITTEST_PREV ((sal_uInt16)0x0008) +#define CALENDAR_HITTEST_NEXT ((sal_uInt16)0x0010) +#define CALENDAR_HITTEST_OUTSIDE ((sal_uInt16)0x1000) + +#define MENU_YEAR_COUNT 3 + +#define TABLE_DATE_SELECTED ((void*)0x00000001) + +using namespace ::com::sun::star; + +// ======================================================================= + +struct ImplDateInfo +{ + XubString maText; + Color* mpTextColor; + Color* mpFrameColor; + sal_uInt16 mnFlags; + + ImplDateInfo( const XubString& rText ) : + maText( rText ) + { mpTextColor = mpFrameColor = NULL; mnFlags = 0; } + ~ImplDateInfo() { delete mpTextColor; delete mpFrameColor; } +}; + +DECLARE_TABLE( ImplDateTable, ImplDateInfo* ) + +// ======================================================================= + +static void ImplCalendarSelectDate( Table* pTable, const Date& rDate, sal_Bool bSelect ) +{ + if ( bSelect ) + pTable->Insert( rDate.GetDate(), TABLE_DATE_SELECTED ); + else + pTable->Remove( rDate.GetDate() ); +} + +// ----------------------------------------------------------------------- + +static void ImplCalendarSelectDateRange( Table* pTable, + const Date& rStartDate, + const Date& rEndDate, + sal_Bool bSelect ) +{ + Date aStartDate = rStartDate; + Date aEndDate = rEndDate; + if ( aStartDate > aEndDate ) + { + Date aTempDate = aStartDate; + aStartDate = aEndDate; + aEndDate = aTempDate; + } + + if ( bSelect ) + { + while ( aStartDate <= aEndDate ) + { + pTable->Insert( aStartDate.GetDate(), TABLE_DATE_SELECTED ); + aStartDate++; + } + } + else + { + void* p = pTable->First(); + while ( p ) + { + Date aDate( pTable->GetCurKey() ); + if ( aDate > aEndDate ) + break; + + if ( aDate >= aStartDate ) + pTable->Remove( aDate.GetDate() ); + else + p = pTable->Next(); + } + } +} + +// ----------------------------------------------------------------------- + +static void ImplCalendarUnSelectDateRange( Table* pTable, + Table* pOldTable, + const Date& rStartDate, + const Date& rEndDate ) +{ + Date aStartDate = rStartDate; + Date aEndDate = rEndDate; + if ( aStartDate > aEndDate ) + { + Date aTempDate = aStartDate; + aStartDate = aEndDate; + aEndDate = aTempDate; + } + + void* p = pTable->First(); + while ( p ) + { + Date aDate( pTable->GetCurKey() ); + if ( aDate > aEndDate ) + break; + + if ( aDate >= aStartDate ) + pTable->Remove( aDate.GetDate() ); + else + p = pTable->Next(); + } + + p = pOldTable->First(); + while ( p ) + { + Date aDate( pOldTable->GetCurKey() ); + if ( aDate > aEndDate ) + break; + if ( aDate >= aStartDate ) + pTable->Insert( aDate.GetDate(), TABLE_DATE_SELECTED ); + + p = pOldTable->Next(); + } +} + +// ----------------------------------------------------------------------- + +inline void ImplCalendarClearSelectDate( Table* pTable ) +{ + pTable->Clear(); +} + +// ======================================================================= + +void Calendar::ImplInit( WinBits nWinStyle ) +{ + mpDateTable = NULL; + mpSelectTable = new Table; + mpOldSelectTable = NULL; + mpRestoreSelectTable = NULL; + mpStandardColor = NULL; + mpSaturdayColor = NULL; + mpSundayColor = NULL; + mnDayCount = 0; + mnWinStyle = nWinStyle; + mnFirstYear = 0; + mnLastYear = 0; + mnRequestYear = 0; + mbCalc = sal_True; + mbFormat = sal_True; + mbDrag = sal_False; + mbSelection = sal_False; + mbMultiSelection = sal_False; + mbWeekSel = sal_False; + mbUnSel = sal_False; + mbMenuDown = sal_False; + mbSpinDown = sal_False; + mbPrevIn = sal_False; + mbNextIn = sal_False; + mbDirect = sal_False; + mbInSelChange = sal_False; + mbTravelSelect = sal_False; + mbScrollDateRange = sal_False; + mbSelLeft = sal_False; + mbAllSel = sal_False; + mbDropPos = sal_False; + + ::rtl::OUString aGregorian( RTL_CONSTASCII_USTRINGPARAM( "gregorian")); + maCalendarWrapper.loadCalendar( aGregorian, + Application::GetAppLocaleDataWrapper().getLocale()); + if (maCalendarWrapper.getUniqueID() != aGregorian) + { +#ifdef DBG_UTIL + ByteString aMsg( "Calendar::ImplInit: No ``gregorian'' calendar available for locale ``"); + lang::Locale aLoc( Application::GetAppLocaleDataWrapper().getLocale()); + aMsg += ByteString( String( aLoc.Language), RTL_TEXTENCODING_UTF8); + aMsg += '-'; + aMsg += ByteString( String( aLoc.Country), RTL_TEXTENCODING_UTF8); + aMsg += "'' and other calendars aren't supported. Using en-US fallback."; + DBG_ERRORFILE( aMsg.GetBuffer()); +#endif + /* If we ever wanted to support other calendars than Gregorian a lot of + * rewrite would be necessary to internally replace use of class Date + * with proper class CalendarWrapper methods, get rid of fixed 12 + * months, fixed 7 days, ... */ + maCalendarWrapper.loadCalendar( aGregorian, lang::Locale( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "en")), + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "US")), + ::rtl::OUString())); + } + + SetFirstDate( maCurDate ); + ImplCalendarSelectDate( mpSelectTable, maCurDate, sal_True ); + + // Sonstige Strings erzeugen + maDayText = XubString( SvtResId( STR_SVT_CALENDAR_DAY ) ); + maWeekText = XubString( SvtResId( STR_SVT_CALENDAR_WEEK ) ); + + // Tagestexte anlegen + for ( sal_uInt16 i = 0; i < 31; i++ ) + mpDayText[i] = new UniString( UniString::CreateFromInt32( i+1 ) ); + + maDragScrollTimer.SetTimeoutHdl( STATIC_LINK( this, Calendar, ScrollHdl ) ); + maDragScrollTimer.SetTimeout( GetSettings().GetMouseSettings().GetScrollRepeat() ); + mnDragScrollHitTest = 0; + + ImplInitSettings(); +} + +// ----------------------------------------------------------------------- + +void Calendar::ImplInitSettings() +{ + const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); + maSelColor = rStyleSettings.GetHighlightTextColor(); + SetPointFont( rStyleSettings.GetToolFont() ); + SetTextColor( rStyleSettings.GetFieldTextColor() ); + SetBackground( Wallpaper( rStyleSettings.GetFieldColor() ) ); +} + +// ----------------------------------------------------------------------- + +Calendar::Calendar( Window* pParent, WinBits nWinStyle ) : + Control( pParent, nWinStyle & (WB_TABSTOP | WB_GROUP | WB_BORDER | WB_3DLOOK | WB_RANGESELECT | WB_MULTISELECT) ), + maCalendarWrapper( Application::GetAppLocaleDataWrapper().getServiceFactory() ), + maOldFormatFirstDate( 0, 0, 1900 ), + maOldFormatLastDate( 0, 0, 1900 ), + maFirstDate( 0, 0, 1900 ), + maOldFirstDate( 0, 0, 1900 ), + maOldCurDate( 0, 0, 1900 ), + maAnchorDate( maCurDate ), + maDropDate( 0, 0, 1900 ) +{ + ImplInit( nWinStyle ); +} + +// ----------------------------------------------------------------------- + +Calendar::Calendar( Window* pParent, const ResId& rResId ) : + Control( pParent, rResId ), + maCalendarWrapper( Application::GetAppLocaleDataWrapper().getServiceFactory() ), + maOldFormatFirstDate( 0, 0, 1900 ), + maOldFormatLastDate( 0, 0, 1900 ), + maFirstDate( 0, 0, 1900 ), + maOldFirstDate( 0, 0, 1900 ), + maOldCurDate( 0, 0, 1900 ), + maAnchorDate( maCurDate ), + maDropDate( 0, 0, 1900 ) +{ + ImplInit( rResId.GetWinBits() ); +} + +// ----------------------------------------------------------------------- + +Calendar::~Calendar() +{ + delete mpStandardColor; + delete mpSaturdayColor; + delete mpSundayColor; + + if ( mpDateTable ) + { + ImplDateInfo* pDateInfo = mpDateTable->First(); + while ( pDateInfo ) + { + delete pDateInfo; + pDateInfo = mpDateTable->Next(); + } + + delete mpDateTable; + } + + delete mpSelectTable; + if ( mpOldSelectTable ) + delete mpOldSelectTable; + if ( mpRestoreSelectTable ) + delete mpRestoreSelectTable; + + for ( sal_uInt16 i = 0; i < 31; i++ ) + delete mpDayText[i]; +} + +// ----------------------------------------------------------------------- + +void Calendar::SetMinimumNumberOfDaysInWeek( sal_Int16 nDays ) +{ + ImplUpdate( sal_True ); + maCalendarWrapper.setMinimumNumberOfDaysForFirstWeek( nDays); +} + +// ----------------------------------------------------------------------- + +void Calendar::SetWeekStart( sal_Int16 nDay ) +{ + ImplUpdate( sal_True ); + switch (nDay) + { + case i18n::Weekdays::SUNDAY : + case i18n::Weekdays::MONDAY : + case i18n::Weekdays::TUESDAY : + case i18n::Weekdays::WEDNESDAY : + case i18n::Weekdays::THURSDAY : + case i18n::Weekdays::FRIDAY : + case i18n::Weekdays::SATURDAY : + ; // nothing + default: + DBG_ERRORFILE("Calendar::SetWeekStart: unknown value for setFirstDayOfWeek() of a Gregorian calendar"); + nDay = i18n::Weekdays::SUNDAY; + } + maCalendarWrapper.setFirstDayOfWeek( nDay); +} + +// ----------------------------------------------------------------------- + +DayOfWeek Calendar::ImplGetWeekStart() const +{ + // Map i18n::Weekdays to Date DayOfWeek + DayOfWeek eDay; + sal_Int16 nDay = maCalendarWrapper.getFirstDayOfWeek(); + switch (nDay) + { + case i18n::Weekdays::SUNDAY : + eDay = SUNDAY; + break; + case i18n::Weekdays::MONDAY : + eDay = MONDAY; + break; + case i18n::Weekdays::TUESDAY : + eDay = TUESDAY; + break; + case i18n::Weekdays::WEDNESDAY : + eDay = WEDNESDAY; + break; + case i18n::Weekdays::THURSDAY : + eDay = THURSDAY; + break; + case i18n::Weekdays::FRIDAY : + eDay = FRIDAY; + break; + case i18n::Weekdays::SATURDAY : + eDay = SATURDAY; + break; + default: + DBG_ERRORFILE("Calendar::ImplGetWeekStart: broken i18n Gregorian calendar (getFirstDayOfWeek())"); + eDay = SUNDAY; + } + return eDay; +} + +// ----------------------------------------------------------------------- + +void Calendar::ImplGetWeekFont( Font& rFont ) const +{ + // Wochennummer geben wir in WEEKNUMBER_HEIGHT%-Fonthoehe aus + Size aFontSize = rFont.GetSize(); + aFontSize.Height() *= WEEKNUMBER_HEIGHT; + aFontSize.Height() /= 100; + rFont.SetSize( aFontSize ); + rFont.SetWeight( WEIGHT_NORMAL ); +} + +// ----------------------------------------------------------------------- + +void Calendar::ImplFormat() +{ + if ( !mbFormat ) + return; + + if ( mbCalc ) + { + Size aOutSize = GetOutputSizePixel(); + + if ( (aOutSize.Width() <= 1) || (aOutSize.Height() <= 1) ) + return; + + XubString a99Text( XubString( RTL_CONSTASCII_USTRINGPARAM( "99" ) ) ); + + Font aOldFont = GetFont(); + + // Wochenanzeige beruecksichtigen + if ( mnWinStyle & WB_WEEKNUMBER ) + { + Font aTempFont = aOldFont; + ImplGetWeekFont( aTempFont ); + SetFont( aTempFont ); + mnWeekWidth = GetTextWidth( a99Text )+WEEKNUMBER_OFFX; + SetFont( aOldFont ); + } + else + mnWeekWidth = 0; + + if ( mnWinStyle & WB_BOLDTEXT ) + { + Font aFont = aOldFont; + if ( aFont.GetWeight() < WEIGHT_BOLD ) + aFont.SetWeight( WEIGHT_BOLD ); + else + aFont.SetWeight( WEIGHT_NORMAL ); + SetFont( aFont ); + } + + long n99TextWidth = GetTextWidth( a99Text ); + long nTextHeight = GetTextHeight(); + + // Breiten und X-Positionen berechnen + mnDayWidth = n99TextWidth+DAY_OFFX; + mnMonthWidth = mnDayWidth*7; + mnMonthWidth += mnWeekWidth; + mnMonthWidth += MONTH_BORDERX*2; + mnMonthPerLine = aOutSize.Width() / mnMonthWidth; + if ( !mnMonthPerLine ) + mnMonthPerLine = 1; + long nOver = ((aOutSize.Width()-(mnMonthPerLine*mnMonthWidth)) / mnMonthPerLine); + mnMonthWidth += nOver; + mnDaysOffX = MONTH_BORDERX; + mnDaysOffX += nOver/2; + mnDaysOffX += mnWeekWidth; + + // Hoehen und Y-Positionen berechnen + mnDayHeight = nTextHeight + DAY_OFFY; + mnWeekDayOffY = nTextHeight + TITLE_OFFY + (TITLE_BORDERY*2); + mnDaysOffY = mnWeekDayOffY + nTextHeight + WEEKDAY_OFFY; + mnMonthHeight = (mnDayHeight*6) + mnDaysOffY; + mnMonthHeight += MONTH_OFFY; + mnLines = aOutSize.Height() / mnMonthHeight; + if ( !mnLines ) + mnLines = 1; + mnMonthHeight += (aOutSize.Height()-(mnLines*mnMonthHeight)) / mnLines; + + // Spinfelder berechnen + long nSpinSize = nTextHeight+TITLE_BORDERY-SPIN_OFFY; + maPrevRect.Left() = SPIN_OFFX; + maPrevRect.Top() = SPIN_OFFY; + maPrevRect.Right() = maPrevRect.Left()+nSpinSize; + maPrevRect.Bottom() = maPrevRect.Top()+nSpinSize; + maNextRect.Left() = aOutSize.Width()-SPIN_OFFX-nSpinSize-1; + maNextRect.Top() = SPIN_OFFY; + maNextRect.Right() = maNextRect.Left()+nSpinSize; + maNextRect.Bottom() = maNextRect.Top()+nSpinSize; + + if ( mnWinStyle & WB_BOLDTEXT ) + SetFont( aOldFont ); + + // Calculate DayOfWeekText (gets displayed in a narrow font) + maDayOfWeekText.Erase(); + long nStartOffX = 0; + sal_Int16 nDay = maCalendarWrapper.getFirstDayOfWeek(); + for ( sal_Int16 nDayOfWeek = 0; nDayOfWeek < 7; nDayOfWeek++ ) + { + // Use first character of full name, since the abbreviated name may + // be roman digits or similar in some locales. Proper + // implementation would need narrow one letter month names defined + // in locale data. + String aDayOfWeek( maCalendarWrapper.getDisplayName( + i18n::CalendarDisplayIndex::DAY, nDay, 1).GetChar(0)); + long nOffX = (mnDayWidth-GetTextWidth( aDayOfWeek ))/2; + if ( mnWinStyle & WB_BOLDTEXT ) + nOffX++; + if ( !nDayOfWeek ) + nStartOffX = nOffX; + else + nOffX -= nStartOffX; + nOffX += nDayOfWeek * mnDayWidth; + mnDayOfWeekAry[nDayOfWeek] = nOffX; + maDayOfWeekText += aDayOfWeek; + nDay++; + nDay %= 7; + } + + mbCalc = sal_False; + } + + // Anzahl Tage berechnen + + DayOfWeek eStartDay = ImplGetWeekStart(); + + sal_uInt16 nWeekDay; + Date aTempDate = GetFirstMonth(); + maFirstDate = aTempDate; + nWeekDay = (sal_uInt16)aTempDate.GetDayOfWeek(); + nWeekDay = (nWeekDay+(7-(sal_uInt16)eStartDay)) % 7; + maFirstDate -= (sal_uLong)nWeekDay; + mnDayCount = nWeekDay; + sal_uInt16 nDaysInMonth; + sal_uInt16 nMonthCount = (sal_uInt16)(mnMonthPerLine*mnLines); + for ( sal_uInt16 i = 0; i < nMonthCount; i++ ) + { + nDaysInMonth = aTempDate.GetDaysInMonth(); + mnDayCount += nDaysInMonth; + aTempDate += nDaysInMonth; + } + Date aTempDate2 = aTempDate; + aTempDate2--; + nDaysInMonth = aTempDate2.GetDaysInMonth(); + aTempDate2 -= nDaysInMonth-1; + nWeekDay = (sal_uInt16)aTempDate2.GetDayOfWeek(); + nWeekDay = (nWeekDay+(7-(sal_uInt16)eStartDay)) % 7; + mnDayCount += 42-nDaysInMonth-nWeekDay; + + // Farben festlegen + maOtherColor = Color( COL_LIGHTGRAY ); + if ( maOtherColor.IsRGBEqual( GetBackground().GetColor() ) ) + maOtherColor.SetColor( COL_GRAY ); + + Date aLastDate = GetLastDate(); + if ( (maOldFormatLastDate != aLastDate) || + (maOldFormatFirstDate != maFirstDate) ) + { + maOldFormatFirstDate = maFirstDate; + maOldFormatLastDate = aLastDate; + DateRangeChanged(); + } + + // DateInfo besorgen + sal_uInt16 nNewFirstYear = maFirstDate.GetYear(); + sal_uInt16 nNewLastYear = GetLastDate().GetYear(); + if ( mnFirstYear ) + { + if ( nNewFirstYear < mnFirstYear ) + { + for ( mnRequestYear = nNewFirstYear; mnRequestYear < mnFirstYear; mnRequestYear++ ) + RequestDateInfo(); + mnFirstYear = nNewFirstYear; + } + if ( nNewLastYear > mnLastYear ) + { + for ( mnRequestYear = mnLastYear; mnRequestYear < nNewLastYear; mnRequestYear++ ) + RequestDateInfo(); + mnLastYear = nNewLastYear; + } + } + else + { + for ( mnRequestYear = nNewFirstYear; mnRequestYear < nNewLastYear; mnRequestYear++ ) + RequestDateInfo(); + mnFirstYear = nNewFirstYear; + mnLastYear = nNewLastYear; + } + mnRequestYear = 0; + + mbFormat = sal_False; +} + +// ----------------------------------------------------------------------- + +sal_uInt16 Calendar::ImplHitTest( const Point& rPos, Date& rDate ) const +{ + if ( mbFormat ) + return 0; + + if ( maPrevRect.IsInside( rPos ) ) + return CALENDAR_HITTEST_PREV; + else if ( maNextRect.IsInside( rPos ) ) + return CALENDAR_HITTEST_NEXT; + + long nX; + long nY; + long nOffX; + long nYMonth; + sal_uInt16 nDay; + DayOfWeek eStartDay = ImplGetWeekStart(); + + rDate = GetFirstMonth(); + nY = 0; + for ( long i = 0; i < mnLines; i++ ) + { + if ( rPos.Y() < nY ) + return 0; + + nX = 0; + nYMonth = nY+mnMonthHeight; + for ( long j = 0; j < mnMonthPerLine; j++ ) + { + if ( (rPos.X() < nX) && (rPos.Y() < nYMonth) ) + return 0; + + sal_uInt16 nDaysInMonth = rDate.GetDaysInMonth(); + + // Entsprechender Monat gefunden + if ( (rPos.X() > nX) && (rPos.Y() < nYMonth) && + (rPos.X() < nX+mnMonthWidth) ) + { + if ( rPos.Y() < (nY+(TITLE_BORDERY*2)+mnDayHeight)) + return CALENDAR_HITTEST_MONTHTITLE; + else + { + long nDayX = nX+mnDaysOffX; + long nDayY = nY+mnDaysOffY; + if ( rPos.Y() < nDayY ) + return 0; + sal_uInt16 nDayIndex = (sal_uInt16)rDate.GetDayOfWeek(); + nDayIndex = (nDayIndex+(7-(sal_uInt16)eStartDay)) % 7; + if ( (i == 0) && (j == 0) ) + { + Date aTempDate = rDate; + aTempDate -= nDayIndex; + for ( nDay = 0; nDay < nDayIndex; nDay++ ) + { + nOffX = nDayX + (nDay*mnDayWidth); + if ( (rPos.Y() >= nDayY) && (rPos.Y() < nDayY+mnDayHeight) && + (rPos.X() >= nOffX) && (rPos.X() < nOffX+mnDayWidth) ) + { + rDate = aTempDate; + rDate += nDay; + return CALENDAR_HITTEST_DAY; + } + } + } + for ( nDay = 1; nDay <= nDaysInMonth; nDay++ ) + { + if ( rPos.Y() < nDayY ) + { + rDate += nDayIndex; + return 0; + } + nOffX = nDayX + (nDayIndex*mnDayWidth); + if ( (rPos.Y() >= nDayY) && (rPos.Y() < nDayY+mnDayHeight) && + (rPos.X() >= nOffX) && (rPos.X() < nOffX+mnDayWidth) ) + { + rDate += nDay-1; + return CALENDAR_HITTEST_DAY; + } + if ( nDayIndex == 6 ) + { + nDayIndex = 0; + nDayY += mnDayHeight; + } + else + nDayIndex++; + } + if ( (i == mnLines-1) && (j == mnMonthPerLine-1) ) + { + sal_uInt16 nWeekDay = (sal_uInt16)rDate.GetDayOfWeek(); + nWeekDay = (nWeekDay+(7-(sal_uInt16)eStartDay)) % 7; + sal_uInt16 nDayCount = 42-nDaysInMonth-nWeekDay; + Date aTempDate = rDate; + aTempDate += nDaysInMonth; + for ( nDay = 1; nDay <= nDayCount; nDay++ ) + { + if ( rPos.Y() < nDayY ) + { + rDate += nDayIndex; + return 0; + } + nOffX = nDayX + (nDayIndex*mnDayWidth); + if ( (rPos.Y() >= nDayY) && (rPos.Y() < nDayY+mnDayHeight) && + (rPos.X() >= nOffX) && (rPos.X() < nOffX+mnDayWidth) ) + { + rDate = aTempDate; + rDate += nDay-1; + return CALENDAR_HITTEST_DAY; + } + if ( nDayIndex == 6 ) + { + nDayIndex = 0; + nDayY += mnDayHeight; + } + else + nDayIndex++; + } + } + } + } + + rDate += nDaysInMonth; + nX += mnMonthWidth; + } + + nY += mnMonthHeight; + } + + return 0; +} + +// ----------------------------------------------------------------------- + +static void ImplDrawSpinArrow( OutputDevice* pDev, const Rectangle& rRect, + sal_Bool bPrev ) +{ + long i; + long n; + long nLines; + long nHeight = rRect.GetHeight(); + long nWidth = rRect.GetWidth(); + if ( nWidth < nHeight ) + n = nWidth; + else + n = nHeight; + if ( !(n & 0x01) ) + n--; + nLines = n/2; + + Rectangle aRect( Point( rRect.Left()+(nWidth/2)-(nLines/2), + rRect.Top()+(nHeight/2) ), + Size( 1, 1 ) ); + if ( !bPrev ) + { + aRect.Left() += nLines; + aRect.Right() += nLines; + } + + pDev->DrawRect( aRect ); + for ( i = 0; i < nLines; i++ ) + { + if ( bPrev ) + { + aRect.Left()++; + aRect.Right()++; + } + else + { + aRect.Left()--; + aRect.Right()--; + } + aRect.Top()--; + aRect.Bottom()++; + pDev->DrawRect( aRect ); + } +} + +// ----------------------------------------------------------------------- + +void Calendar::ImplDrawSpin( sal_Bool bDrawPrev, sal_Bool bDrawNext ) +{ + if ( !bDrawPrev && !bDrawNext ) + return; + + SetLineColor(); + SetFillColor( GetSettings().GetStyleSettings().GetButtonTextColor() ); + if ( bDrawPrev ) + { + Rectangle aOutRect = maPrevRect; + aOutRect.Left() += 3; + aOutRect.Top() += 3; + aOutRect.Right() -= 3; + aOutRect.Bottom() -= 3; + ImplDrawSpinArrow( this, aOutRect, sal_True ); + } + if ( bDrawNext ) + { + Rectangle aOutRect = maNextRect; + aOutRect.Left() += 3; + aOutRect.Top() += 3; + aOutRect.Right() -= 3; + aOutRect.Bottom() -= 3; + ImplDrawSpinArrow( this, aOutRect, sal_False ); + } +} + +// ----------------------------------------------------------------------- + +void Calendar::ImplDrawDate( long nX, long nY, + sal_uInt16 nDay, sal_uInt16 nMonth, sal_uInt16 nYear, + DayOfWeek eDayOfWeek, + sal_Bool bBack, sal_Bool bOther, sal_uLong nToday ) +{ + ImplDateInfo* pDateInfo; + Color* pTextColor = NULL; + const String& rDay = *(mpDayText[nDay-1]); + Rectangle aDateRect( nX, nY, nX+mnDayWidth-1, nY+mnDayHeight-1 ); + + sal_Bool bSel = sal_False; + sal_Bool bFocus = sal_False; + // Aktueller Tag + if ( (nDay == maCurDate.GetDay()) && + (nMonth == maCurDate.GetMonth()) && + (nYear == maCurDate.GetYear()) ) + bFocus = sal_True; + if ( mpSelectTable ) + { + if ( mpSelectTable->IsKeyValid( Date( nDay, nMonth, nYear ).GetDate() ) ) + bSel = sal_True; + } + + // Dateinfo ermitteln + if ( mpDateTable ) + { + pDateInfo = mpDateTable->Get( Date( nDay, nMonth, nYear ).GetDate() ); + if ( !pDateInfo ) + pDateInfo = mpDateTable->Get( Date( nDay, nMonth, 0 ).GetDate() ); + } + else + pDateInfo = NULL; + + // Textfarbe ermitteln + if ( bSel ) + pTextColor = &maSelColor; + else if ( bOther ) + pTextColor = &maOtherColor; + else + { + if ( pDateInfo && pDateInfo->mpTextColor ) + pTextColor = pDateInfo->mpTextColor; + else + { + if ( eDayOfWeek == SATURDAY ) + pTextColor = mpSaturdayColor; + else if ( eDayOfWeek == SUNDAY ) + pTextColor = mpSundayColor; + if ( !pTextColor ) + pTextColor = mpStandardColor; + } + } + + if ( bFocus ) + HideFocus(); + + // Font ermitteln + Font aOldFont = GetFont(); + sal_Bool bBoldFont = sal_False; + if ( (mnWinStyle & WB_BOLDTEXT) && + pDateInfo && (pDateInfo->mnFlags & DIB_BOLD) ) + { + bBoldFont = sal_True; + Font aFont = aOldFont; + if ( aFont.GetWeight() < WEIGHT_BOLD ) + aFont.SetWeight( WEIGHT_BOLD ); + else + aFont.SetWeight( WEIGHT_NORMAL ); + SetFont( aFont ); + } + + // Hintergrund ausgeben + const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); + if ( bSel || bBack ) + { + if ( bSel ) + { + SetLineColor(); + SetFillColor( rStyleSettings.GetHighlightColor() ); + DrawRect( aDateRect ); + } + else + Erase( aDateRect ); + } + + // Text ausgeben + long nTextX = nX+(mnDayWidth-GetTextWidth( rDay ))-(DAY_OFFX/2); + long nTextY = nY+(mnDayHeight-GetTextHeight())/2; + if ( pTextColor ) + { + Color aOldColor = GetTextColor(); + SetTextColor( *pTextColor ); + DrawText( Point( nTextX, nTextY ), rDay ); + SetTextColor( aOldColor ); + } + else + DrawText( Point( nTextX, nTextY ), rDay ); + + // Heute + Date aTodayDate( maCurDate ); + if ( nToday ) + aTodayDate.SetDate( nToday ); + else + aTodayDate = Date(); + if ( (nDay == aTodayDate.GetDay()) && + (nMonth == aTodayDate.GetMonth()) && + (nYear == aTodayDate.GetYear()) ) + { + SetLineColor( rStyleSettings.GetWindowTextColor() ); + SetFillColor(); + DrawRect( aDateRect ); + } + + // Evt. DateInfo ausgeben + if ( (mnWinStyle & WB_FRAMEINFO) && pDateInfo && pDateInfo->mpFrameColor ) + { + SetLineColor( *(pDateInfo->mpFrameColor) ); + SetFillColor(); + Rectangle aFrameRect( aDateRect ); + aFrameRect.Left()++; + aFrameRect.Top()++; + long nFrameWidth = aFrameRect.GetWidth(); + long nFrameHeight = aFrameRect.GetHeight(); + long nFrameOff; + if ( nFrameWidth < nFrameHeight ) + { + nFrameOff = nFrameHeight-nFrameWidth; + aFrameRect.Top() += nFrameOff/2; + nFrameOff %= 2; + aFrameRect.Bottom() -= nFrameOff; + } + else if ( nFrameWidth > nFrameHeight ) + { + nFrameOff = nFrameWidth-nFrameHeight; + aFrameRect.Left() += nFrameOff/2; + nFrameOff %= 2; + aFrameRect.Right() -= nFrameOff; + } + DrawEllipse( aFrameRect ); + } + + // Evt. noch FocusRect + if ( bFocus && HasFocus() ) + ShowFocus( aDateRect ); + + if( mbDropPos && maDropDate == Date( nDay, nMonth, nYear ) ) + ImplInvertDropPos(); + + if ( bBoldFont ) + SetFont( aOldFont ); +} + +// ----------------------------------------------------------------------- + +void Calendar::ImplDraw( sal_Bool bPaint ) +{ + ImplFormat(); + + const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); + Size aOutSize = GetOutputSizePixel(); + long i; + long j; + long nX; + long nY; + long nDeltaX; + long nDeltaY; + long nDayX; + long nDayY; + sal_uLong nToday = Date().GetDate(); + sal_uInt16 nDay; + sal_uInt16 nMonth; + sal_uInt16 nYear; + Date aDate = GetFirstMonth(); + DayOfWeek eStartDay = ImplGetWeekStart(); + + HideFocus(); + + nY = 0; + for ( i = 0; i < mnLines; i++ ) + { + // Titleleiste ausgeben + SetLineColor(); + SetFillColor( rStyleSettings.GetFaceColor() ); + Rectangle aTitleRect( 0, nY, aOutSize.Width()-1, nY+mnDayHeight-DAY_OFFY+TITLE_BORDERY*2 ); + if ( !bPaint ) + { + Rectangle aTempRect( 1, aTitleRect.Top()+TITLE_BORDERY, + aOutSize.Width()-2, + aTitleRect.Bottom()-TITLE_BORDERY ); + if ( !i ) + { + aTempRect.Left() = maPrevRect.Right()+1; + aTempRect.Right() = maNextRect.Left()-1; + } + DrawRect( aTempRect ); + } + else + { + DrawRect( aTitleRect ); + Point aTopLeft1( aTitleRect.Left(), aTitleRect.Top() ); + Point aTopLeft2( aTitleRect.Left(), aTitleRect.Top()+1 ); + Point aBottomRight1( aTitleRect.Right(), aTitleRect.Bottom() ); + Point aBottomRight2( aTitleRect.Right(), aTitleRect.Bottom()-1 ); + SetLineColor( rStyleSettings.GetDarkShadowColor() ); + DrawLine( aTopLeft1, Point( aBottomRight1.X(), aTopLeft1.Y() ) ); + SetLineColor( rStyleSettings.GetLightColor() ); + DrawLine( aTopLeft2, Point( aBottomRight2.X(), aTopLeft2.Y() ) ); + DrawLine( aTopLeft2, Point( aTopLeft2.X(), aBottomRight2.Y() ) ); + SetLineColor( rStyleSettings.GetShadowColor() ); + DrawLine( Point( aTopLeft2.X(), aBottomRight2.Y() ), aBottomRight2 ); + DrawLine( Point( aBottomRight2.X(), aTopLeft2.Y() ), aBottomRight2 ); + SetLineColor( rStyleSettings.GetDarkShadowColor() ); + DrawLine( Point( aTopLeft1.X(), aBottomRight1.Y() ), aBottomRight1 ); + } + Point aSepPos1( 0, aTitleRect.Top()+TITLE_BORDERY ); + Point aSepPos2( 0, aTitleRect.Bottom()-TITLE_BORDERY ); + for ( j = 0; j < mnMonthPerLine-1; j++ ) + { + aSepPos1.X() += mnMonthWidth-1; + aSepPos2.X() = aSepPos1.X(); + SetLineColor( rStyleSettings.GetShadowColor() ); + DrawLine( aSepPos1, aSepPos2 ); + aSepPos1.X()++; + aSepPos2.X() = aSepPos1.X(); + SetLineColor( rStyleSettings.GetLightColor() ); + DrawLine( aSepPos1, aSepPos2 ); + } + + nX = 0; + for ( j = 0; j < mnMonthPerLine; j++ ) + { + nMonth = aDate.GetMonth(); + nYear = aDate.GetYear(); + + // Monat in der Titleleiste ausgeben + nDeltaX = nX; + nDeltaY = nY+TITLE_BORDERY; + String aMonthText( maCalendarWrapper.getDisplayName( + i18n::CalendarDisplayIndex::MONTH, nMonth-1, 1)); + aMonthText += ' '; + aMonthText += String::CreateFromInt64( nYear ); + long nMonthTextWidth = GetTextWidth( aMonthText ); + long nMonthOffX1 = 0; + long nMonthOffX2 = 0; + if ( i == 0 ) + { + if ( j == 0 ) + nMonthOffX1 = maPrevRect.Right()+1; + if ( j == mnMonthPerLine-1 ) + nMonthOffX2 = aOutSize.Width()-maNextRect.Left()+1; + } + long nMaxMonthWidth = mnMonthWidth-nMonthOffX1-nMonthOffX2-4; + if ( nMonthTextWidth > nMaxMonthWidth ) + { + // Abbreviated month name. + aMonthText = maCalendarWrapper.getDisplayName( + i18n::CalendarDisplayIndex::MONTH, nMonth-1, 0); + aMonthText += ' '; + aMonthText += String::CreateFromInt64( nYear ); + nMonthTextWidth = GetTextWidth( aMonthText ); + } + long nTempOff = (mnMonthWidth-nMonthTextWidth+1)/2; + if ( nTempOff < nMonthOffX1 ) + nDeltaX += nMonthOffX1+1; + else + { + if ( nTempOff+nMonthTextWidth > mnMonthWidth-nMonthOffX2 ) + nDeltaX += mnMonthWidth-nMonthOffX2-nMonthTextWidth; + else + nDeltaX += nTempOff; + } + SetTextColor( rStyleSettings.GetButtonTextColor() ); + DrawText( Point( nDeltaX, nDeltaY ), aMonthText ); + SetTextColor( rStyleSettings.GetWindowTextColor() ); + + // Weekleiste ausgeben + if ( bPaint ) + { + nDayX = nX+mnDaysOffX; + nDayY = nY+mnWeekDayOffY; + nDeltaY = nDayY + mnDayHeight; + SetLineColor( rStyleSettings.GetWindowTextColor() ); + Point aStartPos( nDayX, nDeltaY ); + if ( mnWinStyle & WB_WEEKNUMBER ) + aStartPos.X() -= WEEKNUMBER_OFFX-2; + DrawLine( aStartPos, Point( nDayX+(7*mnDayWidth), nDeltaY ) ); + DrawTextArray( Point( nDayX+mnDayOfWeekAry[0], nDayY ), maDayOfWeekText, &(mnDayOfWeekAry[1]) ); + } + + // Week-Numbers ausgeben + if ( mnWinStyle & WB_WEEKNUMBER ) + { + nDayX = nX+mnDaysOffX; + nDayY = nY+mnWeekDayOffY; + nDeltaY = nDayY + mnDayHeight; + long nMonthHeight = mnDayHeight*6; + if ( bPaint ) + DrawLine( Point( nDayX-WEEKNUMBER_OFFX+2, nDeltaY ), Point( nDayX-WEEKNUMBER_OFFX+2, nDeltaY+nMonthHeight ) ); + else + Erase( Rectangle( nDayX-mnWeekWidth-WEEKNUMBER_OFFX, nDeltaY, nDayX-WEEKNUMBER_OFFX-1, nDeltaY+nMonthHeight ) ); + + Font aOldFont = GetFont(); + Font aTempFont = aOldFont; + ImplGetWeekFont( aTempFont ); + SetFont( aTempFont ); + nDayX -= mnWeekWidth; + nDayY = nY+mnDaysOffY; + maCalendarWrapper.setGregorianDateTime( aDate); + for ( sal_uInt16 nWeekCount = 0; nWeekCount < 6; nWeekCount++ ) + { + sal_Int16 nWeek = maCalendarWrapper.getValue( i18n::CalendarFieldIndex::WEEK_OF_YEAR); + String aWeekText( String::CreateFromInt32( nWeek)); + long nOffX = (mnWeekWidth-WEEKNUMBER_OFFX)-GetTextWidth( aWeekText ); + long nOffY = (mnDayHeight-GetTextHeight())/2; + DrawText( Point( nDayX+nOffX, nDayY+nOffY ), aWeekText ); + nDayY += mnDayHeight; + maCalendarWrapper.addValue( i18n::CalendarFieldIndex::DAY_OF_MONTH, 7); + } + SetFont( aOldFont ); + } + + // Tage ausgeben + sal_uInt16 nDaysInMonth = aDate.GetDaysInMonth(); + nDayX = nX+mnDaysOffX; + nDayY = nY+mnDaysOffY; + if ( !bPaint ) + { + Rectangle aClearRect( nDayX, nDayY, + nDayX+(7*mnDayWidth)-1, nDayY+(6*mnDayHeight)-1 ); + Erase( aClearRect ); + } + sal_uInt16 nDayIndex = (sal_uInt16)aDate.GetDayOfWeek(); + nDayIndex = (nDayIndex+(7-(sal_uInt16)eStartDay)) % 7; + if ( (i == 0) && (j == 0) ) + { + Date aTempDate = aDate; + aTempDate -= nDayIndex; + for ( nDay = 0; nDay < nDayIndex; nDay++ ) + { + nDeltaX = nDayX + (nDay*mnDayWidth); + ImplDrawDate( nDeltaX, nDayY, nDay+aTempDate.GetDay(), + aTempDate.GetMonth(), aTempDate.GetYear(), + (DayOfWeek)((nDay+(sal_uInt16)eStartDay)%7), sal_False, sal_True, nToday ); + } + } + for ( nDay = 1; nDay <= nDaysInMonth; nDay++ ) + { + nDeltaX = nDayX + (nDayIndex*mnDayWidth); + ImplDrawDate( nDeltaX, nDayY, nDay, nMonth, nYear, + (DayOfWeek)((nDayIndex+(sal_uInt16)eStartDay)%7), + sal_False, sal_False, nToday ); + if ( nDayIndex == 6 ) + { + nDayIndex = 0; + nDayY += mnDayHeight; + } + else + nDayIndex++; + } + if ( (i == mnLines-1) && (j == mnMonthPerLine-1) ) + { + sal_uInt16 nWeekDay = (sal_uInt16)aDate.GetDayOfWeek(); + nWeekDay = (nWeekDay+(7-(sal_uInt16)eStartDay)) % 7; + sal_uInt16 nDayCount = 42-nDaysInMonth-nWeekDay; + Date aTempDate = aDate; + aTempDate += nDaysInMonth; + for ( nDay = 1; nDay <= nDayCount; nDay++ ) + { + nDeltaX = nDayX + (nDayIndex*mnDayWidth); + ImplDrawDate( nDeltaX, nDayY, nDay, + aTempDate.GetMonth(), aTempDate.GetYear(), + (DayOfWeek)((nDayIndex+(sal_uInt16)eStartDay)%7), + sal_False, sal_True, nToday ); + if ( nDayIndex == 6 ) + { + nDayIndex = 0; + nDayY += mnDayHeight; + } + else + nDayIndex++; + } + } + + aDate += nDaysInMonth; + nX += mnMonthWidth; + } + + nY += mnMonthHeight; + } + + // Spin-Buttons zeichnen + if ( bPaint ) + ImplDrawSpin(); +} + +// ----------------------------------------------------------------------- + +void Calendar::ImplUpdateDate( const Date& rDate ) +{ + if ( IsReallyVisible() && IsUpdateMode() ) + { + Rectangle aDateRect( GetDateRect( rDate ) ); + if ( !aDateRect.IsEmpty() ) + { + sal_Bool bOther = (rDate < GetFirstMonth()) || (rDate > GetLastMonth()); + ImplDrawDate( aDateRect.Left(), aDateRect.Top(), + rDate.GetDay(), rDate.GetMonth(), rDate.GetYear(), + rDate.GetDayOfWeek(), sal_True, bOther ); + } + } +} + +// ----------------------------------------------------------------------- + +void Calendar::ImplUpdateSelection( Table* pOld ) +{ + Table* pNew = mpSelectTable; + void* p; + sal_uLong nKey; + + p = pOld->First(); + while ( p ) + { + nKey = pOld->GetCurKey(); + if ( !pNew->Get( nKey ) ) + { + Date aTempDate( nKey ); + ImplUpdateDate( aTempDate ); + } + + p = pOld->Next(); + } + + p = pNew->First(); + while ( p ) + { + nKey = pNew->GetCurKey(); + if ( !pOld->Get( nKey ) ) + { + Date aTempDate( nKey ); + ImplUpdateDate( aTempDate ); + } + + p = pNew->Next(); + } +} + +// ----------------------------------------------------------------------- + +void Calendar::ImplMouseSelect( const Date& rDate, sal_uInt16 nHitTest, + sal_Bool bMove, sal_Bool bExpand, sal_Bool bExtended ) +{ + Table* pOldSel = new Table( *mpSelectTable ); + Date aOldDate = maCurDate; + Date aTempDate = rDate; + + if ( !(nHitTest & CALENDAR_HITTEST_DAY) ) + aTempDate--; + + if ( mbMultiSelection ) + { + maCurDate = aTempDate; + mbSelLeft = aTempDate < maAnchorDate; + + if ( bMove ) + { + if ( mbSelLeft ) + { + ImplCalendarUnSelectDateRange( mpSelectTable, mpRestoreSelectTable, Date( 1, 1, 0 ), aTempDate ); + ImplCalendarUnSelectDateRange( mpSelectTable, mpRestoreSelectTable, maAnchorDate, Date( 31, 12, 9999 ) ); + } + else + { + ImplCalendarUnSelectDateRange( mpSelectTable, mpRestoreSelectTable, Date( 1, 1, 0 ), maAnchorDate ); + ImplCalendarUnSelectDateRange( mpSelectTable, mpRestoreSelectTable, aTempDate, Date( 31, 12, 9999 ) ); + } + ImplCalendarSelectDateRange( mpSelectTable, aTempDate, maAnchorDate, !mbUnSel ); + } + else + { + if ( bExpand ) + { + if ( !bExtended ) + { + if ( mbSelLeft ) + { + ImplCalendarSelectDateRange( mpSelectTable, Date( 1, 1, 0 ), aTempDate, sal_False ); + ImplCalendarSelectDateRange( mpSelectTable, maAnchorDate, Date( 31, 12, 9999 ), sal_False ); + } + else + { + ImplCalendarSelectDateRange( mpSelectTable, Date( 1, 1, 0 ), maAnchorDate, sal_False ); + ImplCalendarSelectDateRange( mpSelectTable, aTempDate, Date( 31, 12, 9999 ), sal_False ); + } + } + ImplCalendarSelectDateRange( mpSelectTable, aTempDate, maAnchorDate, sal_True ); + } + else if ( bExtended && !(mnWinStyle & WB_RANGESELECT) ) + { + maAnchorDate = aTempDate; + if ( IsDateSelected( aTempDate ) ) + { + mbUnSel = sal_True; + ImplCalendarSelectDate( mpSelectTable, aTempDate, sal_False ); + } + else + { + ImplCalendarSelectDate( mpSelectTable, aTempDate, sal_True ); + } + } + else + { + maAnchorDate = aTempDate; + ImplCalendarClearSelectDate( mpSelectTable ); + ImplCalendarSelectDate( mpSelectTable, aTempDate, sal_True ); + } + + mpRestoreSelectTable = new Table( *mpSelectTable ); + } + } + else + { + if ( aTempDate < maCurDate ) + mbSelLeft = sal_True; + else + mbSelLeft = sal_False; + if ( !(nHitTest & CALENDAR_HITTEST_DAY) ) + aTempDate = maOldCurDate; + if ( !bMove ) + maAnchorDate = aTempDate; + if ( aTempDate != maCurDate ) + { + maCurDate = aTempDate; + ImplCalendarSelectDate( mpSelectTable, aOldDate, sal_False ); + ImplCalendarSelectDate( mpSelectTable, maCurDate, sal_True ); + } + } + + sal_Bool bNewSel = *pOldSel != *mpSelectTable; + if ( (maCurDate != aOldDate) || bNewSel ) + { + if ( bNewSel ) + { + mbInSelChange = sal_True; + SelectionChanging(); + mbInSelChange = sal_False; + } + HideFocus(); + if ( bNewSel ) + ImplUpdateSelection( pOldSel ); + if ( !bNewSel || !pOldSel->Get( aOldDate.GetDate() ) ) + ImplUpdateDate( aOldDate ); + // Damit Focus-Rechteck auch wieder neu ausgegeben wird + if ( HasFocus() || !bNewSel || !mpSelectTable->Get( maCurDate.GetDate() ) ) + ImplUpdateDate( maCurDate ); + } + delete pOldSel; +} + +// ----------------------------------------------------------------------- + +void Calendar::ImplUpdate( sal_Bool bCalcNew ) +{ + if ( IsReallyVisible() && IsUpdateMode() ) + { + if ( bCalcNew && !mbCalc ) + Invalidate(); + else if ( !mbFormat && !mbCalc ) + { + if ( mbDirect ) + { + mbFormat = sal_True; + ImplDraw( sal_False ); + return; + } + else + Invalidate(); + } + } + + if ( bCalcNew ) + mbCalc = sal_True; + mbFormat = sal_True; +} + +// ----------------------------------------------------------------------- + +void Calendar::ImplInvertDropPos() +{ + Rectangle aRect = GetDateRect( maDropDate );//this is one Pixel to width and one to heigh + aRect.Bottom() = aRect.Top()+mnDayHeight-1; + aRect.Right() = aRect.Left()+mnDayWidth-1; + Invert( aRect ); +} + +// ----------------------------------------------------------------------- + +void Calendar::ImplScroll( sal_Bool bPrev ) +{ + Date aNewFirstMonth = GetFirstMonth(); + if ( bPrev ) + { + aNewFirstMonth--; + aNewFirstMonth -= aNewFirstMonth.GetDaysInMonth()-1; + } + else + aNewFirstMonth += aNewFirstMonth.GetDaysInMonth(); + mbDirect = sal_True; + SetFirstDate( aNewFirstMonth ); + mbDirect = sal_False; +} + +// ----------------------------------------------------------------------- + +void Calendar::ImplShowMenu( const Point& rPos, const Date& rDate ) +{ + EndSelection(); + + Date aOldFirstDate = GetFirstMonth(); + PopupMenu aPopupMenu; + PopupMenu* pYearPopupMenus[MENU_YEAR_COUNT]; + sal_uInt16 nMonthOff; + sal_uInt16 nCurItemId; + sal_uInt16 nYear = rDate.GetYear()-1; + sal_uInt16 i; + sal_uInt16 j; + sal_uInt16 nYearIdCount = 1000; + + nMonthOff = (rDate.GetYear()-aOldFirstDate.GetYear())*12; + if ( aOldFirstDate.GetMonth() < rDate.GetMonth() ) + nMonthOff += rDate.GetMonth()-aOldFirstDate.GetMonth(); + else + nMonthOff -= aOldFirstDate.GetMonth()-rDate.GetMonth(); + + // Menu aufbauen (Jahre mit verschiedenen Monaten aufnehmen) + for ( i = 0; i < MENU_YEAR_COUNT; i++ ) + { + pYearPopupMenus[i] = new PopupMenu; + for ( j = 1; j <= 12; j++ ) + pYearPopupMenus[i]->InsertItem( nYearIdCount+j, + maCalendarWrapper.getDisplayName( + i18n::CalendarDisplayIndex::MONTH, j-1, 1)); + aPopupMenu.InsertItem( 10+i, UniString::CreateFromInt32( nYear+i ) ); + aPopupMenu.SetPopupMenu( 10+i, pYearPopupMenus[i] ); + nYearIdCount += 1000; + } + + mbMenuDown = sal_True; + nCurItemId = aPopupMenu.Execute( this, rPos ); + mbMenuDown = sal_False; + + // Menu zerstoeren + aPopupMenu.SetPopupMenu( 2, NULL ); + for ( i = 0; i < MENU_YEAR_COUNT; i++ ) + { + aPopupMenu.SetPopupMenu( 10+i, NULL ); + delete pYearPopupMenus[i]; + } + + if ( nCurItemId ) + { + sal_uInt16 nTempMonthOff = nMonthOff % 12; + sal_uInt16 nTempYearOff = nMonthOff / 12; + sal_uInt16 nNewMonth = nCurItemId % 1000; + sal_uInt16 nNewYear = nYear+((nCurItemId-1000)/1000); + if ( nTempMonthOff < nNewMonth ) + nNewMonth = nNewMonth - nTempMonthOff; + else + { + nNewYear--; + nNewMonth = 12-(nTempMonthOff-nNewMonth); + } + nNewYear = nNewYear - nTempYearOff; + SetFirstDate( Date( 1, nNewMonth, nNewYear ) ); + } +} + +// ----------------------------------------------------------------------- + +void Calendar::ImplTracking( const Point& rPos, sal_Bool bRepeat ) +{ + Date aTempDate = maCurDate; + sal_uInt16 nHitTest = ImplHitTest( rPos, aTempDate ); + + if ( mbSpinDown ) + { + mbPrevIn = (nHitTest & CALENDAR_HITTEST_PREV) != 0; + mbNextIn = (nHitTest & CALENDAR_HITTEST_NEXT) != 0; + + if ( bRepeat && (mbPrevIn || mbNextIn) ) + { + mbScrollDateRange = sal_True; + ImplScroll( mbPrevIn ); + mbScrollDateRange = sal_False; + } + } + else + ImplMouseSelect( aTempDate, nHitTest, sal_True, sal_False, sal_False ); +} + +// ----------------------------------------------------------------------- + +void Calendar::ImplEndTracking( sal_Bool bCancel ) +{ + sal_Bool bSelection = mbSelection; + sal_Bool bSpinDown = mbSpinDown; + + mbDrag = sal_False; + mbSelection = sal_False; + mbMultiSelection = sal_False; + mbUnSel = sal_False; + mbSpinDown = sal_False; + mbPrevIn = sal_False; + mbNextIn = sal_False; + + if ( bCancel ) + { + if ( maOldFirstDate != maFirstDate ) + SetFirstDate( maOldFirstDate ); + + if ( !bSpinDown ) + { + Table* pOldSel = new Table( *mpSelectTable ); + Date aOldDate = maCurDate; + maCurDate = maOldCurDate; + *mpSelectTable = *mpOldSelectTable; + HideFocus(); + ImplUpdateSelection( pOldSel ); + if ( !pOldSel->Get( aOldDate.GetDate() ) ) + ImplUpdateDate( aOldDate ); + // Damit Focus-Rechteck auch wieder neu ausgegeben wird + if ( HasFocus() || !mpSelectTable->Get( maCurDate.GetDate() ) ) + ImplUpdateDate( maCurDate ); + delete pOldSel; + } + } + + if ( !bSpinDown ) + { + if ( !bCancel ) + { + // Feststellen, ob wir sichtbaren Bereich scrollen sollen + sal_uLong nSelCount = mpSelectTable->Count(); + if ( nSelCount ) + { + Date aFirstSelDate( mpSelectTable->GetObjectKey( 0 ) ); + Date aLastSelDate( mpSelectTable->GetObjectKey( nSelCount-1 ) ); + if ( aLastSelDate < GetFirstMonth() ) + ImplScroll( sal_True ); + else if ( GetLastMonth() < aFirstSelDate ) + ImplScroll( sal_False ); + } + } + + if ( mbAllSel || + (!bCancel && ((maCurDate != maOldCurDate) || (*mpOldSelectTable != *mpSelectTable))) ) + Select(); + + if ( !bSelection && (mnWinStyle & WB_TABSTOP) && !bCancel ) + GrabFocus(); + + delete mpOldSelectTable; + mpOldSelectTable = NULL; + delete mpRestoreSelectTable; + mpRestoreSelectTable = NULL; + } +} + +// ----------------------------------------------------------------------- + +IMPL_STATIC_LINK( Calendar, ScrollHdl, Timer*, EMPTYARG ) +{ + sal_Bool bPrevIn = (pThis->mnDragScrollHitTest & CALENDAR_HITTEST_PREV) != 0; + sal_Bool bNextIn = (pThis->mnDragScrollHitTest & CALENDAR_HITTEST_NEXT) != 0; + if( bNextIn || bPrevIn ) + { + pThis->mbScrollDateRange = sal_True; + pThis->ImplScroll( bPrevIn ); + pThis->mbScrollDateRange = sal_False; + } + return 0; +} + +// ----------------------------------------------------------------------- + +void Calendar::MouseButtonDown( const MouseEvent& rMEvt ) +{ + if ( rMEvt.IsLeft() && !mbMenuDown ) + { + Date aTempDate = maCurDate; + sal_uInt16 nHitTest = ImplHitTest( rMEvt.GetPosPixel(), aTempDate ); + if ( nHitTest ) + { + if ( nHitTest & CALENDAR_HITTEST_MONTHTITLE ) + ImplShowMenu( rMEvt.GetPosPixel(), aTempDate ); + else + { + maOldFirstDate = maFirstDate; + + mbPrevIn = (nHitTest & CALENDAR_HITTEST_PREV) != 0; + mbNextIn = (nHitTest & CALENDAR_HITTEST_NEXT) != 0; + if ( mbPrevIn || mbNextIn ) + { + mbSpinDown = sal_True; + mbScrollDateRange = sal_True; + ImplScroll( mbPrevIn ); + mbScrollDateRange = sal_False; + // Hier muss BUTTONREPEAT stehen, also nicht wieder + // auf SCROLLREPEAT aendern, sondern mit TH abklaeren, + // warum es evtl. anders sein sollte (71775) + StartTracking( STARTTRACK_BUTTONREPEAT ); + } + else + { + if ( (rMEvt.GetClicks() == 2) && (nHitTest & CALENDAR_HITTEST_DAY) ) + DoubleClick(); + else + { + if ( mpOldSelectTable ) + delete mpOldSelectTable; + maOldCurDate = maCurDate; + mpOldSelectTable = new Table( *mpSelectTable ); + + if ( !mbSelection ) + { + mbDrag = sal_True; + StartTracking(); + } + + mbMultiSelection = (mnWinStyle & (WB_MULTISELECT | WB_RANGESELECT)) != 0; + if ( (nHitTest & CALENDAR_HITTEST_DAY) && mbMultiSelection ) + mbWeekSel = sal_True; + else + mbWeekSel = sal_False; + ImplMouseSelect( aTempDate, nHitTest, sal_False, rMEvt.IsShift(), rMEvt.IsMod1() ); + } + } + } + } + + return; + } + + Control::MouseButtonDown( rMEvt ); +} + +// ----------------------------------------------------------------------- + +void Calendar::MouseButtonUp( const MouseEvent& rMEvt ) +{ + if ( rMEvt.IsLeft() && mbSelection ) + ImplEndTracking( sal_False ); + else + Control::MouseButtonUp( rMEvt ); +} + +// ----------------------------------------------------------------------- + +void Calendar::MouseMove( const MouseEvent& rMEvt ) +{ + if ( mbSelection && rMEvt.GetButtons() ) + ImplTracking( rMEvt.GetPosPixel(), sal_False ); + else + Control::MouseMove( rMEvt ); +} + +// ----------------------------------------------------------------------- + +void Calendar::Tracking( const TrackingEvent& rTEvt ) +{ + Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel(); + + if ( rTEvt.IsTrackingEnded() ) + ImplEndTracking( rTEvt.IsTrackingCanceled() ); + else + ImplTracking( aMousePos, rTEvt.IsTrackingRepeat() ); +} + +// ----------------------------------------------------------------------- + +void Calendar::KeyInput( const KeyEvent& rKEvt ) +{ + Date aNewDate = maCurDate; + sal_Bool bMultiSel = (mnWinStyle & (WB_RANGESELECT | WB_MULTISELECT)) != 0; + sal_Bool bExpand = rKEvt.GetKeyCode().IsShift(); + sal_Bool bExtended = rKEvt.GetKeyCode().IsMod1(); + + switch ( rKEvt.GetKeyCode().GetCode() ) + { + case KEY_HOME: + aNewDate.SetDay( 1 ); + break; + + case KEY_END: + aNewDate.SetDay( aNewDate.GetDaysInMonth() ); + break; + + case KEY_LEFT: + aNewDate--; + break; + + case KEY_RIGHT: + aNewDate++; + break; + + case KEY_UP: + aNewDate -= 7; + break; + + case KEY_DOWN: + aNewDate += 7; + break; + + case KEY_PAGEUP: + { + Date aTempDate = aNewDate; + aTempDate -= aNewDate.GetDay()+1; + aNewDate -= aTempDate.GetDaysInMonth(); + } + break; + + case KEY_PAGEDOWN: + aNewDate += aNewDate.GetDaysInMonth(); + break; + + case KEY_SPACE: + if ( bMultiSel && !(mnWinStyle & WB_RANGESELECT) ) + { + if ( !bExpand ) + { + sal_Bool bDateSel = IsDateSelected( maCurDate ); + SelectDate( maCurDate, !bDateSel ); + mbSelLeft = sal_False; + SelectionChanging(); + mbTravelSelect = sal_True; + Select(); + mbTravelSelect = sal_False; + } + } + else + Control::KeyInput( rKEvt ); + break; + + default: + Control::KeyInput( rKEvt ); + break; + } + + if ( aNewDate != maCurDate ) + { + if ( bMultiSel && bExpand ) + { + Table* pOldSel = new Table( *mpSelectTable ); + Date aOldAnchorDate = maAnchorDate; + mbSelLeft = aNewDate < maAnchorDate; + if ( !bExtended ) + { + if ( mbSelLeft ) + { + ImplCalendarSelectDateRange( mpSelectTable, Date( 1, 1, 0 ), aNewDate, sal_False ); + ImplCalendarSelectDateRange( mpSelectTable, maAnchorDate, Date( 31, 12, 9999 ), sal_False ); + } + else + { + ImplCalendarSelectDateRange( mpSelectTable, Date( 1, 1, 0 ), maAnchorDate, sal_False ); + ImplCalendarSelectDateRange( mpSelectTable, aNewDate, Date( 31, 12, 9999 ), sal_False ); + } + } + ImplCalendarSelectDateRange( mpSelectTable, aNewDate, maAnchorDate, sal_True ); + mbDirect = sal_True; + SetCurDate( aNewDate ); + mbDirect = sal_False; + maAnchorDate = aOldAnchorDate; + mbInSelChange = sal_True; + SelectionChanging(); + mbInSelChange = sal_False; + ImplUpdateSelection( pOldSel ); + delete pOldSel; + } + else + { + if ( mnWinStyle & WB_RANGESELECT ) + { + SetNoSelection(); + SelectDate( aNewDate, sal_True ); + } + mbDirect = sal_True; + SetCurDate( aNewDate ); + mbDirect = sal_False; + } + mbTravelSelect = sal_True; + Select(); + mbTravelSelect = sal_False; + } +} + +// ----------------------------------------------------------------------- + +void Calendar::Paint( const Rectangle& ) +{ + ImplDraw( sal_True ); +} + +// ----------------------------------------------------------------------- + +void Calendar::GetFocus() +{ + ImplUpdateDate( maCurDate ); + Control::GetFocus(); +} + +// ----------------------------------------------------------------------- + +void Calendar::LoseFocus() +{ + HideFocus(); + Control::LoseFocus(); +} + +// ----------------------------------------------------------------------- + +void Calendar::Resize() +{ + ImplUpdate( sal_True ); + Control::Resize(); +} + +// ----------------------------------------------------------------------- + +void Calendar::RequestHelp( const HelpEvent& rHEvt ) +{ + if ( rHEvt.GetMode() & (HELPMODE_QUICK | HELPMODE_BALLOON) ) + { + Date aDate = maCurDate; + if ( GetDate( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ), aDate ) ) + { + Rectangle aDateRect = GetDateRect( aDate ); + Point aPt = OutputToScreenPixel( aDateRect.TopLeft() ); + aDateRect.Left() = aPt.X(); + aDateRect.Top() = aPt.Y(); + aPt = OutputToScreenPixel( aDateRect.BottomRight() ); + aDateRect.Right() = aPt.X(); + aDateRect.Bottom() = aPt.Y(); + + if ( (rHEvt.GetMode() & HELPMODE_BALLOON) || (mnWinStyle & WB_QUICKHELPSHOWSDATEINFO) ) + { + ImplDateInfo* pInfo; + if ( mpDateTable ) + { + pInfo = mpDateTable->Get( aDate.GetDate() ); + if ( !pInfo ) + pInfo = mpDateTable->Get( Date( aDate.GetDay(), aDate.GetMonth(), 0 ).GetDate() ); + } + else + pInfo = NULL; + if ( pInfo ) + { + XubString aStr = pInfo->maText; + if ( aStr.Len() ) + { + Help::ShowBalloon( this, rHEvt.GetMousePosPixel(), aDateRect, aStr ); + return; + } + } + } + + if ( rHEvt.GetMode() & HELPMODE_QUICK ) + { + maCalendarWrapper.setGregorianDateTime( aDate); + sal_uInt16 nWeek = (sal_uInt16) maCalendarWrapper.getValue( i18n::CalendarFieldIndex::WEEK_OF_YEAR); + sal_uInt16 nMonth = aDate.GetMonth(); + XubString aStr( maDayText ); + aStr.AppendAscii( ": " ); + aStr.Append( XubString::CreateFromInt32( aDate.GetDayOfYear() ) ); + aStr.AppendAscii( " / " ); + aStr.Append( maWeekText ); + aStr.AppendAscii( ": " ); + aStr.Append( XubString::CreateFromInt32( nWeek ) ); + // Evt. noch Jahr hinzufuegen, wenn es nicht das gleiche ist + if ( (nMonth == 12) && (nWeek == 1) ) + { + aStr.AppendAscii( ", " ); + aStr.Append( XubString::CreateFromInt32( aDate.GetYear()+1 ) ); + } + else if ( (nMonth == 1) && (nWeek > 50) ) + { + aStr.AppendAscii( ", " ); + aStr.Append( XubString::CreateFromInt32( aDate.GetYear()-1 ) ); + } + Help::ShowQuickHelp( this, aDateRect, aStr ); + return; + } + } + } + + Control::RequestHelp( rHEvt ); +} + +// ----------------------------------------------------------------------- + +void Calendar::Command( const CommandEvent& rCEvt ) +{ + if ( rCEvt.GetCommand() == COMMAND_CONTEXTMENU ) + { + if ( !mbSelection && rCEvt.IsMouseEvent() ) + { + Date aTempDate = maCurDate; + sal_uInt16 nHitTest = ImplHitTest( rCEvt.GetMousePosPixel(), aTempDate ); + if ( nHitTest & CALENDAR_HITTEST_MONTHTITLE ) + { + ImplShowMenu( rCEvt.GetMousePosPixel(), aTempDate ); + return; + } + } + } + else if ( rCEvt.GetCommand() == COMMAND_WHEEL ) + { + const CommandWheelData* pData = rCEvt.GetWheelData(); + if ( pData->GetMode() == COMMAND_WHEEL_SCROLL ) + { + long nNotchDelta = pData->GetNotchDelta(); + if ( nNotchDelta < 0 ) + { + while ( nNotchDelta < 0 ) + { + ImplScroll( sal_True ); + nNotchDelta++; + } + } + else + { + while ( nNotchDelta > 0 ) + { + ImplScroll( sal_False ); + nNotchDelta--; + } + } + + return; + } + } + + Control::Command( rCEvt ); +} + +// ----------------------------------------------------------------------- + +void Calendar::StateChanged( StateChangedType nType ) +{ + Control::StateChanged( nType ); + + if ( nType == STATE_CHANGE_INITSHOW ) + ImplFormat(); +} + +// ----------------------------------------------------------------------- + +void Calendar::DataChanged( const DataChangedEvent& rDCEvt ) +{ + Control::DataChanged( rDCEvt ); + + if ( (rDCEvt.GetType() == DATACHANGED_FONTS) || + (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) || + ((rDCEvt.GetType() == DATACHANGED_SETTINGS) && + (rDCEvt.GetFlags() & SETTINGS_STYLE)) ) + { + ImplInitSettings(); + Invalidate(); + } +} + +// ----------------------------------------------------------------------- + +void Calendar::SelectionChanging() +{ + maSelectionChangingHdl.Call( this ); +} + +// ----------------------------------------------------------------------- + +void Calendar::DateRangeChanged() +{ + maDateRangeChangedHdl.Call( this ); +} + +// ----------------------------------------------------------------------- + +void Calendar::RequestDateInfo() +{ + maRequestDateInfoHdl.Call( this ); +} + +// ----------------------------------------------------------------------- + +void Calendar::DoubleClick() +{ + maDoubleClickHdl.Call( this ); +} + +// ----------------------------------------------------------------------- + +void Calendar::Select() +{ + maSelectHdl.Call( this ); +} + +// ----------------------------------------------------------------------- + +void Calendar::SelectDate( const Date& rDate, sal_Bool bSelect ) +{ + if ( !rDate.IsValid() ) + return; + + Table* pOldSel; + + if ( !mbInSelChange ) + pOldSel = new Table( *mpSelectTable ); + else + pOldSel = NULL; + + ImplCalendarSelectDate( mpSelectTable, rDate, bSelect ); + + if ( pOldSel ) + { + ImplUpdateSelection( pOldSel ); + delete pOldSel; + } +} + +// ----------------------------------------------------------------------- + +void Calendar::SelectDateRange( const Date& rStartDate, const Date& rEndDate, + sal_Bool bSelect ) +{ + if ( !rStartDate.IsValid() || !rEndDate.IsValid() ) + return; + + Table* pOldSel; + + if ( !mbInSelChange ) + pOldSel = new Table( *mpSelectTable ); + else + pOldSel = NULL; + + ImplCalendarSelectDateRange( mpSelectTable, rStartDate, rEndDate, bSelect ); + + if ( pOldSel ) + { + ImplUpdateSelection( pOldSel ); + delete pOldSel; + } +} + +// ----------------------------------------------------------------------- + +void Calendar::SetNoSelection() +{ + Table* pOldSel; + + if ( !mbInSelChange ) + pOldSel = new Table( *mpSelectTable ); + else + pOldSel = NULL; + + ImplCalendarClearSelectDate( mpSelectTable ); + + if ( pOldSel ) + { + ImplUpdateSelection( pOldSel ); + delete pOldSel; + } +} + +// ----------------------------------------------------------------------- + +sal_Bool Calendar::IsDateSelected( const Date& rDate ) const +{ + return mpSelectTable->IsKeyValid( rDate.GetDate() ); +} + +// ----------------------------------------------------------------------- + +sal_uLong Calendar::GetSelectDateCount() const +{ + return mpSelectTable->Count(); +} + +// ----------------------------------------------------------------------- + +Date Calendar::GetSelectDate( sal_uLong nIndex ) const +{ + if ( nIndex < mpSelectTable->Count() ) + return Date( mpSelectTable->GetObjectKey( nIndex ) ); + else + { + Date aDate( 0, 0, 0 ); + return aDate; + } +} + +// ----------------------------------------------------------------------- + +void Calendar::SetCurDate( const Date& rNewDate ) +{ + if ( !rNewDate.IsValid() ) + return; + + if ( maCurDate != rNewDate ) + { + sal_Bool bUpdate = IsVisible() && IsUpdateMode(); + Date aOldDate = maCurDate; + maCurDate = rNewDate; + maAnchorDate = maCurDate; + + if ( !(mnWinStyle & (WB_RANGESELECT | WB_MULTISELECT)) ) + { + ImplCalendarSelectDate( mpSelectTable, aOldDate, sal_False ); + ImplCalendarSelectDate( mpSelectTable, maCurDate, sal_True ); + } + else if ( !HasFocus() ) + bUpdate = sal_False; + + // Aktuelles Datum noch in den sichtbaren Bereich verschieben + if ( mbFormat || (maCurDate < GetFirstMonth()) ) + SetFirstDate( maCurDate ); + else if ( maCurDate > GetLastMonth() ) + { + Date aTempDate = GetLastMonth(); + long nDateOff = maCurDate-aTempDate; + if ( nDateOff < 365 ) + { + Date aFirstDate = GetFirstMonth(); + aFirstDate += aFirstDate.GetDaysInMonth(); + aTempDate++; + while ( nDateOff > aTempDate.GetDaysInMonth() ) + { + aFirstDate += aFirstDate.GetDaysInMonth(); + long nDaysInMonth = aTempDate.GetDaysInMonth(); + aTempDate += nDaysInMonth; + nDateOff -= nDaysInMonth; + } + SetFirstDate( aFirstDate ); + } + else + SetFirstDate( maCurDate ); + } + else + { + if ( bUpdate ) + { + HideFocus(); + ImplUpdateDate( aOldDate ); + ImplUpdateDate( maCurDate ); + } + } + } +} + +// ----------------------------------------------------------------------- + +void Calendar::SetFirstDate( const Date& rNewFirstDate ) +{ + if ( maFirstDate != rNewFirstDate ) + { + maFirstDate = Date( 1, rNewFirstDate.GetMonth(), rNewFirstDate.GetYear() ); + mbDropPos = sal_False; + ImplUpdate(); + } +} + +// ----------------------------------------------------------------------- + +Date Calendar::GetFirstMonth() const +{ + if ( maFirstDate.GetDay() > 1 ) + { + if ( maFirstDate.GetMonth() == 12 ) + return Date( 1, 1, maFirstDate.GetYear()+1 ); + else + return Date( 1, maFirstDate.GetMonth()+1, maFirstDate.GetYear() ); + } + else + return maFirstDate; +} + +// ----------------------------------------------------------------------- + +Date Calendar::GetLastMonth() const +{ + Date aDate = GetFirstMonth(); + sal_uInt16 nMonthCount = GetMonthCount(); + for ( sal_uInt16 i = 0; i < nMonthCount; i++ ) + aDate += aDate.GetDaysInMonth(); + aDate--; + return aDate; +} + +// ----------------------------------------------------------------------- + +sal_uInt16 Calendar::GetMonthCount() const +{ + if ( mbFormat ) + return 1; + else + return (sal_uInt16)(mnMonthPerLine*mnLines); +} + +// ----------------------------------------------------------------------- + +sal_Bool Calendar::GetDropDate( Date& rDate ) const +{ + if( mbDropPos ) + { + rDate = maDropDate; + return sal_True; + } + return sal_False; +} + +// ----------------------------------------------------------------------- + +sal_Bool Calendar::GetDate( const Point& rPos, Date& rDate ) const +{ + Date aDate = maCurDate; + sal_uInt16 nHitTest = ImplHitTest( rPos, aDate ); + if ( nHitTest & CALENDAR_HITTEST_DAY ) + { + rDate = aDate; + return sal_True; + } + else + return sal_False; +} + +// ----------------------------------------------------------------------- + +Rectangle Calendar::GetDateRect( const Date& rDate ) const +{ + Rectangle aRect; + + if ( mbFormat || (rDate < maFirstDate) || (rDate > (maFirstDate+mnDayCount)) ) + return aRect; + + long nX; + long nY; + sal_uLong nDaysOff; + sal_uInt16 nDayIndex; + Date aDate = GetFirstMonth(); + + if ( rDate < aDate ) + { + aRect = GetDateRect( aDate ); + nDaysOff = aDate-rDate; + nX = (long)(nDaysOff*mnDayWidth); + aRect.Left() -= nX; + aRect.Right() -= nX; + return aRect; + } + else + { + Date aLastDate = GetLastMonth(); + if ( rDate > aLastDate ) + { + sal_uInt16 nWeekDay = (sal_uInt16)aLastDate.GetDayOfWeek(); + nWeekDay = (nWeekDay+(7-(sal_uInt16)ImplGetWeekStart())) % 7; + aLastDate -= nWeekDay; + aRect = GetDateRect( aLastDate ); + nDaysOff = rDate-aLastDate; + nDayIndex = 0; + for ( sal_uInt16 i = 0; i <= nDaysOff; i++ ) + { + if ( aLastDate == rDate ) + { + aRect.Left() += nDayIndex*mnDayWidth; + aRect.Right() = aRect.Left()+mnDayWidth; + return aRect; + } + if ( nDayIndex == 6 ) + { + nDayIndex = 0; + aRect.Top() += mnDayHeight; + aRect.Bottom() += mnDayHeight; + } + else + nDayIndex++; + aLastDate++; + } + } + } + + nY = 0; + for ( long i = 0; i < mnLines; i++ ) + { + nX = 0; + for ( long j = 0; j < mnMonthPerLine; j++ ) + { + sal_uInt16 nDaysInMonth = aDate.GetDaysInMonth(); + + // Monat gerufen + if ( (aDate.GetMonth() == rDate.GetMonth()) && + (aDate.GetYear() == rDate.GetYear()) ) + { + long nDayX = nX+mnDaysOffX; + long nDayY = nY+mnDaysOffY; + nDayIndex = (sal_uInt16)aDate.GetDayOfWeek(); + nDayIndex = (nDayIndex+(7-(sal_uInt16)ImplGetWeekStart())) % 7; + for ( sal_uInt16 nDay = 1; nDay <= nDaysInMonth; nDay++ ) + { + if ( nDay == rDate.GetDay() ) + { + aRect.Left() = nDayX + (nDayIndex*mnDayWidth); + aRect.Top() = nDayY; + aRect.Right() = aRect.Left()+mnDayWidth; + aRect.Bottom() = aRect.Top()+mnDayHeight; + break; + } + if ( nDayIndex == 6 ) + { + nDayIndex = 0; + nDayY += mnDayHeight; + } + else + nDayIndex++; + } + } + + aDate += nDaysInMonth; + nX += mnMonthWidth; + } + + nY += mnMonthHeight; + } + + return aRect; +} + +// ----------------------------------------------------------------------- + +void Calendar::SetStandardColor( const Color& rColor ) +{ + if ( mpStandardColor ) + *mpStandardColor = rColor; + else + mpStandardColor = new Color( rColor ); + ImplUpdate(); +} + +// ----------------------------------------------------------------------- + +void Calendar::SetSaturdayColor( const Color& rColor ) +{ + if ( mpSaturdayColor ) + *mpSaturdayColor = rColor; + else + mpSaturdayColor = new Color( rColor ); + ImplUpdate(); +} + +// ----------------------------------------------------------------------- + +void Calendar::SetSundayColor( const Color& rColor ) +{ + if ( mpSundayColor ) + *mpSundayColor = rColor; + else + mpSundayColor = new Color( rColor ); + ImplUpdate(); +} + +// ----------------------------------------------------------------------- + +void Calendar::AddDateInfo( const Date& rDate, const String& rText, + const Color* pTextColor, const Color* pFrameColor, + sal_uInt16 nFlags ) +{ + if ( !mpDateTable ) + mpDateTable = new ImplDateTable( 256, 256 ); + + sal_Bool bChanged = sal_False; + sal_uLong nKey = rDate.GetDate(); + ImplDateInfo* pDateInfo = mpDateTable->Get( nKey ); + if ( pDateInfo ) + pDateInfo->maText = rText; + else + { + pDateInfo = new ImplDateInfo( rText ); + mpDateTable->Insert( nKey, pDateInfo ); + } + if ( pTextColor ) + { + if ( pDateInfo->mpTextColor ) + { + if ( *(pDateInfo->mpTextColor) != *pTextColor ) + { + *(pDateInfo->mpTextColor) = *pTextColor; + bChanged = sal_True; + } + } + else + { + pDateInfo->mpTextColor = new Color( *pTextColor ); + bChanged = sal_True; + } + } + else + { + if ( pDateInfo->mpTextColor ) + { + delete pDateInfo->mpTextColor; + pDateInfo->mpTextColor = NULL; + bChanged = sal_True; + } + } + if ( pFrameColor ) + { + if ( pDateInfo->mpFrameColor ) + { + if ( *(pDateInfo->mpFrameColor) != *pFrameColor ) + { + *(pDateInfo->mpFrameColor) = *pFrameColor; + bChanged = sal_True; + } + } + else + { + pDateInfo->mpFrameColor = new Color( *pFrameColor ); + bChanged = sal_True; + } + } + else + { + if ( pDateInfo->mpFrameColor ) + { + delete pDateInfo->mpFrameColor; + pDateInfo->mpFrameColor = NULL; + bChanged = sal_True; + } + } + if ( pDateInfo->mnFlags != nFlags ) + { + pDateInfo->mnFlags = nFlags; + bChanged = sal_True; + } + + if ( bChanged ) + ImplUpdateDate( rDate ); +} + +// ----------------------------------------------------------------------- + +void Calendar::RemoveDateInfo( const Date& rDate ) +{ + if ( mpDateTable ) + { + ImplDateInfo* pDateInfo = mpDateTable->Remove( rDate.GetDate() ); + if ( pDateInfo ) + { + delete pDateInfo; + ImplUpdateDate( rDate ); + } + } +} + +// ----------------------------------------------------------------------- + +void Calendar::ClearDateInfo() +{ + if ( mpDateTable ) + { + ImplDateInfo* pDateInfo = mpDateTable->First(); + while ( pDateInfo ) + { + sal_uLong nKey = mpDateTable->GetCurKey(); + mpDateTable->Remove( nKey ); + Date aDate( nKey ); + ImplUpdateDate( aDate ); + delete pDateInfo; + pDateInfo = mpDateTable->First(); + } + delete mpDateTable; + mpDateTable = NULL; + } +} + +// ----------------------------------------------------------------------- + +XubString Calendar::GetDateInfoText( const Date& rDate ) +{ + XubString aRet; + if ( mpDateTable ) + { + sal_uLong nKey = rDate.GetDate(); + ImplDateInfo* pDateInfo = mpDateTable->Get( nKey ); + if ( pDateInfo ) + aRet = pDateInfo->maText; + } + return aRet; +} + +// ----------------------------------------------------------------------- + +sal_Bool Calendar::ShowDropPos( const Point& rPos, Date& rDate ) +{ + Date aTempDate = maCurDate; + mnDragScrollHitTest = ImplHitTest( rPos, aTempDate ); + + if ( mnDragScrollHitTest ) + { + if ( mnDragScrollHitTest & (CALENDAR_HITTEST_PREV | CALENDAR_HITTEST_NEXT) ) + { + if ( !maDragScrollTimer.IsActive() ) + maDragScrollTimer.Start(); + } + else + { + maDragScrollTimer.Stop(); + if ( mnDragScrollHitTest & CALENDAR_HITTEST_DAY ) + { + if ( !mbDropPos || (aTempDate != maDropDate) ) + { + if( mbDropPos ) + ImplInvertDropPos(); + maDropDate = aTempDate; + mbDropPos = sal_True; + ImplInvertDropPos(); + } + + rDate = maDropDate; + return sal_True; + } + } + } + else + maDragScrollTimer.Stop(); + + HideDropPos(); + return sal_False; +} + +// ----------------------------------------------------------------------- + +void Calendar::HideDropPos() +{ + if ( mbDropPos ) + { + ImplInvertDropPos(); + mbDropPos = sal_False; + } +} + +// ----------------------------------------------------------------------- + +void Calendar::StartSelection() +{ + if ( mpOldSelectTable ) + delete mpOldSelectTable; + maOldCurDate = maCurDate; + mpOldSelectTable = new Table( *mpSelectTable ); + + mbSelection = sal_True; +} + +// ----------------------------------------------------------------------- + +void Calendar::EndSelection() +{ + if ( mbDrag || mbSpinDown || mbSelection ) + { + if ( !mbSelection ) + ReleaseMouse(); + + mbDrag = sal_False; + mbSelection = sal_False; + mbMultiSelection = sal_False; + mbSpinDown = sal_False; + mbPrevIn = sal_False; + mbNextIn = sal_False; + } +} + +// ----------------------------------------------------------------------- + +Size Calendar::CalcWindowSizePixel( long nCalcMonthPerLine, + long nCalcLines ) const +{ + XubString a99Text( XubString( RTL_CONSTASCII_USTRINGPARAM( "99" ) ) ); + Font aOldFont = GetFont(); + + // Wochenanzeige beruecksichtigen + long nWeekWidth; + if ( mnWinStyle & WB_WEEKNUMBER ) + { + Font aTempFont = aOldFont; + ImplGetWeekFont( aTempFont ); + ((Calendar*)this)->SetFont( aTempFont ); + nWeekWidth = GetTextWidth( a99Text )+WEEKNUMBER_OFFX; + ((Calendar*)this)->SetFont( aOldFont ); + } + else + nWeekWidth = 0; + + if ( mnWinStyle & WB_BOLDTEXT ) + { + Font aFont = aOldFont; + if ( aFont.GetWeight() < WEIGHT_BOLD ) + aFont.SetWeight( WEIGHT_BOLD ); + else + aFont.SetWeight( WEIGHT_NORMAL ); + ((Calendar*)this)->SetFont( aFont ); + } + + Size aSize; + long n99TextWidth = GetTextWidth( a99Text ); + long nTextHeight = GetTextHeight(); + + if ( mnWinStyle & WB_BOLDTEXT ) + ((Calendar*)this)->SetFont( aOldFont ); + + aSize.Width() += ((n99TextWidth+DAY_OFFX)*7) + nWeekWidth; + aSize.Width() += MONTH_BORDERX*2; + aSize.Width() *= nCalcMonthPerLine; + + aSize.Height() = nTextHeight + TITLE_OFFY + (TITLE_BORDERY*2); + aSize.Height() += nTextHeight + WEEKDAY_OFFY; + aSize.Height() += ((nTextHeight+DAY_OFFY)*6); + aSize.Height() += MONTH_OFFY; + aSize.Height() *= nCalcLines; + + return aSize; +} + +// ======================================================================= + +#define CALFIELD_EXTRA_BUTTON_WIDTH 14 +#define CALFIELD_EXTRA_BUTTON_HEIGHT 8 +#define CALFIELD_SEP_X 6 +#define CALFIELD_BORDERLINE_X 5 +#define CALFIELD_BORDER_YTOP 4 +#define CALFIELD_BORDER_Y 5 + +// ======================================================================= + +class ImplCFieldFloatWin : public FloatingWindow +{ +private: + Calendar* mpCalendar; + PushButton* mpTodayBtn; + PushButton* mpNoneBtn; + FixedLine* mpFixedLine; + +public: + ImplCFieldFloatWin( Window* pParent ); + ~ImplCFieldFloatWin(); + + void SetCalendar( Calendar* pCalendar ) + { mpCalendar = pCalendar; } + + PushButton* EnableTodayBtn( sal_Bool bEnable ); + PushButton* EnableNoneBtn( sal_Bool bEnable ); + void ArrangeButtons(); + + long Notify( NotifyEvent& rNEvt ); +}; + +// ----------------------------------------------------------------------- + +ImplCFieldFloatWin::ImplCFieldFloatWin( Window* pParent ) : + FloatingWindow( pParent, WB_BORDER | WB_SYSTEMWINDOW | WB_NOSHADOW ) +{ + mpCalendar = NULL; + mpTodayBtn = NULL; + mpNoneBtn = NULL; + mpFixedLine = NULL; +} + +// ----------------------------------------------------------------------- + +ImplCFieldFloatWin::~ImplCFieldFloatWin() +{ + delete mpTodayBtn; + delete mpNoneBtn; + delete mpFixedLine; +} + +// ----------------------------------------------------------------------- + +PushButton* ImplCFieldFloatWin::EnableTodayBtn( sal_Bool bEnable ) +{ + if ( bEnable ) + { + if ( !mpTodayBtn ) + { + mpTodayBtn = new PushButton( this, WB_NOPOINTERFOCUS ); + XubString aTodayText( SvtResId( STR_SVT_CALENDAR_TODAY ) ); + mpTodayBtn->SetText( aTodayText ); + Size aSize; + aSize.Width() = mpTodayBtn->GetCtrlTextWidth( mpTodayBtn->GetText() ); + aSize.Height() = mpTodayBtn->GetTextHeight(); + aSize.Width() += CALFIELD_EXTRA_BUTTON_WIDTH; + aSize.Height() += CALFIELD_EXTRA_BUTTON_HEIGHT; + mpTodayBtn->SetSizePixel( aSize ); + mpTodayBtn->Show(); + } + } + else + { + if ( mpTodayBtn ) + { + delete mpTodayBtn; + mpTodayBtn = NULL; + } + } + + return mpTodayBtn; +} + +// ----------------------------------------------------------------------- + +PushButton* ImplCFieldFloatWin::EnableNoneBtn( sal_Bool bEnable ) +{ + if ( bEnable ) + { + if ( !mpNoneBtn ) + { + mpNoneBtn = new PushButton( this, WB_NOPOINTERFOCUS ); + XubString aNoneText( SvtResId( STR_SVT_CALENDAR_NONE ) ); + mpNoneBtn->SetText( aNoneText ); + Size aSize; + aSize.Width() = mpNoneBtn->GetCtrlTextWidth( mpNoneBtn->GetText() ); + aSize.Height() = mpNoneBtn->GetTextHeight(); + aSize.Width() += CALFIELD_EXTRA_BUTTON_WIDTH; + aSize.Height() += CALFIELD_EXTRA_BUTTON_HEIGHT; + mpNoneBtn->SetSizePixel( aSize ); + mpNoneBtn->Show(); + } + } + else + { + if ( mpNoneBtn ) + { + delete mpNoneBtn; + mpNoneBtn = NULL; + } + } + + return mpNoneBtn; +} + +// ----------------------------------------------------------------------- + +void ImplCFieldFloatWin::ArrangeButtons() +{ + long nBtnHeight = 0; + long nBtnWidth = 0; + Size aOutSize = GetOutputSizePixel(); + if ( mpTodayBtn && mpNoneBtn ) + { + Size aTodayBtnSize = mpTodayBtn->GetSizePixel(); + Size aNoneBtnSize = mpNoneBtn->GetSizePixel(); + if ( aTodayBtnSize.Width() < aNoneBtnSize.Width() ) + aTodayBtnSize.Width() = aNoneBtnSize.Width(); + else + aNoneBtnSize.Width() = aTodayBtnSize.Width(); + if ( aTodayBtnSize.Height() < aNoneBtnSize.Height() ) + aTodayBtnSize.Height() = aNoneBtnSize.Height(); + else + aNoneBtnSize.Height() = aTodayBtnSize.Height(); + + nBtnWidth = aTodayBtnSize.Width() + aNoneBtnSize.Width() + CALFIELD_SEP_X; + nBtnHeight = aTodayBtnSize.Height(); + long nX = (aOutSize.Width()-nBtnWidth)/2; + long nY = aOutSize.Height()+CALFIELD_BORDER_Y+CALFIELD_BORDER_YTOP; + mpTodayBtn->SetPosSizePixel( Point( nX, nY ), aTodayBtnSize ); + nX += aTodayBtnSize.Width() + CALFIELD_SEP_X; + mpNoneBtn->SetPosSizePixel( Point( nX, nY ), aNoneBtnSize ); + } + else if ( mpTodayBtn ) + { + Size aTodayBtnSize = mpTodayBtn->GetSizePixel(); + nBtnWidth = aTodayBtnSize.Width(); + nBtnHeight = aTodayBtnSize.Height(); + mpTodayBtn->SetPosPixel( Point( (aOutSize.Width()-nBtnWidth)/2, aOutSize.Height()+CALFIELD_BORDER_Y+CALFIELD_BORDER_YTOP ) ); + } + else if ( mpNoneBtn ) + { + Size aNoneBtnSize = mpNoneBtn->GetSizePixel(); + nBtnWidth = aNoneBtnSize.Width(); + nBtnHeight = aNoneBtnSize.Height(); + mpNoneBtn->SetPosPixel( Point( (aOutSize.Width()-nBtnWidth)/2, aOutSize.Height()+CALFIELD_BORDER_Y+CALFIELD_BORDER_YTOP ) ); + } + + if ( nBtnHeight ) + { + if ( !mpFixedLine ) + { + mpFixedLine = new FixedLine( this ); + mpFixedLine->Show(); + } + long nLineWidth = aOutSize.Width()-(CALFIELD_BORDERLINE_X*2); + mpFixedLine->SetPosSizePixel( (aOutSize.Width()-nLineWidth)/2, aOutSize.Height()+((CALFIELD_BORDER_YTOP-2)/2), + nLineWidth, 2, WINDOW_POSSIZE_POSSIZE ); + aOutSize.Height() += nBtnHeight + (CALFIELD_BORDER_Y*2) + CALFIELD_BORDER_YTOP; + SetOutputSizePixel( aOutSize ); + } + else + { + if ( mpFixedLine ) + { + delete mpFixedLine; + mpFixedLine = NULL; + } + } +} + +// ----------------------------------------------------------------------- + +long ImplCFieldFloatWin::Notify( NotifyEvent& rNEvt ) +{ + if ( rNEvt.GetType() == EVENT_KEYINPUT ) + { + const KeyEvent* pKEvt = rNEvt.GetKeyEvent(); + if ( pKEvt->GetKeyCode().GetCode() == KEY_RETURN ) + mpCalendar->Select(); + } + + return FloatingWindow::Notify( rNEvt ); +} + +// ======================================================================= + +CalendarField::CalendarField( Window* pParent, WinBits nWinStyle ) : + DateField( pParent, nWinStyle ), + maDefaultDate( 0, 0, 0 ) +{ + mpFloatWin = NULL; + mpCalendar = NULL; + mnCalendarStyle = 0; + mbToday = sal_False; + mbNone = sal_False; +} + +// ----------------------------------------------------------------------- + +CalendarField::CalendarField( Window* pParent, const ResId& rResId ) : + DateField( pParent, rResId ), + maDefaultDate( 0, 0, 0 ) +{ + mpFloatWin = NULL; + mpCalendar = NULL; + mnCalendarStyle = 0; + mbToday = sal_False; + mbNone = sal_False; +} + +// ----------------------------------------------------------------------- + +CalendarField::~CalendarField() +{ + if ( mpFloatWin ) + { + delete mpCalendar; + delete mpFloatWin; + } +} + +// ----------------------------------------------------------------------- + +IMPL_LINK( CalendarField, ImplSelectHdl, Calendar*, pCalendar ) +{ + if ( !pCalendar->IsTravelSelect() ) + { + mpFloatWin->EndPopupMode(); + EndDropDown(); + GrabFocus(); + Date aNewDate = mpCalendar->GetSelectDate( 0 ); + if ( IsEmptyDate() || ( aNewDate != GetDate() ) ) + { + SetDate( aNewDate ); + SetModifyFlag(); + Modify(); + } + Select(); + } + return 0; +} + +// ----------------------------------------------------------------------- + +IMPL_LINK( CalendarField, ImplClickHdl, PushButton*, pBtn ) +{ + mpFloatWin->EndPopupMode(); + EndDropDown(); + GrabFocus(); + + if ( pBtn == mpTodayBtn ) + { + Date aToday; + if ( (aToday != GetDate()) || IsEmptyDate() ) + { + SetDate( aToday ); + SetModifyFlag(); + Modify(); + } + } + else if ( pBtn == mpNoneBtn ) + { + if ( !IsEmptyDate() ) + { + SetEmptyDate(); + SetModifyFlag(); + Modify(); + } + } + Select(); + + return 0; +} + +// ----------------------------------------------------------------------- + +IMPL_LINK( CalendarField, ImplPopupModeEndHdl, FloatingWindow*, EMPTYARG ) +{ + EndDropDown(); + GrabFocus(); + mpCalendar->EndSelection(); + return 0; +} + +// ----------------------------------------------------------------------- + +void CalendarField::Select() +{ + maSelectHdl.Call( this ); +} + +// ----------------------------------------------------------------------- + +sal_Bool CalendarField::ShowDropDown( sal_Bool bShow ) +{ + if ( bShow ) + { + Calendar* pCalendar = GetCalendar(); + + Date aDate = GetDate(); + if ( IsEmptyDate() || !aDate.IsValid() ) + { + if ( maDefaultDate.IsValid() ) + aDate = maDefaultDate; + else + aDate = Date(); + } + if ( pCalendar->GetStyle() & (WB_RANGESELECT | WB_MULTISELECT) ) + { + pCalendar->SetNoSelection(); + pCalendar->SelectDate( aDate ); + } + pCalendar->SetCurDate( aDate ); + Point aPos( GetParent()->OutputToScreenPixel( GetPosPixel() ) ); + Rectangle aRect( aPos, GetSizePixel() ); + aRect.Bottom() -= 1; + mpCalendar->SetOutputSizePixel( mpCalendar->CalcWindowSizePixel() ); + mpFloatWin->SetOutputSizePixel( mpCalendar->GetSizePixel() ); + mpFloatWin->SetCalendar( mpCalendar ); + mpTodayBtn = mpFloatWin->EnableTodayBtn( mbToday ); + mpNoneBtn = mpFloatWin->EnableNoneBtn( mbNone ); + if ( mpTodayBtn ) + mpTodayBtn->SetClickHdl( LINK( this, CalendarField, ImplClickHdl ) ); + if ( mpNoneBtn ) + mpNoneBtn->SetClickHdl( LINK( this, CalendarField, ImplClickHdl ) ); + mpFloatWin->ArrangeButtons(); + mpCalendar->EnableCallEverySelect(); + mpCalendar->StartSelection(); + mpCalendar->GrabFocus(); + mpCalendar->Show(); + mpFloatWin->StartPopupMode( aRect, FLOATWIN_POPUPMODE_NOFOCUSCLOSE|FLOATWIN_POPUPMODE_DOWN ); + } + else + { + mpFloatWin->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL ); + mpCalendar->EndSelection(); + EndDropDown(); + } + return sal_True; +} + +// ----------------------------------------------------------------------- + +Calendar* CalendarField::CreateCalendar( Window* pParent ) +{ + return new Calendar( pParent, mnCalendarStyle | WB_TABSTOP ); +} + +// ----------------------------------------------------------------------- + +Calendar* CalendarField::GetCalendar() +{ + if ( !mpFloatWin ) + { + mpFloatWin = new ImplCFieldFloatWin( this ); + mpFloatWin->SetPopupModeEndHdl( LINK( this, CalendarField, ImplPopupModeEndHdl ) ); + mpCalendar = CreateCalendar( mpFloatWin ); + mpCalendar->SetPosPixel( Point() ); + mpCalendar->SetSelectHdl( LINK( this, CalendarField, ImplSelectHdl ) ); + } + + return mpCalendar; +} + +// ----------------------------------------------------------------------- + +void CalendarField::StateChanged( StateChangedType nStateChange ) +{ + DateField::StateChanged( nStateChange ); + + if ( ( nStateChange == STATE_CHANGE_STYLE ) && GetSubEdit() ) + { + WinBits nAllAlignmentBits = ( WB_LEFT | WB_CENTER | WB_RIGHT | WB_TOP | WB_VCENTER | WB_BOTTOM ); + WinBits nMyAlignment = GetStyle() & nAllAlignmentBits; + GetSubEdit()->SetStyle( ( GetSubEdit()->GetStyle() & ~nAllAlignmentBits ) | nMyAlignment ); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |