LCOV - code coverage report
Current view: top level - svtools/source/control - calendar.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 17 1415 1.2 %
Date: 2015-06-13 12:38:46 Functions: 5 88 5.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <rtl/strbuf.hxx>
      21             : #include <vcl/svapp.hxx>
      22             : #include <vcl/help.hxx>
      23             : #include <vcl/menu.hxx>
      24             : #include <vcl/decoview.hxx>
      25             : #include <vcl/floatwin.hxx>
      26             : #include <vcl/button.hxx>
      27             : #include <vcl/fixed.hxx>
      28             : #include <vcl/settings.hxx>
      29             : #include <comphelper/processfactory.hxx>
      30             : #include <unotools/calendarwrapper.hxx>
      31             : #include <unotools/localedatawrapper.hxx>
      32             : #include <com/sun/star/i18n/Weekdays.hpp>
      33             : #include <com/sun/star/i18n/CalendarDisplayIndex.hpp>
      34             : #include <com/sun/star/i18n/CalendarFieldIndex.hpp>
      35             : 
      36             : #include <svtools/svtools.hrc>
      37             : #include <svtools/svtresid.hxx>
      38             : #include <svtools/calendar.hxx>
      39             : #include <boost/scoped_ptr.hpp>
      40             : 
      41             : #define DAY_OFFX                        4
      42             : #define DAY_OFFY                        2
      43             : #define MONTH_BORDERX                   4
      44             : #define MONTH_OFFY                      3
      45             : #define WEEKNUMBER_OFFX                 4
      46             : #define WEEKDAY_OFFY                    3
      47             : #define TITLE_OFFY                      3
      48             : #define TITLE_BORDERY                   2
      49             : #define SPIN_OFFX                       4
      50             : #define SPIN_OFFY                       TITLE_BORDERY
      51             : 
      52             : #define WEEKNUMBER_HEIGHT               85
      53             : 
      54             : #define CALENDAR_HITTEST_DAY            ((sal_uInt16)0x0001)
      55             : #define CALENDAR_HITTEST_MONTHTITLE     ((sal_uInt16)0x0004)
      56             : #define CALENDAR_HITTEST_PREV           ((sal_uInt16)0x0008)
      57             : #define CALENDAR_HITTEST_NEXT           ((sal_uInt16)0x0010)
      58             : 
      59             : #define MENU_YEAR_COUNT                 3
      60             : 
      61             : using namespace ::com::sun::star;
      62             : 
      63           0 : static void ImplCalendarSelectDate( IntDateSet* pTable, const Date& rDate, bool bSelect )
      64             : {
      65           0 :     if ( bSelect )
      66           0 :         pTable->insert( rDate.GetDate() );
      67             :     else
      68           0 :         pTable->erase( rDate.GetDate() );
      69           0 : }
      70             : 
      71           0 : static void ImplCalendarSelectDateRange( IntDateSet* pTable,
      72             :                                          const Date& rStartDate,
      73             :                                          const Date& rEndDate,
      74             :                                          bool bSelect )
      75             : {
      76           0 :     Date aStartDate = rStartDate;
      77           0 :     Date aEndDate = rEndDate;
      78           0 :     if ( aStartDate > aEndDate )
      79             :     {
      80           0 :         Date aTempDate = aStartDate;
      81           0 :         aStartDate = aEndDate;
      82           0 :         aEndDate = aTempDate;
      83             :     }
      84             : 
      85           0 :     if ( bSelect )
      86             :     {
      87           0 :         while ( aStartDate <= aEndDate )
      88             :         {
      89           0 :             pTable->insert( aStartDate.GetDate() );
      90           0 :             ++aStartDate;
      91             :         }
      92             :     }
      93             :     else
      94             :     {
      95           0 :         for ( IntDateSet::const_iterator it = pTable->begin(); it != pTable->end(); )
      96             :         {
      97           0 :             Date aDate( *it );
      98           0 :             if ( aDate > aEndDate )
      99           0 :                 break;
     100             : 
     101           0 :             if ( aDate >= aStartDate )
     102           0 :                 it = pTable->erase(it);
     103             :             else
     104           0 :                 ++it;
     105             :         }
     106             :     }
     107           0 : }
     108             : 
     109           0 : static void ImplCalendarUnSelectDateRange( IntDateSet* pTable,
     110             :                                            IntDateSet* pOldTable,
     111             :                                            const Date& rStartDate,
     112             :                                            const Date& rEndDate )
     113             : {
     114           0 :     Date aStartDate = rStartDate;
     115           0 :     Date aEndDate = rEndDate;
     116           0 :     if ( aStartDate > aEndDate )
     117             :     {
     118           0 :         Date aTempDate = aStartDate;
     119           0 :         aStartDate = aEndDate;
     120           0 :         aEndDate = aTempDate;
     121             :     }
     122             : 
     123           0 :     for ( IntDateSet::const_iterator it = pTable->begin(); it != pTable->end(); )
     124             :     {
     125           0 :         Date aDate( *it );
     126           0 :         if ( aDate > aEndDate )
     127           0 :             break;
     128             : 
     129           0 :         if ( aDate >= aStartDate )
     130           0 :             it = pTable->erase(it);
     131             :         else
     132           0 :             ++it;
     133             :     }
     134             : 
     135           0 :     for ( IntDateSet::const_iterator it = pOldTable->begin(); it != pOldTable->end(); ++it )
     136             :     {
     137           0 :         Date aDate( *it );
     138           0 :         if ( aDate > aEndDate )
     139           0 :             break;
     140           0 :         if ( aDate >= aStartDate )
     141           0 :             pTable->insert( aDate.GetDate() );
     142             :     }
     143           0 : }
     144             : 
     145           0 : inline void ImplCalendarClearSelectDate( IntDateSet* pTable )
     146             : {
     147           0 :     pTable->clear();
     148           0 : }
     149             : 
     150           0 : void Calendar::ImplInit( WinBits nWinStyle )
     151             : {
     152           0 :     mpSelectTable           = new IntDateSet;
     153           0 :     mpOldSelectTable        = NULL;
     154           0 :     mpRestoreSelectTable    = NULL;
     155           0 :     mpStandardColor         = NULL;
     156           0 :     mpSaturdayColor         = NULL;
     157           0 :     mpSundayColor           = NULL;
     158           0 :     mnDayCount              = 0;
     159           0 :     mnWinStyle              = nWinStyle;
     160           0 :     mnFirstYear             = 0;
     161           0 :     mnLastYear              = 0;
     162           0 :     mnRequestYear           = 0;
     163           0 :     mbCalc                  = true;
     164           0 :     mbFormat                = true;
     165           0 :     mbDrag                  = false;
     166           0 :     mbSelection             = false;
     167           0 :     mbMultiSelection        = false;
     168           0 :     mbWeekSel               = false;
     169           0 :     mbUnSel                 = false;
     170           0 :     mbMenuDown              = false;
     171           0 :     mbSpinDown              = false;
     172           0 :     mbPrevIn                = false;
     173           0 :     mbNextIn                = false;
     174           0 :     mbDirect                = false;
     175           0 :     mbInSelChange           = false;
     176           0 :     mbTravelSelect          = false;
     177           0 :     mbScrollDateRange       = false;
     178           0 :     mbSelLeft               = false;
     179           0 :     mbAllSel                = false;
     180           0 :     mbDropPos               = false;
     181             : 
     182           0 :     OUString aGregorian( "gregorian");
     183             :     maCalendarWrapper.loadCalendar( aGregorian,
     184           0 :             Application::GetAppLocaleDataWrapper().getLanguageTag().getLocale());
     185           0 :     if (maCalendarWrapper.getUniqueID() != aGregorian)
     186             :     {
     187             :         SAL_WARN( "svtools.control", "Calendar::ImplInit: No ``gregorian'' calendar available for locale ``"
     188             :             << Application::GetAppLocaleDataWrapper().getLanguageTag().getBcp47()
     189             :             << "'' and other calendars aren't supported. Using en-US fallback." );
     190             : 
     191             :         /* If we ever wanted to support other calendars than Gregorian a lot of
     192             :          * rewrite would be necessary to internally replace use of class Date
     193             :          * with proper class CalendarWrapper methods, get rid of fixed 12
     194             :          * months, fixed 7 days, ... */
     195           0 :         maCalendarWrapper.loadCalendar( aGregorian, lang::Locale( "en", "US", ""));
     196             :     }
     197             : 
     198           0 :     SetFirstDate( maCurDate );
     199           0 :     ImplCalendarSelectDate( mpSelectTable, maCurDate, true );
     200             : 
     201             :     // Sonstige Strings erzeugen
     202           0 :     maDayText = SVT_RESSTR(STR_SVT_CALENDAR_DAY);
     203           0 :     maWeekText = SVT_RESSTR(STR_SVT_CALENDAR_WEEK);
     204             : 
     205             :     // Tagestexte anlegen
     206           0 :     for (sal_Int32 i = 0; i < 31; ++i)
     207           0 :         maDayTexts[i] = OUString::number(i+1);
     208             : 
     209           0 :     maDragScrollTimer.SetTimeoutHdl( LINK( this, Calendar, ScrollHdl ) );
     210           0 :     maDragScrollTimer.SetTimeout( GetSettings().GetMouseSettings().GetScrollRepeat() );
     211           0 :     mnDragScrollHitTest = 0;
     212             : 
     213           0 :     ImplInitSettings();
     214           0 : }
     215             : 
     216           0 : void Calendar::ApplySettings(vcl::RenderContext& rRenderContext)
     217             : {
     218           0 :     const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
     219           0 :     maSelColor = rStyleSettings.GetHighlightTextColor();
     220           0 :     SetPointFont(rRenderContext, rStyleSettings.GetToolFont());
     221           0 :     rRenderContext.SetTextColor(rStyleSettings.GetFieldTextColor());
     222           0 :     rRenderContext.SetBackground(Wallpaper(rStyleSettings.GetFieldColor()));
     223           0 : }
     224             : 
     225           0 : void Calendar::ImplInitSettings()
     226             : {
     227           0 :     const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
     228           0 :     maSelColor = rStyleSettings.GetHighlightTextColor();
     229           0 :     SetPointFont(*this, rStyleSettings.GetToolFont());
     230           0 :     SetTextColor(rStyleSettings.GetFieldTextColor());
     231           0 :     SetBackground(Wallpaper(rStyleSettings.GetFieldColor()));
     232           0 : }
     233             : 
     234           0 : Calendar::Calendar( vcl::Window* pParent, WinBits nWinStyle ) :
     235             :     Control( pParent, nWinStyle & (WB_TABSTOP | WB_GROUP | WB_BORDER | WB_3DLOOK | WB_RANGESELECT | WB_MULTISELECT) ),
     236           0 :     maCalendarWrapper( Application::GetAppLocaleDataWrapper().getComponentContext() ),
     237             :     maOldFormatFirstDate( 0, 0, 1900 ),
     238             :     maOldFormatLastDate( 0, 0, 1900 ),
     239             :     maFirstDate( 0, 0, 1900 ),
     240             :     maOldFirstDate( 0, 0, 1900 ),
     241             :     maCurDate( Date::SYSTEM ),
     242             :     maOldCurDate( 0, 0, 1900 ),
     243             :     maAnchorDate( maCurDate ),
     244           0 :     maDropDate( 0, 0, 1900 )
     245             : {
     246           0 :     ImplInit( nWinStyle );
     247           0 : }
     248             : 
     249           0 : Calendar::~Calendar()
     250             : {
     251           0 :     disposeOnce();
     252           0 : }
     253             : 
     254           0 : void Calendar::dispose()
     255             : {
     256           0 :     delete mpStandardColor;
     257           0 :     delete mpSaturdayColor;
     258           0 :     delete mpSundayColor;
     259             : 
     260           0 :     delete mpSelectTable;
     261           0 :     delete mpOldSelectTable;
     262           0 :     delete mpRestoreSelectTable;
     263           0 :     Control::dispose();
     264           0 : }
     265             : 
     266           0 : DayOfWeek Calendar::ImplGetWeekStart() const
     267             : {
     268             :     // Map i18n::Weekdays to Date DayOfWeek
     269             :     DayOfWeek eDay;
     270           0 :     sal_Int16 nDay = maCalendarWrapper.getFirstDayOfWeek();
     271           0 :     switch (nDay)
     272             :     {
     273             :         case i18n::Weekdays::SUNDAY :
     274           0 :             eDay = SUNDAY;
     275           0 :             break;
     276             :         case i18n::Weekdays::MONDAY :
     277           0 :             eDay = MONDAY;
     278           0 :             break;
     279             :         case i18n::Weekdays::TUESDAY :
     280           0 :             eDay = TUESDAY;
     281           0 :             break;
     282             :         case i18n::Weekdays::WEDNESDAY :
     283           0 :             eDay = WEDNESDAY;
     284           0 :             break;
     285             :         case i18n::Weekdays::THURSDAY :
     286           0 :             eDay = THURSDAY;
     287           0 :             break;
     288             :         case i18n::Weekdays::FRIDAY :
     289           0 :             eDay = FRIDAY;
     290           0 :             break;
     291             :         case i18n::Weekdays::SATURDAY :
     292           0 :             eDay = SATURDAY;
     293           0 :             break;
     294             :         default:
     295             :             SAL_WARN( "svtools.control", "Calendar::ImplGetWeekStart: broken i18n Gregorian calendar (getFirstDayOfWeek())");
     296           0 :             eDay = SUNDAY;
     297             :     }
     298           0 :     return eDay;
     299             : }
     300             : 
     301           0 : void Calendar::ImplGetWeekFont( vcl::Font& rFont ) const
     302             : {
     303             :     // weeknumber is displayed in WEEKNUMBER_HEIGHT%-Fontheight
     304           0 :     Size aFontSize = rFont.GetSize();
     305           0 :     aFontSize.Height() *= WEEKNUMBER_HEIGHT;
     306           0 :     aFontSize.Height() /= 100;
     307           0 :     rFont.SetSize( aFontSize );
     308           0 :     rFont.SetWeight( WEIGHT_NORMAL );
     309           0 : }
     310             : 
     311           0 : void Calendar::ImplFormat()
     312             : {
     313           0 :     if ( !mbFormat )
     314           0 :         return;
     315             : 
     316           0 :     if ( mbCalc )
     317             :     {
     318           0 :         Size aOutSize = GetOutputSizePixel();
     319             : 
     320           0 :         if ( (aOutSize.Width() <= 1) || (aOutSize.Height() <= 1) )
     321           0 :             return;
     322             : 
     323           0 :         OUString a99Text("99");
     324             : 
     325           0 :         vcl::Font aOldFont = GetFont();
     326             : 
     327             :         // Wochenanzeige beruecksichtigen
     328           0 :         if ( mnWinStyle & WB_WEEKNUMBER )
     329             :         {
     330           0 :             vcl::Font aTempFont = aOldFont;
     331           0 :             ImplGetWeekFont( aTempFont );
     332           0 :             SetFont( aTempFont );
     333           0 :             mnWeekWidth = GetTextWidth( a99Text )+WEEKNUMBER_OFFX;
     334           0 :             SetFont( aOldFont );
     335             :         }
     336             :         else
     337           0 :             mnWeekWidth = 0;
     338             : 
     339           0 :         if ( mnWinStyle & WB_BOLDTEXT )
     340             :         {
     341           0 :             vcl::Font aFont = aOldFont;
     342           0 :             if ( aFont.GetWeight() < WEIGHT_BOLD )
     343           0 :                 aFont.SetWeight( WEIGHT_BOLD );
     344             :             else
     345           0 :                 aFont.SetWeight( WEIGHT_NORMAL );
     346           0 :             SetFont( aFont );
     347             :         }
     348             : 
     349           0 :         long n99TextWidth = GetTextWidth( a99Text );
     350           0 :         long nTextHeight = GetTextHeight();
     351             : 
     352             :         // calculate width and x-position
     353           0 :         mnDayWidth      = n99TextWidth+DAY_OFFX;
     354           0 :         mnMonthWidth    = mnDayWidth*7;
     355           0 :         mnMonthWidth   += mnWeekWidth;
     356           0 :         mnMonthWidth   += MONTH_BORDERX*2;
     357           0 :         mnMonthPerLine  = aOutSize.Width() / mnMonthWidth;
     358           0 :         if ( !mnMonthPerLine )
     359           0 :             mnMonthPerLine = 1;
     360           0 :         long nOver      = ((aOutSize.Width()-(mnMonthPerLine*mnMonthWidth)) / mnMonthPerLine);
     361           0 :         mnMonthWidth   += nOver;
     362           0 :         mnDaysOffX      = MONTH_BORDERX;
     363           0 :         mnDaysOffX     += nOver/2;
     364           0 :         mnDaysOffX     += mnWeekWidth;
     365             : 
     366             :         // calculate height and y-position
     367           0 :         mnDayHeight     = nTextHeight + DAY_OFFY;
     368           0 :         mnWeekDayOffY   = nTextHeight + TITLE_OFFY + (TITLE_BORDERY*2);
     369           0 :         mnDaysOffY      = mnWeekDayOffY + nTextHeight + WEEKDAY_OFFY;
     370           0 :         mnMonthHeight   = (mnDayHeight*6) + mnDaysOffY;
     371           0 :         mnMonthHeight  += MONTH_OFFY;
     372           0 :         mnLines         = aOutSize.Height() / mnMonthHeight;
     373           0 :         if ( !mnLines )
     374           0 :             mnLines = 1;
     375           0 :         mnMonthHeight  += (aOutSize.Height()-(mnLines*mnMonthHeight)) / mnLines;
     376             : 
     377             :         // calculate spinfields
     378           0 :         long nSpinSize      = nTextHeight+TITLE_BORDERY-SPIN_OFFY;
     379           0 :         maPrevRect.Left()   = SPIN_OFFX;
     380           0 :         maPrevRect.Top()    = SPIN_OFFY;
     381           0 :         maPrevRect.Right()  = maPrevRect.Left()+nSpinSize;
     382           0 :         maPrevRect.Bottom() = maPrevRect.Top()+nSpinSize;
     383           0 :         maNextRect.Left()   = aOutSize.Width()-SPIN_OFFX-nSpinSize-1;
     384           0 :         maNextRect.Top()    = SPIN_OFFY;
     385           0 :         maNextRect.Right()  = maNextRect.Left()+nSpinSize;
     386           0 :         maNextRect.Bottom() = maNextRect.Top()+nSpinSize;
     387             : 
     388           0 :         if ( mnWinStyle & WB_BOLDTEXT )
     389           0 :             SetFont( aOldFont );
     390             : 
     391             :         // Calculate DayOfWeekText (gets displayed in a narrow font)
     392           0 :         maDayOfWeekText.clear();
     393           0 :         long nStartOffX = 0;
     394           0 :         sal_Int16 nDay = maCalendarWrapper.getFirstDayOfWeek();
     395           0 :         for ( sal_Int16 nDayOfWeek = 0; nDayOfWeek < 7; nDayOfWeek++ )
     396             :         {
     397             :             // Use narrow name.
     398             :             OUString aDayOfWeek( maCalendarWrapper.getDisplayName(
     399           0 :                         i18n::CalendarDisplayIndex::DAY, nDay, 2));
     400           0 :             long nOffX = (mnDayWidth-GetTextWidth( aDayOfWeek ))/2;
     401           0 :             if ( mnWinStyle & WB_BOLDTEXT )
     402           0 :                 nOffX++;
     403           0 :             if ( !nDayOfWeek )
     404           0 :                 nStartOffX = nOffX;
     405             :             else
     406           0 :                 nOffX -= nStartOffX;
     407           0 :             nOffX += nDayOfWeek * mnDayWidth;
     408           0 :             mnDayOfWeekAry[nDayOfWeek] = nOffX;
     409           0 :             maDayOfWeekText += aDayOfWeek;
     410           0 :             nDay++;
     411           0 :             nDay %= 7;
     412           0 :         }
     413             : 
     414           0 :         mbCalc = false;
     415             :     }
     416             : 
     417             :     // calculate number of days
     418             : 
     419           0 :     DayOfWeek eStartDay = ImplGetWeekStart();
     420             : 
     421             :     sal_uInt16 nWeekDay;
     422           0 :     Date aTempDate = GetFirstMonth();
     423           0 :     maFirstDate = aTempDate;
     424           0 :     nWeekDay = (sal_uInt16)aTempDate.GetDayOfWeek();
     425           0 :     nWeekDay = (nWeekDay+(7-(sal_uInt16)eStartDay)) % 7;
     426           0 :     maFirstDate -= (sal_uLong)nWeekDay;
     427           0 :     mnDayCount = nWeekDay;
     428             :     sal_uInt16 nDaysInMonth;
     429           0 :     sal_uInt16 nMonthCount = (sal_uInt16)(mnMonthPerLine*mnLines);
     430           0 :     for ( sal_uInt16 i = 0; i < nMonthCount; i++ )
     431             :     {
     432           0 :         nDaysInMonth = aTempDate.GetDaysInMonth();
     433           0 :         mnDayCount += nDaysInMonth;
     434           0 :         aTempDate += nDaysInMonth;
     435             :     }
     436           0 :     Date aTempDate2 = aTempDate;
     437           0 :     --aTempDate2;
     438           0 :     nDaysInMonth = aTempDate2.GetDaysInMonth();
     439           0 :     aTempDate2 -= nDaysInMonth-1;
     440           0 :     nWeekDay = (sal_uInt16)aTempDate2.GetDayOfWeek();
     441           0 :     nWeekDay = (nWeekDay+(7-(sal_uInt16)eStartDay)) % 7;
     442           0 :     mnDayCount += 42-nDaysInMonth-nWeekDay;
     443             : 
     444             :     // determine colours
     445           0 :     maOtherColor = Color( COL_LIGHTGRAY );
     446           0 :     if ( maOtherColor.IsRGBEqual( GetBackground().GetColor() ) )
     447           0 :         maOtherColor.SetColor( COL_GRAY );
     448             : 
     449           0 :     Date aLastDate = GetLastDate();
     450           0 :     if ( (maOldFormatLastDate != aLastDate) ||
     451           0 :          (maOldFormatFirstDate != maFirstDate) )
     452             :     {
     453           0 :         maOldFormatFirstDate = maFirstDate;
     454           0 :         maOldFormatLastDate  = aLastDate;
     455           0 :         DateRangeChanged();
     456             :     }
     457             : 
     458             :     // get DateInfo
     459           0 :     sal_uInt16 nNewFirstYear = maFirstDate.GetYear();
     460           0 :     sal_uInt16 nNewLastYear = GetLastDate().GetYear();
     461           0 :     if ( mnFirstYear )
     462             :     {
     463           0 :         if ( nNewFirstYear < mnFirstYear )
     464             :         {
     465           0 :             for ( mnRequestYear = nNewFirstYear; mnRequestYear < mnFirstYear; mnRequestYear++ )
     466           0 :                 RequestDateInfo();
     467           0 :             mnFirstYear = nNewFirstYear;
     468             :         }
     469           0 :         if ( nNewLastYear > mnLastYear )
     470             :         {
     471           0 :             for ( mnRequestYear = mnLastYear; mnRequestYear < nNewLastYear; mnRequestYear++ )
     472           0 :                 RequestDateInfo();
     473           0 :             mnLastYear = nNewLastYear;
     474             :         }
     475             :     }
     476             :     else
     477             :     {
     478           0 :         for ( mnRequestYear = nNewFirstYear; mnRequestYear < nNewLastYear; mnRequestYear++ )
     479           0 :             RequestDateInfo();
     480           0 :         mnFirstYear = nNewFirstYear;
     481           0 :         mnLastYear = nNewLastYear;
     482             :     }
     483           0 :     mnRequestYear = 0;
     484             : 
     485           0 :     mbFormat = false;
     486             : }
     487             : 
     488           0 : sal_uInt16 Calendar::ImplHitTest( const Point& rPos, Date& rDate ) const
     489             : {
     490           0 :     if ( mbFormat )
     491           0 :         return 0;
     492             : 
     493           0 :     if ( maPrevRect.IsInside( rPos ) )
     494           0 :         return CALENDAR_HITTEST_PREV;
     495           0 :     else if ( maNextRect.IsInside( rPos ) )
     496           0 :         return CALENDAR_HITTEST_NEXT;
     497             : 
     498             :     long        nY;
     499             :     long        nOffX;
     500             :     sal_uInt16      nDay;
     501           0 :     DayOfWeek   eStartDay = ImplGetWeekStart();
     502             : 
     503           0 :     rDate = GetFirstMonth();
     504           0 :     nY = 0;
     505           0 :     for ( long i = 0; i < mnLines; i++ )
     506             :     {
     507           0 :         if ( rPos.Y() < nY )
     508           0 :             return 0;
     509             : 
     510           0 :         long nX = 0;
     511           0 :         long nYMonth = nY+mnMonthHeight;
     512           0 :         for ( long j = 0; j < mnMonthPerLine; j++ )
     513             :         {
     514           0 :             if ( (rPos.X() < nX) && (rPos.Y() < nYMonth) )
     515           0 :                 return 0;
     516             : 
     517           0 :             sal_uInt16 nDaysInMonth = rDate.GetDaysInMonth();
     518             : 
     519             :             // matching month was found
     520           0 :             if ( (rPos.X() > nX) && (rPos.Y() < nYMonth) &&
     521           0 :                  (rPos.X() < nX+mnMonthWidth) )
     522             :             {
     523           0 :                 if ( rPos.Y() < (nY+(TITLE_BORDERY*2)+mnDayHeight))
     524           0 :                     return CALENDAR_HITTEST_MONTHTITLE;
     525             :                 else
     526             :                 {
     527           0 :                     long nDayX = nX+mnDaysOffX;
     528           0 :                     long nDayY = nY+mnDaysOffY;
     529           0 :                     if ( rPos.Y() < nDayY )
     530           0 :                         return 0;
     531           0 :                     sal_uInt16 nDayIndex = (sal_uInt16)rDate.GetDayOfWeek();
     532           0 :                     nDayIndex = (nDayIndex+(7-(sal_uInt16)eStartDay)) % 7;
     533           0 :                     if ( (i == 0) && (j == 0) )
     534             :                     {
     535           0 :                         Date aTempDate = rDate;
     536           0 :                         aTempDate -= nDayIndex;
     537           0 :                         for ( nDay = 0; nDay < nDayIndex; nDay++ )
     538             :                         {
     539           0 :                             nOffX = nDayX + (nDay*mnDayWidth);
     540           0 :                             if ( (rPos.Y() >= nDayY) && (rPos.Y() < nDayY+mnDayHeight) &&
     541           0 :                                  (rPos.X() >= nOffX) && (rPos.X() < nOffX+mnDayWidth) )
     542             :                             {
     543           0 :                                 rDate = aTempDate;
     544           0 :                                 rDate += nDay;
     545           0 :                                 return CALENDAR_HITTEST_DAY;
     546             :                             }
     547             :                         }
     548             :                     }
     549           0 :                     for ( nDay = 1; nDay <= nDaysInMonth; nDay++ )
     550             :                     {
     551           0 :                         if ( rPos.Y() < nDayY )
     552             :                         {
     553           0 :                             rDate += nDayIndex;
     554           0 :                             return 0;
     555             :                         }
     556           0 :                         nOffX = nDayX + (nDayIndex*mnDayWidth);
     557           0 :                         if ( (rPos.Y() >= nDayY) && (rPos.Y() < nDayY+mnDayHeight) &&
     558           0 :                              (rPos.X() >= nOffX) && (rPos.X() < nOffX+mnDayWidth) )
     559             :                         {
     560           0 :                             rDate += nDay-1;
     561           0 :                             return CALENDAR_HITTEST_DAY;
     562             :                         }
     563           0 :                         if ( nDayIndex == 6 )
     564             :                         {
     565           0 :                             nDayIndex = 0;
     566           0 :                             nDayY += mnDayHeight;
     567             :                         }
     568             :                         else
     569           0 :                             nDayIndex++;
     570             :                     }
     571           0 :                     if ( (i == mnLines-1) && (j == mnMonthPerLine-1) )
     572             :                     {
     573           0 :                         sal_uInt16 nWeekDay = (sal_uInt16)rDate.GetDayOfWeek();
     574           0 :                         nWeekDay = (nWeekDay+(7-(sal_uInt16)eStartDay)) % 7;
     575           0 :                         sal_uInt16 nDayCount = 42-nDaysInMonth-nWeekDay;
     576           0 :                         Date aTempDate = rDate;
     577           0 :                         aTempDate += nDaysInMonth;
     578           0 :                         for ( nDay = 1; nDay <= nDayCount; nDay++ )
     579             :                         {
     580           0 :                             if ( rPos.Y() < nDayY )
     581             :                             {
     582           0 :                                 rDate += nDayIndex;
     583           0 :                                 return 0;
     584             :                             }
     585           0 :                             nOffX = nDayX + (nDayIndex*mnDayWidth);
     586           0 :                             if ( (rPos.Y() >= nDayY) && (rPos.Y() < nDayY+mnDayHeight) &&
     587           0 :                                  (rPos.X() >= nOffX) && (rPos.X() < nOffX+mnDayWidth) )
     588             :                             {
     589           0 :                                 rDate = aTempDate;
     590           0 :                                 rDate += nDay-1;
     591           0 :                                 return CALENDAR_HITTEST_DAY;
     592             :                             }
     593           0 :                             if ( nDayIndex == 6 )
     594             :                             {
     595           0 :                                 nDayIndex = 0;
     596           0 :                                 nDayY += mnDayHeight;
     597             :                             }
     598             :                             else
     599           0 :                                 nDayIndex++;
     600             :                         }
     601             :                     }
     602             :                 }
     603             :             }
     604             : 
     605           0 :             rDate += nDaysInMonth;
     606           0 :             nX += mnMonthWidth;
     607             :         }
     608             : 
     609           0 :         nY += mnMonthHeight;
     610             :     }
     611             : 
     612           0 :     return 0;
     613             : }
     614             : 
     615             : namespace
     616             : {
     617             : 
     618           0 : static void ImplDrawSpinArrow(vcl::RenderContext& rRenderContext, const Rectangle& rRect, bool bPrev)
     619             : {
     620             :     long i;
     621             :     long n;
     622             :     long nLines;
     623           0 :     long nHeight = rRect.GetHeight();
     624           0 :     long nWidth = rRect.GetWidth();
     625           0 :     if (nWidth < nHeight)
     626           0 :         n = nWidth;
     627             :     else
     628           0 :         n = nHeight;
     629           0 :     if (!(n & 0x01))
     630           0 :         n--;
     631           0 :     nLines = n/2;
     632             : 
     633           0 :     Rectangle aRect(Point( rRect.Left() + (nWidth / 2) - (nLines / 2),
     634           0 :                             rRect.Top() + (nHeight / 2) ),
     635           0 :                      Size(1, 1));
     636           0 :     if (!bPrev)
     637             :     {
     638           0 :         aRect.Left()  += nLines;
     639           0 :         aRect.Right() += nLines;
     640             :     }
     641             : 
     642           0 :     rRenderContext.DrawRect(aRect);
     643           0 :     for (i = 0; i < nLines; i++)
     644             :     {
     645           0 :         if (bPrev)
     646             :         {
     647           0 :             aRect.Left()++;
     648           0 :             aRect.Right()++;
     649             :         }
     650             :         else
     651             :         {
     652           0 :             aRect.Left()--;
     653           0 :             aRect.Right()--;
     654             :         }
     655           0 :         aRect.Top()--;
     656           0 :         aRect.Bottom()++;
     657           0 :         rRenderContext.DrawRect(aRect);
     658             :     }
     659           0 : }
     660             : 
     661             : } //end anonymous namespace
     662             : 
     663           0 : void Calendar::ImplDrawSpin(vcl::RenderContext& rRenderContext, bool bDrawPrev, bool bDrawNext )
     664             : {
     665           0 :     if (!bDrawPrev && !bDrawNext)
     666           0 :         return;
     667             : 
     668           0 :     rRenderContext.SetLineColor();
     669           0 :     rRenderContext.SetFillColor(rRenderContext.GetSettings().GetStyleSettings().GetButtonTextColor());
     670           0 :     if (bDrawPrev)
     671             :     {
     672           0 :         Rectangle aOutRect = maPrevRect;
     673           0 :         aOutRect.Left()   += 3;
     674           0 :         aOutRect.Top()    += 3;
     675           0 :         aOutRect.Right()  -= 3;
     676           0 :         aOutRect.Bottom() -= 3;
     677           0 :         ImplDrawSpinArrow(rRenderContext, aOutRect, true);
     678             :     }
     679           0 :     if (bDrawNext)
     680             :     {
     681           0 :         Rectangle aOutRect = maNextRect;
     682           0 :         aOutRect.Left()   += 3;
     683           0 :         aOutRect.Top()    += 3;
     684           0 :         aOutRect.Right()  -= 3;
     685           0 :         aOutRect.Bottom() -= 3;
     686           0 :         ImplDrawSpinArrow(rRenderContext, aOutRect, false);
     687             :     }
     688             : }
     689             : 
     690           0 : void Calendar::ImplDrawDate(vcl::RenderContext& rRenderContext,
     691             :                             long nX, long nY,
     692             :                             sal_uInt16 nDay, sal_uInt16 nMonth, sal_uInt16 nYear,
     693             :                             DayOfWeek eDayOfWeek,
     694             :                             bool bBack, bool bOther, sal_uLong nToday )
     695             : {
     696           0 :     Color* pTextColor = NULL;
     697           0 :     const OUString& rDay = maDayTexts[nDay - 1];
     698           0 :     Rectangle aDateRect(nX, nY, nX + mnDayWidth - 1, nY + mnDayHeight - 1);
     699             : 
     700           0 :     bool bSel = false;
     701           0 :     bool bFocus = false;
     702             :     // actual day
     703           0 :     if ((nDay   == maCurDate.GetDay()) &&
     704           0 :         (nMonth == maCurDate.GetMonth()) &&
     705           0 :         (nYear  == maCurDate.GetYear()))
     706             :     {
     707           0 :         bFocus = true;
     708             :     }
     709           0 :     if (mpSelectTable)
     710             :     {
     711           0 :         if (mpSelectTable->find(Date(nDay, nMonth, nYear).GetDate()) != mpSelectTable->end())
     712           0 :             bSel = true;
     713             :     }
     714             : 
     715             :     // get textcolour
     716           0 :     if (bSel)
     717           0 :         pTextColor = &maSelColor;
     718           0 :     else if (bOther)
     719           0 :         pTextColor = &maOtherColor;
     720             :     else
     721             :     {
     722           0 :         if (eDayOfWeek == SATURDAY)
     723           0 :             pTextColor = mpSaturdayColor;
     724           0 :         else if (eDayOfWeek == SUNDAY)
     725           0 :             pTextColor = mpSundayColor;
     726           0 :         if (!pTextColor)
     727           0 :             pTextColor = mpStandardColor;
     728             :     }
     729             : 
     730           0 :     if (bFocus)
     731           0 :         HideFocus();
     732             : 
     733             :     // display background
     734           0 :     const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
     735           0 :     if (bSel || bBack)
     736             :     {
     737           0 :         if (bSel)
     738             :         {
     739           0 :             rRenderContext.SetLineColor();
     740           0 :             rRenderContext.SetFillColor(rStyleSettings.GetHighlightColor());
     741           0 :             rRenderContext.DrawRect(aDateRect);
     742             :         }
     743             :         else
     744           0 :             rRenderContext.Erase(aDateRect);
     745             :     }
     746             : 
     747             :     // display text
     748           0 :     long nTextX = nX + (mnDayWidth - GetTextWidth(rDay)) - (DAY_OFFX / 2);
     749           0 :     long nTextY = nY + (mnDayHeight - GetTextHeight()) / 2;
     750           0 :     if (pTextColor)
     751             :     {
     752           0 :         Color aOldColor = rRenderContext.GetTextColor();
     753           0 :         rRenderContext.SetTextColor(*pTextColor);
     754           0 :         rRenderContext.DrawText(Point(nTextX, nTextY), rDay);
     755           0 :         rRenderContext.SetTextColor(aOldColor);
     756             :     }
     757             :     else
     758           0 :         rRenderContext.DrawText(Point(nTextX, nTextY), rDay);
     759             : 
     760             :     // today
     761           0 :     Date aTodayDate(maCurDate);
     762           0 :     if (nToday)
     763           0 :         aTodayDate.SetDate(nToday);
     764             :     else
     765           0 :         aTodayDate = Date(Date::SYSTEM);
     766           0 :     if ((nDay   == aTodayDate.GetDay()) &&
     767           0 :         (nMonth == aTodayDate.GetMonth()) &&
     768           0 :         (nYear  == aTodayDate.GetYear()))
     769             :     {
     770           0 :         rRenderContext.SetLineColor(rStyleSettings.GetWindowTextColor());
     771           0 :         rRenderContext.SetFillColor();
     772           0 :         rRenderContext.DrawRect(aDateRect);
     773             :     }
     774             : 
     775             :     // if needed do FocusRect
     776           0 :     if (bFocus && HasFocus())
     777           0 :         ShowFocus(aDateRect);
     778             : 
     779           0 :     if (mbDropPos && maDropDate == Date(nDay, nMonth, nYear))
     780           0 :         ImplInvertDropPos();
     781           0 : }
     782             : 
     783           0 : void Calendar::ImplDraw(vcl::RenderContext& rRenderContext, bool bPaint)
     784             : {
     785           0 :     ImplFormat();
     786             : 
     787           0 :     const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
     788           0 :     Size aOutSize = rRenderContext.GetOutputSizePixel();
     789             :     long i;
     790             :     long j;
     791             :     long nY;
     792             :     long nDeltaX;
     793             :     long nDeltaY;
     794             :     long nDayX;
     795             :     long nDayY;
     796           0 :     sal_uLong nToday = Date(Date::SYSTEM).GetDate();
     797             :     sal_uInt16 nDay;
     798             :     sal_uInt16 nMonth;
     799             :     sal_uInt16 nYear;
     800           0 :     Date aDate = GetFirstMonth();
     801           0 :     DayOfWeek eStartDay = ImplGetWeekStart();
     802             : 
     803           0 :     HideFocus();
     804             : 
     805           0 :     nY = 0;
     806           0 :     for (i = 0; i < mnLines; i++)
     807             :     {
     808             :         // display title bar
     809           0 :         rRenderContext.SetLineColor();
     810           0 :         rRenderContext.SetFillColor(rStyleSettings.GetFaceColor());
     811           0 :         Rectangle aTitleRect(0, nY, aOutSize.Width() - 1, nY + mnDayHeight - DAY_OFFY + TITLE_BORDERY * 2);
     812           0 :         if (!bPaint)
     813             :         {
     814           0 :             Rectangle aTempRect(1, aTitleRect.Top() + TITLE_BORDERY,
     815           0 :                                 aOutSize.Width() - 2,
     816           0 :                                 aTitleRect.Bottom() - TITLE_BORDERY);
     817           0 :             if (!i)
     818             :             {
     819           0 :                 aTempRect.Left()  = maPrevRect.Right() + 1;
     820           0 :                 aTempRect.Right() = maNextRect.Left() - 1;
     821             :             }
     822           0 :             rRenderContext.DrawRect(aTempRect);
     823             :         }
     824             :         else
     825             :         {
     826           0 :             rRenderContext.DrawRect(aTitleRect);
     827           0 :             Point aTopLeft1(aTitleRect.Left(), aTitleRect.Top());
     828           0 :             Point aTopLeft2(aTitleRect.Left(), aTitleRect.Top() + 1);
     829           0 :             Point aBottomRight1(aTitleRect.Right(), aTitleRect.Bottom());
     830           0 :             Point aBottomRight2(aTitleRect.Right(), aTitleRect.Bottom() - 1);
     831           0 :             rRenderContext.SetLineColor(rStyleSettings.GetDarkShadowColor());
     832           0 :             rRenderContext.DrawLine(aTopLeft1, Point(aBottomRight1.X(), aTopLeft1.Y()));
     833           0 :             rRenderContext.SetLineColor(rStyleSettings.GetLightColor() );
     834           0 :             rRenderContext.DrawLine(aTopLeft2, Point(aBottomRight2.X(), aTopLeft2.Y()));
     835           0 :             rRenderContext.DrawLine(aTopLeft2, Point(aTopLeft2.X(), aBottomRight2.Y()));
     836           0 :             rRenderContext.SetLineColor(rStyleSettings.GetShadowColor() );
     837           0 :             rRenderContext.DrawLine(Point(aTopLeft2.X(), aBottomRight2.Y()), aBottomRight2);
     838           0 :             rRenderContext.DrawLine(Point(aBottomRight2.X(), aTopLeft2.Y()), aBottomRight2);
     839           0 :             rRenderContext.SetLineColor(rStyleSettings.GetDarkShadowColor());
     840           0 :             rRenderContext.DrawLine(Point(aTopLeft1.X(), aBottomRight1.Y()), aBottomRight1);
     841             :         }
     842           0 :         Point aSepPos1(0, aTitleRect.Top() + TITLE_BORDERY);
     843           0 :         Point aSepPos2(0, aTitleRect.Bottom() - TITLE_BORDERY);
     844           0 :         for (j = 0; j < mnMonthPerLine-1; j++)
     845             :         {
     846           0 :             aSepPos1.X() += mnMonthWidth-1;
     847           0 :             aSepPos2.X() = aSepPos1.X();
     848           0 :             rRenderContext.SetLineColor(rStyleSettings.GetShadowColor());
     849           0 :             rRenderContext.DrawLine(aSepPos1, aSepPos2);
     850           0 :             aSepPos1.X()++;
     851           0 :             aSepPos2.X() = aSepPos1.X();
     852           0 :             rRenderContext.SetLineColor(rStyleSettings.GetLightColor());
     853           0 :             rRenderContext.DrawLine(aSepPos1, aSepPos2);
     854             :         }
     855             : 
     856           0 :         long nX = 0;
     857           0 :         for (j = 0; j < mnMonthPerLine; j++)
     858             :         {
     859           0 :             nMonth  = aDate.GetMonth();
     860           0 :             nYear   = aDate.GetYear();
     861             : 
     862             :             // display month in title bar
     863           0 :             nDeltaX = nX;
     864           0 :             nDeltaY = nY + TITLE_BORDERY;
     865           0 :             OUString aMonthText(maCalendarWrapper.getDisplayName(i18n::CalendarDisplayIndex::MONTH, nMonth - 1, 1));
     866           0 :             aMonthText += " ";
     867           0 :             aMonthText += OUString::number(nYear);
     868           0 :             long nMonthTextWidth = rRenderContext.GetTextWidth(aMonthText);
     869           0 :             long nMonthOffX1 = 0;
     870           0 :             long nMonthOffX2 = 0;
     871           0 :             if (i == 0)
     872             :             {
     873           0 :                 if (j == 0)
     874           0 :                     nMonthOffX1 = maPrevRect.Right() + 1;
     875           0 :                 if (j == mnMonthPerLine - 1)
     876           0 :                     nMonthOffX2 = aOutSize.Width() - maNextRect.Left() + 1;
     877             :             }
     878           0 :             long nMaxMonthWidth = mnMonthWidth - nMonthOffX1 - nMonthOffX2 - 4;
     879           0 :             if (nMonthTextWidth > nMaxMonthWidth)
     880             :             {
     881             :                 // Abbreviated month name.
     882           0 :                 aMonthText  = maCalendarWrapper.getDisplayName(i18n::CalendarDisplayIndex::MONTH, nMonth - 1, 0);
     883           0 :                 aMonthText += " ";
     884           0 :                 aMonthText += OUString::number(nYear);
     885           0 :                 nMonthTextWidth = rRenderContext.GetTextWidth(aMonthText);
     886             :             }
     887           0 :             long nTempOff = (mnMonthWidth - nMonthTextWidth + 1) / 2;
     888           0 :             if (nTempOff < nMonthOffX1)
     889           0 :                 nDeltaX += nMonthOffX1 + 1;
     890             :             else
     891             :             {
     892           0 :                 if (nTempOff + nMonthTextWidth > mnMonthWidth - nMonthOffX2)
     893           0 :                     nDeltaX += mnMonthWidth - nMonthOffX2 - nMonthTextWidth;
     894             :                 else
     895           0 :                     nDeltaX += nTempOff;
     896             :             }
     897           0 :             rRenderContext.SetTextColor(rStyleSettings.GetButtonTextColor());
     898           0 :             rRenderContext.DrawText(Point(nDeltaX, nDeltaY), aMonthText);
     899           0 :             rRenderContext.SetTextColor(rStyleSettings.GetWindowTextColor());
     900             : 
     901             :             // display week bar
     902           0 :             if (bPaint)
     903             :             {
     904           0 :                 nDayX = nX + mnDaysOffX;
     905           0 :                 nDayY = nY + mnWeekDayOffY;
     906           0 :                 nDeltaY = nDayY + mnDayHeight;
     907           0 :                 rRenderContext.SetLineColor(rStyleSettings.GetWindowTextColor());
     908           0 :                 Point aStartPos(nDayX, nDeltaY);
     909           0 :                 if (mnWinStyle & WB_WEEKNUMBER)
     910           0 :                     aStartPos.X() -= WEEKNUMBER_OFFX - 2;
     911           0 :                 rRenderContext.DrawLine(aStartPos, Point(nDayX + (7 * mnDayWidth), nDeltaY));
     912           0 :                 rRenderContext.DrawTextArray(Point(nDayX + mnDayOfWeekAry[0], nDayY), maDayOfWeekText, &(mnDayOfWeekAry[1]));
     913             :             }
     914             : 
     915             :             // display weeknumbers
     916           0 :             if (mnWinStyle & WB_WEEKNUMBER)
     917             :             {
     918           0 :                 nDayX = nX + mnDaysOffX;
     919           0 :                 nDayY = nY + mnWeekDayOffY;
     920           0 :                 nDeltaY = nDayY + mnDayHeight;
     921           0 :                 long nMonthHeight = mnDayHeight * 6;
     922           0 :                 if (bPaint)
     923             :                 {
     924             :                     rRenderContext.DrawLine(Point(nDayX - WEEKNUMBER_OFFX + 2, nDeltaY),
     925           0 :                                             Point(nDayX - WEEKNUMBER_OFFX + 2, nDeltaY + nMonthHeight));
     926             :                 }
     927             :                 else
     928             :                 {
     929           0 :                     rRenderContext.Erase(Rectangle(nDayX - mnWeekWidth - WEEKNUMBER_OFFX, nDeltaY,
     930           0 :                                                    nDayX - WEEKNUMBER_OFFX - 1, nDeltaY + nMonthHeight));
     931             :                 }
     932           0 :                 vcl::Font aOldFont = rRenderContext.GetFont();
     933           0 :                 vcl::Font aTempFont = aOldFont;
     934           0 :                 ImplGetWeekFont(aTempFont);
     935           0 :                 rRenderContext.SetFont(aTempFont);
     936           0 :                 nDayX -= mnWeekWidth;
     937           0 :                 nDayY = nY + mnDaysOffY;
     938           0 :                 maCalendarWrapper.setGregorianDateTime(aDate);
     939           0 :                 for (sal_uInt16 nWeekCount = 0; nWeekCount < 6; ++nWeekCount)
     940             :                 {
     941           0 :                     sal_Int32 nWeek = maCalendarWrapper.getValue(i18n::CalendarFieldIndex::WEEK_OF_YEAR);
     942           0 :                     OUString aWeekText(OUString::number(nWeek));
     943           0 :                     long nOffX = (mnWeekWidth - WEEKNUMBER_OFFX) - rRenderContext.GetTextWidth(aWeekText);
     944           0 :                     long nOffY = (mnDayHeight - GetTextHeight()) / 2;
     945           0 :                     rRenderContext.DrawText(Point(nDayX + nOffX, nDayY + nOffY), aWeekText);
     946           0 :                     nDayY += mnDayHeight;
     947           0 :                     maCalendarWrapper.addValue(i18n::CalendarFieldIndex::DAY_OF_MONTH, 7);
     948           0 :                 }
     949           0 :                 rRenderContext.SetFont(aOldFont);
     950             :             }
     951             : 
     952             :             // display days
     953           0 :             sal_uInt16 nDaysInMonth = aDate.GetDaysInMonth();
     954           0 :             nDayX = nX + mnDaysOffX;
     955           0 :             nDayY = nY + mnDaysOffY;
     956           0 :             if (!bPaint)
     957             :             {
     958             :                 Rectangle aClearRect(nDayX, nDayY,
     959           0 :                                      nDayX + (7 * mnDayWidth) - 1, nDayY + (6 * mnDayHeight) - 1);
     960           0 :                 rRenderContext.Erase(aClearRect);
     961             :             }
     962           0 :             sal_uInt16 nDayIndex = (sal_uInt16) aDate.GetDayOfWeek();
     963           0 :             nDayIndex = (nDayIndex + (7 - (sal_uInt16)eStartDay)) % 7;
     964           0 :             if (i == 0 && j == 0)
     965             :             {
     966           0 :                 Date aTempDate = aDate;
     967           0 :                 aTempDate -= nDayIndex;
     968           0 :                 for (nDay = 0; nDay < nDayIndex; ++nDay)
     969             :                 {
     970           0 :                     nDeltaX = nDayX + (nDay * mnDayWidth);
     971           0 :                     ImplDrawDate(rRenderContext, nDeltaX, nDayY, nDay + aTempDate.GetDay(),
     972           0 :                                  aTempDate.GetMonth(), aTempDate.GetYear(),
     973           0 :                                  (DayOfWeek)((nDay + (sal_uInt16)eStartDay) % 7), false, true, nToday);
     974             :                 }
     975             :             }
     976           0 :             for (nDay = 1; nDay <= nDaysInMonth; nDay++)
     977             :             {
     978           0 :                 nDeltaX = nDayX + (nDayIndex * mnDayWidth);
     979             :                 ImplDrawDate(rRenderContext, nDeltaX, nDayY, nDay, nMonth, nYear,
     980           0 :                              (DayOfWeek)((nDayIndex + (sal_uInt16)eStartDay) % 7),
     981           0 :                              false, false, nToday);
     982           0 :                 if (nDayIndex == 6)
     983             :                 {
     984           0 :                     nDayIndex = 0;
     985           0 :                     nDayY += mnDayHeight;
     986             :                 }
     987             :                 else
     988           0 :                     nDayIndex++;
     989             :             }
     990           0 :             if ((i == mnLines - 1) && (j == mnMonthPerLine - 1))
     991             :             {
     992           0 :                 sal_uInt16 nWeekDay = (sal_uInt16)aDate.GetDayOfWeek();
     993           0 :                 nWeekDay = (nWeekDay + (7 - (sal_uInt16)eStartDay)) % 7;
     994           0 :                 sal_uInt16 nDayCount = 42 - nDaysInMonth - nWeekDay;
     995           0 :                 Date aTempDate = aDate;
     996           0 :                 aTempDate += nDaysInMonth;
     997           0 :                 for (nDay = 1; nDay <= nDayCount; ++nDay)
     998             :                 {
     999           0 :                     nDeltaX = nDayX + (nDayIndex * mnDayWidth);
    1000             :                     ImplDrawDate(rRenderContext, nDeltaX, nDayY, nDay,
    1001           0 :                                  aTempDate.GetMonth(), aTempDate.GetYear(),
    1002           0 :                                  (DayOfWeek)((nDayIndex + (sal_uInt16)eStartDay) % 7),
    1003           0 :                                  false, true, nToday);
    1004           0 :                     if (nDayIndex == 6)
    1005             :                     {
    1006           0 :                         nDayIndex = 0;
    1007           0 :                         nDayY += mnDayHeight;
    1008             :                     }
    1009             :                     else
    1010           0 :                         nDayIndex++;
    1011             :                 }
    1012             :             }
    1013             : 
    1014           0 :             aDate += nDaysInMonth;
    1015           0 :             nX += mnMonthWidth;
    1016           0 :         }
    1017             : 
    1018           0 :         nY += mnMonthHeight;
    1019             :     }
    1020             : 
    1021             :     // draw spin buttons
    1022           0 :     if (bPaint)
    1023           0 :         ImplDrawSpin(rRenderContext);
    1024           0 : }
    1025             : 
    1026           0 : void Calendar::ImplUpdateDate( const Date& rDate )
    1027             : {
    1028           0 :     if (IsReallyVisible() && IsUpdateMode())
    1029             :     {
    1030           0 :         Rectangle aDateRect(GetDateRect(rDate));
    1031           0 :         if (!aDateRect.IsEmpty())
    1032             :         {
    1033           0 :             Invalidate(aDateRect);
    1034             :         }
    1035             :     }
    1036           0 : }
    1037             : 
    1038           0 : void Calendar::ImplUpdateSelection( IntDateSet* pOld )
    1039             : {
    1040           0 :     IntDateSet*  pNew = mpSelectTable;
    1041             : 
    1042           0 :     for ( IntDateSet::const_iterator it = pOld->begin(); it != pOld->end(); ++it )
    1043             :     {
    1044           0 :         sal_uLong nKey = *it;
    1045           0 :         if ( pNew->find( nKey ) == pNew->end() )
    1046             :         {
    1047           0 :             Date aTempDate( nKey );
    1048           0 :             ImplUpdateDate( aTempDate );
    1049             :         }
    1050             :     }
    1051             : 
    1052           0 :     for ( IntDateSet::const_iterator it = pNew->begin(); it != pNew->end(); ++it )
    1053             :     {
    1054           0 :         sal_uLong nKey = *it;
    1055           0 :         if ( pOld->find( nKey ) == pOld->end() )
    1056             :         {
    1057           0 :             Date aTempDate( nKey );
    1058           0 :             ImplUpdateDate( aTempDate );
    1059             :         }
    1060             :     }
    1061           0 : }
    1062             : 
    1063           0 : void Calendar::ImplMouseSelect( const Date& rDate, sal_uInt16 nHitTest,
    1064             :                                 bool bMove, bool bExpand, bool bExtended )
    1065             : {
    1066           0 :     boost::scoped_ptr<IntDateSet> pOldSel(new IntDateSet( *mpSelectTable ));
    1067           0 :     Date    aOldDate = maCurDate;
    1068           0 :     Date    aTempDate = rDate;
    1069             : 
    1070           0 :     if ( !(nHitTest & CALENDAR_HITTEST_DAY) )
    1071           0 :         --aTempDate;
    1072             : 
    1073           0 :     if ( mbMultiSelection )
    1074             :     {
    1075           0 :         maCurDate = aTempDate;
    1076           0 :         mbSelLeft = aTempDate < maAnchorDate;
    1077             : 
    1078           0 :         if ( bMove )
    1079             :         {
    1080           0 :             if ( mbSelLeft )
    1081             :             {
    1082           0 :                 ImplCalendarUnSelectDateRange( mpSelectTable, mpRestoreSelectTable, Date( 1, 1, 0 ), aTempDate );
    1083           0 :                 ImplCalendarUnSelectDateRange( mpSelectTable, mpRestoreSelectTable, maAnchorDate, Date( 31, 12, 9999 ) );
    1084             :             }
    1085             :             else
    1086             :             {
    1087           0 :                 ImplCalendarUnSelectDateRange( mpSelectTable, mpRestoreSelectTable, Date( 1, 1, 0 ), maAnchorDate );
    1088           0 :                 ImplCalendarUnSelectDateRange( mpSelectTable, mpRestoreSelectTable, aTempDate, Date( 31, 12, 9999 ) );
    1089             :             }
    1090           0 :             ImplCalendarSelectDateRange( mpSelectTable, aTempDate, maAnchorDate, !mbUnSel );
    1091             :         }
    1092             :         else
    1093             :         {
    1094           0 :             if ( bExpand )
    1095             :             {
    1096           0 :                 if ( !bExtended )
    1097             :                 {
    1098           0 :                     if ( mbSelLeft )
    1099             :                     {
    1100           0 :                         ImplCalendarSelectDateRange( mpSelectTable, Date( 1, 1, 0 ), aTempDate, false );
    1101           0 :                         ImplCalendarSelectDateRange( mpSelectTable, maAnchorDate, Date( 31, 12, 9999 ), false );
    1102             :                     }
    1103             :                     else
    1104             :                     {
    1105           0 :                         ImplCalendarSelectDateRange( mpSelectTable, Date( 1, 1, 0 ), maAnchorDate, false );
    1106           0 :                         ImplCalendarSelectDateRange( mpSelectTable, aTempDate, Date( 31, 12, 9999 ), false );
    1107             :                     }
    1108             :                 }
    1109           0 :                 ImplCalendarSelectDateRange( mpSelectTable, aTempDate, maAnchorDate, true );
    1110             :             }
    1111           0 :             else if ( bExtended && !(mnWinStyle & WB_RANGESELECT) )
    1112             :             {
    1113           0 :                 maAnchorDate = aTempDate;
    1114           0 :                 if ( IsDateSelected( aTempDate ) )
    1115             :                 {
    1116           0 :                     mbUnSel = true;
    1117           0 :                     ImplCalendarSelectDate( mpSelectTable, aTempDate, false );
    1118             :                 }
    1119             :                 else
    1120             :                 {
    1121           0 :                     ImplCalendarSelectDate( mpSelectTable, aTempDate, true );
    1122             :                 }
    1123             :             }
    1124             :             else
    1125             :             {
    1126           0 :                 maAnchorDate = aTempDate;
    1127           0 :                 ImplCalendarClearSelectDate( mpSelectTable );
    1128           0 :                 ImplCalendarSelectDate( mpSelectTable, aTempDate, true );
    1129             :             }
    1130             : 
    1131           0 :             mpRestoreSelectTable = new IntDateSet( *mpSelectTable );
    1132             :         }
    1133             :     }
    1134             :     else
    1135             :     {
    1136           0 :         if ( aTempDate < maCurDate )
    1137           0 :             mbSelLeft = true;
    1138             :         else
    1139           0 :             mbSelLeft = false;
    1140           0 :         if ( !(nHitTest & CALENDAR_HITTEST_DAY) )
    1141           0 :             aTempDate = maOldCurDate;
    1142           0 :         if ( !bMove )
    1143           0 :             maAnchorDate = aTempDate;
    1144           0 :         if ( aTempDate != maCurDate )
    1145             :         {
    1146           0 :             maCurDate = aTempDate;
    1147           0 :             ImplCalendarSelectDate( mpSelectTable, aOldDate, false );
    1148           0 :             ImplCalendarSelectDate( mpSelectTable, maCurDate, true );
    1149             :         }
    1150             :     }
    1151             : 
    1152           0 :     bool bNewSel = *pOldSel != *mpSelectTable;
    1153           0 :     if ( (maCurDate != aOldDate) || bNewSel )
    1154             :     {
    1155           0 :         if ( bNewSel )
    1156             :         {
    1157           0 :             mbInSelChange = true;
    1158           0 :             SelectionChanging();
    1159           0 :             mbInSelChange = false;
    1160             :         }
    1161           0 :         HideFocus();
    1162           0 :         if ( bNewSel )
    1163           0 :             ImplUpdateSelection( pOldSel.get() );
    1164           0 :         if ( !bNewSel || pOldSel->find( aOldDate.GetDate() ) == pOldSel->end() )
    1165           0 :             ImplUpdateDate( aOldDate );
    1166             :         // assure focus rectangle is displayed again
    1167           0 :         if ( HasFocus() || !bNewSel
    1168           0 :              || mpSelectTable->find( maCurDate.GetDate() ) == mpSelectTable->end() )
    1169           0 :             ImplUpdateDate( maCurDate );
    1170           0 :     }
    1171           0 : }
    1172             : 
    1173           0 : void Calendar::ImplUpdate( bool bCalcNew )
    1174             : {
    1175           0 :     if (IsReallyVisible() && IsUpdateMode())
    1176             :     {
    1177           0 :         if (bCalcNew && !mbCalc)
    1178             :         {
    1179           0 :             Invalidate();
    1180             :         }
    1181           0 :         else if (!mbFormat && !mbCalc)
    1182             :         {
    1183           0 :             Invalidate();
    1184             :         }
    1185             :     }
    1186             : 
    1187           0 :     if (bCalcNew)
    1188           0 :         mbCalc = true;
    1189           0 :     mbFormat = true;
    1190           0 : }
    1191             : 
    1192           0 : void Calendar::ImplInvertDropPos()
    1193             : {
    1194           0 :     Rectangle aRect = GetDateRect( maDropDate );//this is one Pixel to width and one to heigh
    1195           0 :     aRect.Bottom() = aRect.Top()+mnDayHeight-1;
    1196           0 :     aRect.Right() = aRect.Left()+mnDayWidth-1;
    1197           0 :     Invert( aRect );
    1198           0 : }
    1199             : 
    1200           0 : void Calendar::ImplScroll( bool bPrev )
    1201             : {
    1202           0 :     Date aNewFirstMonth = GetFirstMonth();
    1203           0 :     if ( bPrev )
    1204             :     {
    1205           0 :         --aNewFirstMonth;
    1206           0 :         aNewFirstMonth -= aNewFirstMonth.GetDaysInMonth()-1;
    1207             :     }
    1208             :     else
    1209           0 :         aNewFirstMonth += aNewFirstMonth.GetDaysInMonth();
    1210           0 :     mbDirect = true;
    1211           0 :     SetFirstDate( aNewFirstMonth );
    1212           0 :     mbDirect = false;
    1213           0 : }
    1214             : 
    1215           0 : void Calendar::ImplShowMenu( const Point& rPos, const Date& rDate )
    1216             : {
    1217           0 :     EndSelection();
    1218             : 
    1219           0 :     Date        aOldFirstDate = GetFirstMonth();
    1220           0 :     PopupMenu   aPopupMenu;
    1221             :     PopupMenu*  pYearPopupMenus[MENU_YEAR_COUNT];
    1222             :     sal_uInt16      nMonthOff;
    1223             :     sal_uInt16      nCurItemId;
    1224           0 :     sal_uInt16      nYear = rDate.GetYear()-1;
    1225             :     sal_uInt16      i;
    1226             :     sal_uInt16      j;
    1227           0 :     sal_uInt16      nYearIdCount = 1000;
    1228             : 
    1229           0 :     nMonthOff = (rDate.GetYear()-aOldFirstDate.GetYear())*12;
    1230           0 :     if ( aOldFirstDate.GetMonth() < rDate.GetMonth() )
    1231           0 :         nMonthOff += rDate.GetMonth()-aOldFirstDate.GetMonth();
    1232             :     else
    1233           0 :         nMonthOff -= aOldFirstDate.GetMonth()-rDate.GetMonth();
    1234             : 
    1235             :     // construct menu (include years with different months)
    1236           0 :     for ( i = 0; i < MENU_YEAR_COUNT; i++ )
    1237             :     {
    1238           0 :         pYearPopupMenus[i] = new PopupMenu;
    1239           0 :         for ( j = 1; j <= 12; j++ )
    1240           0 :             pYearPopupMenus[i]->InsertItem( nYearIdCount+j,
    1241             :                     maCalendarWrapper.getDisplayName(
    1242           0 :                         i18n::CalendarDisplayIndex::MONTH, j-1, 1));
    1243           0 :         aPopupMenu.InsertItem( 10+i, OUString::number( nYear+i ) );
    1244           0 :         aPopupMenu.SetPopupMenu( 10+i, pYearPopupMenus[i] );
    1245           0 :         nYearIdCount += 1000;
    1246             :     }
    1247             : 
    1248           0 :     mbMenuDown = true;
    1249           0 :     nCurItemId = aPopupMenu.Execute( this, rPos );
    1250           0 :     mbMenuDown = false;
    1251             : 
    1252             :     // destroy menu
    1253           0 :     aPopupMenu.SetPopupMenu( 2, NULL );
    1254           0 :     for ( i = 0; i < MENU_YEAR_COUNT; i++ )
    1255             :     {
    1256           0 :         aPopupMenu.SetPopupMenu( 10+i, NULL );
    1257           0 :         delete pYearPopupMenus[i];
    1258             :     }
    1259             : 
    1260           0 :     if ( nCurItemId )
    1261             :     {
    1262           0 :         sal_uInt16 nTempMonthOff = nMonthOff % 12;
    1263           0 :         sal_uInt16 nTempYearOff = nMonthOff / 12;
    1264           0 :         sal_uInt16 nNewMonth = nCurItemId % 1000;
    1265           0 :         sal_uInt16 nNewYear = nYear+((nCurItemId-1000)/1000);
    1266           0 :         if ( nTempMonthOff < nNewMonth )
    1267           0 :             nNewMonth = nNewMonth - nTempMonthOff;
    1268             :         else
    1269             :         {
    1270           0 :             nNewYear--;
    1271           0 :             nNewMonth = 12-(nTempMonthOff-nNewMonth);
    1272             :         }
    1273           0 :         nNewYear = nNewYear - nTempYearOff;
    1274           0 :         SetFirstDate( Date( 1, nNewMonth, nNewYear ) );
    1275           0 :     }
    1276           0 : }
    1277             : 
    1278           0 : void Calendar::ImplTracking( const Point& rPos, bool bRepeat )
    1279             : {
    1280           0 :     Date    aTempDate = maCurDate;
    1281           0 :     sal_uInt16  nHitTest = ImplHitTest( rPos, aTempDate );
    1282             : 
    1283           0 :     if ( mbSpinDown )
    1284             :     {
    1285           0 :         mbPrevIn = (nHitTest & CALENDAR_HITTEST_PREV) != 0;
    1286           0 :         mbNextIn = (nHitTest & CALENDAR_HITTEST_NEXT) != 0;
    1287             : 
    1288           0 :         if ( bRepeat && (mbPrevIn || mbNextIn) )
    1289             :         {
    1290           0 :             mbScrollDateRange = true;
    1291           0 :             ImplScroll( mbPrevIn );
    1292           0 :             mbScrollDateRange = false;
    1293             :         }
    1294             :     }
    1295             :     else
    1296           0 :         ImplMouseSelect( aTempDate, nHitTest, true, false, false );
    1297           0 : }
    1298             : 
    1299           0 : void Calendar::ImplEndTracking( bool bCancel )
    1300             : {
    1301           0 :     bool bSelection = mbSelection;
    1302           0 :     bool bSpinDown = mbSpinDown;
    1303             : 
    1304           0 :     mbDrag              = false;
    1305           0 :     mbSelection         = false;
    1306           0 :     mbMultiSelection    = false;
    1307           0 :     mbUnSel             = false;
    1308           0 :     mbSpinDown          = false;
    1309           0 :     mbPrevIn            = false;
    1310           0 :     mbNextIn            = false;
    1311             : 
    1312           0 :     if ( bCancel )
    1313             :     {
    1314           0 :         if ( maOldFirstDate != maFirstDate )
    1315           0 :             SetFirstDate( maOldFirstDate );
    1316             : 
    1317           0 :         if ( !bSpinDown )
    1318             :         {
    1319           0 :             boost::scoped_ptr<IntDateSet> pOldSel(new IntDateSet( *mpSelectTable ));
    1320           0 :             Date    aOldDate = maCurDate;
    1321           0 :             maCurDate       = maOldCurDate;
    1322           0 :             *mpSelectTable  = *mpOldSelectTable;
    1323           0 :             HideFocus();
    1324           0 :             ImplUpdateSelection( pOldSel.get() );
    1325           0 :             if ( pOldSel->find( aOldDate.GetDate() ) == pOldSel->end() )
    1326           0 :                 ImplUpdateDate( aOldDate );
    1327             :             //  assure focus rectangle is displayed again
    1328           0 :             if ( HasFocus() || mpSelectTable->find( maCurDate.GetDate() ) == mpSelectTable->end() )
    1329           0 :                 ImplUpdateDate( maCurDate );
    1330             :         }
    1331             :     }
    1332             : 
    1333           0 :     if ( !bSpinDown )
    1334             :     {
    1335           0 :         if ( !bCancel )
    1336             :         {
    1337             :             // determine if we should scroll the visible area
    1338           0 :             sal_uLong nSelCount = mpSelectTable->size();
    1339           0 :             if ( nSelCount )
    1340             :             {
    1341           0 :                 Date aFirstSelDate( *mpSelectTable->begin() );
    1342           0 :                 Date aLastSelDate( *mpSelectTable->rbegin() );
    1343           0 :                 if ( aLastSelDate < GetFirstMonth() )
    1344           0 :                     ImplScroll( true );
    1345           0 :                 else if ( GetLastMonth() < aFirstSelDate )
    1346           0 :                     ImplScroll( false );
    1347             :             }
    1348             :         }
    1349             : 
    1350           0 :         if ( mbAllSel ||
    1351           0 :              (!bCancel && ((maCurDate != maOldCurDate) || (*mpOldSelectTable != *mpSelectTable))) )
    1352           0 :             Select();
    1353             : 
    1354           0 :         if ( !bSelection && (mnWinStyle & WB_TABSTOP) && !bCancel )
    1355           0 :             GrabFocus();
    1356             : 
    1357           0 :         delete mpOldSelectTable;
    1358           0 :         mpOldSelectTable = NULL;
    1359           0 :         delete mpRestoreSelectTable;
    1360           0 :         mpRestoreSelectTable = NULL;
    1361             :     }
    1362           0 : }
    1363             : 
    1364           0 : IMPL_LINK_NOARG_TYPED( Calendar, ScrollHdl, Timer*, void )
    1365             : {
    1366           0 :     bool bPrevIn = (mnDragScrollHitTest & CALENDAR_HITTEST_PREV) != 0;
    1367           0 :     bool bNextIn = (mnDragScrollHitTest & CALENDAR_HITTEST_NEXT) != 0;
    1368           0 :     if( bNextIn || bPrevIn )
    1369             :     {
    1370           0 :         mbScrollDateRange = true;
    1371           0 :         ImplScroll( bPrevIn );
    1372           0 :         mbScrollDateRange = false;
    1373             :     }
    1374           0 : }
    1375             : 
    1376           0 : void Calendar::MouseButtonDown( const MouseEvent& rMEvt )
    1377             : {
    1378           0 :     if ( rMEvt.IsLeft() && !mbMenuDown )
    1379             :     {
    1380           0 :         Date    aTempDate = maCurDate;
    1381           0 :         sal_uInt16  nHitTest = ImplHitTest( rMEvt.GetPosPixel(), aTempDate );
    1382           0 :         if ( nHitTest )
    1383             :         {
    1384           0 :             if ( nHitTest & CALENDAR_HITTEST_MONTHTITLE )
    1385           0 :                 ImplShowMenu( rMEvt.GetPosPixel(), aTempDate );
    1386             :             else
    1387             :             {
    1388           0 :                 maOldFirstDate = maFirstDate;
    1389             : 
    1390           0 :                 mbPrevIn = (nHitTest & CALENDAR_HITTEST_PREV) != 0;
    1391           0 :                 mbNextIn = (nHitTest & CALENDAR_HITTEST_NEXT) != 0;
    1392           0 :                 if ( mbPrevIn || mbNextIn )
    1393             :                 {
    1394           0 :                     mbSpinDown = true;
    1395           0 :                     mbScrollDateRange = true;
    1396           0 :                     ImplScroll( mbPrevIn );
    1397           0 :                     mbScrollDateRange = false;
    1398             :                     // it should really read BUTTONREPEAT, therefore do not
    1399             :                     // change it to SCROLLREPEAT, check with TH,
    1400             :                     // why it could be different (71775)
    1401           0 :                     StartTracking( StartTrackingFlags::ButtonRepeat );
    1402             :                 }
    1403             :                 else
    1404             :                 {
    1405           0 :                     if ( (rMEvt.GetClicks() == 2) && (nHitTest & CALENDAR_HITTEST_DAY) )
    1406           0 :                         DoubleClick();
    1407             :                     else
    1408             :                     {
    1409           0 :                         if ( mpOldSelectTable )
    1410           0 :                             delete mpOldSelectTable;
    1411           0 :                         maOldCurDate = maCurDate;
    1412           0 :                         mpOldSelectTable = new IntDateSet( *mpSelectTable );
    1413             : 
    1414           0 :                         if ( !mbSelection )
    1415             :                         {
    1416           0 :                             mbDrag = true;
    1417           0 :                             StartTracking();
    1418             :                         }
    1419             : 
    1420           0 :                         mbMultiSelection = (mnWinStyle & (WB_MULTISELECT | WB_RANGESELECT)) != 0;
    1421           0 :                         if ( (nHitTest & CALENDAR_HITTEST_DAY) && mbMultiSelection )
    1422           0 :                             mbWeekSel = true;
    1423             :                         else
    1424           0 :                             mbWeekSel = false;
    1425           0 :                         ImplMouseSelect( aTempDate, nHitTest, false, rMEvt.IsShift(), rMEvt.IsMod1() );
    1426             :                     }
    1427             :                 }
    1428             :             }
    1429             :         }
    1430             : 
    1431           0 :         return;
    1432             :     }
    1433             : 
    1434           0 :     Control::MouseButtonDown( rMEvt );
    1435             : }
    1436             : 
    1437           0 : void Calendar::MouseButtonUp( const MouseEvent& rMEvt )
    1438             : {
    1439           0 :     if ( rMEvt.IsLeft() && mbSelection )
    1440           0 :         ImplEndTracking( false );
    1441             :     else
    1442           0 :         Control::MouseButtonUp( rMEvt );
    1443           0 : }
    1444             : 
    1445           0 : void Calendar::MouseMove( const MouseEvent& rMEvt )
    1446             : {
    1447           0 :     if ( mbSelection && rMEvt.GetButtons() )
    1448           0 :         ImplTracking( rMEvt.GetPosPixel(), false );
    1449             :     else
    1450           0 :         Control::MouseMove( rMEvt );
    1451           0 : }
    1452             : 
    1453           0 : void Calendar::Tracking( const TrackingEvent& rTEvt )
    1454             : {
    1455           0 :     Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel();
    1456             : 
    1457           0 :     if ( rTEvt.IsTrackingEnded() )
    1458           0 :         ImplEndTracking( rTEvt.IsTrackingCanceled() );
    1459             :     else
    1460           0 :         ImplTracking( aMousePos, rTEvt.IsTrackingRepeat() );
    1461           0 : }
    1462             : 
    1463           0 : void Calendar::KeyInput( const KeyEvent& rKEvt )
    1464             : {
    1465           0 :     Date    aNewDate = maCurDate;
    1466           0 :     bool    bMultiSel = (mnWinStyle & (WB_RANGESELECT | WB_MULTISELECT)) != 0;
    1467           0 :     bool    bExpand = rKEvt.GetKeyCode().IsShift();
    1468           0 :     bool    bExtended = rKEvt.GetKeyCode().IsMod1();
    1469             : 
    1470           0 :     switch ( rKEvt.GetKeyCode().GetCode() )
    1471             :     {
    1472             :         case KEY_HOME:
    1473           0 :             aNewDate.SetDay( 1 );
    1474           0 :             break;
    1475             : 
    1476             :         case KEY_END:
    1477           0 :             aNewDate.SetDay( aNewDate.GetDaysInMonth() );
    1478           0 :             break;
    1479             : 
    1480             :         case KEY_LEFT:
    1481           0 :             --aNewDate;
    1482           0 :             break;
    1483             : 
    1484             :         case KEY_RIGHT:
    1485           0 :             ++aNewDate;
    1486           0 :             break;
    1487             : 
    1488             :         case KEY_UP:
    1489           0 :             aNewDate -= 7;
    1490           0 :             break;
    1491             : 
    1492             :         case KEY_DOWN:
    1493           0 :             aNewDate += 7;
    1494           0 :             break;
    1495             : 
    1496             :         case KEY_PAGEUP:
    1497             :             {
    1498           0 :             Date aTempDate = aNewDate;
    1499           0 :             aTempDate -= aNewDate.GetDay()+1;
    1500           0 :             aNewDate -= aTempDate.GetDaysInMonth();
    1501             :             }
    1502           0 :             break;
    1503             : 
    1504             :         case KEY_PAGEDOWN:
    1505           0 :             aNewDate += aNewDate.GetDaysInMonth();
    1506           0 :             break;
    1507             : 
    1508             :         case KEY_SPACE:
    1509           0 :             if ( bMultiSel && !(mnWinStyle & WB_RANGESELECT) )
    1510             :             {
    1511           0 :                 if ( !bExpand )
    1512             :                 {
    1513           0 :                     bool bDateSel = IsDateSelected( maCurDate );
    1514           0 :                     SelectDate( maCurDate, !bDateSel );
    1515           0 :                     mbSelLeft = false;
    1516           0 :                     SelectionChanging();
    1517           0 :                     mbTravelSelect = true;
    1518           0 :                     Select();
    1519           0 :                     mbTravelSelect = false;
    1520           0 :                 }
    1521             :             }
    1522             :             else
    1523           0 :                 Control::KeyInput( rKEvt );
    1524           0 :             break;
    1525             : 
    1526             :         default:
    1527           0 :             Control::KeyInput( rKEvt );
    1528           0 :             break;
    1529             :     }
    1530             : 
    1531           0 :     if ( aNewDate != maCurDate )
    1532             :     {
    1533           0 :         if ( bMultiSel && bExpand )
    1534             :         {
    1535           0 :             boost::scoped_ptr<IntDateSet> pOldSel(new IntDateSet( *mpSelectTable ));
    1536           0 :             Date aOldAnchorDate = maAnchorDate;
    1537           0 :             mbSelLeft = aNewDate < maAnchorDate;
    1538           0 :             if ( !bExtended )
    1539             :             {
    1540           0 :                 if ( mbSelLeft )
    1541             :                 {
    1542           0 :                     ImplCalendarSelectDateRange( mpSelectTable, Date( 1, 1, 0 ), aNewDate, false );
    1543           0 :                     ImplCalendarSelectDateRange( mpSelectTable, maAnchorDate, Date( 31, 12, 9999 ), false );
    1544             :                 }
    1545             :                 else
    1546             :                 {
    1547           0 :                     ImplCalendarSelectDateRange( mpSelectTable, Date( 1, 1, 0 ), maAnchorDate, false );
    1548           0 :                     ImplCalendarSelectDateRange( mpSelectTable, aNewDate, Date( 31, 12, 9999 ), false );
    1549             :                 }
    1550             :             }
    1551           0 :             ImplCalendarSelectDateRange( mpSelectTable, aNewDate, maAnchorDate, true );
    1552           0 :             mbDirect = true;
    1553           0 :             SetCurDate( aNewDate );
    1554           0 :             mbDirect = false;
    1555           0 :             maAnchorDate = aOldAnchorDate;
    1556           0 :             mbInSelChange = true;
    1557           0 :             SelectionChanging();
    1558           0 :             mbInSelChange = false;
    1559           0 :             ImplUpdateSelection( pOldSel.get() );
    1560             :         }
    1561             :         else
    1562             :         {
    1563           0 :             if ( mnWinStyle & WB_RANGESELECT )
    1564             :             {
    1565           0 :                 SetNoSelection();
    1566           0 :                 SelectDate( aNewDate, true );
    1567             :             }
    1568           0 :             mbDirect = true;
    1569           0 :             SetCurDate( aNewDate );
    1570           0 :             mbDirect = false;
    1571             :         }
    1572           0 :         mbTravelSelect = true;
    1573           0 :         Select();
    1574           0 :         mbTravelSelect = false;
    1575             :     }
    1576           0 : }
    1577             : 
    1578           0 : void Calendar::Paint( vcl::RenderContext& rRenderContext, const Rectangle& )
    1579             : {
    1580           0 :     ImplDraw(rRenderContext, true);
    1581           0 : }
    1582             : 
    1583           0 : void Calendar::GetFocus()
    1584             : {
    1585           0 :     ImplUpdateDate( maCurDate );
    1586           0 :     Control::GetFocus();
    1587           0 : }
    1588             : 
    1589           0 : void Calendar::LoseFocus()
    1590             : {
    1591           0 :     HideFocus();
    1592           0 :     Control::LoseFocus();
    1593           0 : }
    1594             : 
    1595           0 : void Calendar::Resize()
    1596             : {
    1597           0 :     ImplUpdate( true );
    1598           0 :     Control::Resize();
    1599           0 : }
    1600             : 
    1601           0 : void Calendar::RequestHelp( const HelpEvent& rHEvt )
    1602             : {
    1603           0 :     if ( rHEvt.GetMode() & (HelpEventMode::QUICK | HelpEventMode::BALLOON) )
    1604             :     {
    1605           0 :         Date aDate = maCurDate;
    1606           0 :         if ( GetDate( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ), aDate ) )
    1607             :         {
    1608           0 :             Rectangle aDateRect = GetDateRect( aDate );
    1609           0 :             Point aPt = OutputToScreenPixel( aDateRect.TopLeft() );
    1610           0 :             aDateRect.Left()   = aPt.X();
    1611           0 :             aDateRect.Top()    = aPt.Y();
    1612           0 :             aPt = OutputToScreenPixel( aDateRect.BottomRight() );
    1613           0 :             aDateRect.Right()  = aPt.X();
    1614           0 :             aDateRect.Bottom() = aPt.Y();
    1615             : 
    1616           0 :             if ( rHEvt.GetMode() & HelpEventMode::QUICK )
    1617             :             {
    1618           0 :                 maCalendarWrapper.setGregorianDateTime( aDate);
    1619           0 :                 sal_uInt16      nWeek = (sal_uInt16) maCalendarWrapper.getValue( i18n::CalendarFieldIndex::WEEK_OF_YEAR);
    1620           0 :                 sal_uInt16      nMonth = aDate.GetMonth();
    1621           0 :                 OUString   aStr( maDayText );
    1622           0 :                 aStr += ": ";
    1623           0 :                 aStr += OUString::number(aDate.GetDayOfYear());
    1624           0 :                 aStr += " / ";
    1625           0 :                 aStr += maWeekText;
    1626           0 :                 aStr += ": ";
    1627           0 :                 aStr += OUString::number(nWeek);
    1628             :         // if year is not the same, add it
    1629           0 :                 if ( (nMonth == 12) && (nWeek == 1) )
    1630             :                 {
    1631           0 :                     aStr += ",  ";
    1632           0 :                     aStr += OUString::number(aDate.GetYear()+1);
    1633             :                 }
    1634           0 :                 else if ( (nMonth == 1) && (nWeek > 50) )
    1635             :                 {
    1636           0 :                     aStr += ", ";
    1637           0 :                     aStr += OUString::number(aDate.GetYear()-1);
    1638             :                 }
    1639           0 :                 Help::ShowQuickHelp( this, aDateRect, aStr );
    1640           0 :                 return;
    1641             :             }
    1642             :         }
    1643             :     }
    1644             : 
    1645           0 :     Control::RequestHelp( rHEvt );
    1646             : }
    1647             : 
    1648           0 : void Calendar::Command( const CommandEvent& rCEvt )
    1649             : {
    1650           0 :     if ( rCEvt.GetCommand() == CommandEventId::ContextMenu )
    1651             :     {
    1652           0 :         if ( !mbSelection && rCEvt.IsMouseEvent() )
    1653             :         {
    1654           0 :             Date    aTempDate = maCurDate;
    1655           0 :             sal_uInt16  nHitTest = ImplHitTest( rCEvt.GetMousePosPixel(), aTempDate );
    1656           0 :             if ( nHitTest & CALENDAR_HITTEST_MONTHTITLE )
    1657             :             {
    1658           0 :                 ImplShowMenu( rCEvt.GetMousePosPixel(), aTempDate );
    1659           0 :                 return;
    1660             :             }
    1661             :         }
    1662             :     }
    1663           0 :     else if ( rCEvt.GetCommand() == CommandEventId::Wheel )
    1664             :     {
    1665           0 :         const CommandWheelData* pData = rCEvt.GetWheelData();
    1666           0 :         if ( pData->GetMode() == CommandWheelMode::SCROLL )
    1667             :         {
    1668           0 :             long nNotchDelta = pData->GetNotchDelta();
    1669           0 :             if ( nNotchDelta < 0 )
    1670             :             {
    1671           0 :                 while ( nNotchDelta < 0 )
    1672             :                 {
    1673           0 :                     ImplScroll( true );
    1674           0 :                     nNotchDelta++;
    1675             :                 }
    1676             :             }
    1677             :             else
    1678             :             {
    1679           0 :                 while ( nNotchDelta > 0 )
    1680             :                 {
    1681           0 :                     ImplScroll( false );
    1682           0 :                     nNotchDelta--;
    1683             :                 }
    1684             :             }
    1685             : 
    1686           0 :             return;
    1687             :         }
    1688             :     }
    1689             : 
    1690           0 :     Control::Command( rCEvt );
    1691             : }
    1692             : 
    1693           0 : void Calendar::StateChanged( StateChangedType nType )
    1694             : {
    1695           0 :     Control::StateChanged( nType );
    1696             : 
    1697           0 :     if ( nType == StateChangedType::InitShow )
    1698           0 :         ImplFormat();
    1699           0 : }
    1700             : 
    1701           0 : void Calendar::DataChanged( const DataChangedEvent& rDCEvt )
    1702             : {
    1703           0 :     Control::DataChanged( rDCEvt );
    1704             : 
    1705           0 :     if ( (rDCEvt.GetType() == DataChangedEventType::FONTS) ||
    1706           0 :          (rDCEvt.GetType() == DataChangedEventType::FONTSUBSTITUTION) ||
    1707           0 :          ((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
    1708           0 :           (rDCEvt.GetFlags() & AllSettingsFlags::STYLE)) )
    1709             :     {
    1710           0 :         ImplInitSettings();
    1711           0 :         Invalidate();
    1712             :     }
    1713           0 : }
    1714             : 
    1715           0 : void Calendar::SelectionChanging()
    1716             : {
    1717           0 :     maSelectionChangingHdl.Call( this );
    1718           0 : }
    1719             : 
    1720           0 : void Calendar::DateRangeChanged()
    1721             : {
    1722           0 :     maDateRangeChangedHdl.Call( this );
    1723           0 : }
    1724             : 
    1725           0 : void Calendar::RequestDateInfo()
    1726             : {
    1727           0 :     maRequestDateInfoHdl.Call( this );
    1728           0 : }
    1729             : 
    1730           0 : void Calendar::DoubleClick()
    1731             : {
    1732           0 :     maDoubleClickHdl.Call( this );
    1733           0 : }
    1734             : 
    1735           0 : void Calendar::Select()
    1736             : {
    1737           0 :     maSelectHdl.Call( this );
    1738           0 : }
    1739             : 
    1740           0 : void Calendar::SelectDate( const Date& rDate, bool bSelect )
    1741             : {
    1742           0 :     if ( !rDate.IsValidAndGregorian() )
    1743           0 :         return;
    1744             : 
    1745           0 :     boost::scoped_ptr<IntDateSet> pOldSel;
    1746             : 
    1747           0 :     if ( !mbInSelChange )
    1748           0 :         pOldSel.reset(new IntDateSet( *mpSelectTable ));
    1749             : 
    1750           0 :     ImplCalendarSelectDate( mpSelectTable, rDate, bSelect );
    1751             : 
    1752           0 :     if ( pOldSel )
    1753           0 :         ImplUpdateSelection( pOldSel.get() );
    1754             : }
    1755             : 
    1756           0 : void Calendar::SetNoSelection()
    1757             : {
    1758           0 :     boost::scoped_ptr<IntDateSet> pOldSel;
    1759             : 
    1760           0 :     if ( !mbInSelChange )
    1761           0 :         pOldSel.reset(new IntDateSet( *mpSelectTable ));
    1762             : 
    1763           0 :     ImplCalendarClearSelectDate( mpSelectTable );
    1764             : 
    1765           0 :     if ( pOldSel )
    1766           0 :         ImplUpdateSelection( pOldSel.get() );
    1767           0 : }
    1768             : 
    1769           0 : bool Calendar::IsDateSelected( const Date& rDate ) const
    1770             : {
    1771           0 :     return mpSelectTable->find( rDate.GetDate() ) != mpSelectTable->end();
    1772             : }
    1773             : 
    1774           0 : Date Calendar::GetFirstSelectedDate() const
    1775             : {
    1776           0 :     if ( !mpSelectTable->empty() )
    1777           0 :         return Date( *mpSelectTable->begin() );
    1778             :     else
    1779             :     {
    1780           0 :         Date aDate( 0, 0, 0 );
    1781           0 :         return aDate;
    1782             :     }
    1783             : }
    1784             : 
    1785           0 : void Calendar::SetCurDate( const Date& rNewDate )
    1786             : {
    1787           0 :     if ( !rNewDate.IsValidAndGregorian() )
    1788           0 :         return;
    1789             : 
    1790           0 :     if ( maCurDate != rNewDate )
    1791             :     {
    1792           0 :         bool bUpdate    = IsVisible() && IsUpdateMode();
    1793           0 :         Date aOldDate   = maCurDate;
    1794           0 :         maCurDate       = rNewDate;
    1795           0 :         maAnchorDate    = maCurDate;
    1796             : 
    1797           0 :         if ( !(mnWinStyle & (WB_RANGESELECT | WB_MULTISELECT)) )
    1798             :         {
    1799           0 :             ImplCalendarSelectDate( mpSelectTable, aOldDate, false );
    1800           0 :             ImplCalendarSelectDate( mpSelectTable, maCurDate, true );
    1801             :         }
    1802           0 :         else if ( !HasFocus() )
    1803           0 :             bUpdate = false;
    1804             : 
    1805             :         // shift actual date in the visible area
    1806           0 :         if ( mbFormat || (maCurDate < GetFirstMonth()) )
    1807           0 :             SetFirstDate( maCurDate );
    1808           0 :         else if ( maCurDate > GetLastMonth() )
    1809             :         {
    1810           0 :             Date aTempDate = GetLastMonth();
    1811           0 :             long nDateOff = maCurDate-aTempDate;
    1812           0 :             if ( nDateOff < 365 )
    1813             :             {
    1814           0 :                 Date aFirstDate = GetFirstMonth();
    1815           0 :                 aFirstDate += aFirstDate.GetDaysInMonth();
    1816           0 :                 ++aTempDate;
    1817           0 :                 while ( nDateOff > aTempDate.GetDaysInMonth() )
    1818             :                 {
    1819           0 :                     aFirstDate += aFirstDate.GetDaysInMonth();
    1820           0 :                     long nDaysInMonth = aTempDate.GetDaysInMonth();
    1821           0 :                     aTempDate += nDaysInMonth;
    1822           0 :                     nDateOff -= nDaysInMonth;
    1823             :                 }
    1824           0 :                 SetFirstDate( aFirstDate );
    1825             :             }
    1826             :             else
    1827           0 :                 SetFirstDate( maCurDate );
    1828             :         }
    1829             :         else
    1830             :         {
    1831           0 :             if ( bUpdate )
    1832             :             {
    1833           0 :                 HideFocus();
    1834           0 :                 ImplUpdateDate( aOldDate );
    1835           0 :                 ImplUpdateDate( maCurDate );
    1836             :             }
    1837             :         }
    1838             :     }
    1839             : }
    1840             : 
    1841           0 : void Calendar::SetFirstDate( const Date& rNewFirstDate )
    1842             : {
    1843           0 :     if ( maFirstDate != rNewFirstDate )
    1844             :     {
    1845           0 :         maFirstDate = Date( 1, rNewFirstDate.GetMonth(), rNewFirstDate.GetYear() );
    1846           0 :         mbDropPos = false;
    1847           0 :         ImplUpdate();
    1848             :     }
    1849           0 : }
    1850             : 
    1851           0 : Date Calendar::GetFirstMonth() const
    1852             : {
    1853           0 :     if ( maFirstDate.GetDay() > 1 )
    1854             :     {
    1855           0 :         if ( maFirstDate.GetMonth() == 12 )
    1856           0 :             return Date( 1, 1, maFirstDate.GetYear()+1 );
    1857             :         else
    1858           0 :             return Date( 1, maFirstDate.GetMonth()+1, maFirstDate.GetYear() );
    1859             :     }
    1860             :     else
    1861           0 :         return maFirstDate;
    1862             : }
    1863             : 
    1864           0 : Date Calendar::GetLastMonth() const
    1865             : {
    1866           0 :     Date aDate = GetFirstMonth();
    1867           0 :     sal_uInt16 nMonthCount = GetMonthCount();
    1868           0 :     for ( sal_uInt16 i = 0; i < nMonthCount; i++ )
    1869           0 :         aDate += aDate.GetDaysInMonth();
    1870           0 :     --aDate;
    1871           0 :     return aDate;
    1872             : }
    1873             : 
    1874           0 : sal_uInt16 Calendar::GetMonthCount() const
    1875             : {
    1876           0 :     if ( mbFormat )
    1877           0 :         return 1;
    1878             :     else
    1879           0 :         return (sal_uInt16)(mnMonthPerLine*mnLines);
    1880             : }
    1881             : 
    1882           0 : bool Calendar::GetDate( const Point& rPos, Date& rDate ) const
    1883             : {
    1884           0 :     Date    aDate = maCurDate;
    1885           0 :     sal_uInt16  nHitTest = ImplHitTest( rPos, aDate );
    1886           0 :     if ( nHitTest & CALENDAR_HITTEST_DAY )
    1887             :     {
    1888           0 :         rDate = aDate;
    1889           0 :         return true;
    1890             :     }
    1891             :     else
    1892           0 :         return false;
    1893             : }
    1894             : 
    1895           0 : Rectangle Calendar::GetDateRect( const Date& rDate ) const
    1896             : {
    1897           0 :     Rectangle aRect;
    1898             : 
    1899           0 :     if ( mbFormat || (rDate < maFirstDate) || (rDate > (maFirstDate+mnDayCount)) )
    1900           0 :         return aRect;
    1901             : 
    1902             :     long    nX;
    1903             :     long    nY;
    1904             :     sal_uLong   nDaysOff;
    1905             :     sal_uInt16  nDayIndex;
    1906           0 :     Date    aDate = GetFirstMonth();
    1907             : 
    1908           0 :     if ( rDate < aDate )
    1909             :     {
    1910           0 :         aRect = GetDateRect( aDate );
    1911           0 :         nDaysOff = aDate-rDate;
    1912           0 :         nX = (long)(nDaysOff*mnDayWidth);
    1913           0 :         aRect.Left() -= nX;
    1914           0 :         aRect.Right() -= nX;
    1915           0 :         return aRect;
    1916             :     }
    1917             :     else
    1918             :     {
    1919           0 :         Date aLastDate = GetLastMonth();
    1920           0 :         if ( rDate > aLastDate )
    1921             :         {
    1922           0 :             sal_uInt16 nWeekDay = (sal_uInt16)aLastDate.GetDayOfWeek();
    1923           0 :             nWeekDay = (nWeekDay+(7-(sal_uInt16)ImplGetWeekStart())) % 7;
    1924           0 :             aLastDate -= nWeekDay;
    1925           0 :             aRect = GetDateRect( aLastDate );
    1926           0 :             nDaysOff = rDate-aLastDate;
    1927           0 :             nDayIndex = 0;
    1928           0 :             for ( sal_uLong i = 0; i <= nDaysOff; i++ )
    1929             :             {
    1930           0 :                 if ( aLastDate == rDate )
    1931             :                 {
    1932           0 :                     aRect.Left() += nDayIndex*mnDayWidth;
    1933           0 :                     aRect.Right() = aRect.Left()+mnDayWidth;
    1934           0 :                     return aRect;
    1935             :                 }
    1936           0 :                 if ( nDayIndex == 6 )
    1937             :                 {
    1938           0 :                     nDayIndex = 0;
    1939           0 :                     aRect.Top() += mnDayHeight;
    1940           0 :                     aRect.Bottom() += mnDayHeight;
    1941             :                 }
    1942             :                 else
    1943           0 :                     nDayIndex++;
    1944           0 :                 ++aLastDate;
    1945             :             }
    1946             :         }
    1947             :     }
    1948             : 
    1949           0 :     nY = 0;
    1950           0 :     for ( long i = 0; i < mnLines; i++ )
    1951             :     {
    1952           0 :         nX = 0;
    1953           0 :         for ( long j = 0; j < mnMonthPerLine; j++ )
    1954             :         {
    1955           0 :             sal_uInt16 nDaysInMonth = aDate.GetDaysInMonth();
    1956             : 
    1957             :             // month is called
    1958           0 :             if ( (aDate.GetMonth() == rDate.GetMonth()) &&
    1959           0 :                  (aDate.GetYear() == rDate.GetYear()) )
    1960             :             {
    1961           0 :                 long nDayX = nX+mnDaysOffX;
    1962           0 :                 long nDayY = nY+mnDaysOffY;
    1963           0 :                 nDayIndex = (sal_uInt16)aDate.GetDayOfWeek();
    1964           0 :                 nDayIndex = (nDayIndex+(7-(sal_uInt16)ImplGetWeekStart())) % 7;
    1965           0 :                 for ( sal_uInt16 nDay = 1; nDay <= nDaysInMonth; nDay++ )
    1966             :                 {
    1967           0 :                     if ( nDay == rDate.GetDay() )
    1968             :                     {
    1969           0 :                         aRect.Left()    = nDayX + (nDayIndex*mnDayWidth);
    1970           0 :                         aRect.Top()     = nDayY;
    1971           0 :                         aRect.Right()   = aRect.Left()+mnDayWidth;
    1972           0 :                         aRect.Bottom()  = aRect.Top()+mnDayHeight;
    1973           0 :                         break;
    1974             :                     }
    1975           0 :                     if ( nDayIndex == 6 )
    1976             :                     {
    1977           0 :                         nDayIndex = 0;
    1978           0 :                         nDayY += mnDayHeight;
    1979             :                     }
    1980             :                     else
    1981           0 :                         nDayIndex++;
    1982             :                 }
    1983             :             }
    1984             : 
    1985           0 :             aDate += nDaysInMonth;
    1986           0 :             nX += mnMonthWidth;
    1987             :         }
    1988             : 
    1989           0 :         nY += mnMonthHeight;
    1990             :     }
    1991             : 
    1992           0 :     return aRect;
    1993             : }
    1994             : 
    1995           0 : void Calendar::StartSelection()
    1996             : {
    1997           0 :     if ( mpOldSelectTable )
    1998           0 :         delete mpOldSelectTable;
    1999           0 :     maOldCurDate = maCurDate;
    2000           0 :     mpOldSelectTable = new IntDateSet( *mpSelectTable );
    2001             : 
    2002           0 :     mbSelection = true;
    2003           0 : }
    2004             : 
    2005           0 : void Calendar::EndSelection()
    2006             : {
    2007           0 :     if ( mbDrag || mbSpinDown || mbSelection )
    2008             :     {
    2009           0 :         if ( !mbSelection )
    2010           0 :             ReleaseMouse();
    2011             : 
    2012           0 :         mbDrag              = false;
    2013           0 :         mbSelection         = false;
    2014           0 :         mbMultiSelection    = false;
    2015           0 :         mbSpinDown          = false;
    2016           0 :         mbPrevIn            = false;
    2017           0 :         mbNextIn            = false;
    2018             :     }
    2019           0 : }
    2020             : 
    2021           0 : Size Calendar::CalcWindowSizePixel( long nCalcMonthPerLine,
    2022             :                                     long nCalcLines ) const
    2023             : {
    2024           0 :     OUString  a99Text("99");
    2025           0 :     vcl::Font aOldFont = GetFont();
    2026             : 
    2027             :     // take display of week into account
    2028             :     long nWeekWidth;
    2029           0 :     if ( mnWinStyle & WB_WEEKNUMBER )
    2030             :     {
    2031           0 :         vcl::Font aTempFont = aOldFont;
    2032           0 :         ImplGetWeekFont( aTempFont );
    2033           0 :         const_cast<Calendar*>(this)->SetFont( aTempFont );
    2034           0 :         nWeekWidth = GetTextWidth( a99Text )+WEEKNUMBER_OFFX;
    2035           0 :         const_cast<Calendar*>(this)->SetFont( aOldFont );
    2036             :     }
    2037             :     else
    2038           0 :         nWeekWidth = 0;
    2039             : 
    2040           0 :     if ( mnWinStyle & WB_BOLDTEXT )
    2041             :     {
    2042           0 :         vcl::Font aFont = aOldFont;
    2043           0 :         if ( aFont.GetWeight() < WEIGHT_BOLD )
    2044           0 :             aFont.SetWeight( WEIGHT_BOLD );
    2045             :         else
    2046           0 :             aFont.SetWeight( WEIGHT_NORMAL );
    2047           0 :         const_cast<Calendar*>(this)->SetFont( aFont );
    2048             :     }
    2049             : 
    2050           0 :     Size    aSize;
    2051           0 :     long    n99TextWidth = GetTextWidth( a99Text );
    2052           0 :     long    nTextHeight = GetTextHeight();
    2053             : 
    2054           0 :     if ( mnWinStyle & WB_BOLDTEXT )
    2055           0 :         const_cast<Calendar*>(this)->SetFont( aOldFont );
    2056             : 
    2057           0 :     aSize.Width()  += ((n99TextWidth+DAY_OFFX)*7) + nWeekWidth;
    2058           0 :     aSize.Width()  += MONTH_BORDERX*2;
    2059           0 :     aSize.Width()  *= nCalcMonthPerLine;
    2060             : 
    2061           0 :     aSize.Height()  = nTextHeight + TITLE_OFFY + (TITLE_BORDERY*2);
    2062           0 :     aSize.Height() += nTextHeight + WEEKDAY_OFFY;
    2063           0 :     aSize.Height() += ((nTextHeight+DAY_OFFY)*6);
    2064           0 :     aSize.Height() += MONTH_OFFY;
    2065           0 :     aSize.Height() *= nCalcLines;
    2066             : 
    2067           0 :     return aSize;
    2068             : }
    2069             : 
    2070             : #define CALFIELD_EXTRA_BUTTON_WIDTH         14
    2071             : #define CALFIELD_EXTRA_BUTTON_HEIGHT        8
    2072             : #define CALFIELD_SEP_X                      6
    2073             : #define CALFIELD_BORDERLINE_X               5
    2074             : #define CALFIELD_BORDER_YTOP                4
    2075             : #define CALFIELD_BORDER_Y                   5
    2076             : 
    2077             : class ImplCFieldFloatWin : public FloatingWindow
    2078             : {
    2079             : private:
    2080             :     VclPtr<Calendar>    mpCalendar;
    2081             :     VclPtr<PushButton>  mpTodayBtn;
    2082             :     VclPtr<PushButton>  mpNoneBtn;
    2083             :     VclPtr<FixedLine>   mpFixedLine;
    2084             : 
    2085             : public:
    2086             :                     explicit ImplCFieldFloatWin( vcl::Window* pParent );
    2087             :     virtual         ~ImplCFieldFloatWin();
    2088             :     virtual void    dispose() SAL_OVERRIDE;
    2089             : 
    2090           0 :     void            SetCalendar( Calendar* pCalendar )
    2091           0 :                         { mpCalendar = pCalendar; }
    2092             : 
    2093             :     PushButton*     EnableTodayBtn( bool bEnable );
    2094             :     PushButton*     EnableNoneBtn( bool bEnable );
    2095             :     void            ArrangeButtons();
    2096             : 
    2097             :     virtual bool    Notify( NotifyEvent& rNEvt ) SAL_OVERRIDE;
    2098             : };
    2099             : 
    2100           0 : ImplCFieldFloatWin::ImplCFieldFloatWin( vcl::Window* pParent ) :
    2101           0 :     FloatingWindow( pParent, WB_BORDER | WB_SYSTEMWINDOW | WB_NOSHADOW  )
    2102             : {
    2103           0 :     mpCalendar  = NULL;
    2104           0 :     mpTodayBtn  = NULL;
    2105           0 :     mpNoneBtn   = NULL;
    2106           0 :     mpFixedLine = NULL;
    2107           0 : }
    2108             : 
    2109           0 : ImplCFieldFloatWin::~ImplCFieldFloatWin()
    2110             : {
    2111           0 :     disposeOnce();
    2112           0 : }
    2113             : 
    2114           0 : void ImplCFieldFloatWin::dispose()
    2115             : {
    2116           0 :     mpTodayBtn.disposeAndClear();
    2117           0 :     mpNoneBtn.disposeAndClear();
    2118           0 :     mpFixedLine.disposeAndClear();
    2119           0 :     mpCalendar.clear();
    2120           0 :     FloatingWindow::dispose();
    2121           0 : }
    2122             : 
    2123           0 : PushButton* ImplCFieldFloatWin::EnableTodayBtn( bool bEnable )
    2124             : {
    2125           0 :     if ( bEnable )
    2126             :     {
    2127           0 :         if ( !mpTodayBtn )
    2128             :         {
    2129           0 :             mpTodayBtn = VclPtr<PushButton>::Create( this, WB_NOPOINTERFOCUS );
    2130           0 :             OUString aTodayText(SVT_RESSTR(STR_SVT_CALENDAR_TODAY));
    2131           0 :             mpTodayBtn->SetText( aTodayText );
    2132           0 :             Size aSize;
    2133           0 :             aSize.Width()   = mpTodayBtn->GetCtrlTextWidth( mpTodayBtn->GetText() );
    2134           0 :             aSize.Height()  = mpTodayBtn->GetTextHeight();
    2135           0 :             aSize.Width()  += CALFIELD_EXTRA_BUTTON_WIDTH;
    2136           0 :             aSize.Height() += CALFIELD_EXTRA_BUTTON_HEIGHT;
    2137           0 :             mpTodayBtn->SetSizePixel( aSize );
    2138           0 :             mpTodayBtn->Show();
    2139             :         }
    2140             :     }
    2141             :     else
    2142             :     {
    2143           0 :         mpTodayBtn.disposeAndClear();
    2144             :     }
    2145             : 
    2146           0 :     return mpTodayBtn;
    2147             : }
    2148             : 
    2149           0 : PushButton* ImplCFieldFloatWin::EnableNoneBtn( bool bEnable )
    2150             : {
    2151           0 :     if ( bEnable )
    2152             :     {
    2153           0 :         if ( !mpNoneBtn )
    2154             :         {
    2155           0 :             mpNoneBtn = VclPtr<PushButton>::Create( this, WB_NOPOINTERFOCUS );
    2156           0 :             OUString aNoneText(SVT_RESSTR(STR_SVT_CALENDAR_NONE));
    2157           0 :             mpNoneBtn->SetText( aNoneText );
    2158           0 :             Size aSize;
    2159           0 :             aSize.Width()   = mpNoneBtn->GetCtrlTextWidth( mpNoneBtn->GetText() );
    2160           0 :             aSize.Height()  = mpNoneBtn->GetTextHeight();
    2161           0 :             aSize.Width()  += CALFIELD_EXTRA_BUTTON_WIDTH;
    2162           0 :             aSize.Height() += CALFIELD_EXTRA_BUTTON_HEIGHT;
    2163           0 :             mpNoneBtn->SetSizePixel( aSize );
    2164           0 :             mpNoneBtn->Show();
    2165             :         }
    2166             :     }
    2167             :     else
    2168             :     {
    2169           0 :         mpNoneBtn.disposeAndClear();
    2170             :     }
    2171             : 
    2172           0 :     return mpNoneBtn;
    2173             : }
    2174             : 
    2175           0 : void ImplCFieldFloatWin::ArrangeButtons()
    2176             : {
    2177           0 :     long nBtnHeight = 0;
    2178           0 :     long nBtnWidth  = 0;
    2179           0 :     Size aOutSize   = GetOutputSizePixel();
    2180           0 :     if ( mpTodayBtn && mpNoneBtn )
    2181             :     {
    2182           0 :         Size aTodayBtnSize = mpTodayBtn->GetSizePixel();
    2183           0 :         Size aNoneBtnSize  = mpNoneBtn->GetSizePixel();
    2184           0 :         if ( aTodayBtnSize.Width() < aNoneBtnSize.Width() )
    2185           0 :             aTodayBtnSize.Width() = aNoneBtnSize.Width();
    2186             :         else
    2187           0 :             aNoneBtnSize.Width() = aTodayBtnSize.Width();
    2188           0 :         if ( aTodayBtnSize.Height() < aNoneBtnSize.Height() )
    2189           0 :             aTodayBtnSize.Height() = aNoneBtnSize.Height();
    2190             :         else
    2191           0 :             aNoneBtnSize.Height() = aTodayBtnSize.Height();
    2192             : 
    2193           0 :         nBtnWidth  = aTodayBtnSize.Width() + aNoneBtnSize.Width() + CALFIELD_SEP_X;
    2194           0 :         nBtnHeight = aTodayBtnSize.Height();
    2195           0 :         long nX = (aOutSize.Width()-nBtnWidth)/2;
    2196           0 :         long nY = aOutSize.Height()+CALFIELD_BORDER_Y+CALFIELD_BORDER_YTOP;
    2197           0 :         mpTodayBtn->SetPosSizePixel( Point( nX, nY ), aTodayBtnSize );
    2198           0 :         nX += aTodayBtnSize.Width() + CALFIELD_SEP_X;
    2199           0 :         mpNoneBtn->SetPosSizePixel( Point( nX, nY ), aNoneBtnSize );
    2200             :     }
    2201           0 :     else if ( mpTodayBtn )
    2202             :     {
    2203           0 :         Size aTodayBtnSize = mpTodayBtn->GetSizePixel();
    2204           0 :         nBtnWidth  = aTodayBtnSize.Width();
    2205           0 :         nBtnHeight = aTodayBtnSize.Height();
    2206           0 :         mpTodayBtn->SetPosPixel( Point( (aOutSize.Width()-nBtnWidth)/2, aOutSize.Height()+CALFIELD_BORDER_Y+CALFIELD_BORDER_YTOP ) );
    2207             :     }
    2208           0 :     else if ( mpNoneBtn )
    2209             :     {
    2210           0 :         Size aNoneBtnSize  = mpNoneBtn->GetSizePixel();
    2211           0 :         nBtnWidth  = aNoneBtnSize.Width();
    2212           0 :         nBtnHeight = aNoneBtnSize.Height();
    2213           0 :         mpNoneBtn->SetPosPixel( Point( (aOutSize.Width()-nBtnWidth)/2, aOutSize.Height()+CALFIELD_BORDER_Y+CALFIELD_BORDER_YTOP ) );
    2214             :     }
    2215             : 
    2216           0 :     if ( nBtnHeight )
    2217             :     {
    2218           0 :         if ( !mpFixedLine )
    2219             :         {
    2220           0 :             mpFixedLine = VclPtr<FixedLine>::Create( this );
    2221           0 :             mpFixedLine->Show();
    2222             :         }
    2223           0 :         long nLineWidth = aOutSize.Width()-(CALFIELD_BORDERLINE_X*2);
    2224           0 :         mpFixedLine->setPosSizePixel( (aOutSize.Width()-nLineWidth)/2, aOutSize.Height()+((CALFIELD_BORDER_YTOP-2)/2),
    2225           0 :                                       nLineWidth, 2, PosSizeFlags::PosSize );
    2226           0 :         aOutSize.Height() += nBtnHeight + (CALFIELD_BORDER_Y*2) + CALFIELD_BORDER_YTOP;
    2227           0 :         SetOutputSizePixel( aOutSize );
    2228             :     }
    2229             :     else
    2230             :     {
    2231           0 :         mpFixedLine.disposeAndClear();
    2232             :     }
    2233           0 : }
    2234             : 
    2235           0 : bool ImplCFieldFloatWin::Notify( NotifyEvent& rNEvt )
    2236             : {
    2237           0 :     if ( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT )
    2238             :     {
    2239           0 :         const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
    2240           0 :         if ( pKEvt->GetKeyCode().GetCode() == KEY_RETURN )
    2241           0 :             mpCalendar->Select();
    2242             :     }
    2243             : 
    2244           0 :     return FloatingWindow::Notify( rNEvt );
    2245             : }
    2246             : 
    2247          34 : CalendarField::CalendarField(vcl::Window* pParent, WinBits nWinStyle)
    2248             :     : DateField(pParent, nWinStyle)
    2249             :     , mpFloatWin(NULL)
    2250             :     , mpCalendar(NULL)
    2251             :     , mnCalendarStyle(0)
    2252             :     , mpTodayBtn(NULL)
    2253             :     , mpNoneBtn(NULL)
    2254             :     , maDefaultDate( 0, 0, 0 )
    2255             :     , mbToday(false)
    2256          34 :     , mbNone(false)
    2257             : {
    2258          34 : }
    2259             : 
    2260           0 : CalendarField::~CalendarField()
    2261             : {
    2262           0 :     disposeOnce();
    2263           0 : }
    2264             : 
    2265          34 : void CalendarField::dispose()
    2266             : {
    2267          34 :     mpCalendar.disposeAndClear();
    2268          34 :     mpFloatWin.disposeAndClear();
    2269          34 :     mpTodayBtn.clear();
    2270          34 :     mpNoneBtn.clear();
    2271          34 :     DateField::dispose();
    2272          34 : }
    2273             : 
    2274           0 : IMPL_LINK( CalendarField, ImplSelectHdl, Calendar*, pCalendar )
    2275             : {
    2276           0 :     if ( !pCalendar->IsTravelSelect() )
    2277             :     {
    2278           0 :         mpFloatWin->EndPopupMode();
    2279           0 :         EndDropDown();
    2280           0 :         GrabFocus();
    2281           0 :         Date aNewDate = mpCalendar->GetFirstSelectedDate();
    2282           0 :         if ( IsEmptyDate() || ( aNewDate != GetDate() ) )
    2283             :         {
    2284           0 :             SetDate( aNewDate );
    2285           0 :             SetModifyFlag();
    2286           0 :             Modify();
    2287             :         }
    2288           0 :         Select();
    2289             :     }
    2290           0 :     return 0;
    2291             : }
    2292             : 
    2293           0 : IMPL_LINK( CalendarField, ImplClickHdl, PushButton*, pBtn )
    2294             : {
    2295           0 :     mpFloatWin->EndPopupMode();
    2296           0 :     EndDropDown();
    2297           0 :     GrabFocus();
    2298             : 
    2299           0 :     if ( pBtn == mpTodayBtn )
    2300             :     {
    2301           0 :         Date aToday( Date::SYSTEM );
    2302           0 :         if ( (aToday != GetDate()) || IsEmptyDate() )
    2303             :         {
    2304           0 :             SetDate( aToday );
    2305           0 :             SetModifyFlag();
    2306           0 :             Modify();
    2307             :         }
    2308             :     }
    2309           0 :     else if ( pBtn == mpNoneBtn )
    2310             :     {
    2311           0 :         if ( !IsEmptyDate() )
    2312             :         {
    2313           0 :             SetEmptyDate();
    2314           0 :             SetModifyFlag();
    2315           0 :             Modify();
    2316             :         }
    2317             :     }
    2318           0 :     Select();
    2319             : 
    2320           0 :     return 0;
    2321             : }
    2322             : 
    2323           0 : IMPL_LINK_NOARG(CalendarField, ImplPopupModeEndHdl)
    2324             : {
    2325           0 :     EndDropDown();
    2326           0 :     GrabFocus();
    2327           0 :     mpCalendar->EndSelection();
    2328           0 :     return 0;
    2329             : }
    2330             : 
    2331           0 : void CalendarField::Select()
    2332             : {
    2333           0 :     maSelectHdl.Call( this );
    2334           0 : }
    2335             : 
    2336           0 : bool CalendarField::ShowDropDown( bool bShow )
    2337             : {
    2338           0 :     if ( bShow )
    2339             :     {
    2340           0 :         Calendar* pCalendar = GetCalendar();
    2341             : 
    2342           0 :         Date aDate = GetDate();
    2343           0 :         if ( IsEmptyDate() || !aDate.IsValidAndGregorian() )
    2344             :         {
    2345           0 :             if ( maDefaultDate.IsValidAndGregorian() )
    2346           0 :                 aDate = maDefaultDate;
    2347             :             else
    2348           0 :                 aDate = Date( Date::SYSTEM );
    2349             :         }
    2350           0 :         if ( pCalendar->GetStyle() & (WB_RANGESELECT | WB_MULTISELECT) )
    2351             :         {
    2352           0 :             pCalendar->SetNoSelection();
    2353           0 :             pCalendar->SelectDate( aDate );
    2354             :         }
    2355           0 :         pCalendar->SetCurDate( aDate );
    2356           0 :         Point       aPos( GetParent()->OutputToScreenPixel( GetPosPixel() ) );
    2357           0 :         Rectangle   aRect( aPos, GetSizePixel() );
    2358           0 :         aRect.Bottom() -= 1;
    2359           0 :         mpCalendar->SetOutputSizePixel( mpCalendar->CalcWindowSizePixel() );
    2360           0 :         mpFloatWin->SetOutputSizePixel( mpCalendar->GetSizePixel() );
    2361           0 :         mpFloatWin->SetCalendar( mpCalendar );
    2362           0 :         mpTodayBtn = mpFloatWin->EnableTodayBtn( mbToday );
    2363           0 :         mpNoneBtn = mpFloatWin->EnableNoneBtn( mbNone );
    2364           0 :         if ( mpTodayBtn )
    2365           0 :             mpTodayBtn->SetClickHdl( LINK( this, CalendarField, ImplClickHdl ) );
    2366           0 :         if ( mpNoneBtn )
    2367           0 :             mpNoneBtn->SetClickHdl( LINK( this, CalendarField, ImplClickHdl ) );
    2368           0 :         mpFloatWin->ArrangeButtons();
    2369           0 :         mpCalendar->EnableCallEverySelect();
    2370           0 :         mpCalendar->StartSelection();
    2371           0 :         mpCalendar->GrabFocus();
    2372           0 :         mpCalendar->Show();
    2373           0 :         mpFloatWin->StartPopupMode( aRect, FloatWinPopupFlags::NoFocusClose|FloatWinPopupFlags::Down );
    2374             :     }
    2375             :     else
    2376             :     {
    2377           0 :         mpFloatWin->EndPopupMode( FloatWinPopupEndFlags::Cancel );
    2378           0 :         mpCalendar->EndSelection();
    2379           0 :         EndDropDown();
    2380             :     }
    2381           0 :     return true;
    2382             : }
    2383             : 
    2384           0 : VclPtr<Calendar> CalendarField::CreateCalendar( vcl::Window* pParent )
    2385             : {
    2386           0 :     return VclPtr<Calendar>::Create( pParent, mnCalendarStyle | WB_TABSTOP );
    2387             : }
    2388             : 
    2389           0 : Calendar* CalendarField::GetCalendar()
    2390             : {
    2391           0 :     if ( !mpFloatWin )
    2392             :     {
    2393           0 :         mpFloatWin = VclPtr<ImplCFieldFloatWin>::Create( this );
    2394           0 :         mpFloatWin->SetPopupModeEndHdl( LINK( this, CalendarField, ImplPopupModeEndHdl ) );
    2395           0 :         mpCalendar = CreateCalendar( mpFloatWin );
    2396           0 :         mpCalendar->SetPosPixel( Point() );
    2397           0 :         mpCalendar->SetSelectHdl( LINK( this, CalendarField, ImplSelectHdl ) );
    2398             :     }
    2399             : 
    2400           0 :     return mpCalendar;
    2401             : }
    2402             : 
    2403        1097 : void CalendarField::StateChanged( StateChangedType nStateChange )
    2404             : {
    2405        1097 :     DateField::StateChanged( nStateChange );
    2406             : 
    2407        1097 :     if ( ( nStateChange == StateChangedType::Style ) && GetSubEdit() )
    2408             :     {
    2409          94 :         WinBits nAllAlignmentBits = ( WB_LEFT | WB_CENTER | WB_RIGHT | WB_TOP | WB_VCENTER | WB_BOTTOM );
    2410          94 :         WinBits nMyAlignment = GetStyle() & nAllAlignmentBits;
    2411          94 :         GetSubEdit()->SetStyle( ( GetSubEdit()->GetStyle() & ~nAllAlignmentBits ) | nMyAlignment );
    2412             :     }
    2413        1895 : }
    2414             : 
    2415             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11