| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the 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 ); |
| } |
| } |
| |