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 .
21 #include <rtl/strbuf.hxx>
22 #include <vcl/svapp.hxx>
23 #include <vcl/help.hxx>
24 #include <vcl/menu.hxx>
25 #include <vcl/decoview.hxx>
26 #include <vcl/floatwin.hxx>
27 #include <vcl/button.hxx>
28 #include <vcl/fixed.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>
40 // =======================================================================
44 #define MONTH_BORDERX 4
46 #define WEEKNUMBER_OFFX 4
47 #define WEEKDAY_OFFY 3
49 #define TITLE_BORDERY 2
51 #define SPIN_OFFY TITLE_BORDERY
53 #define WEEKNUMBER_HEIGHT 85
55 #define CALENDAR_HITTEST_DAY ((sal_uInt16)0x0001)
56 #define CALENDAR_HITTEST_MONTHTITLE ((sal_uInt16)0x0004)
57 #define CALENDAR_HITTEST_PREV ((sal_uInt16)0x0008)
58 #define CALENDAR_HITTEST_NEXT ((sal_uInt16)0x0010)
60 #define MENU_YEAR_COUNT 3
62 using namespace ::com::sun::star
;
64 // =======================================================================
66 static void ImplCalendarSelectDate( IntDateSet
* pTable
, const Date
& rDate
, sal_Bool bSelect
)
69 pTable
->insert( rDate
.GetDate() );
71 pTable
->erase( rDate
.GetDate() );
74 // -----------------------------------------------------------------------
76 static void ImplCalendarSelectDateRange( IntDateSet
* pTable
,
77 const Date
& rStartDate
,
81 Date aStartDate
= rStartDate
;
82 Date aEndDate
= rEndDate
;
83 if ( aStartDate
> aEndDate
)
85 Date aTempDate
= aStartDate
;
86 aStartDate
= aEndDate
;
92 while ( aStartDate
<= aEndDate
)
94 pTable
->insert( aStartDate
.GetDate() );
100 for ( IntDateSet::const_iterator it
= pTable
->begin(); it
!= pTable
->end(); )
103 if ( aDate
> aEndDate
)
106 if ( aDate
>= aStartDate
)
107 pTable
->erase( it
++ );
114 // -----------------------------------------------------------------------
116 static void ImplCalendarUnSelectDateRange( IntDateSet
* pTable
,
117 IntDateSet
* pOldTable
,
118 const Date
& rStartDate
,
119 const Date
& rEndDate
)
121 Date aStartDate
= rStartDate
;
122 Date aEndDate
= rEndDate
;
123 if ( aStartDate
> aEndDate
)
125 Date aTempDate
= aStartDate
;
126 aStartDate
= aEndDate
;
127 aEndDate
= aTempDate
;
130 for ( IntDateSet::const_iterator it
= pTable
->begin(); it
!= pTable
->end(); )
133 if ( aDate
> aEndDate
)
136 if ( aDate
>= aStartDate
)
137 pTable
->erase( it
++ );
142 for ( IntDateSet::const_iterator it
= pOldTable
->begin(); it
!= pOldTable
->end(); ++it
)
145 if ( aDate
> aEndDate
)
147 if ( aDate
>= aStartDate
)
148 pTable
->insert( aDate
.GetDate() );
152 // -----------------------------------------------------------------------
154 inline void ImplCalendarClearSelectDate( IntDateSet
* pTable
)
159 // =======================================================================
161 void Calendar::ImplInit( WinBits nWinStyle
)
163 mpSelectTable
= new IntDateSet
;
164 mpOldSelectTable
= NULL
;
165 mpRestoreSelectTable
= NULL
;
166 mpStandardColor
= NULL
;
167 mpSaturdayColor
= NULL
;
168 mpSundayColor
= NULL
;
170 mnWinStyle
= nWinStyle
;
177 mbSelection
= sal_False
;
178 mbMultiSelection
= sal_False
;
179 mbWeekSel
= sal_False
;
181 mbMenuDown
= sal_False
;
182 mbSpinDown
= sal_False
;
183 mbPrevIn
= sal_False
;
184 mbNextIn
= sal_False
;
185 mbDirect
= sal_False
;
186 mbInSelChange
= sal_False
;
187 mbTravelSelect
= sal_False
;
188 mbScrollDateRange
= sal_False
;
189 mbSelLeft
= sal_False
;
190 mbAllSel
= sal_False
;
191 mbDropPos
= sal_False
;
193 OUString
aGregorian( "gregorian");
194 maCalendarWrapper
.loadCalendar( aGregorian
,
195 Application::GetAppLocaleDataWrapper().getLanguageTag().getLocale());
196 if (maCalendarWrapper
.getUniqueID() != aGregorian
)
198 SAL_WARN( "svtools.control", "Calendar::ImplInit: No ``gregorian'' calendar available for locale ``"
199 << Application::GetAppLocaleDataWrapper().getLanguageTag().getBcp47()
200 << "'' and other calendars aren't supported. Using en-US fallback." );
202 /* If we ever wanted to support other calendars than Gregorian a lot of
203 * rewrite would be necessary to internally replace use of class Date
204 * with proper class CalendarWrapper methods, get rid of fixed 12
205 * months, fixed 7 days, ... */
206 maCalendarWrapper
.loadCalendar( aGregorian
, lang::Locale( "en", "US", ""));
209 SetFirstDate( maCurDate
);
210 ImplCalendarSelectDate( mpSelectTable
, maCurDate
, sal_True
);
212 // Sonstige Strings erzeugen
213 maDayText
= SVT_RESSTR(STR_SVT_CALENDAR_DAY
);
214 maWeekText
= SVT_RESSTR(STR_SVT_CALENDAR_WEEK
);
216 // Tagestexte anlegen
217 for (sal_Int32 i
= 0; i
< 31; ++i
)
218 maDayTexts
[i
] = OUString::number(i
+1);
220 maDragScrollTimer
.SetTimeoutHdl( STATIC_LINK( this, Calendar
, ScrollHdl
) );
221 maDragScrollTimer
.SetTimeout( GetSettings().GetMouseSettings().GetScrollRepeat() );
222 mnDragScrollHitTest
= 0;
227 // -----------------------------------------------------------------------
229 void Calendar::ImplInitSettings()
231 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
232 maSelColor
= rStyleSettings
.GetHighlightTextColor();
233 SetPointFont( rStyleSettings
.GetToolFont() );
234 SetTextColor( rStyleSettings
.GetFieldTextColor() );
235 SetBackground( Wallpaper( rStyleSettings
.GetFieldColor() ) );
238 // -----------------------------------------------------------------------
240 Calendar::Calendar( Window
* pParent
, WinBits nWinStyle
) :
241 Control( pParent
, nWinStyle
& (WB_TABSTOP
| WB_GROUP
| WB_BORDER
| WB_3DLOOK
| WB_RANGESELECT
| WB_MULTISELECT
) ),
242 maCalendarWrapper( Application::GetAppLocaleDataWrapper().getComponentContext() ),
243 maOldFormatFirstDate( 0, 0, 1900 ),
244 maOldFormatLastDate( 0, 0, 1900 ),
245 maFirstDate( 0, 0, 1900 ),
246 maOldFirstDate( 0, 0, 1900 ),
247 maCurDate( Date::SYSTEM
),
248 maOldCurDate( 0, 0, 1900 ),
249 maAnchorDate( maCurDate
),
250 maDropDate( 0, 0, 1900 )
252 ImplInit( nWinStyle
);
255 // -----------------------------------------------------------------------
257 Calendar::~Calendar()
259 delete mpStandardColor
;
260 delete mpSaturdayColor
;
261 delete mpSundayColor
;
263 delete mpSelectTable
;
264 delete mpOldSelectTable
;
265 delete mpRestoreSelectTable
;
268 // -----------------------------------------------------------------------
270 DayOfWeek
Calendar::ImplGetWeekStart() const
272 // Map i18n::Weekdays to Date DayOfWeek
274 sal_Int16 nDay
= maCalendarWrapper
.getFirstDayOfWeek();
277 case i18n::Weekdays::SUNDAY
:
280 case i18n::Weekdays::MONDAY
:
283 case i18n::Weekdays::TUESDAY
:
286 case i18n::Weekdays::WEDNESDAY
:
289 case i18n::Weekdays::THURSDAY
:
292 case i18n::Weekdays::FRIDAY
:
295 case i18n::Weekdays::SATURDAY
:
299 SAL_WARN( "svtools.control", "Calendar::ImplGetWeekStart: broken i18n Gregorian calendar (getFirstDayOfWeek())");
305 // -----------------------------------------------------------------------
307 void Calendar::ImplGetWeekFont( Font
& rFont
) const
309 // Wochennummer geben wir in WEEKNUMBER_HEIGHT%-Fonthoehe aus
310 Size aFontSize
= rFont
.GetSize();
311 aFontSize
.Height() *= WEEKNUMBER_HEIGHT
;
312 aFontSize
.Height() /= 100;
313 rFont
.SetSize( aFontSize
);
314 rFont
.SetWeight( WEIGHT_NORMAL
);
317 // -----------------------------------------------------------------------
319 void Calendar::ImplFormat()
326 Size aOutSize
= GetOutputSizePixel();
328 if ( (aOutSize
.Width() <= 1) || (aOutSize
.Height() <= 1) )
331 OUString
a99Text("99");
333 Font aOldFont
= GetFont();
335 // Wochenanzeige beruecksichtigen
336 if ( mnWinStyle
& WB_WEEKNUMBER
)
338 Font aTempFont
= aOldFont
;
339 ImplGetWeekFont( aTempFont
);
340 SetFont( aTempFont
);
341 mnWeekWidth
= GetTextWidth( a99Text
)+WEEKNUMBER_OFFX
;
347 if ( mnWinStyle
& WB_BOLDTEXT
)
349 Font aFont
= aOldFont
;
350 if ( aFont
.GetWeight() < WEIGHT_BOLD
)
351 aFont
.SetWeight( WEIGHT_BOLD
);
353 aFont
.SetWeight( WEIGHT_NORMAL
);
357 long n99TextWidth
= GetTextWidth( a99Text
);
358 long nTextHeight
= GetTextHeight();
360 // Breiten und X-Positionen berechnen
361 mnDayWidth
= n99TextWidth
+DAY_OFFX
;
362 mnMonthWidth
= mnDayWidth
*7;
363 mnMonthWidth
+= mnWeekWidth
;
364 mnMonthWidth
+= MONTH_BORDERX
*2;
365 mnMonthPerLine
= aOutSize
.Width() / mnMonthWidth
;
366 if ( !mnMonthPerLine
)
368 long nOver
= ((aOutSize
.Width()-(mnMonthPerLine
*mnMonthWidth
)) / mnMonthPerLine
);
369 mnMonthWidth
+= nOver
;
370 mnDaysOffX
= MONTH_BORDERX
;
371 mnDaysOffX
+= nOver
/2;
372 mnDaysOffX
+= mnWeekWidth
;
374 // Hoehen und Y-Positionen berechnen
375 mnDayHeight
= nTextHeight
+ DAY_OFFY
;
376 mnWeekDayOffY
= nTextHeight
+ TITLE_OFFY
+ (TITLE_BORDERY
*2);
377 mnDaysOffY
= mnWeekDayOffY
+ nTextHeight
+ WEEKDAY_OFFY
;
378 mnMonthHeight
= (mnDayHeight
*6) + mnDaysOffY
;
379 mnMonthHeight
+= MONTH_OFFY
;
380 mnLines
= aOutSize
.Height() / mnMonthHeight
;
383 mnMonthHeight
+= (aOutSize
.Height()-(mnLines
*mnMonthHeight
)) / mnLines
;
385 // Spinfelder berechnen
386 long nSpinSize
= nTextHeight
+TITLE_BORDERY
-SPIN_OFFY
;
387 maPrevRect
.Left() = SPIN_OFFX
;
388 maPrevRect
.Top() = SPIN_OFFY
;
389 maPrevRect
.Right() = maPrevRect
.Left()+nSpinSize
;
390 maPrevRect
.Bottom() = maPrevRect
.Top()+nSpinSize
;
391 maNextRect
.Left() = aOutSize
.Width()-SPIN_OFFX
-nSpinSize
-1;
392 maNextRect
.Top() = SPIN_OFFY
;
393 maNextRect
.Right() = maNextRect
.Left()+nSpinSize
;
394 maNextRect
.Bottom() = maNextRect
.Top()+nSpinSize
;
396 if ( mnWinStyle
& WB_BOLDTEXT
)
399 // Calculate DayOfWeekText (gets displayed in a narrow font)
400 maDayOfWeekText
= "";
402 sal_Int16 nDay
= maCalendarWrapper
.getFirstDayOfWeek();
403 for ( sal_Int16 nDayOfWeek
= 0; nDayOfWeek
< 7; nDayOfWeek
++ )
406 OUString
aDayOfWeek( maCalendarWrapper
.getDisplayName(
407 i18n::CalendarDisplayIndex::DAY
, nDay
, 2));
408 long nOffX
= (mnDayWidth
-GetTextWidth( aDayOfWeek
))/2;
409 if ( mnWinStyle
& WB_BOLDTEXT
)
415 nOffX
+= nDayOfWeek
* mnDayWidth
;
416 mnDayOfWeekAry
[nDayOfWeek
] = nOffX
;
417 maDayOfWeekText
+= aDayOfWeek
;
425 // Anzahl Tage berechnen
427 DayOfWeek eStartDay
= ImplGetWeekStart();
430 Date aTempDate
= GetFirstMonth();
431 maFirstDate
= aTempDate
;
432 nWeekDay
= (sal_uInt16
)aTempDate
.GetDayOfWeek();
433 nWeekDay
= (nWeekDay
+(7-(sal_uInt16
)eStartDay
)) % 7;
434 maFirstDate
-= (sal_uLong
)nWeekDay
;
435 mnDayCount
= nWeekDay
;
436 sal_uInt16 nDaysInMonth
;
437 sal_uInt16 nMonthCount
= (sal_uInt16
)(mnMonthPerLine
*mnLines
);
438 for ( sal_uInt16 i
= 0; i
< nMonthCount
; i
++ )
440 nDaysInMonth
= aTempDate
.GetDaysInMonth();
441 mnDayCount
+= nDaysInMonth
;
442 aTempDate
+= nDaysInMonth
;
444 Date aTempDate2
= aTempDate
;
446 nDaysInMonth
= aTempDate2
.GetDaysInMonth();
447 aTempDate2
-= nDaysInMonth
-1;
448 nWeekDay
= (sal_uInt16
)aTempDate2
.GetDayOfWeek();
449 nWeekDay
= (nWeekDay
+(7-(sal_uInt16
)eStartDay
)) % 7;
450 mnDayCount
+= 42-nDaysInMonth
-nWeekDay
;
453 maOtherColor
= Color( COL_LIGHTGRAY
);
454 if ( maOtherColor
.IsRGBEqual( GetBackground().GetColor() ) )
455 maOtherColor
.SetColor( COL_GRAY
);
457 Date aLastDate
= GetLastDate();
458 if ( (maOldFormatLastDate
!= aLastDate
) ||
459 (maOldFormatFirstDate
!= maFirstDate
) )
461 maOldFormatFirstDate
= maFirstDate
;
462 maOldFormatLastDate
= aLastDate
;
467 sal_uInt16 nNewFirstYear
= maFirstDate
.GetYear();
468 sal_uInt16 nNewLastYear
= GetLastDate().GetYear();
471 if ( nNewFirstYear
< mnFirstYear
)
473 for ( mnRequestYear
= nNewFirstYear
; mnRequestYear
< mnFirstYear
; mnRequestYear
++ )
475 mnFirstYear
= nNewFirstYear
;
477 if ( nNewLastYear
> mnLastYear
)
479 for ( mnRequestYear
= mnLastYear
; mnRequestYear
< nNewLastYear
; mnRequestYear
++ )
481 mnLastYear
= nNewLastYear
;
486 for ( mnRequestYear
= nNewFirstYear
; mnRequestYear
< nNewLastYear
; mnRequestYear
++ )
488 mnFirstYear
= nNewFirstYear
;
489 mnLastYear
= nNewLastYear
;
493 mbFormat
= sal_False
;
496 // -----------------------------------------------------------------------
498 sal_uInt16
Calendar::ImplHitTest( const Point
& rPos
, Date
& rDate
) const
503 if ( maPrevRect
.IsInside( rPos
) )
504 return CALENDAR_HITTEST_PREV
;
505 else if ( maNextRect
.IsInside( rPos
) )
506 return CALENDAR_HITTEST_NEXT
;
513 DayOfWeek eStartDay
= ImplGetWeekStart();
515 rDate
= GetFirstMonth();
517 for ( long i
= 0; i
< mnLines
; i
++ )
523 nYMonth
= nY
+mnMonthHeight
;
524 for ( long j
= 0; j
< mnMonthPerLine
; j
++ )
526 if ( (rPos
.X() < nX
) && (rPos
.Y() < nYMonth
) )
529 sal_uInt16 nDaysInMonth
= rDate
.GetDaysInMonth();
531 // Entsprechender Monat gefunden
532 if ( (rPos
.X() > nX
) && (rPos
.Y() < nYMonth
) &&
533 (rPos
.X() < nX
+mnMonthWidth
) )
535 if ( rPos
.Y() < (nY
+(TITLE_BORDERY
*2)+mnDayHeight
))
536 return CALENDAR_HITTEST_MONTHTITLE
;
539 long nDayX
= nX
+mnDaysOffX
;
540 long nDayY
= nY
+mnDaysOffY
;
541 if ( rPos
.Y() < nDayY
)
543 sal_uInt16 nDayIndex
= (sal_uInt16
)rDate
.GetDayOfWeek();
544 nDayIndex
= (nDayIndex
+(7-(sal_uInt16
)eStartDay
)) % 7;
545 if ( (i
== 0) && (j
== 0) )
547 Date aTempDate
= rDate
;
548 aTempDate
-= nDayIndex
;
549 for ( nDay
= 0; nDay
< nDayIndex
; nDay
++ )
551 nOffX
= nDayX
+ (nDay
*mnDayWidth
);
552 if ( (rPos
.Y() >= nDayY
) && (rPos
.Y() < nDayY
+mnDayHeight
) &&
553 (rPos
.X() >= nOffX
) && (rPos
.X() < nOffX
+mnDayWidth
) )
557 return CALENDAR_HITTEST_DAY
;
561 for ( nDay
= 1; nDay
<= nDaysInMonth
; nDay
++ )
563 if ( rPos
.Y() < nDayY
)
568 nOffX
= nDayX
+ (nDayIndex
*mnDayWidth
);
569 if ( (rPos
.Y() >= nDayY
) && (rPos
.Y() < nDayY
+mnDayHeight
) &&
570 (rPos
.X() >= nOffX
) && (rPos
.X() < nOffX
+mnDayWidth
) )
573 return CALENDAR_HITTEST_DAY
;
575 if ( nDayIndex
== 6 )
578 nDayY
+= mnDayHeight
;
583 if ( (i
== mnLines
-1) && (j
== mnMonthPerLine
-1) )
585 sal_uInt16 nWeekDay
= (sal_uInt16
)rDate
.GetDayOfWeek();
586 nWeekDay
= (nWeekDay
+(7-(sal_uInt16
)eStartDay
)) % 7;
587 sal_uInt16 nDayCount
= 42-nDaysInMonth
-nWeekDay
;
588 Date aTempDate
= rDate
;
589 aTempDate
+= nDaysInMonth
;
590 for ( nDay
= 1; nDay
<= nDayCount
; nDay
++ )
592 if ( rPos
.Y() < nDayY
)
597 nOffX
= nDayX
+ (nDayIndex
*mnDayWidth
);
598 if ( (rPos
.Y() >= nDayY
) && (rPos
.Y() < nDayY
+mnDayHeight
) &&
599 (rPos
.X() >= nOffX
) && (rPos
.X() < nOffX
+mnDayWidth
) )
603 return CALENDAR_HITTEST_DAY
;
605 if ( nDayIndex
== 6 )
608 nDayY
+= mnDayHeight
;
617 rDate
+= nDaysInMonth
;
627 // -----------------------------------------------------------------------
629 static void ImplDrawSpinArrow( OutputDevice
* pDev
, const Rectangle
& rRect
,
635 long nHeight
= rRect
.GetHeight();
636 long nWidth
= rRect
.GetWidth();
637 if ( nWidth
< nHeight
)
645 Rectangle
aRect( Point( rRect
.Left()+(nWidth
/2)-(nLines
/2),
646 rRect
.Top()+(nHeight
/2) ),
650 aRect
.Left() += nLines
;
651 aRect
.Right() += nLines
;
654 pDev
->DrawRect( aRect
);
655 for ( i
= 0; i
< nLines
; i
++ )
669 pDev
->DrawRect( aRect
);
673 // -----------------------------------------------------------------------
675 void Calendar::ImplDrawSpin( sal_Bool bDrawPrev
, sal_Bool bDrawNext
)
677 if ( !bDrawPrev
&& !bDrawNext
)
681 SetFillColor( GetSettings().GetStyleSettings().GetButtonTextColor() );
684 Rectangle aOutRect
= maPrevRect
;
685 aOutRect
.Left() += 3;
687 aOutRect
.Right() -= 3;
688 aOutRect
.Bottom() -= 3;
689 ImplDrawSpinArrow( this, aOutRect
, sal_True
);
693 Rectangle aOutRect
= maNextRect
;
694 aOutRect
.Left() += 3;
696 aOutRect
.Right() -= 3;
697 aOutRect
.Bottom() -= 3;
698 ImplDrawSpinArrow( this, aOutRect
, sal_False
);
702 // -----------------------------------------------------------------------
704 void Calendar::ImplDrawDate( long nX
, long nY
,
705 sal_uInt16 nDay
, sal_uInt16 nMonth
, sal_uInt16 nYear
,
706 DayOfWeek eDayOfWeek
,
707 sal_Bool bBack
, sal_Bool bOther
, sal_uLong nToday
)
709 Color
* pTextColor
= NULL
;
710 const OUString
& rDay
= maDayTexts
[nDay
-1];
711 Rectangle
aDateRect( nX
, nY
, nX
+mnDayWidth
-1, nY
+mnDayHeight
-1 );
713 sal_Bool bSel
= sal_False
;
714 sal_Bool bFocus
= sal_False
;
716 if ( (nDay
== maCurDate
.GetDay()) &&
717 (nMonth
== maCurDate
.GetMonth()) &&
718 (nYear
== maCurDate
.GetYear()) )
722 if ( mpSelectTable
->find( Date( nDay
, nMonth
, nYear
).GetDate() ) != mpSelectTable
->end() )
726 // Textfarbe ermitteln
728 pTextColor
= &maSelColor
;
730 pTextColor
= &maOtherColor
;
733 if ( eDayOfWeek
== SATURDAY
)
734 pTextColor
= mpSaturdayColor
;
735 else if ( eDayOfWeek
== SUNDAY
)
736 pTextColor
= mpSundayColor
;
738 pTextColor
= mpStandardColor
;
745 Font aOldFont
= GetFont();
746 sal_Bool bBoldFont
= sal_False
;
748 // Hintergrund ausgeben
749 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
755 SetFillColor( rStyleSettings
.GetHighlightColor() );
756 DrawRect( aDateRect
);
763 long nTextX
= nX
+(mnDayWidth
-GetTextWidth( rDay
))-(DAY_OFFX
/2);
764 long nTextY
= nY
+(mnDayHeight
-GetTextHeight())/2;
767 Color aOldColor
= GetTextColor();
768 SetTextColor( *pTextColor
);
769 DrawText( Point( nTextX
, nTextY
), rDay
);
770 SetTextColor( aOldColor
);
773 DrawText( Point( nTextX
, nTextY
), rDay
);
776 Date
aTodayDate( maCurDate
);
778 aTodayDate
.SetDate( nToday
);
780 aTodayDate
= Date( Date::SYSTEM
);
781 if ( (nDay
== aTodayDate
.GetDay()) &&
782 (nMonth
== aTodayDate
.GetMonth()) &&
783 (nYear
== aTodayDate
.GetYear()) )
785 SetLineColor( rStyleSettings
.GetWindowTextColor() );
787 DrawRect( aDateRect
);
790 // Evt. noch FocusRect
791 if ( bFocus
&& HasFocus() )
792 ShowFocus( aDateRect
);
794 if( mbDropPos
&& maDropDate
== Date( nDay
, nMonth
, nYear
) )
801 // -----------------------------------------------------------------------
803 void Calendar::ImplDraw( sal_Bool bPaint
)
807 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
808 Size aOutSize
= GetOutputSizePixel();
817 sal_uLong nToday
= Date( Date::SYSTEM
).GetDate();
821 Date aDate
= GetFirstMonth();
822 DayOfWeek eStartDay
= ImplGetWeekStart();
827 for ( i
= 0; i
< mnLines
; i
++ )
829 // Titleleiste ausgeben
831 SetFillColor( rStyleSettings
.GetFaceColor() );
832 Rectangle
aTitleRect( 0, nY
, aOutSize
.Width()-1, nY
+mnDayHeight
-DAY_OFFY
+TITLE_BORDERY
*2 );
835 Rectangle
aTempRect( 1, aTitleRect
.Top()+TITLE_BORDERY
,
837 aTitleRect
.Bottom()-TITLE_BORDERY
);
840 aTempRect
.Left() = maPrevRect
.Right()+1;
841 aTempRect
.Right() = maNextRect
.Left()-1;
843 DrawRect( aTempRect
);
847 DrawRect( aTitleRect
);
848 Point
aTopLeft1( aTitleRect
.Left(), aTitleRect
.Top() );
849 Point
aTopLeft2( aTitleRect
.Left(), aTitleRect
.Top()+1 );
850 Point
aBottomRight1( aTitleRect
.Right(), aTitleRect
.Bottom() );
851 Point
aBottomRight2( aTitleRect
.Right(), aTitleRect
.Bottom()-1 );
852 SetLineColor( rStyleSettings
.GetDarkShadowColor() );
853 DrawLine( aTopLeft1
, Point( aBottomRight1
.X(), aTopLeft1
.Y() ) );
854 SetLineColor( rStyleSettings
.GetLightColor() );
855 DrawLine( aTopLeft2
, Point( aBottomRight2
.X(), aTopLeft2
.Y() ) );
856 DrawLine( aTopLeft2
, Point( aTopLeft2
.X(), aBottomRight2
.Y() ) );
857 SetLineColor( rStyleSettings
.GetShadowColor() );
858 DrawLine( Point( aTopLeft2
.X(), aBottomRight2
.Y() ), aBottomRight2
);
859 DrawLine( Point( aBottomRight2
.X(), aTopLeft2
.Y() ), aBottomRight2
);
860 SetLineColor( rStyleSettings
.GetDarkShadowColor() );
861 DrawLine( Point( aTopLeft1
.X(), aBottomRight1
.Y() ), aBottomRight1
);
863 Point
aSepPos1( 0, aTitleRect
.Top()+TITLE_BORDERY
);
864 Point
aSepPos2( 0, aTitleRect
.Bottom()-TITLE_BORDERY
);
865 for ( j
= 0; j
< mnMonthPerLine
-1; j
++ )
867 aSepPos1
.X() += mnMonthWidth
-1;
868 aSepPos2
.X() = aSepPos1
.X();
869 SetLineColor( rStyleSettings
.GetShadowColor() );
870 DrawLine( aSepPos1
, aSepPos2
);
872 aSepPos2
.X() = aSepPos1
.X();
873 SetLineColor( rStyleSettings
.GetLightColor() );
874 DrawLine( aSepPos1
, aSepPos2
);
878 for ( j
= 0; j
< mnMonthPerLine
; j
++ )
880 nMonth
= aDate
.GetMonth();
881 nYear
= aDate
.GetYear();
883 // Monat in der Titleleiste ausgeben
885 nDeltaY
= nY
+TITLE_BORDERY
;
886 OUString
aMonthText( maCalendarWrapper
.getDisplayName(
887 i18n::CalendarDisplayIndex::MONTH
, nMonth
-1, 1));
889 aMonthText
+= OUString::number(nYear
);
890 long nMonthTextWidth
= GetTextWidth( aMonthText
);
891 long nMonthOffX1
= 0;
892 long nMonthOffX2
= 0;
896 nMonthOffX1
= maPrevRect
.Right()+1;
897 if ( j
== mnMonthPerLine
-1 )
898 nMonthOffX2
= aOutSize
.Width()-maNextRect
.Left()+1;
900 long nMaxMonthWidth
= mnMonthWidth
-nMonthOffX1
-nMonthOffX2
-4;
901 if ( nMonthTextWidth
> nMaxMonthWidth
)
903 // Abbreviated month name.
904 aMonthText
= maCalendarWrapper
.getDisplayName(
905 i18n::CalendarDisplayIndex::MONTH
, nMonth
-1, 0);
907 aMonthText
+= OUString::number(nYear
);
908 nMonthTextWidth
= GetTextWidth( aMonthText
);
910 long nTempOff
= (mnMonthWidth
-nMonthTextWidth
+1)/2;
911 if ( nTempOff
< nMonthOffX1
)
912 nDeltaX
+= nMonthOffX1
+1;
915 if ( nTempOff
+nMonthTextWidth
> mnMonthWidth
-nMonthOffX2
)
916 nDeltaX
+= mnMonthWidth
-nMonthOffX2
-nMonthTextWidth
;
920 SetTextColor( rStyleSettings
.GetButtonTextColor() );
921 DrawText( Point( nDeltaX
, nDeltaY
), aMonthText
);
922 SetTextColor( rStyleSettings
.GetWindowTextColor() );
924 // Weekleiste ausgeben
927 nDayX
= nX
+mnDaysOffX
;
928 nDayY
= nY
+mnWeekDayOffY
;
929 nDeltaY
= nDayY
+ mnDayHeight
;
930 SetLineColor( rStyleSettings
.GetWindowTextColor() );
931 Point
aStartPos( nDayX
, nDeltaY
);
932 if ( mnWinStyle
& WB_WEEKNUMBER
)
933 aStartPos
.X() -= WEEKNUMBER_OFFX
-2;
934 DrawLine( aStartPos
, Point( nDayX
+(7*mnDayWidth
), nDeltaY
) );
935 DrawTextArray( Point( nDayX
+mnDayOfWeekAry
[0], nDayY
), maDayOfWeekText
, &(mnDayOfWeekAry
[1]) );
938 // Week-Numbers ausgeben
939 if ( mnWinStyle
& WB_WEEKNUMBER
)
941 nDayX
= nX
+mnDaysOffX
;
942 nDayY
= nY
+mnWeekDayOffY
;
943 nDeltaY
= nDayY
+ mnDayHeight
;
944 long nMonthHeight
= mnDayHeight
*6;
946 DrawLine( Point( nDayX
-WEEKNUMBER_OFFX
+2, nDeltaY
), Point( nDayX
-WEEKNUMBER_OFFX
+2, nDeltaY
+nMonthHeight
) );
948 Erase( Rectangle( nDayX
-mnWeekWidth
-WEEKNUMBER_OFFX
, nDeltaY
, nDayX
-WEEKNUMBER_OFFX
-1, nDeltaY
+nMonthHeight
) );
950 Font aOldFont
= GetFont();
951 Font aTempFont
= aOldFont
;
952 ImplGetWeekFont( aTempFont
);
953 SetFont( aTempFont
);
954 nDayX
-= mnWeekWidth
;
955 nDayY
= nY
+mnDaysOffY
;
956 maCalendarWrapper
.setGregorianDateTime( aDate
);
957 for ( sal_uInt16 nWeekCount
= 0; nWeekCount
< 6; nWeekCount
++ )
959 sal_Int32 nWeek
= maCalendarWrapper
.getValue( i18n::CalendarFieldIndex::WEEK_OF_YEAR
);
960 OUString
aWeekText(OUString::number(nWeek
));
961 long nOffX
= (mnWeekWidth
-WEEKNUMBER_OFFX
)-GetTextWidth( aWeekText
);
962 long nOffY
= (mnDayHeight
-GetTextHeight())/2;
963 DrawText( Point( nDayX
+nOffX
, nDayY
+nOffY
), aWeekText
);
964 nDayY
+= mnDayHeight
;
965 maCalendarWrapper
.addValue( i18n::CalendarFieldIndex::DAY_OF_MONTH
, 7);
971 sal_uInt16 nDaysInMonth
= aDate
.GetDaysInMonth();
972 nDayX
= nX
+mnDaysOffX
;
973 nDayY
= nY
+mnDaysOffY
;
976 Rectangle
aClearRect( nDayX
, nDayY
,
977 nDayX
+(7*mnDayWidth
)-1, nDayY
+(6*mnDayHeight
)-1 );
980 sal_uInt16 nDayIndex
= (sal_uInt16
)aDate
.GetDayOfWeek();
981 nDayIndex
= (nDayIndex
+(7-(sal_uInt16
)eStartDay
)) % 7;
982 if ( (i
== 0) && (j
== 0) )
984 Date aTempDate
= aDate
;
985 aTempDate
-= nDayIndex
;
986 for ( nDay
= 0; nDay
< nDayIndex
; nDay
++ )
988 nDeltaX
= nDayX
+ (nDay
*mnDayWidth
);
989 ImplDrawDate( nDeltaX
, nDayY
, nDay
+aTempDate
.GetDay(),
990 aTempDate
.GetMonth(), aTempDate
.GetYear(),
991 (DayOfWeek
)((nDay
+(sal_uInt16
)eStartDay
)%7), sal_False
, sal_True
, nToday
);
994 for ( nDay
= 1; nDay
<= nDaysInMonth
; nDay
++ )
996 nDeltaX
= nDayX
+ (nDayIndex
*mnDayWidth
);
997 ImplDrawDate( nDeltaX
, nDayY
, nDay
, nMonth
, nYear
,
998 (DayOfWeek
)((nDayIndex
+(sal_uInt16
)eStartDay
)%7),
999 sal_False
, sal_False
, nToday
);
1000 if ( nDayIndex
== 6 )
1003 nDayY
+= mnDayHeight
;
1008 if ( (i
== mnLines
-1) && (j
== mnMonthPerLine
-1) )
1010 sal_uInt16 nWeekDay
= (sal_uInt16
)aDate
.GetDayOfWeek();
1011 nWeekDay
= (nWeekDay
+(7-(sal_uInt16
)eStartDay
)) % 7;
1012 sal_uInt16 nDayCount
= 42-nDaysInMonth
-nWeekDay
;
1013 Date aTempDate
= aDate
;
1014 aTempDate
+= nDaysInMonth
;
1015 for ( nDay
= 1; nDay
<= nDayCount
; nDay
++ )
1017 nDeltaX
= nDayX
+ (nDayIndex
*mnDayWidth
);
1018 ImplDrawDate( nDeltaX
, nDayY
, nDay
,
1019 aTempDate
.GetMonth(), aTempDate
.GetYear(),
1020 (DayOfWeek
)((nDayIndex
+(sal_uInt16
)eStartDay
)%7),
1021 sal_False
, sal_True
, nToday
);
1022 if ( nDayIndex
== 6 )
1025 nDayY
+= mnDayHeight
;
1032 aDate
+= nDaysInMonth
;
1036 nY
+= mnMonthHeight
;
1039 // Spin-Buttons zeichnen
1044 // -----------------------------------------------------------------------
1046 void Calendar::ImplUpdateDate( const Date
& rDate
)
1048 if ( IsReallyVisible() && IsUpdateMode() )
1050 Rectangle
aDateRect( GetDateRect( rDate
) );
1051 if ( !aDateRect
.IsEmpty() )
1053 sal_Bool bOther
= (rDate
< GetFirstMonth()) || (rDate
> GetLastMonth());
1054 ImplDrawDate( aDateRect
.Left(), aDateRect
.Top(),
1055 rDate
.GetDay(), rDate
.GetMonth(), rDate
.GetYear(),
1056 rDate
.GetDayOfWeek(), sal_True
, bOther
);
1061 // -----------------------------------------------------------------------
1063 void Calendar::ImplUpdateSelection( IntDateSet
* pOld
)
1065 IntDateSet
* pNew
= mpSelectTable
;
1067 for ( IntDateSet::const_iterator it
= pOld
->begin(); it
!= pOld
->end(); ++it
)
1069 sal_uLong nKey
= *it
;
1070 if ( pNew
->find( nKey
) == pNew
->end() )
1072 Date
aTempDate( nKey
);
1073 ImplUpdateDate( aTempDate
);
1077 for ( IntDateSet::const_iterator it
= pNew
->begin(); it
!= pNew
->end(); ++it
)
1079 sal_uLong nKey
= *it
;
1080 if ( pOld
->find( nKey
) == pOld
->end() )
1082 Date
aTempDate( nKey
);
1083 ImplUpdateDate( aTempDate
);
1088 // -----------------------------------------------------------------------
1090 void Calendar::ImplMouseSelect( const Date
& rDate
, sal_uInt16 nHitTest
,
1091 sal_Bool bMove
, sal_Bool bExpand
, sal_Bool bExtended
)
1093 IntDateSet
* pOldSel
= new IntDateSet( *mpSelectTable
);
1094 Date aOldDate
= maCurDate
;
1095 Date aTempDate
= rDate
;
1097 if ( !(nHitTest
& CALENDAR_HITTEST_DAY
) )
1100 if ( mbMultiSelection
)
1102 maCurDate
= aTempDate
;
1103 mbSelLeft
= aTempDate
< maAnchorDate
;
1109 ImplCalendarUnSelectDateRange( mpSelectTable
, mpRestoreSelectTable
, Date( 1, 1, 0 ), aTempDate
);
1110 ImplCalendarUnSelectDateRange( mpSelectTable
, mpRestoreSelectTable
, maAnchorDate
, Date( 31, 12, 9999 ) );
1114 ImplCalendarUnSelectDateRange( mpSelectTable
, mpRestoreSelectTable
, Date( 1, 1, 0 ), maAnchorDate
);
1115 ImplCalendarUnSelectDateRange( mpSelectTable
, mpRestoreSelectTable
, aTempDate
, Date( 31, 12, 9999 ) );
1117 ImplCalendarSelectDateRange( mpSelectTable
, aTempDate
, maAnchorDate
, !mbUnSel
);
1127 ImplCalendarSelectDateRange( mpSelectTable
, Date( 1, 1, 0 ), aTempDate
, sal_False
);
1128 ImplCalendarSelectDateRange( mpSelectTable
, maAnchorDate
, Date( 31, 12, 9999 ), sal_False
);
1132 ImplCalendarSelectDateRange( mpSelectTable
, Date( 1, 1, 0 ), maAnchorDate
, sal_False
);
1133 ImplCalendarSelectDateRange( mpSelectTable
, aTempDate
, Date( 31, 12, 9999 ), sal_False
);
1136 ImplCalendarSelectDateRange( mpSelectTable
, aTempDate
, maAnchorDate
, sal_True
);
1138 else if ( bExtended
&& !(mnWinStyle
& WB_RANGESELECT
) )
1140 maAnchorDate
= aTempDate
;
1141 if ( IsDateSelected( aTempDate
) )
1144 ImplCalendarSelectDate( mpSelectTable
, aTempDate
, sal_False
);
1148 ImplCalendarSelectDate( mpSelectTable
, aTempDate
, sal_True
);
1153 maAnchorDate
= aTempDate
;
1154 ImplCalendarClearSelectDate( mpSelectTable
);
1155 ImplCalendarSelectDate( mpSelectTable
, aTempDate
, sal_True
);
1158 mpRestoreSelectTable
= new IntDateSet( *mpSelectTable
);
1163 if ( aTempDate
< maCurDate
)
1164 mbSelLeft
= sal_True
;
1166 mbSelLeft
= sal_False
;
1167 if ( !(nHitTest
& CALENDAR_HITTEST_DAY
) )
1168 aTempDate
= maOldCurDate
;
1170 maAnchorDate
= aTempDate
;
1171 if ( aTempDate
!= maCurDate
)
1173 maCurDate
= aTempDate
;
1174 ImplCalendarSelectDate( mpSelectTable
, aOldDate
, sal_False
);
1175 ImplCalendarSelectDate( mpSelectTable
, maCurDate
, sal_True
);
1179 sal_Bool bNewSel
= *pOldSel
!= *mpSelectTable
;
1180 if ( (maCurDate
!= aOldDate
) || bNewSel
)
1184 mbInSelChange
= sal_True
;
1185 SelectionChanging();
1186 mbInSelChange
= sal_False
;
1190 ImplUpdateSelection( pOldSel
);
1191 if ( !bNewSel
|| pOldSel
->find( aOldDate
.GetDate() ) == pOldSel
->end() )
1192 ImplUpdateDate( aOldDate
);
1193 // Damit Focus-Rechteck auch wieder neu ausgegeben wird
1194 if ( HasFocus() || !bNewSel
1195 || mpSelectTable
->find( maCurDate
.GetDate() ) == mpSelectTable
->end() )
1196 ImplUpdateDate( maCurDate
);
1201 // -----------------------------------------------------------------------
1203 void Calendar::ImplUpdate( sal_Bool bCalcNew
)
1205 if ( IsReallyVisible() && IsUpdateMode() )
1207 if ( bCalcNew
&& !mbCalc
)
1209 else if ( !mbFormat
&& !mbCalc
)
1213 mbFormat
= sal_True
;
1214 ImplDraw( sal_False
);
1224 mbFormat
= sal_True
;
1227 // -----------------------------------------------------------------------
1229 void Calendar::ImplInvertDropPos()
1231 Rectangle aRect
= GetDateRect( maDropDate
);//this is one Pixel to width and one to heigh
1232 aRect
.Bottom() = aRect
.Top()+mnDayHeight
-1;
1233 aRect
.Right() = aRect
.Left()+mnDayWidth
-1;
1237 // -----------------------------------------------------------------------
1239 void Calendar::ImplScroll( sal_Bool bPrev
)
1241 Date aNewFirstMonth
= GetFirstMonth();
1245 aNewFirstMonth
-= aNewFirstMonth
.GetDaysInMonth()-1;
1248 aNewFirstMonth
+= aNewFirstMonth
.GetDaysInMonth();
1249 mbDirect
= sal_True
;
1250 SetFirstDate( aNewFirstMonth
);
1251 mbDirect
= sal_False
;
1254 // -----------------------------------------------------------------------
1256 void Calendar::ImplShowMenu( const Point
& rPos
, const Date
& rDate
)
1260 Date aOldFirstDate
= GetFirstMonth();
1261 PopupMenu aPopupMenu
;
1262 PopupMenu
* pYearPopupMenus
[MENU_YEAR_COUNT
];
1263 sal_uInt16 nMonthOff
;
1264 sal_uInt16 nCurItemId
;
1265 sal_uInt16 nYear
= rDate
.GetYear()-1;
1268 sal_uInt16 nYearIdCount
= 1000;
1270 nMonthOff
= (rDate
.GetYear()-aOldFirstDate
.GetYear())*12;
1271 if ( aOldFirstDate
.GetMonth() < rDate
.GetMonth() )
1272 nMonthOff
+= rDate
.GetMonth()-aOldFirstDate
.GetMonth();
1274 nMonthOff
-= aOldFirstDate
.GetMonth()-rDate
.GetMonth();
1276 // Menu aufbauen (Jahre mit verschiedenen Monaten aufnehmen)
1277 for ( i
= 0; i
< MENU_YEAR_COUNT
; i
++ )
1279 pYearPopupMenus
[i
] = new PopupMenu
;
1280 for ( j
= 1; j
<= 12; j
++ )
1281 pYearPopupMenus
[i
]->InsertItem( nYearIdCount
+j
,
1282 maCalendarWrapper
.getDisplayName(
1283 i18n::CalendarDisplayIndex::MONTH
, j
-1, 1));
1284 aPopupMenu
.InsertItem( 10+i
, OUString::number( nYear
+i
) );
1285 aPopupMenu
.SetPopupMenu( 10+i
, pYearPopupMenus
[i
] );
1286 nYearIdCount
+= 1000;
1289 mbMenuDown
= sal_True
;
1290 nCurItemId
= aPopupMenu
.Execute( this, rPos
);
1291 mbMenuDown
= sal_False
;
1294 aPopupMenu
.SetPopupMenu( 2, NULL
);
1295 for ( i
= 0; i
< MENU_YEAR_COUNT
; i
++ )
1297 aPopupMenu
.SetPopupMenu( 10+i
, NULL
);
1298 delete pYearPopupMenus
[i
];
1303 sal_uInt16 nTempMonthOff
= nMonthOff
% 12;
1304 sal_uInt16 nTempYearOff
= nMonthOff
/ 12;
1305 sal_uInt16 nNewMonth
= nCurItemId
% 1000;
1306 sal_uInt16 nNewYear
= nYear
+((nCurItemId
-1000)/1000);
1307 if ( nTempMonthOff
< nNewMonth
)
1308 nNewMonth
= nNewMonth
- nTempMonthOff
;
1312 nNewMonth
= 12-(nTempMonthOff
-nNewMonth
);
1314 nNewYear
= nNewYear
- nTempYearOff
;
1315 SetFirstDate( Date( 1, nNewMonth
, nNewYear
) );
1319 // -----------------------------------------------------------------------
1321 void Calendar::ImplTracking( const Point
& rPos
, sal_Bool bRepeat
)
1323 Date aTempDate
= maCurDate
;
1324 sal_uInt16 nHitTest
= ImplHitTest( rPos
, aTempDate
);
1328 mbPrevIn
= (nHitTest
& CALENDAR_HITTEST_PREV
) != 0;
1329 mbNextIn
= (nHitTest
& CALENDAR_HITTEST_NEXT
) != 0;
1331 if ( bRepeat
&& (mbPrevIn
|| mbNextIn
) )
1333 mbScrollDateRange
= sal_True
;
1334 ImplScroll( mbPrevIn
);
1335 mbScrollDateRange
= sal_False
;
1339 ImplMouseSelect( aTempDate
, nHitTest
, sal_True
, sal_False
, sal_False
);
1342 // -----------------------------------------------------------------------
1344 void Calendar::ImplEndTracking( sal_Bool bCancel
)
1346 sal_Bool bSelection
= mbSelection
;
1347 sal_Bool bSpinDown
= mbSpinDown
;
1350 mbSelection
= sal_False
;
1351 mbMultiSelection
= sal_False
;
1352 mbUnSel
= sal_False
;
1353 mbSpinDown
= sal_False
;
1354 mbPrevIn
= sal_False
;
1355 mbNextIn
= sal_False
;
1359 if ( maOldFirstDate
!= maFirstDate
)
1360 SetFirstDate( maOldFirstDate
);
1364 IntDateSet
* pOldSel
= new IntDateSet( *mpSelectTable
);
1365 Date aOldDate
= maCurDate
;
1366 maCurDate
= maOldCurDate
;
1367 *mpSelectTable
= *mpOldSelectTable
;
1369 ImplUpdateSelection( pOldSel
);
1370 if ( pOldSel
->find( aOldDate
.GetDate() ) == pOldSel
->end() )
1371 ImplUpdateDate( aOldDate
);
1372 // Damit Focus-Rechteck auch wieder neu ausgegeben wird
1373 if ( HasFocus() || mpSelectTable
->find( maCurDate
.GetDate() ) == mpSelectTable
->end() )
1374 ImplUpdateDate( maCurDate
);
1383 // Feststellen, ob wir sichtbaren Bereich scrollen sollen
1384 sal_uLong nSelCount
= mpSelectTable
->size();
1387 Date
aFirstSelDate( *mpSelectTable
->begin() );
1388 Date
aLastSelDate( *mpSelectTable
->rbegin() );
1389 if ( aLastSelDate
< GetFirstMonth() )
1390 ImplScroll( sal_True
);
1391 else if ( GetLastMonth() < aFirstSelDate
)
1392 ImplScroll( sal_False
);
1397 (!bCancel
&& ((maCurDate
!= maOldCurDate
) || (*mpOldSelectTable
!= *mpSelectTable
))) )
1400 if ( !bSelection
&& (mnWinStyle
& WB_TABSTOP
) && !bCancel
)
1403 delete mpOldSelectTable
;
1404 mpOldSelectTable
= NULL
;
1405 delete mpRestoreSelectTable
;
1406 mpRestoreSelectTable
= NULL
;
1410 // -----------------------------------------------------------------------
1412 IMPL_STATIC_LINK( Calendar
, ScrollHdl
, Timer
*, EMPTYARG
)
1414 sal_Bool bPrevIn
= (pThis
->mnDragScrollHitTest
& CALENDAR_HITTEST_PREV
) != 0;
1415 sal_Bool bNextIn
= (pThis
->mnDragScrollHitTest
& CALENDAR_HITTEST_NEXT
) != 0;
1416 if( bNextIn
|| bPrevIn
)
1418 pThis
->mbScrollDateRange
= sal_True
;
1419 pThis
->ImplScroll( bPrevIn
);
1420 pThis
->mbScrollDateRange
= sal_False
;
1425 // -----------------------------------------------------------------------
1427 void Calendar::MouseButtonDown( const MouseEvent
& rMEvt
)
1429 if ( rMEvt
.IsLeft() && !mbMenuDown
)
1431 Date aTempDate
= maCurDate
;
1432 sal_uInt16 nHitTest
= ImplHitTest( rMEvt
.GetPosPixel(), aTempDate
);
1435 if ( nHitTest
& CALENDAR_HITTEST_MONTHTITLE
)
1436 ImplShowMenu( rMEvt
.GetPosPixel(), aTempDate
);
1439 maOldFirstDate
= maFirstDate
;
1441 mbPrevIn
= (nHitTest
& CALENDAR_HITTEST_PREV
) != 0;
1442 mbNextIn
= (nHitTest
& CALENDAR_HITTEST_NEXT
) != 0;
1443 if ( mbPrevIn
|| mbNextIn
)
1445 mbSpinDown
= sal_True
;
1446 mbScrollDateRange
= sal_True
;
1447 ImplScroll( mbPrevIn
);
1448 mbScrollDateRange
= sal_False
;
1449 // Hier muss BUTTONREPEAT stehen, also nicht wieder
1450 // auf SCROLLREPEAT aendern, sondern mit TH abklaeren,
1451 // warum es evtl. anders sein sollte (71775)
1452 StartTracking( STARTTRACK_BUTTONREPEAT
);
1456 if ( (rMEvt
.GetClicks() == 2) && (nHitTest
& CALENDAR_HITTEST_DAY
) )
1460 if ( mpOldSelectTable
)
1461 delete mpOldSelectTable
;
1462 maOldCurDate
= maCurDate
;
1463 mpOldSelectTable
= new IntDateSet( *mpSelectTable
);
1471 mbMultiSelection
= (mnWinStyle
& (WB_MULTISELECT
| WB_RANGESELECT
)) != 0;
1472 if ( (nHitTest
& CALENDAR_HITTEST_DAY
) && mbMultiSelection
)
1473 mbWeekSel
= sal_True
;
1475 mbWeekSel
= sal_False
;
1476 ImplMouseSelect( aTempDate
, nHitTest
, sal_False
, rMEvt
.IsShift(), rMEvt
.IsMod1() );
1485 Control::MouseButtonDown( rMEvt
);
1488 // -----------------------------------------------------------------------
1490 void Calendar::MouseButtonUp( const MouseEvent
& rMEvt
)
1492 if ( rMEvt
.IsLeft() && mbSelection
)
1493 ImplEndTracking( sal_False
);
1495 Control::MouseButtonUp( rMEvt
);
1498 // -----------------------------------------------------------------------
1500 void Calendar::MouseMove( const MouseEvent
& rMEvt
)
1502 if ( mbSelection
&& rMEvt
.GetButtons() )
1503 ImplTracking( rMEvt
.GetPosPixel(), sal_False
);
1505 Control::MouseMove( rMEvt
);
1508 // -----------------------------------------------------------------------
1510 void Calendar::Tracking( const TrackingEvent
& rTEvt
)
1512 Point aMousePos
= rTEvt
.GetMouseEvent().GetPosPixel();
1514 if ( rTEvt
.IsTrackingEnded() )
1515 ImplEndTracking( rTEvt
.IsTrackingCanceled() );
1517 ImplTracking( aMousePos
, rTEvt
.IsTrackingRepeat() );
1520 // -----------------------------------------------------------------------
1522 void Calendar::KeyInput( const KeyEvent
& rKEvt
)
1524 Date aNewDate
= maCurDate
;
1525 sal_Bool bMultiSel
= (mnWinStyle
& (WB_RANGESELECT
| WB_MULTISELECT
)) != 0;
1526 sal_Bool bExpand
= rKEvt
.GetKeyCode().IsShift();
1527 sal_Bool bExtended
= rKEvt
.GetKeyCode().IsMod1();
1529 switch ( rKEvt
.GetKeyCode().GetCode() )
1532 aNewDate
.SetDay( 1 );
1536 aNewDate
.SetDay( aNewDate
.GetDaysInMonth() );
1557 Date aTempDate
= aNewDate
;
1558 aTempDate
-= aNewDate
.GetDay()+1;
1559 aNewDate
-= aTempDate
.GetDaysInMonth();
1564 aNewDate
+= aNewDate
.GetDaysInMonth();
1568 if ( bMultiSel
&& !(mnWinStyle
& WB_RANGESELECT
) )
1572 sal_Bool bDateSel
= IsDateSelected( maCurDate
);
1573 SelectDate( maCurDate
, !bDateSel
);
1574 mbSelLeft
= sal_False
;
1575 SelectionChanging();
1576 mbTravelSelect
= sal_True
;
1578 mbTravelSelect
= sal_False
;
1582 Control::KeyInput( rKEvt
);
1586 Control::KeyInput( rKEvt
);
1590 if ( aNewDate
!= maCurDate
)
1592 if ( bMultiSel
&& bExpand
)
1594 IntDateSet
* pOldSel
= new IntDateSet( *mpSelectTable
);
1595 Date aOldAnchorDate
= maAnchorDate
;
1596 mbSelLeft
= aNewDate
< maAnchorDate
;
1601 ImplCalendarSelectDateRange( mpSelectTable
, Date( 1, 1, 0 ), aNewDate
, sal_False
);
1602 ImplCalendarSelectDateRange( mpSelectTable
, maAnchorDate
, Date( 31, 12, 9999 ), sal_False
);
1606 ImplCalendarSelectDateRange( mpSelectTable
, Date( 1, 1, 0 ), maAnchorDate
, sal_False
);
1607 ImplCalendarSelectDateRange( mpSelectTable
, aNewDate
, Date( 31, 12, 9999 ), sal_False
);
1610 ImplCalendarSelectDateRange( mpSelectTable
, aNewDate
, maAnchorDate
, sal_True
);
1611 mbDirect
= sal_True
;
1612 SetCurDate( aNewDate
);
1613 mbDirect
= sal_False
;
1614 maAnchorDate
= aOldAnchorDate
;
1615 mbInSelChange
= sal_True
;
1616 SelectionChanging();
1617 mbInSelChange
= sal_False
;
1618 ImplUpdateSelection( pOldSel
);
1623 if ( mnWinStyle
& WB_RANGESELECT
)
1626 SelectDate( aNewDate
, sal_True
);
1628 mbDirect
= sal_True
;
1629 SetCurDate( aNewDate
);
1630 mbDirect
= sal_False
;
1632 mbTravelSelect
= sal_True
;
1634 mbTravelSelect
= sal_False
;
1638 // -----------------------------------------------------------------------
1640 void Calendar::Paint( const Rectangle
& )
1642 ImplDraw( sal_True
);
1645 // -----------------------------------------------------------------------
1647 void Calendar::GetFocus()
1649 ImplUpdateDate( maCurDate
);
1650 Control::GetFocus();
1653 // -----------------------------------------------------------------------
1655 void Calendar::LoseFocus()
1658 Control::LoseFocus();
1661 // -----------------------------------------------------------------------
1663 void Calendar::Resize()
1665 ImplUpdate( sal_True
);
1669 // -----------------------------------------------------------------------
1671 void Calendar::RequestHelp( const HelpEvent
& rHEvt
)
1673 if ( rHEvt
.GetMode() & (HELPMODE_QUICK
| HELPMODE_BALLOON
) )
1675 Date aDate
= maCurDate
;
1676 if ( GetDate( ScreenToOutputPixel( rHEvt
.GetMousePosPixel() ), aDate
) )
1678 Rectangle aDateRect
= GetDateRect( aDate
);
1679 Point aPt
= OutputToScreenPixel( aDateRect
.TopLeft() );
1680 aDateRect
.Left() = aPt
.X();
1681 aDateRect
.Top() = aPt
.Y();
1682 aPt
= OutputToScreenPixel( aDateRect
.BottomRight() );
1683 aDateRect
.Right() = aPt
.X();
1684 aDateRect
.Bottom() = aPt
.Y();
1686 if ( rHEvt
.GetMode() & HELPMODE_QUICK
)
1688 maCalendarWrapper
.setGregorianDateTime( aDate
);
1689 sal_uInt16 nWeek
= (sal_uInt16
) maCalendarWrapper
.getValue( i18n::CalendarFieldIndex::WEEK_OF_YEAR
);
1690 sal_uInt16 nMonth
= aDate
.GetMonth();
1691 OUString
aStr( maDayText
);
1693 aStr
+= OUString::number(aDate
.GetDayOfYear());
1697 aStr
+= OUString::number(nWeek
);
1698 // Evt. noch Jahr hinzufuegen, wenn es nicht das gleiche ist
1699 if ( (nMonth
== 12) && (nWeek
== 1) )
1702 aStr
+= OUString::number(aDate
.GetYear()+1);
1704 else if ( (nMonth
== 1) && (nWeek
> 50) )
1707 aStr
+= OUString::number(aDate
.GetYear()-1);
1709 Help::ShowQuickHelp( this, aDateRect
, aStr
);
1715 Control::RequestHelp( rHEvt
);
1718 // -----------------------------------------------------------------------
1720 void Calendar::Command( const CommandEvent
& rCEvt
)
1722 if ( rCEvt
.GetCommand() == COMMAND_CONTEXTMENU
)
1724 if ( !mbSelection
&& rCEvt
.IsMouseEvent() )
1726 Date aTempDate
= maCurDate
;
1727 sal_uInt16 nHitTest
= ImplHitTest( rCEvt
.GetMousePosPixel(), aTempDate
);
1728 if ( nHitTest
& CALENDAR_HITTEST_MONTHTITLE
)
1730 ImplShowMenu( rCEvt
.GetMousePosPixel(), aTempDate
);
1735 else if ( rCEvt
.GetCommand() == COMMAND_WHEEL
)
1737 const CommandWheelData
* pData
= rCEvt
.GetWheelData();
1738 if ( pData
->GetMode() == COMMAND_WHEEL_SCROLL
)
1740 long nNotchDelta
= pData
->GetNotchDelta();
1741 if ( nNotchDelta
< 0 )
1743 while ( nNotchDelta
< 0 )
1745 ImplScroll( sal_True
);
1751 while ( nNotchDelta
> 0 )
1753 ImplScroll( sal_False
);
1762 Control::Command( rCEvt
);
1765 // -----------------------------------------------------------------------
1767 void Calendar::StateChanged( StateChangedType nType
)
1769 Control::StateChanged( nType
);
1771 if ( nType
== STATE_CHANGE_INITSHOW
)
1775 // -----------------------------------------------------------------------
1777 void Calendar::DataChanged( const DataChangedEvent
& rDCEvt
)
1779 Control::DataChanged( rDCEvt
);
1781 if ( (rDCEvt
.GetType() == DATACHANGED_FONTS
) ||
1782 (rDCEvt
.GetType() == DATACHANGED_FONTSUBSTITUTION
) ||
1783 ((rDCEvt
.GetType() == DATACHANGED_SETTINGS
) &&
1784 (rDCEvt
.GetFlags() & SETTINGS_STYLE
)) )
1791 // -----------------------------------------------------------------------
1793 void Calendar::SelectionChanging()
1795 maSelectionChangingHdl
.Call( this );
1798 // -----------------------------------------------------------------------
1800 void Calendar::DateRangeChanged()
1802 maDateRangeChangedHdl
.Call( this );
1805 // -----------------------------------------------------------------------
1807 void Calendar::RequestDateInfo()
1809 maRequestDateInfoHdl
.Call( this );
1812 // -----------------------------------------------------------------------
1814 void Calendar::DoubleClick()
1816 maDoubleClickHdl
.Call( this );
1819 // -----------------------------------------------------------------------
1821 void Calendar::Select()
1823 maSelectHdl
.Call( this );
1826 // -----------------------------------------------------------------------
1828 void Calendar::SelectDate( const Date
& rDate
, sal_Bool bSelect
)
1830 if ( !rDate
.IsValidAndGregorian() )
1833 IntDateSet
* pOldSel
;
1835 if ( !mbInSelChange
)
1836 pOldSel
= new IntDateSet( *mpSelectTable
);
1840 ImplCalendarSelectDate( mpSelectTable
, rDate
, bSelect
);
1844 ImplUpdateSelection( pOldSel
);
1849 // -----------------------------------------------------------------------
1851 void Calendar::SetNoSelection()
1853 IntDateSet
* pOldSel
;
1855 if ( !mbInSelChange
)
1856 pOldSel
= new IntDateSet( *mpSelectTable
);
1860 ImplCalendarClearSelectDate( mpSelectTable
);
1864 ImplUpdateSelection( pOldSel
);
1869 // -----------------------------------------------------------------------
1871 sal_Bool
Calendar::IsDateSelected( const Date
& rDate
) const
1873 return mpSelectTable
->find( rDate
.GetDate() ) != mpSelectTable
->end();
1876 // -----------------------------------------------------------------------
1878 Date
Calendar::GetFirstSelectedDate() const
1880 if ( !mpSelectTable
->empty() )
1881 return Date( *mpSelectTable
->begin() );
1884 Date
aDate( 0, 0, 0 );
1889 // -----------------------------------------------------------------------
1891 void Calendar::SetCurDate( const Date
& rNewDate
)
1893 if ( !rNewDate
.IsValidAndGregorian() )
1896 if ( maCurDate
!= rNewDate
)
1898 sal_Bool bUpdate
= IsVisible() && IsUpdateMode();
1899 Date aOldDate
= maCurDate
;
1900 maCurDate
= rNewDate
;
1901 maAnchorDate
= maCurDate
;
1903 if ( !(mnWinStyle
& (WB_RANGESELECT
| WB_MULTISELECT
)) )
1905 ImplCalendarSelectDate( mpSelectTable
, aOldDate
, sal_False
);
1906 ImplCalendarSelectDate( mpSelectTable
, maCurDate
, sal_True
);
1908 else if ( !HasFocus() )
1909 bUpdate
= sal_False
;
1911 // Aktuelles Datum noch in den sichtbaren Bereich verschieben
1912 if ( mbFormat
|| (maCurDate
< GetFirstMonth()) )
1913 SetFirstDate( maCurDate
);
1914 else if ( maCurDate
> GetLastMonth() )
1916 Date aTempDate
= GetLastMonth();
1917 long nDateOff
= maCurDate
-aTempDate
;
1918 if ( nDateOff
< 365 )
1920 Date aFirstDate
= GetFirstMonth();
1921 aFirstDate
+= aFirstDate
.GetDaysInMonth();
1923 while ( nDateOff
> aTempDate
.GetDaysInMonth() )
1925 aFirstDate
+= aFirstDate
.GetDaysInMonth();
1926 long nDaysInMonth
= aTempDate
.GetDaysInMonth();
1927 aTempDate
+= nDaysInMonth
;
1928 nDateOff
-= nDaysInMonth
;
1930 SetFirstDate( aFirstDate
);
1933 SetFirstDate( maCurDate
);
1940 ImplUpdateDate( aOldDate
);
1941 ImplUpdateDate( maCurDate
);
1947 // -----------------------------------------------------------------------
1949 void Calendar::SetFirstDate( const Date
& rNewFirstDate
)
1951 if ( maFirstDate
!= rNewFirstDate
)
1953 maFirstDate
= Date( 1, rNewFirstDate
.GetMonth(), rNewFirstDate
.GetYear() );
1954 mbDropPos
= sal_False
;
1959 // -----------------------------------------------------------------------
1961 Date
Calendar::GetFirstMonth() const
1963 if ( maFirstDate
.GetDay() > 1 )
1965 if ( maFirstDate
.GetMonth() == 12 )
1966 return Date( 1, 1, maFirstDate
.GetYear()+1 );
1968 return Date( 1, maFirstDate
.GetMonth()+1, maFirstDate
.GetYear() );
1974 // -----------------------------------------------------------------------
1976 Date
Calendar::GetLastMonth() const
1978 Date aDate
= GetFirstMonth();
1979 sal_uInt16 nMonthCount
= GetMonthCount();
1980 for ( sal_uInt16 i
= 0; i
< nMonthCount
; i
++ )
1981 aDate
+= aDate
.GetDaysInMonth();
1986 // -----------------------------------------------------------------------
1988 sal_uInt16
Calendar::GetMonthCount() const
1993 return (sal_uInt16
)(mnMonthPerLine
*mnLines
);
1996 // -----------------------------------------------------------------------
1998 sal_Bool
Calendar::GetDate( const Point
& rPos
, Date
& rDate
) const
2000 Date aDate
= maCurDate
;
2001 sal_uInt16 nHitTest
= ImplHitTest( rPos
, aDate
);
2002 if ( nHitTest
& CALENDAR_HITTEST_DAY
)
2011 // -----------------------------------------------------------------------
2013 Rectangle
Calendar::GetDateRect( const Date
& rDate
) const
2017 if ( mbFormat
|| (rDate
< maFirstDate
) || (rDate
> (maFirstDate
+mnDayCount
)) )
2023 sal_uInt16 nDayIndex
;
2024 Date aDate
= GetFirstMonth();
2026 if ( rDate
< aDate
)
2028 aRect
= GetDateRect( aDate
);
2029 nDaysOff
= aDate
-rDate
;
2030 nX
= (long)(nDaysOff
*mnDayWidth
);
2032 aRect
.Right() -= nX
;
2037 Date aLastDate
= GetLastMonth();
2038 if ( rDate
> aLastDate
)
2040 sal_uInt16 nWeekDay
= (sal_uInt16
)aLastDate
.GetDayOfWeek();
2041 nWeekDay
= (nWeekDay
+(7-(sal_uInt16
)ImplGetWeekStart())) % 7;
2042 aLastDate
-= nWeekDay
;
2043 aRect
= GetDateRect( aLastDate
);
2044 nDaysOff
= rDate
-aLastDate
;
2046 for ( sal_uInt16 i
= 0; i
<= nDaysOff
; i
++ )
2048 if ( aLastDate
== rDate
)
2050 aRect
.Left() += nDayIndex
*mnDayWidth
;
2051 aRect
.Right() = aRect
.Left()+mnDayWidth
;
2054 if ( nDayIndex
== 6 )
2057 aRect
.Top() += mnDayHeight
;
2058 aRect
.Bottom() += mnDayHeight
;
2068 for ( long i
= 0; i
< mnLines
; i
++ )
2071 for ( long j
= 0; j
< mnMonthPerLine
; j
++ )
2073 sal_uInt16 nDaysInMonth
= aDate
.GetDaysInMonth();
2076 if ( (aDate
.GetMonth() == rDate
.GetMonth()) &&
2077 (aDate
.GetYear() == rDate
.GetYear()) )
2079 long nDayX
= nX
+mnDaysOffX
;
2080 long nDayY
= nY
+mnDaysOffY
;
2081 nDayIndex
= (sal_uInt16
)aDate
.GetDayOfWeek();
2082 nDayIndex
= (nDayIndex
+(7-(sal_uInt16
)ImplGetWeekStart())) % 7;
2083 for ( sal_uInt16 nDay
= 1; nDay
<= nDaysInMonth
; nDay
++ )
2085 if ( nDay
== rDate
.GetDay() )
2087 aRect
.Left() = nDayX
+ (nDayIndex
*mnDayWidth
);
2088 aRect
.Top() = nDayY
;
2089 aRect
.Right() = aRect
.Left()+mnDayWidth
;
2090 aRect
.Bottom() = aRect
.Top()+mnDayHeight
;
2093 if ( nDayIndex
== 6 )
2096 nDayY
+= mnDayHeight
;
2103 aDate
+= nDaysInMonth
;
2107 nY
+= mnMonthHeight
;
2113 // -----------------------------------------------------------------------
2115 void Calendar::StartSelection()
2117 if ( mpOldSelectTable
)
2118 delete mpOldSelectTable
;
2119 maOldCurDate
= maCurDate
;
2120 mpOldSelectTable
= new IntDateSet( *mpSelectTable
);
2122 mbSelection
= sal_True
;
2125 // -----------------------------------------------------------------------
2127 void Calendar::EndSelection()
2129 if ( mbDrag
|| mbSpinDown
|| mbSelection
)
2135 mbSelection
= sal_False
;
2136 mbMultiSelection
= sal_False
;
2137 mbSpinDown
= sal_False
;
2138 mbPrevIn
= sal_False
;
2139 mbNextIn
= sal_False
;
2143 // -----------------------------------------------------------------------
2145 Size
Calendar::CalcWindowSizePixel( long nCalcMonthPerLine
,
2146 long nCalcLines
) const
2148 OUString
a99Text("99");
2149 Font aOldFont
= GetFont();
2151 // Wochenanzeige beruecksichtigen
2153 if ( mnWinStyle
& WB_WEEKNUMBER
)
2155 Font aTempFont
= aOldFont
;
2156 ImplGetWeekFont( aTempFont
);
2157 ((Calendar
*)this)->SetFont( aTempFont
);
2158 nWeekWidth
= GetTextWidth( a99Text
)+WEEKNUMBER_OFFX
;
2159 ((Calendar
*)this)->SetFont( aOldFont
);
2164 if ( mnWinStyle
& WB_BOLDTEXT
)
2166 Font aFont
= aOldFont
;
2167 if ( aFont
.GetWeight() < WEIGHT_BOLD
)
2168 aFont
.SetWeight( WEIGHT_BOLD
);
2170 aFont
.SetWeight( WEIGHT_NORMAL
);
2171 ((Calendar
*)this)->SetFont( aFont
);
2175 long n99TextWidth
= GetTextWidth( a99Text
);
2176 long nTextHeight
= GetTextHeight();
2178 if ( mnWinStyle
& WB_BOLDTEXT
)
2179 ((Calendar
*)this)->SetFont( aOldFont
);
2181 aSize
.Width() += ((n99TextWidth
+DAY_OFFX
)*7) + nWeekWidth
;
2182 aSize
.Width() += MONTH_BORDERX
*2;
2183 aSize
.Width() *= nCalcMonthPerLine
;
2185 aSize
.Height() = nTextHeight
+ TITLE_OFFY
+ (TITLE_BORDERY
*2);
2186 aSize
.Height() += nTextHeight
+ WEEKDAY_OFFY
;
2187 aSize
.Height() += ((nTextHeight
+DAY_OFFY
)*6);
2188 aSize
.Height() += MONTH_OFFY
;
2189 aSize
.Height() *= nCalcLines
;
2194 // =======================================================================
2196 #define CALFIELD_EXTRA_BUTTON_WIDTH 14
2197 #define CALFIELD_EXTRA_BUTTON_HEIGHT 8
2198 #define CALFIELD_SEP_X 6
2199 #define CALFIELD_BORDERLINE_X 5
2200 #define CALFIELD_BORDER_YTOP 4
2201 #define CALFIELD_BORDER_Y 5
2203 // =======================================================================
2205 class ImplCFieldFloatWin
: public FloatingWindow
2208 Calendar
* mpCalendar
;
2209 PushButton
* mpTodayBtn
;
2210 PushButton
* mpNoneBtn
;
2211 FixedLine
* mpFixedLine
;
2214 ImplCFieldFloatWin( Window
* pParent
);
2215 ~ImplCFieldFloatWin();
2217 void SetCalendar( Calendar
* pCalendar
)
2218 { mpCalendar
= pCalendar
; }
2220 PushButton
* EnableTodayBtn( sal_Bool bEnable
);
2221 PushButton
* EnableNoneBtn( sal_Bool bEnable
);
2222 void ArrangeButtons();
2224 long Notify( NotifyEvent
& rNEvt
);
2227 // -----------------------------------------------------------------------
2229 ImplCFieldFloatWin::ImplCFieldFloatWin( Window
* pParent
) :
2230 FloatingWindow( pParent
, WB_BORDER
| WB_SYSTEMWINDOW
| WB_NOSHADOW
)
2238 // -----------------------------------------------------------------------
2240 ImplCFieldFloatWin::~ImplCFieldFloatWin()
2247 // -----------------------------------------------------------------------
2249 PushButton
* ImplCFieldFloatWin::EnableTodayBtn( sal_Bool bEnable
)
2255 mpTodayBtn
= new PushButton( this, WB_NOPOINTERFOCUS
);
2256 OUString
aTodayText(SVT_RESSTR(STR_SVT_CALENDAR_TODAY
));
2257 mpTodayBtn
->SetText( aTodayText
);
2259 aSize
.Width() = mpTodayBtn
->GetCtrlTextWidth( mpTodayBtn
->GetText() );
2260 aSize
.Height() = mpTodayBtn
->GetTextHeight();
2261 aSize
.Width() += CALFIELD_EXTRA_BUTTON_WIDTH
;
2262 aSize
.Height() += CALFIELD_EXTRA_BUTTON_HEIGHT
;
2263 mpTodayBtn
->SetSizePixel( aSize
);
2279 // -----------------------------------------------------------------------
2281 PushButton
* ImplCFieldFloatWin::EnableNoneBtn( sal_Bool bEnable
)
2287 mpNoneBtn
= new PushButton( this, WB_NOPOINTERFOCUS
);
2288 OUString
aNoneText(SVT_RESSTR(STR_SVT_CALENDAR_NONE
));
2289 mpNoneBtn
->SetText( aNoneText
);
2291 aSize
.Width() = mpNoneBtn
->GetCtrlTextWidth( mpNoneBtn
->GetText() );
2292 aSize
.Height() = mpNoneBtn
->GetTextHeight();
2293 aSize
.Width() += CALFIELD_EXTRA_BUTTON_WIDTH
;
2294 aSize
.Height() += CALFIELD_EXTRA_BUTTON_HEIGHT
;
2295 mpNoneBtn
->SetSizePixel( aSize
);
2311 // -----------------------------------------------------------------------
2313 void ImplCFieldFloatWin::ArrangeButtons()
2315 long nBtnHeight
= 0;
2317 Size aOutSize
= GetOutputSizePixel();
2318 if ( mpTodayBtn
&& mpNoneBtn
)
2320 Size aTodayBtnSize
= mpTodayBtn
->GetSizePixel();
2321 Size aNoneBtnSize
= mpNoneBtn
->GetSizePixel();
2322 if ( aTodayBtnSize
.Width() < aNoneBtnSize
.Width() )
2323 aTodayBtnSize
.Width() = aNoneBtnSize
.Width();
2325 aNoneBtnSize
.Width() = aTodayBtnSize
.Width();
2326 if ( aTodayBtnSize
.Height() < aNoneBtnSize
.Height() )
2327 aTodayBtnSize
.Height() = aNoneBtnSize
.Height();
2329 aNoneBtnSize
.Height() = aTodayBtnSize
.Height();
2331 nBtnWidth
= aTodayBtnSize
.Width() + aNoneBtnSize
.Width() + CALFIELD_SEP_X
;
2332 nBtnHeight
= aTodayBtnSize
.Height();
2333 long nX
= (aOutSize
.Width()-nBtnWidth
)/2;
2334 long nY
= aOutSize
.Height()+CALFIELD_BORDER_Y
+CALFIELD_BORDER_YTOP
;
2335 mpTodayBtn
->SetPosSizePixel( Point( nX
, nY
), aTodayBtnSize
);
2336 nX
+= aTodayBtnSize
.Width() + CALFIELD_SEP_X
;
2337 mpNoneBtn
->SetPosSizePixel( Point( nX
, nY
), aNoneBtnSize
);
2339 else if ( mpTodayBtn
)
2341 Size aTodayBtnSize
= mpTodayBtn
->GetSizePixel();
2342 nBtnWidth
= aTodayBtnSize
.Width();
2343 nBtnHeight
= aTodayBtnSize
.Height();
2344 mpTodayBtn
->SetPosPixel( Point( (aOutSize
.Width()-nBtnWidth
)/2, aOutSize
.Height()+CALFIELD_BORDER_Y
+CALFIELD_BORDER_YTOP
) );
2346 else if ( mpNoneBtn
)
2348 Size aNoneBtnSize
= mpNoneBtn
->GetSizePixel();
2349 nBtnWidth
= aNoneBtnSize
.Width();
2350 nBtnHeight
= aNoneBtnSize
.Height();
2351 mpNoneBtn
->SetPosPixel( Point( (aOutSize
.Width()-nBtnWidth
)/2, aOutSize
.Height()+CALFIELD_BORDER_Y
+CALFIELD_BORDER_YTOP
) );
2358 mpFixedLine
= new FixedLine( this );
2359 mpFixedLine
->Show();
2361 long nLineWidth
= aOutSize
.Width()-(CALFIELD_BORDERLINE_X
*2);
2362 mpFixedLine
->setPosSizePixel( (aOutSize
.Width()-nLineWidth
)/2, aOutSize
.Height()+((CALFIELD_BORDER_YTOP
-2)/2),
2363 nLineWidth
, 2, WINDOW_POSSIZE_POSSIZE
);
2364 aOutSize
.Height() += nBtnHeight
+ (CALFIELD_BORDER_Y
*2) + CALFIELD_BORDER_YTOP
;
2365 SetOutputSizePixel( aOutSize
);
2377 // -----------------------------------------------------------------------
2379 long ImplCFieldFloatWin::Notify( NotifyEvent
& rNEvt
)
2381 if ( rNEvt
.GetType() == EVENT_KEYINPUT
)
2383 const KeyEvent
* pKEvt
= rNEvt
.GetKeyEvent();
2384 if ( pKEvt
->GetKeyCode().GetCode() == KEY_RETURN
)
2385 mpCalendar
->Select();
2388 return FloatingWindow::Notify( rNEvt
);
2391 // =======================================================================
2393 CalendarField::CalendarField( Window
* pParent
, WinBits nWinStyle
) :
2394 DateField( pParent
, nWinStyle
),
2395 maDefaultDate( 0, 0, 0 )
2399 mnCalendarStyle
= 0;
2400 mbToday
= sal_False
;
2404 // -----------------------------------------------------------------------
2406 CalendarField::~CalendarField()
2415 // -----------------------------------------------------------------------
2417 IMPL_LINK( CalendarField
, ImplSelectHdl
, Calendar
*, pCalendar
)
2419 if ( !pCalendar
->IsTravelSelect() )
2421 mpFloatWin
->EndPopupMode();
2424 Date aNewDate
= mpCalendar
->GetFirstSelectedDate();
2425 if ( IsEmptyDate() || ( aNewDate
!= GetDate() ) )
2427 SetDate( aNewDate
);
2436 // -----------------------------------------------------------------------
2438 IMPL_LINK( CalendarField
, ImplClickHdl
, PushButton
*, pBtn
)
2440 mpFloatWin
->EndPopupMode();
2444 if ( pBtn
== mpTodayBtn
)
2446 Date
aToday( Date::SYSTEM
);
2447 if ( (aToday
!= GetDate()) || IsEmptyDate() )
2454 else if ( pBtn
== mpNoneBtn
)
2456 if ( !IsEmptyDate() )
2468 // -----------------------------------------------------------------------
2470 IMPL_LINK_NOARG(CalendarField
, ImplPopupModeEndHdl
)
2474 mpCalendar
->EndSelection();
2478 // -----------------------------------------------------------------------
2480 void CalendarField::Select()
2482 maSelectHdl
.Call( this );
2485 // -----------------------------------------------------------------------
2487 sal_Bool
CalendarField::ShowDropDown( sal_Bool bShow
)
2491 Calendar
* pCalendar
= GetCalendar();
2493 Date aDate
= GetDate();
2494 if ( IsEmptyDate() || !aDate
.IsValidAndGregorian() )
2496 if ( maDefaultDate
.IsValidAndGregorian() )
2497 aDate
= maDefaultDate
;
2499 aDate
= Date( Date::SYSTEM
);
2501 if ( pCalendar
->GetStyle() & (WB_RANGESELECT
| WB_MULTISELECT
) )
2503 pCalendar
->SetNoSelection();
2504 pCalendar
->SelectDate( aDate
);
2506 pCalendar
->SetCurDate( aDate
);
2507 Point
aPos( GetParent()->OutputToScreenPixel( GetPosPixel() ) );
2508 Rectangle
aRect( aPos
, GetSizePixel() );
2509 aRect
.Bottom() -= 1;
2510 mpCalendar
->SetOutputSizePixel( mpCalendar
->CalcWindowSizePixel() );
2511 mpFloatWin
->SetOutputSizePixel( mpCalendar
->GetSizePixel() );
2512 mpFloatWin
->SetCalendar( mpCalendar
);
2513 mpTodayBtn
= mpFloatWin
->EnableTodayBtn( mbToday
);
2514 mpNoneBtn
= mpFloatWin
->EnableNoneBtn( mbNone
);
2516 mpTodayBtn
->SetClickHdl( LINK( this, CalendarField
, ImplClickHdl
) );
2518 mpNoneBtn
->SetClickHdl( LINK( this, CalendarField
, ImplClickHdl
) );
2519 mpFloatWin
->ArrangeButtons();
2520 mpCalendar
->EnableCallEverySelect();
2521 mpCalendar
->StartSelection();
2522 mpCalendar
->GrabFocus();
2524 mpFloatWin
->StartPopupMode( aRect
, FLOATWIN_POPUPMODE_NOFOCUSCLOSE
|FLOATWIN_POPUPMODE_DOWN
);
2528 mpFloatWin
->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL
);
2529 mpCalendar
->EndSelection();
2535 // -----------------------------------------------------------------------
2537 Calendar
* CalendarField::CreateCalendar( Window
* pParent
)
2539 return new Calendar( pParent
, mnCalendarStyle
| WB_TABSTOP
);
2542 // -----------------------------------------------------------------------
2544 Calendar
* CalendarField::GetCalendar()
2548 mpFloatWin
= new ImplCFieldFloatWin( this );
2549 mpFloatWin
->SetPopupModeEndHdl( LINK( this, CalendarField
, ImplPopupModeEndHdl
) );
2550 mpCalendar
= CreateCalendar( mpFloatWin
);
2551 mpCalendar
->SetPosPixel( Point() );
2552 mpCalendar
->SetSelectHdl( LINK( this, CalendarField
, ImplSelectHdl
) );
2558 // -----------------------------------------------------------------------
2560 void CalendarField::StateChanged( StateChangedType nStateChange
)
2562 DateField::StateChanged( nStateChange
);
2564 if ( ( nStateChange
== STATE_CHANGE_STYLE
) && GetSubEdit() )
2566 WinBits nAllAlignmentBits
= ( WB_LEFT
| WB_CENTER
| WB_RIGHT
| WB_TOP
| WB_VCENTER
| WB_BOTTOM
);
2567 WinBits nMyAlignment
= GetStyle() & nAllAlignmentBits
;
2568 GetSubEdit()->SetStyle( ( GetSubEdit()->GetStyle() & ~nAllAlignmentBits
) | nMyAlignment
);
2572 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */