1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <vcl/svapp.hxx>
21 #include <vcl/help.hxx>
22 #include <vcl/menu.hxx>
23 #include <vcl/settings.hxx>
24 #include <vcl/event.hxx>
25 #include <vcl/commandevent.hxx>
26 #include <unotools/calendarwrapper.hxx>
27 #include <unotools/localedatawrapper.hxx>
28 #include <com/sun/star/i18n/Weekdays.hpp>
29 #include <com/sun/star/i18n/CalendarDisplayIndex.hpp>
30 #include <com/sun/star/i18n/CalendarFieldIndex.hpp>
31 #include <sal/log.hxx>
33 #include <vcl/calendar.hxx>
35 #include <strings.hrc>
40 #define MONTH_BORDERX 4
42 #define WEEKDAY_OFFY 3
44 #define TITLE_BORDERY 2
46 #define SPIN_OFFY TITLE_BORDERY
48 #define CALENDAR_HITTEST_DAY (sal_uInt16(0x0001))
49 #define CALENDAR_HITTEST_MONTHTITLE (sal_uInt16(0x0004))
50 #define CALENDAR_HITTEST_PREV (sal_uInt16(0x0008))
51 #define CALENDAR_HITTEST_NEXT (sal_uInt16(0x0010))
53 #define MENU_YEAR_COUNT 3
55 using namespace ::com::sun::star
;
57 static void ImplCalendarSelectDate( IntDateSet
* pTable
, const Date
& rDate
, bool bSelect
)
60 pTable
->insert( rDate
.GetDate() );
62 pTable
->erase( rDate
.GetDate() );
67 void Calendar::ImplInit( WinBits nWinStyle
)
69 mpSelectTable
.reset(new IntDateSet
);
71 mnWinStyle
= nWinStyle
;
82 mbTravelSelect
= false;
85 OUString
aGregorian( "gregorian");
86 maCalendarWrapper
.loadCalendar( aGregorian
,
87 Application::GetAppLocaleDataWrapper().getLanguageTag().getLocale());
88 if (maCalendarWrapper
.getUniqueID() != aGregorian
)
90 SAL_WARN( "vcl.control", "Calendar::ImplInit: No ``gregorian'' calendar available for locale ``"
91 << Application::GetAppLocaleDataWrapper().getLanguageTag().getBcp47()
92 << "'' and other calendars aren't supported. Using en-US fallback." );
94 /* If we ever wanted to support other calendars than Gregorian a lot of
95 * rewrite would be necessary to internally replace use of class Date
96 * with proper class CalendarWrapper methods, get rid of fixed 12
97 * months, fixed 7 days, ... */
98 maCalendarWrapper
.loadCalendar( aGregorian
, lang::Locale( "en", "US", ""));
101 SetFirstDate( maCurDate
);
102 ImplCalendarSelectDate( mpSelectTable
.get(), maCurDate
, true );
104 // Sonstige Strings erzeugen
105 maDayText
= VclResId(STR_SVT_CALENDAR_DAY
);
106 maWeekText
= VclResId(STR_SVT_CALENDAR_WEEK
);
108 // Tagestexte anlegen
109 for (sal_Int32 i
= 0; i
< 31; ++i
)
110 maDayTexts
[i
] = OUString::number(i
+1);
115 void Calendar::ApplySettings(vcl::RenderContext
& rRenderContext
)
117 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
118 maSelColor
= rStyleSettings
.GetHighlightTextColor();
119 SetPointFont(rRenderContext
, rStyleSettings
.GetToolFont());
120 rRenderContext
.SetTextColor(rStyleSettings
.GetFieldTextColor());
121 rRenderContext
.SetBackground(Wallpaper(rStyleSettings
.GetFieldColor()));
124 void Calendar::ImplInitSettings()
126 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
127 maSelColor
= rStyleSettings
.GetHighlightTextColor();
128 SetPointFont(*this, rStyleSettings
.GetToolFont());
129 SetTextColor(rStyleSettings
.GetFieldTextColor());
130 SetBackground(Wallpaper(rStyleSettings
.GetFieldColor()));
133 Calendar::Calendar( vcl::Window
* pParent
, WinBits nWinStyle
) :
134 Control( pParent
, nWinStyle
& (WB_TABSTOP
| WB_GROUP
| WB_BORDER
| WB_3DLOOK
) ),
135 maCalendarWrapper( Application::GetAppLocaleDataWrapper().getComponentContext() ),
136 maOldFormatFirstDate( 0, 0, 1900 ),
137 maOldFormatLastDate( 0, 0, 1900 ),
138 maFirstDate( 0, 0, 1900 ),
139 maOldFirstDate( 0, 0, 1900 ),
140 maCurDate( Date::SYSTEM
),
141 maOldCurDate( 0, 0, 1900 )
143 ImplInit( nWinStyle
);
146 Calendar::~Calendar()
151 void Calendar::dispose()
153 mpSelectTable
.reset();
154 mpOldSelectTable
.reset();
158 DayOfWeek
Calendar::ImplGetWeekStart() const
160 // Map i18n::Weekdays to Date DayOfWeek
162 sal_Int16 nDay
= maCalendarWrapper
.getFirstDayOfWeek();
165 case i18n::Weekdays::SUNDAY
:
168 case i18n::Weekdays::MONDAY
:
171 case i18n::Weekdays::TUESDAY
:
174 case i18n::Weekdays::WEDNESDAY
:
177 case i18n::Weekdays::THURSDAY
:
180 case i18n::Weekdays::FRIDAY
:
183 case i18n::Weekdays::SATURDAY
:
187 SAL_WARN( "vcl.control", "Calendar::ImplGetWeekStart: broken i18n Gregorian calendar (getFirstDayOfWeek())");
193 void Calendar::ImplFormat()
200 Size aOutSize
= GetOutputSizePixel();
202 if ( (aOutSize
.Width() <= 1) || (aOutSize
.Height() <= 1) )
205 OUString
const a99Text("99");
207 vcl::Font aOldFont
= GetFont();
209 long n99TextWidth
= GetTextWidth( a99Text
);
210 long nTextHeight
= GetTextHeight();
212 // calculate width and x-position
213 mnDayWidth
= n99TextWidth
+DAY_OFFX
;
214 mnMonthWidth
= mnDayWidth
*7;
215 mnMonthWidth
+= MONTH_BORDERX
*2;
216 mnMonthPerLine
= aOutSize
.Width() / mnMonthWidth
;
217 if ( !mnMonthPerLine
)
219 long nOver
= (aOutSize
.Width()-(mnMonthPerLine
*mnMonthWidth
)) / mnMonthPerLine
;
220 mnMonthWidth
+= nOver
;
221 mnDaysOffX
= MONTH_BORDERX
;
222 mnDaysOffX
+= nOver
/2;
224 // calculate height and y-position
225 mnDayHeight
= nTextHeight
+ DAY_OFFY
;
226 mnWeekDayOffY
= nTextHeight
+ TITLE_OFFY
+ (TITLE_BORDERY
*2);
227 mnDaysOffY
= mnWeekDayOffY
+ nTextHeight
+ WEEKDAY_OFFY
;
228 mnMonthHeight
= (mnDayHeight
*6) + mnDaysOffY
;
229 mnMonthHeight
+= MONTH_OFFY
;
230 mnLines
= aOutSize
.Height() / mnMonthHeight
;
233 mnMonthHeight
+= (aOutSize
.Height()-(mnLines
*mnMonthHeight
)) / mnLines
;
235 // calculate spinfields
236 long nSpinSize
= nTextHeight
+TITLE_BORDERY
-SPIN_OFFY
;
237 maPrevRect
.SetLeft( SPIN_OFFX
);
238 maPrevRect
.SetTop( SPIN_OFFY
);
239 maPrevRect
.SetRight( maPrevRect
.Left()+nSpinSize
);
240 maPrevRect
.SetBottom( maPrevRect
.Top()+nSpinSize
);
241 maNextRect
.SetLeft( aOutSize
.Width()-SPIN_OFFX
-nSpinSize
-1 );
242 maNextRect
.SetTop( SPIN_OFFY
);
243 maNextRect
.SetRight( maNextRect
.Left()+nSpinSize
);
244 maNextRect
.SetBottom( maNextRect
.Top()+nSpinSize
);
246 // Calculate DayOfWeekText (gets displayed in a narrow font)
247 maDayOfWeekText
.clear();
249 sal_Int16 nDay
= maCalendarWrapper
.getFirstDayOfWeek();
250 for ( sal_Int16 nDayOfWeek
= 0; nDayOfWeek
< 7; nDayOfWeek
++ )
253 OUString
aDayOfWeek( maCalendarWrapper
.getDisplayName(
254 i18n::CalendarDisplayIndex::DAY
, nDay
, 2));
255 long nOffX
= (mnDayWidth
-GetTextWidth( aDayOfWeek
))/2;
260 nOffX
+= nDayOfWeek
* mnDayWidth
;
261 mnDayOfWeekAry
[nDayOfWeek
] = nOffX
;
262 maDayOfWeekText
+= aDayOfWeek
;
270 // calculate number of days
272 DayOfWeek eStartDay
= ImplGetWeekStart();
275 Date aTempDate
= GetFirstMonth();
276 maFirstDate
= aTempDate
;
277 nWeekDay
= static_cast<sal_uInt16
>(aTempDate
.GetDayOfWeek());
278 nWeekDay
= (nWeekDay
+(7-static_cast<sal_uInt16
>(eStartDay
))) % 7;
279 maFirstDate
.AddDays( -nWeekDay
);
280 mnDayCount
= nWeekDay
;
281 sal_uInt16 nDaysInMonth
;
282 sal_uInt16 nMonthCount
= static_cast<sal_uInt16
>(mnMonthPerLine
*mnLines
);
283 for ( sal_uInt16 i
= 0; i
< nMonthCount
; i
++ )
285 nDaysInMonth
= aTempDate
.GetDaysInMonth();
286 mnDayCount
+= nDaysInMonth
;
287 aTempDate
.AddDays( nDaysInMonth
);
289 Date aTempDate2
= aTempDate
;
291 nDaysInMonth
= aTempDate2
.GetDaysInMonth();
292 aTempDate2
.AddDays( -(nDaysInMonth
-1) );
293 nWeekDay
= static_cast<sal_uInt16
>(aTempDate2
.GetDayOfWeek());
294 nWeekDay
= (nWeekDay
+(7-static_cast<sal_uInt16
>(eStartDay
))) % 7;
295 mnDayCount
+= 42-nDaysInMonth
-nWeekDay
;
298 maOtherColor
= COL_LIGHTGRAY
;
299 if ( maOtherColor
.IsRGBEqual( GetBackground().GetColor() ) )
300 maOtherColor
= COL_GRAY
;
302 Date aLastDate
= GetLastDate();
303 if ( (maOldFormatLastDate
!= aLastDate
) ||
304 (maOldFormatFirstDate
!= maFirstDate
) )
306 maOldFormatFirstDate
= maFirstDate
;
307 maOldFormatLastDate
= aLastDate
;
311 sal_Int16 nNewFirstYear
= maFirstDate
.GetYear();
312 sal_Int16 nNewLastYear
= GetLastDate().GetYear();
315 if ( nNewFirstYear
< mnFirstYear
)
317 mnFirstYear
= nNewFirstYear
;
319 if ( nNewLastYear
> mnLastYear
)
321 mnLastYear
= nNewLastYear
;
326 mnFirstYear
= nNewFirstYear
;
327 mnLastYear
= nNewLastYear
;
333 sal_uInt16
Calendar::ImplHitTest( const Point
& rPos
, Date
& rDate
) const
338 if ( maPrevRect
.IsInside( rPos
) )
339 return CALENDAR_HITTEST_PREV
;
340 else if ( maNextRect
.IsInside( rPos
) )
341 return CALENDAR_HITTEST_NEXT
;
346 DayOfWeek eStartDay
= ImplGetWeekStart();
348 rDate
= GetFirstMonth();
350 for ( long i
= 0; i
< mnLines
; i
++ )
356 long nYMonth
= nY
+mnMonthHeight
;
357 for ( long j
= 0; j
< mnMonthPerLine
; j
++ )
359 if ( (rPos
.X() < nX
) && (rPos
.Y() < nYMonth
) )
362 sal_uInt16 nDaysInMonth
= rDate
.GetDaysInMonth();
364 // matching month was found
365 if ( (rPos
.X() > nX
) && (rPos
.Y() < nYMonth
) &&
366 (rPos
.X() < nX
+mnMonthWidth
) )
368 if ( rPos
.Y() < (nY
+(TITLE_BORDERY
*2)+mnDayHeight
))
369 return CALENDAR_HITTEST_MONTHTITLE
;
372 long nDayX
= nX
+mnDaysOffX
;
373 long nDayY
= nY
+mnDaysOffY
;
374 if ( rPos
.Y() < nDayY
)
376 sal_Int32 nDayIndex
= static_cast<sal_Int32
>(rDate
.GetDayOfWeek());
377 nDayIndex
= (nDayIndex
+(7-static_cast<sal_Int32
>(eStartDay
))) % 7;
378 if ( (i
== 0) && (j
== 0) )
380 Date aTempDate
= rDate
;
381 aTempDate
.AddDays( -nDayIndex
);
382 for ( nDay
= 0; nDay
< nDayIndex
; nDay
++ )
384 nOffX
= nDayX
+ (nDay
*mnDayWidth
);
385 if ( (rPos
.Y() >= nDayY
) && (rPos
.Y() < nDayY
+mnDayHeight
) &&
386 (rPos
.X() >= nOffX
) && (rPos
.X() < nOffX
+mnDayWidth
) )
389 rDate
.AddDays( nDay
);
390 return CALENDAR_HITTEST_DAY
;
394 for ( nDay
= 1; nDay
<= nDaysInMonth
; nDay
++ )
396 if ( rPos
.Y() < nDayY
)
398 rDate
.AddDays( nDayIndex
);
401 nOffX
= nDayX
+ (nDayIndex
*mnDayWidth
);
402 if ( (rPos
.Y() >= nDayY
) && (rPos
.Y() < nDayY
+mnDayHeight
) &&
403 (rPos
.X() >= nOffX
) && (rPos
.X() < nOffX
+mnDayWidth
) )
405 rDate
.AddDays( nDay
-1 );
406 return CALENDAR_HITTEST_DAY
;
408 if ( nDayIndex
== 6 )
411 nDayY
+= mnDayHeight
;
416 if ( (i
== mnLines
-1) && (j
== mnMonthPerLine
-1) )
418 sal_uInt16 nWeekDay
= static_cast<sal_uInt16
>(rDate
.GetDayOfWeek());
419 nWeekDay
= (nWeekDay
+(7-static_cast<sal_uInt16
>(eStartDay
))) % 7;
420 sal_Int32 nDayCount
= 42-nDaysInMonth
-nWeekDay
;
421 Date aTempDate
= rDate
;
422 aTempDate
.AddDays( nDaysInMonth
);
423 for ( nDay
= 1; nDay
<= nDayCount
; nDay
++ )
425 if ( rPos
.Y() < nDayY
)
427 rDate
.AddDays( nDayIndex
);
430 nOffX
= nDayX
+ (nDayIndex
*mnDayWidth
);
431 if ( (rPos
.Y() >= nDayY
) && (rPos
.Y() < nDayY
+mnDayHeight
) &&
432 (rPos
.X() >= nOffX
) && (rPos
.X() < nOffX
+mnDayWidth
) )
435 rDate
.AddDays( nDay
-1 );
436 return CALENDAR_HITTEST_DAY
;
438 if ( nDayIndex
== 6 )
441 nDayY
+= mnDayHeight
;
450 rDate
.AddDays( nDaysInMonth
);
463 void ImplDrawSpinArrow(vcl::RenderContext
& rRenderContext
, const tools::Rectangle
& rRect
, bool bPrev
)
468 long nHeight
= rRect
.GetHeight();
469 long nWidth
= rRect
.GetWidth();
470 if (nWidth
< nHeight
)
478 tools::Rectangle
aRect(Point( rRect
.Left() + (nWidth
/ 2) - (nLines
/ 2),
479 rRect
.Top() + (nHeight
/ 2) ),
483 aRect
.AdjustLeft(nLines
);
484 aRect
.AdjustRight(nLines
);
487 rRenderContext
.DrawRect(aRect
);
488 for (i
= 0; i
< nLines
; i
++)
492 aRect
.AdjustLeft( 1 );
493 aRect
.AdjustRight( 1 );
497 aRect
.AdjustLeft( -1 );
498 aRect
.AdjustRight( -1 );
500 aRect
.AdjustTop( -1 );
501 aRect
.AdjustBottom( 1 );
502 rRenderContext
.DrawRect(aRect
);
506 } //end anonymous namespace
508 void Calendar::ImplDrawSpin(vcl::RenderContext
& rRenderContext
)
510 rRenderContext
.SetLineColor();
511 rRenderContext
.SetFillColor(rRenderContext
.GetSettings().GetStyleSettings().GetButtonTextColor());
512 tools::Rectangle aOutRect
= maPrevRect
;
513 aOutRect
.AdjustLeft(3 );
514 aOutRect
.AdjustTop(3 );
515 aOutRect
.AdjustRight( -3 );
516 aOutRect
.AdjustBottom( -3 );
517 ImplDrawSpinArrow(rRenderContext
, aOutRect
, true);
518 aOutRect
= maNextRect
;
519 aOutRect
.AdjustLeft(3 );
520 aOutRect
.AdjustTop(3 );
521 aOutRect
.AdjustRight( -3 );
522 aOutRect
.AdjustBottom( -3 );
523 ImplDrawSpinArrow(rRenderContext
, aOutRect
, false);
526 void Calendar::ImplDrawDate(vcl::RenderContext
& rRenderContext
,
528 sal_uInt16 nDay
, sal_uInt16 nMonth
, sal_Int16 nYear
,
529 bool bOther
, sal_Int32 nToday
)
531 Color
const * pTextColor
= nullptr;
532 const OUString
& rDay
= maDayTexts
[nDay
- 1];
533 tools::Rectangle
aDateRect(nX
, nY
, nX
+ mnDayWidth
- 1, nY
+ mnDayHeight
- 1);
538 if ((nDay
== maCurDate
.GetDay()) &&
539 (nMonth
== maCurDate
.GetMonth()) &&
540 (nYear
== maCurDate
.GetYear()))
546 if (mpSelectTable
->find(Date(nDay
, nMonth
, nYear
).GetDate()) != mpSelectTable
->end())
552 pTextColor
= &maSelColor
;
554 pTextColor
= &maOtherColor
;
559 // display background
560 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
563 rRenderContext
.SetLineColor();
564 rRenderContext
.SetFillColor(rStyleSettings
.GetHighlightColor());
565 rRenderContext
.DrawRect(aDateRect
);
569 long nTextX
= nX
+ (mnDayWidth
- GetTextWidth(rDay
)) - (DAY_OFFX
/ 2);
570 long nTextY
= nY
+ (mnDayHeight
- GetTextHeight()) / 2;
573 Color aOldColor
= rRenderContext
.GetTextColor();
574 rRenderContext
.SetTextColor(*pTextColor
);
575 rRenderContext
.DrawText(Point(nTextX
, nTextY
), rDay
);
576 rRenderContext
.SetTextColor(aOldColor
);
579 rRenderContext
.DrawText(Point(nTextX
, nTextY
), rDay
);
582 Date
aTodayDate(maCurDate
);
584 aTodayDate
.SetDate(nToday
);
586 aTodayDate
= Date(Date::SYSTEM
);
587 if ((nDay
== aTodayDate
.GetDay()) &&
588 (nMonth
== aTodayDate
.GetMonth()) &&
589 (nYear
== aTodayDate
.GetYear()))
591 rRenderContext
.SetLineColor(rStyleSettings
.GetWindowTextColor());
592 rRenderContext
.SetFillColor();
593 rRenderContext
.DrawRect(aDateRect
);
596 // if needed do FocusRect
597 if (bFocus
&& HasFocus())
598 ShowFocus(aDateRect
);
601 void Calendar::ImplDraw(vcl::RenderContext
& rRenderContext
)
605 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
606 Size
aOutSize(GetOutputSizePixel());
614 sal_Int32 nToday
= Date(Date::SYSTEM
).GetDate();
618 Date aDate
= GetFirstMonth();
619 DayOfWeek eStartDay
= ImplGetWeekStart();
624 for (i
= 0; i
< mnLines
; i
++)
627 rRenderContext
.SetLineColor();
628 rRenderContext
.SetFillColor(rStyleSettings
.GetFaceColor());
629 tools::Rectangle
aTitleRect(0, nY
, aOutSize
.Width() - 1, nY
+ mnDayHeight
- DAY_OFFY
+ TITLE_BORDERY
* 2);
630 rRenderContext
.DrawRect(aTitleRect
);
631 Point
aTopLeft1(aTitleRect
.Left(), aTitleRect
.Top());
632 Point
aTopLeft2(aTitleRect
.Left(), aTitleRect
.Top() + 1);
633 Point
aBottomRight1(aTitleRect
.Right(), aTitleRect
.Bottom());
634 Point
aBottomRight2(aTitleRect
.Right(), aTitleRect
.Bottom() - 1);
635 rRenderContext
.SetLineColor(rStyleSettings
.GetDarkShadowColor());
636 rRenderContext
.DrawLine(aTopLeft1
, Point(aBottomRight1
.X(), aTopLeft1
.Y()));
637 rRenderContext
.SetLineColor(rStyleSettings
.GetLightColor() );
638 rRenderContext
.DrawLine(aTopLeft2
, Point(aBottomRight2
.X(), aTopLeft2
.Y()));
639 rRenderContext
.DrawLine(aTopLeft2
, Point(aTopLeft2
.X(), aBottomRight2
.Y()));
640 rRenderContext
.SetLineColor(rStyleSettings
.GetShadowColor() );
641 rRenderContext
.DrawLine(Point(aTopLeft2
.X(), aBottomRight2
.Y()), aBottomRight2
);
642 rRenderContext
.DrawLine(Point(aBottomRight2
.X(), aTopLeft2
.Y()), aBottomRight2
);
643 rRenderContext
.SetLineColor(rStyleSettings
.GetDarkShadowColor());
644 rRenderContext
.DrawLine(Point(aTopLeft1
.X(), aBottomRight1
.Y()), aBottomRight1
);
645 Point
aSepPos1(0, aTitleRect
.Top() + TITLE_BORDERY
);
646 Point
aSepPos2(0, aTitleRect
.Bottom() - TITLE_BORDERY
);
647 for (j
= 0; j
< mnMonthPerLine
-1; j
++)
649 aSepPos1
.AdjustX(mnMonthWidth
-1 );
650 aSepPos2
.setX( aSepPos1
.X() );
651 rRenderContext
.SetLineColor(rStyleSettings
.GetShadowColor());
652 rRenderContext
.DrawLine(aSepPos1
, aSepPos2
);
653 aSepPos1
.AdjustX( 1 );
654 aSepPos2
.setX( aSepPos1
.X() );
655 rRenderContext
.SetLineColor(rStyleSettings
.GetLightColor());
656 rRenderContext
.DrawLine(aSepPos1
, aSepPos2
);
660 for (j
= 0; j
< mnMonthPerLine
; j
++)
662 nMonth
= aDate
.GetMonth();
663 nYear
= aDate
.GetYear();
665 // display month in title bar
667 nDeltaY
= nY
+ TITLE_BORDERY
;
668 OUString aMonthText
= maCalendarWrapper
.getDisplayName(i18n::CalendarDisplayIndex::MONTH
, nMonth
- 1, 1)
670 + OUString::number(nYear
);
671 long nMonthTextWidth
= rRenderContext
.GetTextWidth(aMonthText
);
672 long nMonthOffX1
= 0;
673 long nMonthOffX2
= 0;
677 nMonthOffX1
= maPrevRect
.Right() + 1;
678 if (j
== mnMonthPerLine
- 1)
679 nMonthOffX2
= aOutSize
.Width() - maNextRect
.Left() + 1;
681 long nMaxMonthWidth
= mnMonthWidth
- nMonthOffX1
- nMonthOffX2
- 4;
682 if (nMonthTextWidth
> nMaxMonthWidth
)
684 // Abbreviated month name.
685 aMonthText
= maCalendarWrapper
.getDisplayName(i18n::CalendarDisplayIndex::MONTH
, nMonth
- 1, 0)
687 + OUString::number(nYear
);
688 nMonthTextWidth
= rRenderContext
.GetTextWidth(aMonthText
);
690 long nTempOff
= (mnMonthWidth
- nMonthTextWidth
+ 1) / 2;
691 if (nTempOff
< nMonthOffX1
)
692 nDeltaX
+= nMonthOffX1
+ 1;
695 if (nTempOff
+ nMonthTextWidth
> mnMonthWidth
- nMonthOffX2
)
696 nDeltaX
+= mnMonthWidth
- nMonthOffX2
- nMonthTextWidth
;
700 rRenderContext
.SetTextColor(rStyleSettings
.GetButtonTextColor());
701 rRenderContext
.DrawText(Point(nDeltaX
, nDeltaY
), aMonthText
);
702 rRenderContext
.SetTextColor(rStyleSettings
.GetWindowTextColor());
705 nDayX
= nX
+ mnDaysOffX
;
706 nDayY
= nY
+ mnWeekDayOffY
;
707 nDeltaY
= nDayY
+ mnDayHeight
;
708 rRenderContext
.SetLineColor(rStyleSettings
.GetWindowTextColor());
709 Point
aStartPos(nDayX
, nDeltaY
);
710 rRenderContext
.DrawLine(aStartPos
, Point(nDayX
+ (7 * mnDayWidth
), nDeltaY
));
711 rRenderContext
.DrawTextArray(Point(nDayX
+ mnDayOfWeekAry
[0], nDayY
), maDayOfWeekText
, &(mnDayOfWeekAry
[1]));
714 sal_uInt16 nDaysInMonth
= aDate
.GetDaysInMonth();
715 nDayX
= nX
+ mnDaysOffX
;
716 nDayY
= nY
+ mnDaysOffY
;
717 sal_uInt16 nDayIndex
= static_cast<sal_uInt16
>(aDate
.GetDayOfWeek());
718 nDayIndex
= (nDayIndex
+ (7 - static_cast<sal_uInt16
>(eStartDay
))) % 7;
719 if (i
== 0 && j
== 0)
721 Date aTempDate
= aDate
;
722 aTempDate
.AddDays( -nDayIndex
);
723 for (nDay
= 0; nDay
< nDayIndex
; ++nDay
)
725 nDeltaX
= nDayX
+ (nDay
* mnDayWidth
);
726 ImplDrawDate(rRenderContext
, nDeltaX
, nDayY
, nDay
+ aTempDate
.GetDay(),
727 aTempDate
.GetMonth(), aTempDate
.GetYear(),
731 for (nDay
= 1; nDay
<= nDaysInMonth
; nDay
++)
733 nDeltaX
= nDayX
+ (nDayIndex
* mnDayWidth
);
734 ImplDrawDate(rRenderContext
, nDeltaX
, nDayY
, nDay
, nMonth
, nYear
,
739 nDayY
+= mnDayHeight
;
744 if ((i
== mnLines
- 1) && (j
== mnMonthPerLine
- 1))
746 sal_uInt16 nWeekDay
= static_cast<sal_uInt16
>(aDate
.GetDayOfWeek());
747 nWeekDay
= (nWeekDay
+ (7 - static_cast<sal_uInt16
>(eStartDay
))) % 7;
748 sal_uInt16 nDayCount
= 42 - nDaysInMonth
- nWeekDay
;
749 Date aTempDate
= aDate
;
750 aTempDate
.AddDays( nDaysInMonth
);
751 for (nDay
= 1; nDay
<= nDayCount
; ++nDay
)
753 nDeltaX
= nDayX
+ (nDayIndex
* mnDayWidth
);
754 ImplDrawDate(rRenderContext
, nDeltaX
, nDayY
, nDay
,
755 aTempDate
.GetMonth(), aTempDate
.GetYear(),
760 nDayY
+= mnDayHeight
;
767 aDate
.AddDays( nDaysInMonth
);
775 ImplDrawSpin(rRenderContext
);
778 void Calendar::ImplUpdateDate( const Date
& rDate
)
780 if (IsReallyVisible() && IsUpdateMode())
782 tools::Rectangle
aDateRect(GetDateRect(rDate
));
783 if (!aDateRect
.IsEmpty())
785 Invalidate(aDateRect
);
790 void Calendar::ImplUpdateSelection( IntDateSet
* pOld
)
792 IntDateSet
* pNew
= mpSelectTable
.get();
794 for (auto const& nKey
: *pOld
)
796 if ( pNew
->find(nKey
) == pNew
->end() )
798 Date
aTempDate(nKey
);
799 ImplUpdateDate(aTempDate
);
803 for (auto const& nKey
: *pNew
)
805 if ( pOld
->find(nKey
) == pOld
->end() )
807 Date
aTempDate(nKey
);
808 ImplUpdateDate(aTempDate
);
813 void Calendar::ImplMouseSelect( const Date
& rDate
, sal_uInt16 nHitTest
)
815 std::unique_ptr
<IntDateSet
> pOldSel(new IntDateSet( *mpSelectTable
));
816 Date aOldDate
= maCurDate
;
817 Date aTempDate
= rDate
;
819 if ( !(nHitTest
& CALENDAR_HITTEST_DAY
) )
822 if ( !(nHitTest
& CALENDAR_HITTEST_DAY
) )
823 aTempDate
= maOldCurDate
;
824 if ( aTempDate
!= maCurDate
)
826 maCurDate
= aTempDate
;
827 ImplCalendarSelectDate( mpSelectTable
.get(), aOldDate
, false );
828 ImplCalendarSelectDate( mpSelectTable
.get(), maCurDate
, true );
831 bool bNewSel
= *pOldSel
!= *mpSelectTable
;
832 if ( (maCurDate
!= aOldDate
) || bNewSel
)
836 ImplUpdateSelection( pOldSel
.get() );
837 if ( !bNewSel
|| pOldSel
->find( aOldDate
.GetDate() ) == pOldSel
->end() )
838 ImplUpdateDate( aOldDate
);
839 // assure focus rectangle is displayed again
840 if ( HasFocus() || !bNewSel
841 || mpSelectTable
->find( maCurDate
.GetDate() ) == mpSelectTable
->end() )
842 ImplUpdateDate( maCurDate
);
846 void Calendar::ImplUpdate( bool bCalcNew
)
848 if (IsReallyVisible() && IsUpdateMode())
850 if (bCalcNew
&& !mbCalc
)
854 else if (!mbFormat
&& !mbCalc
)
865 void Calendar::ImplScroll( bool bPrev
)
867 Date aNewFirstMonth
= GetFirstMonth();
871 aNewFirstMonth
.AddDays( -(aNewFirstMonth
.GetDaysInMonth()-1));
874 aNewFirstMonth
.AddDays( aNewFirstMonth
.GetDaysInMonth());
875 SetFirstDate( aNewFirstMonth
);
878 void Calendar::ImplShowMenu( const Point
& rPos
, const Date
& rDate
)
882 Date aOldFirstDate
= GetFirstMonth();
883 ScopedVclPtrInstance
<PopupMenu
> aPopupMenu
;
884 sal_uInt16 nMonthOff
;
885 sal_uInt16 nCurItemId
;
886 sal_uInt16 nYear
= rDate
.GetYear()-1;
889 sal_uInt16 nYearIdCount
= 1000;
891 nMonthOff
= (rDate
.GetYear()-aOldFirstDate
.GetYear())*12;
892 if ( aOldFirstDate
.GetMonth() < rDate
.GetMonth() )
893 nMonthOff
+= rDate
.GetMonth()-aOldFirstDate
.GetMonth();
895 nMonthOff
-= aOldFirstDate
.GetMonth()-rDate
.GetMonth();
897 // construct menu (include years with different months)
898 for ( i
= 0; i
< MENU_YEAR_COUNT
; i
++ )
900 VclPtrInstance
<PopupMenu
> pYearPopupMenu
;
901 for ( j
= 1; j
<= 12; j
++ )
902 pYearPopupMenu
->InsertItem( nYearIdCount
+j
,
903 maCalendarWrapper
.getDisplayName(
904 i18n::CalendarDisplayIndex::MONTH
, j
-1, 1));
905 aPopupMenu
->InsertItem( 10+i
, OUString::number( nYear
+i
) );
906 aPopupMenu
->SetPopupMenu( 10+i
, pYearPopupMenu
);
907 nYearIdCount
+= 1000;
911 nCurItemId
= aPopupMenu
->Execute( this, rPos
);
917 sal_uInt16 nTempMonthOff
= nMonthOff
% 12;
918 sal_uInt16 nTempYearOff
= nMonthOff
/ 12;
919 sal_uInt16 nNewMonth
= nCurItemId
% 1000;
920 sal_uInt16 nNewYear
= nYear
+((nCurItemId
-1000)/1000);
921 if ( nTempMonthOff
< nNewMonth
)
922 nNewMonth
= nNewMonth
- nTempMonthOff
;
926 nNewMonth
= 12-(nTempMonthOff
-nNewMonth
);
928 nNewYear
= nNewYear
- nTempYearOff
;
929 SetFirstDate( Date( 1, nNewMonth
, nNewYear
) );
932 void Calendar::ImplTracking( const Point
& rPos
, bool bRepeat
)
934 Date aTempDate
= maCurDate
;
935 sal_uInt16 nHitTest
= ImplHitTest( rPos
, aTempDate
);
939 mbPrevIn
= (nHitTest
& CALENDAR_HITTEST_PREV
) != 0;
940 mbNextIn
= (nHitTest
& CALENDAR_HITTEST_NEXT
) != 0;
942 if ( bRepeat
&& (mbPrevIn
|| mbNextIn
) )
944 ImplScroll( mbPrevIn
);
948 ImplMouseSelect( aTempDate
, nHitTest
);
951 void Calendar::ImplEndTracking( bool bCancel
)
953 bool bSelection
= mbSelection
;
954 bool bSpinDown
= mbSpinDown
;
964 if ( maOldFirstDate
!= maFirstDate
)
965 SetFirstDate( maOldFirstDate
);
969 std::unique_ptr
<IntDateSet
> pOldSel(new IntDateSet( *mpSelectTable
));
970 Date aOldDate
= maCurDate
;
971 maCurDate
= maOldCurDate
;
972 *mpSelectTable
= *mpOldSelectTable
;
974 ImplUpdateSelection( pOldSel
.get() );
975 if ( pOldSel
->find( aOldDate
.GetDate() ) == pOldSel
->end() )
976 ImplUpdateDate( aOldDate
);
977 // assure focus rectangle is displayed again
978 if ( HasFocus() || mpSelectTable
->find( maCurDate
.GetDate() ) == mpSelectTable
->end() )
979 ImplUpdateDate( maCurDate
);
988 // determine if we should scroll the visible area
989 if ( !mpSelectTable
->empty() )
991 Date
aFirstSelDate( *mpSelectTable
->begin() );
992 Date
aLastSelDate( *mpSelectTable
->rbegin() );
993 if ( aLastSelDate
< GetFirstMonth() )
995 else if ( GetLastMonth() < aFirstSelDate
)
1001 (!bCancel
&& ((maCurDate
!= maOldCurDate
) || (*mpOldSelectTable
!= *mpSelectTable
))) )
1004 if ( !bSelection
&& (mnWinStyle
& WB_TABSTOP
) && !bCancel
)
1007 mpOldSelectTable
.reset();
1010 void Calendar::MouseButtonDown( const MouseEvent
& rMEvt
)
1012 if ( rMEvt
.IsLeft() && !mbMenuDown
)
1014 Date aTempDate
= maCurDate
;
1015 sal_uInt16 nHitTest
= ImplHitTest( rMEvt
.GetPosPixel(), aTempDate
);
1018 if ( nHitTest
& CALENDAR_HITTEST_MONTHTITLE
)
1019 ImplShowMenu( rMEvt
.GetPosPixel(), aTempDate
);
1022 maOldFirstDate
= maFirstDate
;
1024 mbPrevIn
= (nHitTest
& CALENDAR_HITTEST_PREV
) != 0;
1025 mbNextIn
= (nHitTest
& CALENDAR_HITTEST_NEXT
) != 0;
1026 if ( mbPrevIn
|| mbNextIn
)
1029 ImplScroll( mbPrevIn
);
1030 // it should really read BUTTONREPEAT, therefore do not
1031 // change it to SCROLLREPEAT, check with TH,
1032 // why it could be different (71775)
1033 StartTracking( StartTrackingFlags::ButtonRepeat
);
1037 if ( (rMEvt
.GetClicks() != 2) || !(nHitTest
& CALENDAR_HITTEST_DAY
) )
1039 maOldCurDate
= maCurDate
;
1040 mpOldSelectTable
.reset(new IntDateSet( *mpSelectTable
));
1048 ImplMouseSelect( aTempDate
, nHitTest
);
1050 if (rMEvt
.GetClicks() == 2)
1051 maActivateHdl
.Call(this);
1059 Control::MouseButtonDown( rMEvt
);
1062 void Calendar::MouseButtonUp( const MouseEvent
& rMEvt
)
1064 if ( rMEvt
.IsLeft() && mbSelection
)
1065 ImplEndTracking( false );
1067 Control::MouseButtonUp( rMEvt
);
1070 void Calendar::MouseMove( const MouseEvent
& rMEvt
)
1072 if ( mbSelection
&& rMEvt
.GetButtons() )
1073 ImplTracking( rMEvt
.GetPosPixel(), false );
1075 Control::MouseMove( rMEvt
);
1078 void Calendar::Tracking( const TrackingEvent
& rTEvt
)
1080 Point aMousePos
= rTEvt
.GetMouseEvent().GetPosPixel();
1082 if ( rTEvt
.IsTrackingEnded() )
1083 ImplEndTracking( rTEvt
.IsTrackingCanceled() );
1085 ImplTracking( aMousePos
, rTEvt
.IsTrackingRepeat() );
1088 void Calendar::KeyInput( const KeyEvent
& rKEvt
)
1090 Date aNewDate
= maCurDate
;
1092 switch ( rKEvt
.GetKeyCode().GetCode() )
1095 aNewDate
.SetDay( 1 );
1099 aNewDate
.SetDay( aNewDate
.GetDaysInMonth() );
1111 aNewDate
.AddDays( -7 );
1115 aNewDate
.AddDays( 7 );
1120 Date aTempDate
= aNewDate
;
1121 aTempDate
.AddDays( -(aNewDate
.GetDay()+1) );
1122 aNewDate
.AddDays( -aTempDate
.GetDaysInMonth() );
1127 aNewDate
.AddDays( aNewDate
.GetDaysInMonth() );
1134 Control::KeyInput( rKEvt
);
1138 if ( aNewDate
!= maCurDate
)
1140 SetCurDate( aNewDate
);
1141 mbTravelSelect
= true;
1143 mbTravelSelect
= false;
1146 if (rKEvt
.GetKeyCode().GetCode() == KEY_RETURN
)
1148 if (maActivateHdl
.IsSet())
1149 maActivateHdl
.Call(this);
1151 Control::KeyInput(rKEvt
);
1155 void Calendar::Paint( vcl::RenderContext
& rRenderContext
, const tools::Rectangle
& )
1157 ImplDraw(rRenderContext
);
1160 void Calendar::GetFocus()
1162 ImplUpdateDate( maCurDate
);
1163 Control::GetFocus();
1166 void Calendar::LoseFocus()
1169 Control::LoseFocus();
1172 void Calendar::Resize()
1178 void Calendar::RequestHelp( const HelpEvent
& rHEvt
)
1180 if ( rHEvt
.GetMode() & (HelpEventMode::QUICK
| HelpEventMode::BALLOON
) )
1182 Date aDate
= maCurDate
;
1183 if ( GetDate( ScreenToOutputPixel( rHEvt
.GetMousePosPixel() ), aDate
) )
1185 tools::Rectangle aDateRect
= GetDateRect( aDate
);
1186 Point aPt
= OutputToScreenPixel( aDateRect
.TopLeft() );
1187 aDateRect
.SetLeft( aPt
.X() );
1188 aDateRect
.SetTop( aPt
.Y() );
1189 aPt
= OutputToScreenPixel( aDateRect
.BottomRight() );
1190 aDateRect
.SetRight( aPt
.X() );
1191 aDateRect
.SetBottom( aPt
.Y() );
1193 if ( rHEvt
.GetMode() & HelpEventMode::QUICK
)
1195 maCalendarWrapper
.setGregorianDateTime( aDate
);
1196 sal_uInt16 nWeek
= static_cast<sal_uInt16
>(maCalendarWrapper
.getValue( i18n::CalendarFieldIndex::WEEK_OF_YEAR
));
1197 sal_uInt16 nMonth
= aDate
.GetMonth();
1198 OUString aStr
= maDayText
1200 + OUString::number(aDate
.GetDayOfYear())
1204 + OUString::number(nWeek
);
1205 // if year is not the same, add it
1206 if ( (nMonth
== 12) && (nWeek
== 1) )
1208 aStr
+= ", " + OUString::number(aDate
.GetNextYear());
1210 else if ( (nMonth
== 1) && (nWeek
> 50) )
1212 aStr
+= ", " + OUString::number(aDate
.GetYear()-1);
1214 Help::ShowQuickHelp( this, aDateRect
, aStr
);
1220 Control::RequestHelp( rHEvt
);
1223 void Calendar::Command( const CommandEvent
& rCEvt
)
1225 if ( rCEvt
.GetCommand() == CommandEventId::ContextMenu
)
1227 if ( !mbSelection
&& rCEvt
.IsMouseEvent() )
1229 Date aTempDate
= maCurDate
;
1230 sal_uInt16 nHitTest
= ImplHitTest( rCEvt
.GetMousePosPixel(), aTempDate
);
1231 if ( nHitTest
& CALENDAR_HITTEST_MONTHTITLE
)
1233 ImplShowMenu( rCEvt
.GetMousePosPixel(), aTempDate
);
1238 else if ( rCEvt
.GetCommand() == CommandEventId::Wheel
)
1240 const CommandWheelData
* pData
= rCEvt
.GetWheelData();
1241 if ( pData
->GetMode() == CommandWheelMode::SCROLL
)
1243 long nNotchDelta
= pData
->GetNotchDelta();
1244 if ( nNotchDelta
< 0 )
1246 while ( nNotchDelta
< 0 )
1254 while ( nNotchDelta
> 0 )
1256 ImplScroll( false );
1265 Control::Command( rCEvt
);
1268 void Calendar::StateChanged( StateChangedType nType
)
1270 Control::StateChanged( nType
);
1272 if ( nType
== StateChangedType::InitShow
)
1276 void Calendar::DataChanged( const DataChangedEvent
& rDCEvt
)
1278 Control::DataChanged( rDCEvt
);
1280 if ( (rDCEvt
.GetType() == DataChangedEventType::FONTS
) ||
1281 (rDCEvt
.GetType() == DataChangedEventType::FONTSUBSTITUTION
) ||
1282 ((rDCEvt
.GetType() == DataChangedEventType::SETTINGS
) &&
1283 (rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
)) )
1290 void Calendar::Select()
1292 maSelectHdl
.Call( this );
1295 Date
Calendar::GetFirstSelectedDate() const
1297 if ( !mpSelectTable
->empty() )
1298 return Date( *mpSelectTable
->begin() );
1301 Date
aDate( 0, 0, 0 );
1306 void Calendar::SetCurDate( const Date
& rNewDate
)
1308 if ( !rNewDate
.IsValidAndGregorian() )
1311 if ( maCurDate
== rNewDate
)
1314 bool bUpdate
= IsVisible() && IsUpdateMode();
1315 Date aOldDate
= maCurDate
;
1316 maCurDate
= rNewDate
;
1318 ImplCalendarSelectDate( mpSelectTable
.get(), aOldDate
, false );
1319 ImplCalendarSelectDate( mpSelectTable
.get(), maCurDate
, true );
1321 // shift actual date in the visible area
1322 if ( mbFormat
|| (maCurDate
< GetFirstMonth()) )
1323 SetFirstDate( maCurDate
);
1324 else if ( maCurDate
> GetLastMonth() )
1326 Date aTempDate
= GetLastMonth();
1327 long nDateOff
= maCurDate
-aTempDate
;
1328 if ( nDateOff
< 365 )
1330 Date aFirstDate
= GetFirstMonth();
1331 aFirstDate
.AddDays( aFirstDate
.GetDaysInMonth() );
1333 while ( nDateOff
> aTempDate
.GetDaysInMonth() )
1335 aFirstDate
.AddDays( aFirstDate
.GetDaysInMonth() );
1336 sal_Int32 nDaysInMonth
= aTempDate
.GetDaysInMonth();
1337 aTempDate
.AddDays( nDaysInMonth
);
1338 nDateOff
-= nDaysInMonth
;
1340 SetFirstDate( aFirstDate
);
1343 SetFirstDate( maCurDate
);
1350 ImplUpdateDate( aOldDate
);
1351 ImplUpdateDate( maCurDate
);
1356 void Calendar::SetFirstDate( const Date
& rNewFirstDate
)
1358 if ( maFirstDate
!= rNewFirstDate
)
1360 maFirstDate
= Date( 1, rNewFirstDate
.GetMonth(), rNewFirstDate
.GetYear() );
1365 Date
Calendar::GetFirstMonth() const
1367 if ( maFirstDate
.GetDay() > 1 )
1369 if ( maFirstDate
.GetMonth() == 12 )
1370 return Date( 1, 1, maFirstDate
.GetNextYear() );
1372 return Date( 1, maFirstDate
.GetMonth()+1, maFirstDate
.GetYear() );
1378 Date
Calendar::GetLastMonth() const
1380 Date aDate
= GetFirstMonth();
1381 sal_uInt16 nMonthCount
= GetMonthCount();
1382 for ( sal_uInt16 i
= 0; i
< nMonthCount
; i
++ )
1383 aDate
.AddDays( aDate
.GetDaysInMonth() );
1388 sal_uInt16
Calendar::GetMonthCount() const
1393 return static_cast<sal_uInt16
>(mnMonthPerLine
*mnLines
);
1396 bool Calendar::GetDate( const Point
& rPos
, Date
& rDate
) const
1398 Date aDate
= maCurDate
;
1399 sal_uInt16 nHitTest
= ImplHitTest( rPos
, aDate
);
1400 if ( nHitTest
& CALENDAR_HITTEST_DAY
)
1409 tools::Rectangle
Calendar::GetDateRect( const Date
& rDate
) const
1411 tools::Rectangle aRect
;
1413 if ( mbFormat
|| (rDate
< maFirstDate
) || (rDate
> (maFirstDate
+mnDayCount
)) )
1419 sal_uInt16 nDayIndex
;
1420 Date aDate
= GetFirstMonth();
1422 if ( rDate
< aDate
)
1424 aRect
= GetDateRect( aDate
);
1425 nDaysOff
= aDate
-rDate
;
1426 nX
= nDaysOff
*mnDayWidth
;
1427 aRect
.AdjustLeft( -nX
);
1428 aRect
.AdjustRight( -nX
);
1433 Date aLastDate
= GetLastMonth();
1434 if ( rDate
> aLastDate
)
1436 sal_Int32 nWeekDay
= static_cast<sal_Int32
>(aLastDate
.GetDayOfWeek());
1437 nWeekDay
= (nWeekDay
+(7-ImplGetWeekStart())) % 7;
1438 aLastDate
.AddDays( -nWeekDay
);
1439 aRect
= GetDateRect( aLastDate
);
1440 nDaysOff
= rDate
-aLastDate
;
1442 for ( sal_Int32 i
= 0; i
<= nDaysOff
; i
++ )
1444 if ( aLastDate
== rDate
)
1446 aRect
.AdjustLeft(nDayIndex
*mnDayWidth
);
1447 aRect
.SetRight( aRect
.Left()+mnDayWidth
);
1450 if ( nDayIndex
== 6 )
1453 aRect
.AdjustTop(mnDayHeight
);
1454 aRect
.AdjustBottom(mnDayHeight
);
1464 for ( long i
= 0; i
< mnLines
; i
++ )
1467 for ( long j
= 0; j
< mnMonthPerLine
; j
++ )
1469 sal_uInt16 nDaysInMonth
= aDate
.GetDaysInMonth();
1472 if ( (aDate
.GetMonth() == rDate
.GetMonth()) &&
1473 (aDate
.GetYear() == rDate
.GetYear()) )
1475 long nDayX
= nX
+mnDaysOffX
;
1476 long nDayY
= nY
+mnDaysOffY
;
1477 nDayIndex
= static_cast<sal_uInt16
>(aDate
.GetDayOfWeek());
1478 nDayIndex
= (nDayIndex
+(7-static_cast<sal_uInt16
>(ImplGetWeekStart()))) % 7;
1479 for ( sal_uInt16 nDay
= 1; nDay
<= nDaysInMonth
; nDay
++ )
1481 if ( nDay
== rDate
.GetDay() )
1483 aRect
.SetLeft( nDayX
+ (nDayIndex
*mnDayWidth
) );
1484 aRect
.SetTop( nDayY
);
1485 aRect
.SetRight( aRect
.Left()+mnDayWidth
);
1486 aRect
.SetBottom( aRect
.Top()+mnDayHeight
);
1489 if ( nDayIndex
== 6 )
1492 nDayY
+= mnDayHeight
;
1499 aDate
.AddDays( nDaysInMonth
);
1503 nY
+= mnMonthHeight
;
1509 void Calendar::StartSelection()
1511 maOldCurDate
= maCurDate
;
1512 mpOldSelectTable
.reset(new IntDateSet( *mpSelectTable
));
1517 void Calendar::EndSelection()
1519 if ( mbDrag
|| mbSpinDown
|| mbSelection
)
1525 mbSelection
= false;
1532 Size
Calendar::CalcWindowSizePixel() const
1534 OUString
const a99Text("99");
1535 vcl::Font aOldFont
= GetFont();
1538 long n99TextWidth
= GetTextWidth( a99Text
);
1539 long nTextHeight
= GetTextHeight();
1541 aSize
.AdjustWidth((n99TextWidth
+DAY_OFFX
)*7);
1542 aSize
.AdjustWidth(MONTH_BORDERX
*2 );
1544 aSize
.setHeight( nTextHeight
+ TITLE_OFFY
+ (TITLE_BORDERY
*2) );
1545 aSize
.AdjustHeight(nTextHeight
+ WEEKDAY_OFFY
);
1546 aSize
.AdjustHeight((nTextHeight
+DAY_OFFY
)*6);
1547 aSize
.AdjustHeight(MONTH_OFFY
);
1552 Size
Calendar::GetOptimalSize() const
1554 return CalcWindowSizePixel();
1557 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */