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 <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>
36 #include <svtools/svtools.hrc>
37 #include <svtools/svtresid.hxx>
38 #include <svtools/calendar.hxx>
39 #include <boost/scoped_ptr.hpp>
43 #define MONTH_BORDERX 4
45 #define WEEKNUMBER_OFFX 4
46 #define WEEKDAY_OFFY 3
48 #define TITLE_BORDERY 2
50 #define SPIN_OFFY TITLE_BORDERY
52 #define WEEKNUMBER_HEIGHT 85
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)
59 #define MENU_YEAR_COUNT 3
61 using namespace ::com::sun::star
;
63 static void ImplCalendarSelectDate( IntDateSet
* pTable
, const Date
& rDate
, bool bSelect
)
66 pTable
->insert( rDate
.GetDate() );
68 pTable
->erase( rDate
.GetDate() );
71 static void ImplCalendarSelectDateRange( IntDateSet
* pTable
,
72 const Date
& rStartDate
,
76 Date aStartDate
= rStartDate
;
77 Date aEndDate
= rEndDate
;
78 if ( aStartDate
> aEndDate
)
80 Date aTempDate
= aStartDate
;
81 aStartDate
= aEndDate
;
87 while ( aStartDate
<= aEndDate
)
89 pTable
->insert( aStartDate
.GetDate() );
95 for ( IntDateSet::const_iterator it
= pTable
->begin(); it
!= pTable
->end(); )
98 if ( aDate
> aEndDate
)
101 if ( aDate
>= aStartDate
)
102 it
= pTable
->erase(it
);
109 static void ImplCalendarUnSelectDateRange( IntDateSet
* pTable
,
110 IntDateSet
* pOldTable
,
111 const Date
& rStartDate
,
112 const Date
& rEndDate
)
114 Date aStartDate
= rStartDate
;
115 Date aEndDate
= rEndDate
;
116 if ( aStartDate
> aEndDate
)
118 Date aTempDate
= aStartDate
;
119 aStartDate
= aEndDate
;
120 aEndDate
= aTempDate
;
123 for ( IntDateSet::const_iterator it
= pTable
->begin(); it
!= pTable
->end(); )
126 if ( aDate
> aEndDate
)
129 if ( aDate
>= aStartDate
)
130 it
= pTable
->erase(it
);
135 for ( IntDateSet::const_iterator it
= pOldTable
->begin(); it
!= pOldTable
->end(); ++it
)
138 if ( aDate
> aEndDate
)
140 if ( aDate
>= aStartDate
)
141 pTable
->insert( aDate
.GetDate() );
145 inline void ImplCalendarClearSelectDate( IntDateSet
* pTable
)
150 void Calendar::ImplInit( WinBits nWinStyle
)
152 mpSelectTable
= new IntDateSet
;
153 mpOldSelectTable
= NULL
;
154 mpRestoreSelectTable
= NULL
;
155 mpStandardColor
= NULL
;
156 mpSaturdayColor
= NULL
;
157 mpSundayColor
= NULL
;
159 mnWinStyle
= nWinStyle
;
167 mbMultiSelection
= false;
175 mbInSelChange
= false;
176 mbTravelSelect
= false;
177 mbScrollDateRange
= false;
182 OUString
aGregorian( "gregorian");
183 maCalendarWrapper
.loadCalendar( aGregorian
,
184 Application::GetAppLocaleDataWrapper().getLanguageTag().getLocale());
185 if (maCalendarWrapper
.getUniqueID() != aGregorian
)
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." );
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 maCalendarWrapper
.loadCalendar( aGregorian
, lang::Locale( "en", "US", ""));
198 SetFirstDate( maCurDate
);
199 ImplCalendarSelectDate( mpSelectTable
, maCurDate
, true );
201 // Sonstige Strings erzeugen
202 maDayText
= SVT_RESSTR(STR_SVT_CALENDAR_DAY
);
203 maWeekText
= SVT_RESSTR(STR_SVT_CALENDAR_WEEK
);
205 // Tagestexte anlegen
206 for (sal_Int32 i
= 0; i
< 31; ++i
)
207 maDayTexts
[i
] = OUString::number(i
+1);
209 maDragScrollTimer
.SetTimeoutHdl( LINK( this, Calendar
, ScrollHdl
) );
210 maDragScrollTimer
.SetTimeout( GetSettings().GetMouseSettings().GetScrollRepeat() );
211 mnDragScrollHitTest
= 0;
216 void Calendar::ApplySettings(vcl::RenderContext
& rRenderContext
)
218 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
219 maSelColor
= rStyleSettings
.GetHighlightTextColor();
220 SetPointFont(rRenderContext
, rStyleSettings
.GetToolFont());
221 rRenderContext
.SetTextColor(rStyleSettings
.GetFieldTextColor());
222 rRenderContext
.SetBackground(Wallpaper(rStyleSettings
.GetFieldColor()));
225 void Calendar::ImplInitSettings()
227 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
228 maSelColor
= rStyleSettings
.GetHighlightTextColor();
229 SetPointFont(*this, rStyleSettings
.GetToolFont());
230 SetTextColor(rStyleSettings
.GetFieldTextColor());
231 SetBackground(Wallpaper(rStyleSettings
.GetFieldColor()));
234 Calendar::Calendar( vcl::Window
* pParent
, WinBits nWinStyle
) :
235 Control( pParent
, nWinStyle
& (WB_TABSTOP
| WB_GROUP
| WB_BORDER
| WB_3DLOOK
| WB_RANGESELECT
| WB_MULTISELECT
) ),
236 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 maDropDate( 0, 0, 1900 )
246 ImplInit( nWinStyle
);
249 Calendar::~Calendar()
254 void Calendar::dispose()
256 delete mpStandardColor
;
257 delete mpSaturdayColor
;
258 delete mpSundayColor
;
260 delete mpSelectTable
;
261 delete mpOldSelectTable
;
262 delete mpRestoreSelectTable
;
266 DayOfWeek
Calendar::ImplGetWeekStart() const
268 // Map i18n::Weekdays to Date DayOfWeek
270 sal_Int16 nDay
= maCalendarWrapper
.getFirstDayOfWeek();
273 case i18n::Weekdays::SUNDAY
:
276 case i18n::Weekdays::MONDAY
:
279 case i18n::Weekdays::TUESDAY
:
282 case i18n::Weekdays::WEDNESDAY
:
285 case i18n::Weekdays::THURSDAY
:
288 case i18n::Weekdays::FRIDAY
:
291 case i18n::Weekdays::SATURDAY
:
295 SAL_WARN( "svtools.control", "Calendar::ImplGetWeekStart: broken i18n Gregorian calendar (getFirstDayOfWeek())");
301 void Calendar::ImplGetWeekFont( vcl::Font
& rFont
) const
303 // weeknumber is displayed in WEEKNUMBER_HEIGHT%-Fontheight
304 Size aFontSize
= rFont
.GetSize();
305 aFontSize
.Height() *= WEEKNUMBER_HEIGHT
;
306 aFontSize
.Height() /= 100;
307 rFont
.SetSize( aFontSize
);
308 rFont
.SetWeight( WEIGHT_NORMAL
);
311 void Calendar::ImplFormat()
318 Size aOutSize
= GetOutputSizePixel();
320 if ( (aOutSize
.Width() <= 1) || (aOutSize
.Height() <= 1) )
323 OUString
a99Text("99");
325 vcl::Font aOldFont
= GetFont();
327 // Wochenanzeige beruecksichtigen
328 if ( mnWinStyle
& WB_WEEKNUMBER
)
330 vcl::Font aTempFont
= aOldFont
;
331 ImplGetWeekFont( aTempFont
);
332 SetFont( aTempFont
);
333 mnWeekWidth
= GetTextWidth( a99Text
)+WEEKNUMBER_OFFX
;
339 if ( mnWinStyle
& WB_BOLDTEXT
)
341 vcl::Font aFont
= aOldFont
;
342 if ( aFont
.GetWeight() < WEIGHT_BOLD
)
343 aFont
.SetWeight( WEIGHT_BOLD
);
345 aFont
.SetWeight( WEIGHT_NORMAL
);
349 long n99TextWidth
= GetTextWidth( a99Text
);
350 long nTextHeight
= GetTextHeight();
352 // calculate width and x-position
353 mnDayWidth
= n99TextWidth
+DAY_OFFX
;
354 mnMonthWidth
= mnDayWidth
*7;
355 mnMonthWidth
+= mnWeekWidth
;
356 mnMonthWidth
+= MONTH_BORDERX
*2;
357 mnMonthPerLine
= aOutSize
.Width() / mnMonthWidth
;
358 if ( !mnMonthPerLine
)
360 long nOver
= ((aOutSize
.Width()-(mnMonthPerLine
*mnMonthWidth
)) / mnMonthPerLine
);
361 mnMonthWidth
+= nOver
;
362 mnDaysOffX
= MONTH_BORDERX
;
363 mnDaysOffX
+= nOver
/2;
364 mnDaysOffX
+= mnWeekWidth
;
366 // calculate height and y-position
367 mnDayHeight
= nTextHeight
+ DAY_OFFY
;
368 mnWeekDayOffY
= nTextHeight
+ TITLE_OFFY
+ (TITLE_BORDERY
*2);
369 mnDaysOffY
= mnWeekDayOffY
+ nTextHeight
+ WEEKDAY_OFFY
;
370 mnMonthHeight
= (mnDayHeight
*6) + mnDaysOffY
;
371 mnMonthHeight
+= MONTH_OFFY
;
372 mnLines
= aOutSize
.Height() / mnMonthHeight
;
375 mnMonthHeight
+= (aOutSize
.Height()-(mnLines
*mnMonthHeight
)) / mnLines
;
377 // calculate spinfields
378 long nSpinSize
= nTextHeight
+TITLE_BORDERY
-SPIN_OFFY
;
379 maPrevRect
.Left() = SPIN_OFFX
;
380 maPrevRect
.Top() = SPIN_OFFY
;
381 maPrevRect
.Right() = maPrevRect
.Left()+nSpinSize
;
382 maPrevRect
.Bottom() = maPrevRect
.Top()+nSpinSize
;
383 maNextRect
.Left() = aOutSize
.Width()-SPIN_OFFX
-nSpinSize
-1;
384 maNextRect
.Top() = SPIN_OFFY
;
385 maNextRect
.Right() = maNextRect
.Left()+nSpinSize
;
386 maNextRect
.Bottom() = maNextRect
.Top()+nSpinSize
;
388 if ( mnWinStyle
& WB_BOLDTEXT
)
391 // Calculate DayOfWeekText (gets displayed in a narrow font)
392 maDayOfWeekText
.clear();
394 sal_Int16 nDay
= maCalendarWrapper
.getFirstDayOfWeek();
395 for ( sal_Int16 nDayOfWeek
= 0; nDayOfWeek
< 7; nDayOfWeek
++ )
398 OUString
aDayOfWeek( maCalendarWrapper
.getDisplayName(
399 i18n::CalendarDisplayIndex::DAY
, nDay
, 2));
400 long nOffX
= (mnDayWidth
-GetTextWidth( aDayOfWeek
))/2;
401 if ( mnWinStyle
& WB_BOLDTEXT
)
407 nOffX
+= nDayOfWeek
* mnDayWidth
;
408 mnDayOfWeekAry
[nDayOfWeek
] = nOffX
;
409 maDayOfWeekText
+= aDayOfWeek
;
417 // calculate number of days
419 DayOfWeek eStartDay
= ImplGetWeekStart();
422 Date aTempDate
= GetFirstMonth();
423 maFirstDate
= aTempDate
;
424 nWeekDay
= (sal_uInt16
)aTempDate
.GetDayOfWeek();
425 nWeekDay
= (nWeekDay
+(7-(sal_uInt16
)eStartDay
)) % 7;
426 maFirstDate
-= (sal_uLong
)nWeekDay
;
427 mnDayCount
= nWeekDay
;
428 sal_uInt16 nDaysInMonth
;
429 sal_uInt16 nMonthCount
= (sal_uInt16
)(mnMonthPerLine
*mnLines
);
430 for ( sal_uInt16 i
= 0; i
< nMonthCount
; i
++ )
432 nDaysInMonth
= aTempDate
.GetDaysInMonth();
433 mnDayCount
+= nDaysInMonth
;
434 aTempDate
+= nDaysInMonth
;
436 Date aTempDate2
= aTempDate
;
438 nDaysInMonth
= aTempDate2
.GetDaysInMonth();
439 aTempDate2
-= nDaysInMonth
-1;
440 nWeekDay
= (sal_uInt16
)aTempDate2
.GetDayOfWeek();
441 nWeekDay
= (nWeekDay
+(7-(sal_uInt16
)eStartDay
)) % 7;
442 mnDayCount
+= 42-nDaysInMonth
-nWeekDay
;
445 maOtherColor
= Color( COL_LIGHTGRAY
);
446 if ( maOtherColor
.IsRGBEqual( GetBackground().GetColor() ) )
447 maOtherColor
.SetColor( COL_GRAY
);
449 Date aLastDate
= GetLastDate();
450 if ( (maOldFormatLastDate
!= aLastDate
) ||
451 (maOldFormatFirstDate
!= maFirstDate
) )
453 maOldFormatFirstDate
= maFirstDate
;
454 maOldFormatLastDate
= aLastDate
;
459 sal_uInt16 nNewFirstYear
= maFirstDate
.GetYear();
460 sal_uInt16 nNewLastYear
= GetLastDate().GetYear();
463 if ( nNewFirstYear
< mnFirstYear
)
465 for ( mnRequestYear
= nNewFirstYear
; mnRequestYear
< mnFirstYear
; mnRequestYear
++ )
467 mnFirstYear
= nNewFirstYear
;
469 if ( nNewLastYear
> mnLastYear
)
471 for ( mnRequestYear
= mnLastYear
; mnRequestYear
< nNewLastYear
; mnRequestYear
++ )
473 mnLastYear
= nNewLastYear
;
478 for ( mnRequestYear
= nNewFirstYear
; mnRequestYear
< nNewLastYear
; mnRequestYear
++ )
480 mnFirstYear
= nNewFirstYear
;
481 mnLastYear
= nNewLastYear
;
488 sal_uInt16
Calendar::ImplHitTest( const Point
& rPos
, Date
& rDate
) const
493 if ( maPrevRect
.IsInside( rPos
) )
494 return CALENDAR_HITTEST_PREV
;
495 else if ( maNextRect
.IsInside( rPos
) )
496 return CALENDAR_HITTEST_NEXT
;
501 DayOfWeek eStartDay
= ImplGetWeekStart();
503 rDate
= GetFirstMonth();
505 for ( long i
= 0; i
< mnLines
; i
++ )
511 long nYMonth
= nY
+mnMonthHeight
;
512 for ( long j
= 0; j
< mnMonthPerLine
; j
++ )
514 if ( (rPos
.X() < nX
) && (rPos
.Y() < nYMonth
) )
517 sal_uInt16 nDaysInMonth
= rDate
.GetDaysInMonth();
519 // matching month was found
520 if ( (rPos
.X() > nX
) && (rPos
.Y() < nYMonth
) &&
521 (rPos
.X() < nX
+mnMonthWidth
) )
523 if ( rPos
.Y() < (nY
+(TITLE_BORDERY
*2)+mnDayHeight
))
524 return CALENDAR_HITTEST_MONTHTITLE
;
527 long nDayX
= nX
+mnDaysOffX
;
528 long nDayY
= nY
+mnDaysOffY
;
529 if ( rPos
.Y() < nDayY
)
531 sal_uInt16 nDayIndex
= (sal_uInt16
)rDate
.GetDayOfWeek();
532 nDayIndex
= (nDayIndex
+(7-(sal_uInt16
)eStartDay
)) % 7;
533 if ( (i
== 0) && (j
== 0) )
535 Date aTempDate
= rDate
;
536 aTempDate
-= nDayIndex
;
537 for ( nDay
= 0; nDay
< nDayIndex
; nDay
++ )
539 nOffX
= nDayX
+ (nDay
*mnDayWidth
);
540 if ( (rPos
.Y() >= nDayY
) && (rPos
.Y() < nDayY
+mnDayHeight
) &&
541 (rPos
.X() >= nOffX
) && (rPos
.X() < nOffX
+mnDayWidth
) )
545 return CALENDAR_HITTEST_DAY
;
549 for ( nDay
= 1; nDay
<= nDaysInMonth
; nDay
++ )
551 if ( rPos
.Y() < nDayY
)
556 nOffX
= nDayX
+ (nDayIndex
*mnDayWidth
);
557 if ( (rPos
.Y() >= nDayY
) && (rPos
.Y() < nDayY
+mnDayHeight
) &&
558 (rPos
.X() >= nOffX
) && (rPos
.X() < nOffX
+mnDayWidth
) )
561 return CALENDAR_HITTEST_DAY
;
563 if ( nDayIndex
== 6 )
566 nDayY
+= mnDayHeight
;
571 if ( (i
== mnLines
-1) && (j
== mnMonthPerLine
-1) )
573 sal_uInt16 nWeekDay
= (sal_uInt16
)rDate
.GetDayOfWeek();
574 nWeekDay
= (nWeekDay
+(7-(sal_uInt16
)eStartDay
)) % 7;
575 sal_uInt16 nDayCount
= 42-nDaysInMonth
-nWeekDay
;
576 Date aTempDate
= rDate
;
577 aTempDate
+= nDaysInMonth
;
578 for ( nDay
= 1; nDay
<= nDayCount
; nDay
++ )
580 if ( rPos
.Y() < nDayY
)
585 nOffX
= nDayX
+ (nDayIndex
*mnDayWidth
);
586 if ( (rPos
.Y() >= nDayY
) && (rPos
.Y() < nDayY
+mnDayHeight
) &&
587 (rPos
.X() >= nOffX
) && (rPos
.X() < nOffX
+mnDayWidth
) )
591 return CALENDAR_HITTEST_DAY
;
593 if ( nDayIndex
== 6 )
596 nDayY
+= mnDayHeight
;
605 rDate
+= nDaysInMonth
;
618 static void ImplDrawSpinArrow(vcl::RenderContext
& rRenderContext
, const Rectangle
& rRect
, bool bPrev
)
623 long nHeight
= rRect
.GetHeight();
624 long nWidth
= rRect
.GetWidth();
625 if (nWidth
< nHeight
)
633 Rectangle
aRect(Point( rRect
.Left() + (nWidth
/ 2) - (nLines
/ 2),
634 rRect
.Top() + (nHeight
/ 2) ),
638 aRect
.Left() += nLines
;
639 aRect
.Right() += nLines
;
642 rRenderContext
.DrawRect(aRect
);
643 for (i
= 0; i
< nLines
; i
++)
657 rRenderContext
.DrawRect(aRect
);
661 } //end anonymous namespace
663 void Calendar::ImplDrawSpin(vcl::RenderContext
& rRenderContext
, bool bDrawPrev
, bool bDrawNext
)
665 if (!bDrawPrev
&& !bDrawNext
)
668 rRenderContext
.SetLineColor();
669 rRenderContext
.SetFillColor(rRenderContext
.GetSettings().GetStyleSettings().GetButtonTextColor());
672 Rectangle aOutRect
= maPrevRect
;
673 aOutRect
.Left() += 3;
675 aOutRect
.Right() -= 3;
676 aOutRect
.Bottom() -= 3;
677 ImplDrawSpinArrow(rRenderContext
, aOutRect
, true);
681 Rectangle aOutRect
= maNextRect
;
682 aOutRect
.Left() += 3;
684 aOutRect
.Right() -= 3;
685 aOutRect
.Bottom() -= 3;
686 ImplDrawSpinArrow(rRenderContext
, aOutRect
, false);
690 void Calendar::ImplDrawDate(vcl::RenderContext
& rRenderContext
,
692 sal_uInt16 nDay
, sal_uInt16 nMonth
, sal_uInt16 nYear
,
693 DayOfWeek eDayOfWeek
,
694 bool bBack
, bool bOther
, sal_uLong nToday
)
696 Color
* pTextColor
= NULL
;
697 const OUString
& rDay
= maDayTexts
[nDay
- 1];
698 Rectangle
aDateRect(nX
, nY
, nX
+ mnDayWidth
- 1, nY
+ mnDayHeight
- 1);
703 if ((nDay
== maCurDate
.GetDay()) &&
704 (nMonth
== maCurDate
.GetMonth()) &&
705 (nYear
== maCurDate
.GetYear()))
711 if (mpSelectTable
->find(Date(nDay
, nMonth
, nYear
).GetDate()) != mpSelectTable
->end())
717 pTextColor
= &maSelColor
;
719 pTextColor
= &maOtherColor
;
722 if (eDayOfWeek
== SATURDAY
)
723 pTextColor
= mpSaturdayColor
;
724 else if (eDayOfWeek
== SUNDAY
)
725 pTextColor
= mpSundayColor
;
727 pTextColor
= mpStandardColor
;
733 // display background
734 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
739 rRenderContext
.SetLineColor();
740 rRenderContext
.SetFillColor(rStyleSettings
.GetHighlightColor());
741 rRenderContext
.DrawRect(aDateRect
);
744 rRenderContext
.Erase(aDateRect
);
748 long nTextX
= nX
+ (mnDayWidth
- GetTextWidth(rDay
)) - (DAY_OFFX
/ 2);
749 long nTextY
= nY
+ (mnDayHeight
- GetTextHeight()) / 2;
752 Color aOldColor
= rRenderContext
.GetTextColor();
753 rRenderContext
.SetTextColor(*pTextColor
);
754 rRenderContext
.DrawText(Point(nTextX
, nTextY
), rDay
);
755 rRenderContext
.SetTextColor(aOldColor
);
758 rRenderContext
.DrawText(Point(nTextX
, nTextY
), rDay
);
761 Date
aTodayDate(maCurDate
);
763 aTodayDate
.SetDate(nToday
);
765 aTodayDate
= Date(Date::SYSTEM
);
766 if ((nDay
== aTodayDate
.GetDay()) &&
767 (nMonth
== aTodayDate
.GetMonth()) &&
768 (nYear
== aTodayDate
.GetYear()))
770 rRenderContext
.SetLineColor(rStyleSettings
.GetWindowTextColor());
771 rRenderContext
.SetFillColor();
772 rRenderContext
.DrawRect(aDateRect
);
775 // if needed do FocusRect
776 if (bFocus
&& HasFocus())
777 ShowFocus(aDateRect
);
779 if (mbDropPos
&& maDropDate
== Date(nDay
, nMonth
, nYear
))
783 void Calendar::ImplDraw(vcl::RenderContext
& rRenderContext
, bool bPaint
)
787 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
788 Size
aOutSize(GetOutputSizePixel());
796 sal_uLong nToday
= Date(Date::SYSTEM
).GetDate();
800 Date aDate
= GetFirstMonth();
801 DayOfWeek eStartDay
= ImplGetWeekStart();
806 for (i
= 0; i
< mnLines
; i
++)
809 rRenderContext
.SetLineColor();
810 rRenderContext
.SetFillColor(rStyleSettings
.GetFaceColor());
811 Rectangle
aTitleRect(0, nY
, aOutSize
.Width() - 1, nY
+ mnDayHeight
- DAY_OFFY
+ TITLE_BORDERY
* 2);
814 Rectangle
aTempRect(1, aTitleRect
.Top() + TITLE_BORDERY
,
815 aOutSize
.Width() - 2,
816 aTitleRect
.Bottom() - TITLE_BORDERY
);
819 aTempRect
.Left() = maPrevRect
.Right() + 1;
820 aTempRect
.Right() = maNextRect
.Left() - 1;
822 rRenderContext
.DrawRect(aTempRect
);
826 rRenderContext
.DrawRect(aTitleRect
);
827 Point
aTopLeft1(aTitleRect
.Left(), aTitleRect
.Top());
828 Point
aTopLeft2(aTitleRect
.Left(), aTitleRect
.Top() + 1);
829 Point
aBottomRight1(aTitleRect
.Right(), aTitleRect
.Bottom());
830 Point
aBottomRight2(aTitleRect
.Right(), aTitleRect
.Bottom() - 1);
831 rRenderContext
.SetLineColor(rStyleSettings
.GetDarkShadowColor());
832 rRenderContext
.DrawLine(aTopLeft1
, Point(aBottomRight1
.X(), aTopLeft1
.Y()));
833 rRenderContext
.SetLineColor(rStyleSettings
.GetLightColor() );
834 rRenderContext
.DrawLine(aTopLeft2
, Point(aBottomRight2
.X(), aTopLeft2
.Y()));
835 rRenderContext
.DrawLine(aTopLeft2
, Point(aTopLeft2
.X(), aBottomRight2
.Y()));
836 rRenderContext
.SetLineColor(rStyleSettings
.GetShadowColor() );
837 rRenderContext
.DrawLine(Point(aTopLeft2
.X(), aBottomRight2
.Y()), aBottomRight2
);
838 rRenderContext
.DrawLine(Point(aBottomRight2
.X(), aTopLeft2
.Y()), aBottomRight2
);
839 rRenderContext
.SetLineColor(rStyleSettings
.GetDarkShadowColor());
840 rRenderContext
.DrawLine(Point(aTopLeft1
.X(), aBottomRight1
.Y()), aBottomRight1
);
842 Point
aSepPos1(0, aTitleRect
.Top() + TITLE_BORDERY
);
843 Point
aSepPos2(0, aTitleRect
.Bottom() - TITLE_BORDERY
);
844 for (j
= 0; j
< mnMonthPerLine
-1; j
++)
846 aSepPos1
.X() += mnMonthWidth
-1;
847 aSepPos2
.X() = aSepPos1
.X();
848 rRenderContext
.SetLineColor(rStyleSettings
.GetShadowColor());
849 rRenderContext
.DrawLine(aSepPos1
, aSepPos2
);
851 aSepPos2
.X() = aSepPos1
.X();
852 rRenderContext
.SetLineColor(rStyleSettings
.GetLightColor());
853 rRenderContext
.DrawLine(aSepPos1
, aSepPos2
);
857 for (j
= 0; j
< mnMonthPerLine
; j
++)
859 nMonth
= aDate
.GetMonth();
860 nYear
= aDate
.GetYear();
862 // display month in title bar
864 nDeltaY
= nY
+ TITLE_BORDERY
;
865 OUString
aMonthText(maCalendarWrapper
.getDisplayName(i18n::CalendarDisplayIndex::MONTH
, nMonth
- 1, 1));
867 aMonthText
+= OUString::number(nYear
);
868 long nMonthTextWidth
= rRenderContext
.GetTextWidth(aMonthText
);
869 long nMonthOffX1
= 0;
870 long nMonthOffX2
= 0;
874 nMonthOffX1
= maPrevRect
.Right() + 1;
875 if (j
== mnMonthPerLine
- 1)
876 nMonthOffX2
= aOutSize
.Width() - maNextRect
.Left() + 1;
878 long nMaxMonthWidth
= mnMonthWidth
- nMonthOffX1
- nMonthOffX2
- 4;
879 if (nMonthTextWidth
> nMaxMonthWidth
)
881 // Abbreviated month name.
882 aMonthText
= maCalendarWrapper
.getDisplayName(i18n::CalendarDisplayIndex::MONTH
, nMonth
- 1, 0);
884 aMonthText
+= OUString::number(nYear
);
885 nMonthTextWidth
= rRenderContext
.GetTextWidth(aMonthText
);
887 long nTempOff
= (mnMonthWidth
- nMonthTextWidth
+ 1) / 2;
888 if (nTempOff
< nMonthOffX1
)
889 nDeltaX
+= nMonthOffX1
+ 1;
892 if (nTempOff
+ nMonthTextWidth
> mnMonthWidth
- nMonthOffX2
)
893 nDeltaX
+= mnMonthWidth
- nMonthOffX2
- nMonthTextWidth
;
897 rRenderContext
.SetTextColor(rStyleSettings
.GetButtonTextColor());
898 rRenderContext
.DrawText(Point(nDeltaX
, nDeltaY
), aMonthText
);
899 rRenderContext
.SetTextColor(rStyleSettings
.GetWindowTextColor());
904 nDayX
= nX
+ mnDaysOffX
;
905 nDayY
= nY
+ mnWeekDayOffY
;
906 nDeltaY
= nDayY
+ mnDayHeight
;
907 rRenderContext
.SetLineColor(rStyleSettings
.GetWindowTextColor());
908 Point
aStartPos(nDayX
, nDeltaY
);
909 if (mnWinStyle
& WB_WEEKNUMBER
)
910 aStartPos
.X() -= WEEKNUMBER_OFFX
- 2;
911 rRenderContext
.DrawLine(aStartPos
, Point(nDayX
+ (7 * mnDayWidth
), nDeltaY
));
912 rRenderContext
.DrawTextArray(Point(nDayX
+ mnDayOfWeekAry
[0], nDayY
), maDayOfWeekText
, &(mnDayOfWeekAry
[1]));
915 // display weeknumbers
916 if (mnWinStyle
& WB_WEEKNUMBER
)
918 nDayX
= nX
+ mnDaysOffX
;
919 nDayY
= nY
+ mnWeekDayOffY
;
920 nDeltaY
= nDayY
+ mnDayHeight
;
921 long nMonthHeight
= mnDayHeight
* 6;
924 rRenderContext
.DrawLine(Point(nDayX
- WEEKNUMBER_OFFX
+ 2, nDeltaY
),
925 Point(nDayX
- WEEKNUMBER_OFFX
+ 2, nDeltaY
+ nMonthHeight
));
929 rRenderContext
.Erase(Rectangle(nDayX
- mnWeekWidth
- WEEKNUMBER_OFFX
, nDeltaY
,
930 nDayX
- WEEKNUMBER_OFFX
- 1, nDeltaY
+ nMonthHeight
));
932 vcl::Font aOldFont
= rRenderContext
.GetFont();
933 vcl::Font aTempFont
= aOldFont
;
934 ImplGetWeekFont(aTempFont
);
935 rRenderContext
.SetFont(aTempFont
);
936 nDayX
-= mnWeekWidth
;
937 nDayY
= nY
+ mnDaysOffY
;
938 maCalendarWrapper
.setGregorianDateTime(aDate
);
939 for (sal_uInt16 nWeekCount
= 0; nWeekCount
< 6; ++nWeekCount
)
941 sal_Int32 nWeek
= maCalendarWrapper
.getValue(i18n::CalendarFieldIndex::WEEK_OF_YEAR
);
942 OUString
aWeekText(OUString::number(nWeek
));
943 long nOffX
= (mnWeekWidth
- WEEKNUMBER_OFFX
) - rRenderContext
.GetTextWidth(aWeekText
);
944 long nOffY
= (mnDayHeight
- GetTextHeight()) / 2;
945 rRenderContext
.DrawText(Point(nDayX
+ nOffX
, nDayY
+ nOffY
), aWeekText
);
946 nDayY
+= mnDayHeight
;
947 maCalendarWrapper
.addValue(i18n::CalendarFieldIndex::DAY_OF_MONTH
, 7);
949 rRenderContext
.SetFont(aOldFont
);
953 sal_uInt16 nDaysInMonth
= aDate
.GetDaysInMonth();
954 nDayX
= nX
+ mnDaysOffX
;
955 nDayY
= nY
+ mnDaysOffY
;
958 Rectangle
aClearRect(nDayX
, nDayY
,
959 nDayX
+ (7 * mnDayWidth
) - 1, nDayY
+ (6 * mnDayHeight
) - 1);
960 rRenderContext
.Erase(aClearRect
);
962 sal_uInt16 nDayIndex
= (sal_uInt16
) aDate
.GetDayOfWeek();
963 nDayIndex
= (nDayIndex
+ (7 - (sal_uInt16
)eStartDay
)) % 7;
964 if (i
== 0 && j
== 0)
966 Date aTempDate
= aDate
;
967 aTempDate
-= nDayIndex
;
968 for (nDay
= 0; nDay
< nDayIndex
; ++nDay
)
970 nDeltaX
= nDayX
+ (nDay
* mnDayWidth
);
971 ImplDrawDate(rRenderContext
, nDeltaX
, nDayY
, nDay
+ aTempDate
.GetDay(),
972 aTempDate
.GetMonth(), aTempDate
.GetYear(),
973 (DayOfWeek
)((nDay
+ (sal_uInt16
)eStartDay
) % 7), false, true, nToday
);
976 for (nDay
= 1; nDay
<= nDaysInMonth
; nDay
++)
978 nDeltaX
= nDayX
+ (nDayIndex
* mnDayWidth
);
979 ImplDrawDate(rRenderContext
, nDeltaX
, nDayY
, nDay
, nMonth
, nYear
,
980 (DayOfWeek
)((nDayIndex
+ (sal_uInt16
)eStartDay
) % 7),
981 false, false, nToday
);
985 nDayY
+= mnDayHeight
;
990 if ((i
== mnLines
- 1) && (j
== mnMonthPerLine
- 1))
992 sal_uInt16 nWeekDay
= (sal_uInt16
)aDate
.GetDayOfWeek();
993 nWeekDay
= (nWeekDay
+ (7 - (sal_uInt16
)eStartDay
)) % 7;
994 sal_uInt16 nDayCount
= 42 - nDaysInMonth
- nWeekDay
;
995 Date aTempDate
= aDate
;
996 aTempDate
+= nDaysInMonth
;
997 for (nDay
= 1; nDay
<= nDayCount
; ++nDay
)
999 nDeltaX
= nDayX
+ (nDayIndex
* mnDayWidth
);
1000 ImplDrawDate(rRenderContext
, nDeltaX
, nDayY
, nDay
,
1001 aTempDate
.GetMonth(), aTempDate
.GetYear(),
1002 (DayOfWeek
)((nDayIndex
+ (sal_uInt16
)eStartDay
) % 7),
1003 false, true, nToday
);
1007 nDayY
+= mnDayHeight
;
1014 aDate
+= nDaysInMonth
;
1018 nY
+= mnMonthHeight
;
1021 // draw spin buttons
1023 ImplDrawSpin(rRenderContext
);
1026 void Calendar::ImplUpdateDate( const Date
& rDate
)
1028 if (IsReallyVisible() && IsUpdateMode())
1030 Rectangle
aDateRect(GetDateRect(rDate
));
1031 if (!aDateRect
.IsEmpty())
1033 Invalidate(aDateRect
);
1038 void Calendar::ImplUpdateSelection( IntDateSet
* pOld
)
1040 IntDateSet
* pNew
= mpSelectTable
;
1042 for ( IntDateSet::const_iterator it
= pOld
->begin(); it
!= pOld
->end(); ++it
)
1044 sal_uLong nKey
= *it
;
1045 if ( pNew
->find( nKey
) == pNew
->end() )
1047 Date
aTempDate( nKey
);
1048 ImplUpdateDate( aTempDate
);
1052 for ( IntDateSet::const_iterator it
= pNew
->begin(); it
!= pNew
->end(); ++it
)
1054 sal_uLong nKey
= *it
;
1055 if ( pOld
->find( nKey
) == pOld
->end() )
1057 Date
aTempDate( nKey
);
1058 ImplUpdateDate( aTempDate
);
1063 void Calendar::ImplMouseSelect( const Date
& rDate
, sal_uInt16 nHitTest
,
1064 bool bMove
, bool bExpand
, bool bExtended
)
1066 boost::scoped_ptr
<IntDateSet
> pOldSel(new IntDateSet( *mpSelectTable
));
1067 Date aOldDate
= maCurDate
;
1068 Date aTempDate
= rDate
;
1070 if ( !(nHitTest
& CALENDAR_HITTEST_DAY
) )
1073 if ( mbMultiSelection
)
1075 maCurDate
= aTempDate
;
1076 mbSelLeft
= aTempDate
< maAnchorDate
;
1082 ImplCalendarUnSelectDateRange( mpSelectTable
, mpRestoreSelectTable
, Date( 1, 1, 0 ), aTempDate
);
1083 ImplCalendarUnSelectDateRange( mpSelectTable
, mpRestoreSelectTable
, maAnchorDate
, Date( 31, 12, 9999 ) );
1087 ImplCalendarUnSelectDateRange( mpSelectTable
, mpRestoreSelectTable
, Date( 1, 1, 0 ), maAnchorDate
);
1088 ImplCalendarUnSelectDateRange( mpSelectTable
, mpRestoreSelectTable
, aTempDate
, Date( 31, 12, 9999 ) );
1090 ImplCalendarSelectDateRange( mpSelectTable
, aTempDate
, maAnchorDate
, !mbUnSel
);
1100 ImplCalendarSelectDateRange( mpSelectTable
, Date( 1, 1, 0 ), aTempDate
, false );
1101 ImplCalendarSelectDateRange( mpSelectTable
, maAnchorDate
, Date( 31, 12, 9999 ), false );
1105 ImplCalendarSelectDateRange( mpSelectTable
, Date( 1, 1, 0 ), maAnchorDate
, false );
1106 ImplCalendarSelectDateRange( mpSelectTable
, aTempDate
, Date( 31, 12, 9999 ), false );
1109 ImplCalendarSelectDateRange( mpSelectTable
, aTempDate
, maAnchorDate
, true );
1111 else if ( bExtended
&& !(mnWinStyle
& WB_RANGESELECT
) )
1113 maAnchorDate
= aTempDate
;
1114 if ( IsDateSelected( aTempDate
) )
1117 ImplCalendarSelectDate( mpSelectTable
, aTempDate
, false );
1121 ImplCalendarSelectDate( mpSelectTable
, aTempDate
, true );
1126 maAnchorDate
= aTempDate
;
1127 ImplCalendarClearSelectDate( mpSelectTable
);
1128 ImplCalendarSelectDate( mpSelectTable
, aTempDate
, true );
1131 mpRestoreSelectTable
= new IntDateSet( *mpSelectTable
);
1136 if ( aTempDate
< maCurDate
)
1140 if ( !(nHitTest
& CALENDAR_HITTEST_DAY
) )
1141 aTempDate
= maOldCurDate
;
1143 maAnchorDate
= aTempDate
;
1144 if ( aTempDate
!= maCurDate
)
1146 maCurDate
= aTempDate
;
1147 ImplCalendarSelectDate( mpSelectTable
, aOldDate
, false );
1148 ImplCalendarSelectDate( mpSelectTable
, maCurDate
, true );
1152 bool bNewSel
= *pOldSel
!= *mpSelectTable
;
1153 if ( (maCurDate
!= aOldDate
) || bNewSel
)
1157 mbInSelChange
= true;
1158 SelectionChanging();
1159 mbInSelChange
= false;
1163 ImplUpdateSelection( pOldSel
.get() );
1164 if ( !bNewSel
|| pOldSel
->find( aOldDate
.GetDate() ) == pOldSel
->end() )
1165 ImplUpdateDate( aOldDate
);
1166 // assure focus rectangle is displayed again
1167 if ( HasFocus() || !bNewSel
1168 || mpSelectTable
->find( maCurDate
.GetDate() ) == mpSelectTable
->end() )
1169 ImplUpdateDate( maCurDate
);
1173 void Calendar::ImplUpdate( bool bCalcNew
)
1175 if (IsReallyVisible() && IsUpdateMode())
1177 if (bCalcNew
&& !mbCalc
)
1181 else if (!mbFormat
&& !mbCalc
)
1192 void Calendar::ImplInvertDropPos()
1194 Rectangle aRect
= GetDateRect( maDropDate
);//this is one Pixel to width and one to heigh
1195 aRect
.Bottom() = aRect
.Top()+mnDayHeight
-1;
1196 aRect
.Right() = aRect
.Left()+mnDayWidth
-1;
1200 void Calendar::ImplScroll( bool bPrev
)
1202 Date aNewFirstMonth
= GetFirstMonth();
1206 aNewFirstMonth
-= aNewFirstMonth
.GetDaysInMonth()-1;
1209 aNewFirstMonth
+= aNewFirstMonth
.GetDaysInMonth();
1211 SetFirstDate( aNewFirstMonth
);
1215 void Calendar::ImplShowMenu( const Point
& rPos
, const Date
& rDate
)
1219 Date aOldFirstDate
= GetFirstMonth();
1220 PopupMenu aPopupMenu
;
1221 PopupMenu
* pYearPopupMenus
[MENU_YEAR_COUNT
];
1222 sal_uInt16 nMonthOff
;
1223 sal_uInt16 nCurItemId
;
1224 sal_uInt16 nYear
= rDate
.GetYear()-1;
1227 sal_uInt16 nYearIdCount
= 1000;
1229 nMonthOff
= (rDate
.GetYear()-aOldFirstDate
.GetYear())*12;
1230 if ( aOldFirstDate
.GetMonth() < rDate
.GetMonth() )
1231 nMonthOff
+= rDate
.GetMonth()-aOldFirstDate
.GetMonth();
1233 nMonthOff
-= aOldFirstDate
.GetMonth()-rDate
.GetMonth();
1235 // construct menu (include years with different months)
1236 for ( i
= 0; i
< MENU_YEAR_COUNT
; i
++ )
1238 pYearPopupMenus
[i
] = new PopupMenu
;
1239 for ( j
= 1; j
<= 12; j
++ )
1240 pYearPopupMenus
[i
]->InsertItem( nYearIdCount
+j
,
1241 maCalendarWrapper
.getDisplayName(
1242 i18n::CalendarDisplayIndex::MONTH
, j
-1, 1));
1243 aPopupMenu
.InsertItem( 10+i
, OUString::number( nYear
+i
) );
1244 aPopupMenu
.SetPopupMenu( 10+i
, pYearPopupMenus
[i
] );
1245 nYearIdCount
+= 1000;
1249 nCurItemId
= aPopupMenu
.Execute( this, rPos
);
1253 aPopupMenu
.SetPopupMenu( 2, NULL
);
1254 for ( i
= 0; i
< MENU_YEAR_COUNT
; i
++ )
1256 aPopupMenu
.SetPopupMenu( 10+i
, NULL
);
1257 delete pYearPopupMenus
[i
];
1262 sal_uInt16 nTempMonthOff
= nMonthOff
% 12;
1263 sal_uInt16 nTempYearOff
= nMonthOff
/ 12;
1264 sal_uInt16 nNewMonth
= nCurItemId
% 1000;
1265 sal_uInt16 nNewYear
= nYear
+((nCurItemId
-1000)/1000);
1266 if ( nTempMonthOff
< nNewMonth
)
1267 nNewMonth
= nNewMonth
- nTempMonthOff
;
1271 nNewMonth
= 12-(nTempMonthOff
-nNewMonth
);
1273 nNewYear
= nNewYear
- nTempYearOff
;
1274 SetFirstDate( Date( 1, nNewMonth
, nNewYear
) );
1278 void Calendar::ImplTracking( const Point
& rPos
, bool bRepeat
)
1280 Date aTempDate
= maCurDate
;
1281 sal_uInt16 nHitTest
= ImplHitTest( rPos
, aTempDate
);
1285 mbPrevIn
= (nHitTest
& CALENDAR_HITTEST_PREV
) != 0;
1286 mbNextIn
= (nHitTest
& CALENDAR_HITTEST_NEXT
) != 0;
1288 if ( bRepeat
&& (mbPrevIn
|| mbNextIn
) )
1290 mbScrollDateRange
= true;
1291 ImplScroll( mbPrevIn
);
1292 mbScrollDateRange
= false;
1296 ImplMouseSelect( aTempDate
, nHitTest
, true, false, false );
1299 void Calendar::ImplEndTracking( bool bCancel
)
1301 bool bSelection
= mbSelection
;
1302 bool bSpinDown
= mbSpinDown
;
1305 mbSelection
= false;
1306 mbMultiSelection
= false;
1314 if ( maOldFirstDate
!= maFirstDate
)
1315 SetFirstDate( maOldFirstDate
);
1319 boost::scoped_ptr
<IntDateSet
> pOldSel(new IntDateSet( *mpSelectTable
));
1320 Date aOldDate
= maCurDate
;
1321 maCurDate
= maOldCurDate
;
1322 *mpSelectTable
= *mpOldSelectTable
;
1324 ImplUpdateSelection( pOldSel
.get() );
1325 if ( pOldSel
->find( aOldDate
.GetDate() ) == pOldSel
->end() )
1326 ImplUpdateDate( aOldDate
);
1327 // assure focus rectangle is displayed again
1328 if ( HasFocus() || mpSelectTable
->find( maCurDate
.GetDate() ) == mpSelectTable
->end() )
1329 ImplUpdateDate( maCurDate
);
1337 // determine if we should scroll the visible area
1338 sal_uLong nSelCount
= mpSelectTable
->size();
1341 Date
aFirstSelDate( *mpSelectTable
->begin() );
1342 Date
aLastSelDate( *mpSelectTable
->rbegin() );
1343 if ( aLastSelDate
< GetFirstMonth() )
1345 else if ( GetLastMonth() < aFirstSelDate
)
1346 ImplScroll( false );
1351 (!bCancel
&& ((maCurDate
!= maOldCurDate
) || (*mpOldSelectTable
!= *mpSelectTable
))) )
1354 if ( !bSelection
&& (mnWinStyle
& WB_TABSTOP
) && !bCancel
)
1357 delete mpOldSelectTable
;
1358 mpOldSelectTable
= NULL
;
1359 delete mpRestoreSelectTable
;
1360 mpRestoreSelectTable
= NULL
;
1364 IMPL_LINK_NOARG_TYPED( Calendar
, ScrollHdl
, Timer
*, void )
1366 bool bPrevIn
= (mnDragScrollHitTest
& CALENDAR_HITTEST_PREV
) != 0;
1367 bool bNextIn
= (mnDragScrollHitTest
& CALENDAR_HITTEST_NEXT
) != 0;
1368 if( bNextIn
|| bPrevIn
)
1370 mbScrollDateRange
= true;
1371 ImplScroll( bPrevIn
);
1372 mbScrollDateRange
= false;
1376 void Calendar::MouseButtonDown( const MouseEvent
& rMEvt
)
1378 if ( rMEvt
.IsLeft() && !mbMenuDown
)
1380 Date aTempDate
= maCurDate
;
1381 sal_uInt16 nHitTest
= ImplHitTest( rMEvt
.GetPosPixel(), aTempDate
);
1384 if ( nHitTest
& CALENDAR_HITTEST_MONTHTITLE
)
1385 ImplShowMenu( rMEvt
.GetPosPixel(), aTempDate
);
1388 maOldFirstDate
= maFirstDate
;
1390 mbPrevIn
= (nHitTest
& CALENDAR_HITTEST_PREV
) != 0;
1391 mbNextIn
= (nHitTest
& CALENDAR_HITTEST_NEXT
) != 0;
1392 if ( mbPrevIn
|| mbNextIn
)
1395 mbScrollDateRange
= true;
1396 ImplScroll( mbPrevIn
);
1397 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 StartTracking( STARTTRACK_BUTTONREPEAT
);
1405 if ( (rMEvt
.GetClicks() == 2) && (nHitTest
& CALENDAR_HITTEST_DAY
) )
1409 if ( mpOldSelectTable
)
1410 delete mpOldSelectTable
;
1411 maOldCurDate
= maCurDate
;
1412 mpOldSelectTable
= new IntDateSet( *mpSelectTable
);
1420 mbMultiSelection
= (mnWinStyle
& (WB_MULTISELECT
| WB_RANGESELECT
)) != 0;
1421 if ( (nHitTest
& CALENDAR_HITTEST_DAY
) && mbMultiSelection
)
1425 ImplMouseSelect( aTempDate
, nHitTest
, false, rMEvt
.IsShift(), rMEvt
.IsMod1() );
1434 Control::MouseButtonDown( rMEvt
);
1437 void Calendar::MouseButtonUp( const MouseEvent
& rMEvt
)
1439 if ( rMEvt
.IsLeft() && mbSelection
)
1440 ImplEndTracking( false );
1442 Control::MouseButtonUp( rMEvt
);
1445 void Calendar::MouseMove( const MouseEvent
& rMEvt
)
1447 if ( mbSelection
&& rMEvt
.GetButtons() )
1448 ImplTracking( rMEvt
.GetPosPixel(), false );
1450 Control::MouseMove( rMEvt
);
1453 void Calendar::Tracking( const TrackingEvent
& rTEvt
)
1455 Point aMousePos
= rTEvt
.GetMouseEvent().GetPosPixel();
1457 if ( rTEvt
.IsTrackingEnded() )
1458 ImplEndTracking( rTEvt
.IsTrackingCanceled() );
1460 ImplTracking( aMousePos
, rTEvt
.IsTrackingRepeat() );
1463 void Calendar::KeyInput( const KeyEvent
& rKEvt
)
1465 Date aNewDate
= maCurDate
;
1466 bool bMultiSel
= (mnWinStyle
& (WB_RANGESELECT
| WB_MULTISELECT
)) != 0;
1467 bool bExpand
= rKEvt
.GetKeyCode().IsShift();
1468 bool bExtended
= rKEvt
.GetKeyCode().IsMod1();
1470 switch ( rKEvt
.GetKeyCode().GetCode() )
1473 aNewDate
.SetDay( 1 );
1477 aNewDate
.SetDay( aNewDate
.GetDaysInMonth() );
1498 Date aTempDate
= aNewDate
;
1499 aTempDate
-= aNewDate
.GetDay()+1;
1500 aNewDate
-= aTempDate
.GetDaysInMonth();
1505 aNewDate
+= aNewDate
.GetDaysInMonth();
1509 if ( bMultiSel
&& !(mnWinStyle
& WB_RANGESELECT
) )
1513 bool bDateSel
= IsDateSelected( maCurDate
);
1514 SelectDate( maCurDate
, !bDateSel
);
1516 SelectionChanging();
1517 mbTravelSelect
= true;
1519 mbTravelSelect
= false;
1523 Control::KeyInput( rKEvt
);
1527 Control::KeyInput( rKEvt
);
1531 if ( aNewDate
!= maCurDate
)
1533 if ( bMultiSel
&& bExpand
)
1535 boost::scoped_ptr
<IntDateSet
> pOldSel(new IntDateSet( *mpSelectTable
));
1536 Date aOldAnchorDate
= maAnchorDate
;
1537 mbSelLeft
= aNewDate
< maAnchorDate
;
1542 ImplCalendarSelectDateRange( mpSelectTable
, Date( 1, 1, 0 ), aNewDate
, false );
1543 ImplCalendarSelectDateRange( mpSelectTable
, maAnchorDate
, Date( 31, 12, 9999 ), false );
1547 ImplCalendarSelectDateRange( mpSelectTable
, Date( 1, 1, 0 ), maAnchorDate
, false );
1548 ImplCalendarSelectDateRange( mpSelectTable
, aNewDate
, Date( 31, 12, 9999 ), false );
1551 ImplCalendarSelectDateRange( mpSelectTable
, aNewDate
, maAnchorDate
, true );
1553 SetCurDate( aNewDate
);
1555 maAnchorDate
= aOldAnchorDate
;
1556 mbInSelChange
= true;
1557 SelectionChanging();
1558 mbInSelChange
= false;
1559 ImplUpdateSelection( pOldSel
.get() );
1563 if ( mnWinStyle
& WB_RANGESELECT
)
1566 SelectDate( aNewDate
, true );
1569 SetCurDate( aNewDate
);
1572 mbTravelSelect
= true;
1574 mbTravelSelect
= false;
1578 void Calendar::Paint( vcl::RenderContext
& rRenderContext
, const Rectangle
& )
1580 ImplDraw(rRenderContext
, true);
1583 void Calendar::GetFocus()
1585 ImplUpdateDate( maCurDate
);
1586 Control::GetFocus();
1589 void Calendar::LoseFocus()
1592 Control::LoseFocus();
1595 void Calendar::Resize()
1601 void Calendar::RequestHelp( const HelpEvent
& rHEvt
)
1603 if ( rHEvt
.GetMode() & (HelpEventMode::QUICK
| HelpEventMode::BALLOON
) )
1605 Date aDate
= maCurDate
;
1606 if ( GetDate( ScreenToOutputPixel( rHEvt
.GetMousePosPixel() ), aDate
) )
1608 Rectangle aDateRect
= GetDateRect( aDate
);
1609 Point aPt
= OutputToScreenPixel( aDateRect
.TopLeft() );
1610 aDateRect
.Left() = aPt
.X();
1611 aDateRect
.Top() = aPt
.Y();
1612 aPt
= OutputToScreenPixel( aDateRect
.BottomRight() );
1613 aDateRect
.Right() = aPt
.X();
1614 aDateRect
.Bottom() = aPt
.Y();
1616 if ( rHEvt
.GetMode() & HelpEventMode::QUICK
)
1618 maCalendarWrapper
.setGregorianDateTime( aDate
);
1619 sal_uInt16 nWeek
= (sal_uInt16
) maCalendarWrapper
.getValue( i18n::CalendarFieldIndex::WEEK_OF_YEAR
);
1620 sal_uInt16 nMonth
= aDate
.GetMonth();
1621 OUString
aStr( maDayText
);
1623 aStr
+= OUString::number(aDate
.GetDayOfYear());
1627 aStr
+= OUString::number(nWeek
);
1628 // if year is not the same, add it
1629 if ( (nMonth
== 12) && (nWeek
== 1) )
1632 aStr
+= OUString::number(aDate
.GetYear()+1);
1634 else if ( (nMonth
== 1) && (nWeek
> 50) )
1637 aStr
+= OUString::number(aDate
.GetYear()-1);
1639 Help::ShowQuickHelp( this, aDateRect
, aStr
);
1645 Control::RequestHelp( rHEvt
);
1648 void Calendar::Command( const CommandEvent
& rCEvt
)
1650 if ( rCEvt
.GetCommand() == CommandEventId::ContextMenu
)
1652 if ( !mbSelection
&& rCEvt
.IsMouseEvent() )
1654 Date aTempDate
= maCurDate
;
1655 sal_uInt16 nHitTest
= ImplHitTest( rCEvt
.GetMousePosPixel(), aTempDate
);
1656 if ( nHitTest
& CALENDAR_HITTEST_MONTHTITLE
)
1658 ImplShowMenu( rCEvt
.GetMousePosPixel(), aTempDate
);
1663 else if ( rCEvt
.GetCommand() == CommandEventId::Wheel
)
1665 const CommandWheelData
* pData
= rCEvt
.GetWheelData();
1666 if ( pData
->GetMode() == CommandWheelMode::SCROLL
)
1668 long nNotchDelta
= pData
->GetNotchDelta();
1669 if ( nNotchDelta
< 0 )
1671 while ( nNotchDelta
< 0 )
1679 while ( nNotchDelta
> 0 )
1681 ImplScroll( false );
1690 Control::Command( rCEvt
);
1693 void Calendar::StateChanged( StateChangedType nType
)
1695 Control::StateChanged( nType
);
1697 if ( nType
== StateChangedType::InitShow
)
1701 void Calendar::DataChanged( const DataChangedEvent
& rDCEvt
)
1703 Control::DataChanged( rDCEvt
);
1705 if ( (rDCEvt
.GetType() == DataChangedEventType::FONTS
) ||
1706 (rDCEvt
.GetType() == DataChangedEventType::FONTSUBSTITUTION
) ||
1707 ((rDCEvt
.GetType() == DataChangedEventType::SETTINGS
) &&
1708 (rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
)) )
1715 void Calendar::SelectionChanging()
1717 maSelectionChangingHdl
.Call( this );
1720 void Calendar::DateRangeChanged()
1722 maDateRangeChangedHdl
.Call( this );
1725 void Calendar::RequestDateInfo()
1727 maRequestDateInfoHdl
.Call( this );
1730 void Calendar::DoubleClick()
1732 maDoubleClickHdl
.Call( this );
1735 void Calendar::Select()
1737 maSelectHdl
.Call( this );
1740 void Calendar::SelectDate( const Date
& rDate
, bool bSelect
)
1742 if ( !rDate
.IsValidAndGregorian() )
1745 boost::scoped_ptr
<IntDateSet
> pOldSel
;
1747 if ( !mbInSelChange
)
1748 pOldSel
.reset(new IntDateSet( *mpSelectTable
));
1750 ImplCalendarSelectDate( mpSelectTable
, rDate
, bSelect
);
1753 ImplUpdateSelection( pOldSel
.get() );
1756 void Calendar::SetNoSelection()
1758 boost::scoped_ptr
<IntDateSet
> pOldSel
;
1760 if ( !mbInSelChange
)
1761 pOldSel
.reset(new IntDateSet( *mpSelectTable
));
1763 ImplCalendarClearSelectDate( mpSelectTable
);
1766 ImplUpdateSelection( pOldSel
.get() );
1769 bool Calendar::IsDateSelected( const Date
& rDate
) const
1771 return mpSelectTable
->find( rDate
.GetDate() ) != mpSelectTable
->end();
1774 Date
Calendar::GetFirstSelectedDate() const
1776 if ( !mpSelectTable
->empty() )
1777 return Date( *mpSelectTable
->begin() );
1780 Date
aDate( 0, 0, 0 );
1785 void Calendar::SetCurDate( const Date
& rNewDate
)
1787 if ( !rNewDate
.IsValidAndGregorian() )
1790 if ( maCurDate
!= rNewDate
)
1792 bool bUpdate
= IsVisible() && IsUpdateMode();
1793 Date aOldDate
= maCurDate
;
1794 maCurDate
= rNewDate
;
1795 maAnchorDate
= maCurDate
;
1797 if ( !(mnWinStyle
& (WB_RANGESELECT
| WB_MULTISELECT
)) )
1799 ImplCalendarSelectDate( mpSelectTable
, aOldDate
, false );
1800 ImplCalendarSelectDate( mpSelectTable
, maCurDate
, true );
1802 else if ( !HasFocus() )
1805 // shift actual date in the visible area
1806 if ( mbFormat
|| (maCurDate
< GetFirstMonth()) )
1807 SetFirstDate( maCurDate
);
1808 else if ( maCurDate
> GetLastMonth() )
1810 Date aTempDate
= GetLastMonth();
1811 long nDateOff
= maCurDate
-aTempDate
;
1812 if ( nDateOff
< 365 )
1814 Date aFirstDate
= GetFirstMonth();
1815 aFirstDate
+= aFirstDate
.GetDaysInMonth();
1817 while ( nDateOff
> aTempDate
.GetDaysInMonth() )
1819 aFirstDate
+= aFirstDate
.GetDaysInMonth();
1820 long nDaysInMonth
= aTempDate
.GetDaysInMonth();
1821 aTempDate
+= nDaysInMonth
;
1822 nDateOff
-= nDaysInMonth
;
1824 SetFirstDate( aFirstDate
);
1827 SetFirstDate( maCurDate
);
1834 ImplUpdateDate( aOldDate
);
1835 ImplUpdateDate( maCurDate
);
1841 void Calendar::SetFirstDate( const Date
& rNewFirstDate
)
1843 if ( maFirstDate
!= rNewFirstDate
)
1845 maFirstDate
= Date( 1, rNewFirstDate
.GetMonth(), rNewFirstDate
.GetYear() );
1851 Date
Calendar::GetFirstMonth() const
1853 if ( maFirstDate
.GetDay() > 1 )
1855 if ( maFirstDate
.GetMonth() == 12 )
1856 return Date( 1, 1, maFirstDate
.GetYear()+1 );
1858 return Date( 1, maFirstDate
.GetMonth()+1, maFirstDate
.GetYear() );
1864 Date
Calendar::GetLastMonth() const
1866 Date aDate
= GetFirstMonth();
1867 sal_uInt16 nMonthCount
= GetMonthCount();
1868 for ( sal_uInt16 i
= 0; i
< nMonthCount
; i
++ )
1869 aDate
+= aDate
.GetDaysInMonth();
1874 sal_uInt16
Calendar::GetMonthCount() const
1879 return (sal_uInt16
)(mnMonthPerLine
*mnLines
);
1882 bool Calendar::GetDate( const Point
& rPos
, Date
& rDate
) const
1884 Date aDate
= maCurDate
;
1885 sal_uInt16 nHitTest
= ImplHitTest( rPos
, aDate
);
1886 if ( nHitTest
& CALENDAR_HITTEST_DAY
)
1895 Rectangle
Calendar::GetDateRect( const Date
& rDate
) const
1899 if ( mbFormat
|| (rDate
< maFirstDate
) || (rDate
> (maFirstDate
+mnDayCount
)) )
1905 sal_uInt16 nDayIndex
;
1906 Date aDate
= GetFirstMonth();
1908 if ( rDate
< aDate
)
1910 aRect
= GetDateRect( aDate
);
1911 nDaysOff
= aDate
-rDate
;
1912 nX
= (long)(nDaysOff
*mnDayWidth
);
1914 aRect
.Right() -= nX
;
1919 Date aLastDate
= GetLastMonth();
1920 if ( rDate
> aLastDate
)
1922 sal_uInt16 nWeekDay
= (sal_uInt16
)aLastDate
.GetDayOfWeek();
1923 nWeekDay
= (nWeekDay
+(7-(sal_uInt16
)ImplGetWeekStart())) % 7;
1924 aLastDate
-= nWeekDay
;
1925 aRect
= GetDateRect( aLastDate
);
1926 nDaysOff
= rDate
-aLastDate
;
1928 for ( sal_uInt16 i
= 0; i
<= nDaysOff
; i
++ )
1930 if ( aLastDate
== rDate
)
1932 aRect
.Left() += nDayIndex
*mnDayWidth
;
1933 aRect
.Right() = aRect
.Left()+mnDayWidth
;
1936 if ( nDayIndex
== 6 )
1939 aRect
.Top() += mnDayHeight
;
1940 aRect
.Bottom() += mnDayHeight
;
1950 for ( long i
= 0; i
< mnLines
; i
++ )
1953 for ( long j
= 0; j
< mnMonthPerLine
; j
++ )
1955 sal_uInt16 nDaysInMonth
= aDate
.GetDaysInMonth();
1958 if ( (aDate
.GetMonth() == rDate
.GetMonth()) &&
1959 (aDate
.GetYear() == rDate
.GetYear()) )
1961 long nDayX
= nX
+mnDaysOffX
;
1962 long nDayY
= nY
+mnDaysOffY
;
1963 nDayIndex
= (sal_uInt16
)aDate
.GetDayOfWeek();
1964 nDayIndex
= (nDayIndex
+(7-(sal_uInt16
)ImplGetWeekStart())) % 7;
1965 for ( sal_uInt16 nDay
= 1; nDay
<= nDaysInMonth
; nDay
++ )
1967 if ( nDay
== rDate
.GetDay() )
1969 aRect
.Left() = nDayX
+ (nDayIndex
*mnDayWidth
);
1970 aRect
.Top() = nDayY
;
1971 aRect
.Right() = aRect
.Left()+mnDayWidth
;
1972 aRect
.Bottom() = aRect
.Top()+mnDayHeight
;
1975 if ( nDayIndex
== 6 )
1978 nDayY
+= mnDayHeight
;
1985 aDate
+= nDaysInMonth
;
1989 nY
+= mnMonthHeight
;
1995 void Calendar::StartSelection()
1997 if ( mpOldSelectTable
)
1998 delete mpOldSelectTable
;
1999 maOldCurDate
= maCurDate
;
2000 mpOldSelectTable
= new IntDateSet( *mpSelectTable
);
2005 void Calendar::EndSelection()
2007 if ( mbDrag
|| mbSpinDown
|| mbSelection
)
2013 mbSelection
= false;
2014 mbMultiSelection
= false;
2021 Size
Calendar::CalcWindowSizePixel( long nCalcMonthPerLine
,
2022 long nCalcLines
) const
2024 OUString
a99Text("99");
2025 vcl::Font aOldFont
= GetFont();
2027 // take display of week into account
2029 if ( mnWinStyle
& WB_WEEKNUMBER
)
2031 vcl::Font aTempFont
= aOldFont
;
2032 ImplGetWeekFont( aTempFont
);
2033 const_cast<Calendar
*>(this)->SetFont( aTempFont
);
2034 nWeekWidth
= GetTextWidth( a99Text
)+WEEKNUMBER_OFFX
;
2035 const_cast<Calendar
*>(this)->SetFont( aOldFont
);
2040 if ( mnWinStyle
& WB_BOLDTEXT
)
2042 vcl::Font aFont
= aOldFont
;
2043 if ( aFont
.GetWeight() < WEIGHT_BOLD
)
2044 aFont
.SetWeight( WEIGHT_BOLD
);
2046 aFont
.SetWeight( WEIGHT_NORMAL
);
2047 const_cast<Calendar
*>(this)->SetFont( aFont
);
2051 long n99TextWidth
= GetTextWidth( a99Text
);
2052 long nTextHeight
= GetTextHeight();
2054 if ( mnWinStyle
& WB_BOLDTEXT
)
2055 const_cast<Calendar
*>(this)->SetFont( aOldFont
);
2057 aSize
.Width() += ((n99TextWidth
+DAY_OFFX
)*7) + nWeekWidth
;
2058 aSize
.Width() += MONTH_BORDERX
*2;
2059 aSize
.Width() *= nCalcMonthPerLine
;
2061 aSize
.Height() = nTextHeight
+ TITLE_OFFY
+ (TITLE_BORDERY
*2);
2062 aSize
.Height() += nTextHeight
+ WEEKDAY_OFFY
;
2063 aSize
.Height() += ((nTextHeight
+DAY_OFFY
)*6);
2064 aSize
.Height() += MONTH_OFFY
;
2065 aSize
.Height() *= nCalcLines
;
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
2077 class ImplCFieldFloatWin
: public FloatingWindow
2080 VclPtr
<Calendar
> mpCalendar
;
2081 VclPtr
<PushButton
> mpTodayBtn
;
2082 VclPtr
<PushButton
> mpNoneBtn
;
2083 VclPtr
<FixedLine
> mpFixedLine
;
2086 ImplCFieldFloatWin( vcl::Window
* pParent
);
2087 virtual ~ImplCFieldFloatWin();
2088 virtual void dispose() SAL_OVERRIDE
;
2090 void SetCalendar( Calendar
* pCalendar
)
2091 { mpCalendar
= pCalendar
; }
2093 PushButton
* EnableTodayBtn( bool bEnable
);
2094 PushButton
* EnableNoneBtn( bool bEnable
);
2095 void ArrangeButtons();
2097 virtual bool Notify( NotifyEvent
& rNEvt
) SAL_OVERRIDE
;
2100 ImplCFieldFloatWin::ImplCFieldFloatWin( vcl::Window
* pParent
) :
2101 FloatingWindow( pParent
, WB_BORDER
| WB_SYSTEMWINDOW
| WB_NOSHADOW
)
2109 ImplCFieldFloatWin::~ImplCFieldFloatWin()
2114 void ImplCFieldFloatWin::dispose()
2116 mpTodayBtn
.disposeAndClear();
2117 mpNoneBtn
.disposeAndClear();
2118 mpFixedLine
.disposeAndClear();
2120 FloatingWindow::dispose();
2123 PushButton
* ImplCFieldFloatWin::EnableTodayBtn( bool bEnable
)
2129 mpTodayBtn
= VclPtr
<PushButton
>::Create( this, WB_NOPOINTERFOCUS
);
2130 OUString
aTodayText(SVT_RESSTR(STR_SVT_CALENDAR_TODAY
));
2131 mpTodayBtn
->SetText( aTodayText
);
2133 aSize
.Width() = mpTodayBtn
->GetCtrlTextWidth( mpTodayBtn
->GetText() );
2134 aSize
.Height() = mpTodayBtn
->GetTextHeight();
2135 aSize
.Width() += CALFIELD_EXTRA_BUTTON_WIDTH
;
2136 aSize
.Height() += CALFIELD_EXTRA_BUTTON_HEIGHT
;
2137 mpTodayBtn
->SetSizePixel( aSize
);
2143 mpTodayBtn
.disposeAndClear();
2149 PushButton
* ImplCFieldFloatWin::EnableNoneBtn( bool bEnable
)
2155 mpNoneBtn
= VclPtr
<PushButton
>::Create( this, WB_NOPOINTERFOCUS
);
2156 OUString
aNoneText(SVT_RESSTR(STR_SVT_CALENDAR_NONE
));
2157 mpNoneBtn
->SetText( aNoneText
);
2159 aSize
.Width() = mpNoneBtn
->GetCtrlTextWidth( mpNoneBtn
->GetText() );
2160 aSize
.Height() = mpNoneBtn
->GetTextHeight();
2161 aSize
.Width() += CALFIELD_EXTRA_BUTTON_WIDTH
;
2162 aSize
.Height() += CALFIELD_EXTRA_BUTTON_HEIGHT
;
2163 mpNoneBtn
->SetSizePixel( aSize
);
2169 mpNoneBtn
.disposeAndClear();
2175 void ImplCFieldFloatWin::ArrangeButtons()
2177 long nBtnHeight
= 0;
2179 Size aOutSize
= GetOutputSizePixel();
2180 if ( mpTodayBtn
&& mpNoneBtn
)
2182 Size aTodayBtnSize
= mpTodayBtn
->GetSizePixel();
2183 Size aNoneBtnSize
= mpNoneBtn
->GetSizePixel();
2184 if ( aTodayBtnSize
.Width() < aNoneBtnSize
.Width() )
2185 aTodayBtnSize
.Width() = aNoneBtnSize
.Width();
2187 aNoneBtnSize
.Width() = aTodayBtnSize
.Width();
2188 if ( aTodayBtnSize
.Height() < aNoneBtnSize
.Height() )
2189 aTodayBtnSize
.Height() = aNoneBtnSize
.Height();
2191 aNoneBtnSize
.Height() = aTodayBtnSize
.Height();
2193 nBtnWidth
= aTodayBtnSize
.Width() + aNoneBtnSize
.Width() + CALFIELD_SEP_X
;
2194 nBtnHeight
= aTodayBtnSize
.Height();
2195 long nX
= (aOutSize
.Width()-nBtnWidth
)/2;
2196 long nY
= aOutSize
.Height()+CALFIELD_BORDER_Y
+CALFIELD_BORDER_YTOP
;
2197 mpTodayBtn
->SetPosSizePixel( Point( nX
, nY
), aTodayBtnSize
);
2198 nX
+= aTodayBtnSize
.Width() + CALFIELD_SEP_X
;
2199 mpNoneBtn
->SetPosSizePixel( Point( nX
, nY
), aNoneBtnSize
);
2201 else if ( mpTodayBtn
)
2203 Size aTodayBtnSize
= mpTodayBtn
->GetSizePixel();
2204 nBtnWidth
= aTodayBtnSize
.Width();
2205 nBtnHeight
= aTodayBtnSize
.Height();
2206 mpTodayBtn
->SetPosPixel( Point( (aOutSize
.Width()-nBtnWidth
)/2, aOutSize
.Height()+CALFIELD_BORDER_Y
+CALFIELD_BORDER_YTOP
) );
2208 else if ( mpNoneBtn
)
2210 Size aNoneBtnSize
= mpNoneBtn
->GetSizePixel();
2211 nBtnWidth
= aNoneBtnSize
.Width();
2212 nBtnHeight
= aNoneBtnSize
.Height();
2213 mpNoneBtn
->SetPosPixel( Point( (aOutSize
.Width()-nBtnWidth
)/2, aOutSize
.Height()+CALFIELD_BORDER_Y
+CALFIELD_BORDER_YTOP
) );
2220 mpFixedLine
= VclPtr
<FixedLine
>::Create( this );
2221 mpFixedLine
->Show();
2223 long nLineWidth
= aOutSize
.Width()-(CALFIELD_BORDERLINE_X
*2);
2224 mpFixedLine
->setPosSizePixel( (aOutSize
.Width()-nLineWidth
)/2, aOutSize
.Height()+((CALFIELD_BORDER_YTOP
-2)/2),
2225 nLineWidth
, 2, PosSizeFlags::PosSize
);
2226 aOutSize
.Height() += nBtnHeight
+ (CALFIELD_BORDER_Y
*2) + CALFIELD_BORDER_YTOP
;
2227 SetOutputSizePixel( aOutSize
);
2231 mpFixedLine
.disposeAndClear();
2235 bool ImplCFieldFloatWin::Notify( NotifyEvent
& rNEvt
)
2237 if ( rNEvt
.GetType() == MouseNotifyEvent::KEYINPUT
)
2239 const KeyEvent
* pKEvt
= rNEvt
.GetKeyEvent();
2240 if ( pKEvt
->GetKeyCode().GetCode() == KEY_RETURN
)
2241 mpCalendar
->Select();
2244 return FloatingWindow::Notify( rNEvt
);
2247 CalendarField::CalendarField(vcl::Window
* pParent
, WinBits nWinStyle
)
2248 : DateField(pParent
, nWinStyle
)
2251 , mnCalendarStyle(0)
2254 , maDefaultDate( 0, 0, 0 )
2260 CalendarField::~CalendarField()
2265 void CalendarField::dispose()
2267 mpCalendar
.disposeAndClear();
2268 mpFloatWin
.disposeAndClear();
2271 DateField::dispose();
2274 IMPL_LINK( CalendarField
, ImplSelectHdl
, Calendar
*, pCalendar
)
2276 if ( !pCalendar
->IsTravelSelect() )
2278 mpFloatWin
->EndPopupMode();
2281 Date aNewDate
= mpCalendar
->GetFirstSelectedDate();
2282 if ( IsEmptyDate() || ( aNewDate
!= GetDate() ) )
2284 SetDate( aNewDate
);
2293 IMPL_LINK( CalendarField
, ImplClickHdl
, PushButton
*, pBtn
)
2295 mpFloatWin
->EndPopupMode();
2299 if ( pBtn
== mpTodayBtn
)
2301 Date
aToday( Date::SYSTEM
);
2302 if ( (aToday
!= GetDate()) || IsEmptyDate() )
2309 else if ( pBtn
== mpNoneBtn
)
2311 if ( !IsEmptyDate() )
2323 IMPL_LINK_NOARG(CalendarField
, ImplPopupModeEndHdl
)
2327 mpCalendar
->EndSelection();
2331 void CalendarField::Select()
2333 maSelectHdl
.Call( this );
2336 bool CalendarField::ShowDropDown( bool bShow
)
2340 Calendar
* pCalendar
= GetCalendar();
2342 Date aDate
= GetDate();
2343 if ( IsEmptyDate() || !aDate
.IsValidAndGregorian() )
2345 if ( maDefaultDate
.IsValidAndGregorian() )
2346 aDate
= maDefaultDate
;
2348 aDate
= Date( Date::SYSTEM
);
2350 if ( pCalendar
->GetStyle() & (WB_RANGESELECT
| WB_MULTISELECT
) )
2352 pCalendar
->SetNoSelection();
2353 pCalendar
->SelectDate( aDate
);
2355 pCalendar
->SetCurDate( aDate
);
2356 Point
aPos( GetParent()->OutputToScreenPixel( GetPosPixel() ) );
2357 Rectangle
aRect( aPos
, GetSizePixel() );
2358 aRect
.Bottom() -= 1;
2359 mpCalendar
->SetOutputSizePixel( mpCalendar
->CalcWindowSizePixel() );
2360 mpFloatWin
->SetOutputSizePixel( mpCalendar
->GetSizePixel() );
2361 mpFloatWin
->SetCalendar( mpCalendar
);
2362 mpTodayBtn
= mpFloatWin
->EnableTodayBtn( mbToday
);
2363 mpNoneBtn
= mpFloatWin
->EnableNoneBtn( mbNone
);
2365 mpTodayBtn
->SetClickHdl( LINK( this, CalendarField
, ImplClickHdl
) );
2367 mpNoneBtn
->SetClickHdl( LINK( this, CalendarField
, ImplClickHdl
) );
2368 mpFloatWin
->ArrangeButtons();
2369 mpCalendar
->EnableCallEverySelect();
2370 mpCalendar
->StartSelection();
2371 mpCalendar
->GrabFocus();
2373 mpFloatWin
->StartPopupMode( aRect
, FloatWinPopupFlags::NoFocusClose
|FloatWinPopupFlags::Down
);
2377 mpFloatWin
->EndPopupMode( FloatWinPopupEndFlags::Cancel
);
2378 mpCalendar
->EndSelection();
2384 VclPtr
<Calendar
> CalendarField::CreateCalendar( vcl::Window
* pParent
)
2386 return VclPtr
<Calendar
>::Create( pParent
, mnCalendarStyle
| WB_TABSTOP
);
2389 Calendar
* CalendarField::GetCalendar()
2393 mpFloatWin
= VclPtr
<ImplCFieldFloatWin
>::Create( this );
2394 mpFloatWin
->SetPopupModeEndHdl( LINK( this, CalendarField
, ImplPopupModeEndHdl
) );
2395 mpCalendar
= CreateCalendar( mpFloatWin
);
2396 mpCalendar
->SetPosPixel( Point() );
2397 mpCalendar
->SetSelectHdl( LINK( this, CalendarField
, ImplSelectHdl
) );
2403 void CalendarField::StateChanged( StateChangedType nStateChange
)
2405 DateField::StateChanged( nStateChange
);
2407 if ( ( nStateChange
== StateChangedType::Style
) && GetSubEdit() )
2409 WinBits nAllAlignmentBits
= ( WB_LEFT
| WB_CENTER
| WB_RIGHT
| WB_TOP
| WB_VCENTER
| WB_BOTTOM
);
2410 WinBits nMyAlignment
= GetStyle() & nAllAlignmentBits
;
2411 GetSubEdit()->SetStyle( ( GetSubEdit()->GetStyle() & ~nAllAlignmentBits
) | nMyAlignment
);
2415 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */