1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: calendar.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
35 #include <vcl/svapp.hxx>
38 #include <tools/table.hxx>
41 #include <vcl/help.hxx>
44 #include <vcl/menu.hxx>
47 #include <vcl/decoview.hxx>
50 #include <vcl/floatwin.hxx>
53 #include <vcl/button.hxx>
56 #include <vcl/fixed.hxx>
58 #include <unotools/calendarwrapper.hxx>
59 #include <unotools/localedatawrapper.hxx>
60 #include <com/sun/star/i18n/Weekdays.hpp>
61 #include <com/sun/star/i18n/CalendarDisplayIndex.hpp>
62 #include <com/sun/star/i18n/CalendarFieldIndex.hpp>
64 #define _SV_CALENDAR_CXX
65 #include <svtools/svtools.hrc>
66 #include <svtools/svtdata.hxx>
67 #include <calendar.hxx>
69 // =======================================================================
73 #define MONTH_BORDERX 4
75 #define WEEKNUMBER_OFFX 4
76 #define WEEKDAY_OFFY 3
78 #define TITLE_BORDERY 2
80 #define SPIN_OFFY TITLE_BORDERY
82 #define WEEKNUMBER_HEIGHT 85
84 #define CALENDAR_HITTEST_DAY ((USHORT)0x0001)
85 #define CALENDAR_HITTEST_WEEK ((USHORT)0x0002)
86 #define CALENDAR_HITTEST_MONTHTITLE ((USHORT)0x0004)
87 #define CALENDAR_HITTEST_PREV ((USHORT)0x0008)
88 #define CALENDAR_HITTEST_NEXT ((USHORT)0x0010)
89 #define CALENDAR_HITTEST_OUTSIDE ((USHORT)0x1000)
91 #define MENU_YEAR_COUNT 3
93 #define TABLE_DATE_SELECTED ((void*)0x00000001)
95 using namespace ::com::sun::star
;
97 // =======================================================================
106 ImplDateInfo( const XubString
& rText
) :
108 { mpTextColor
= mpFrameColor
= NULL
; mnFlags
= 0; }
109 ~ImplDateInfo() { delete mpTextColor
; delete mpFrameColor
; }
112 DECLARE_TABLE( ImplDateTable
, ImplDateInfo
* )
114 // =======================================================================
116 static void ImplCalendarSelectDate( Table
* pTable
, const Date
& rDate
, BOOL bSelect
)
119 pTable
->Insert( rDate
.GetDate(), TABLE_DATE_SELECTED
);
121 pTable
->Remove( rDate
.GetDate() );
124 // -----------------------------------------------------------------------
126 static void ImplCalendarSelectDateRange( Table
* pTable
,
127 const Date
& rStartDate
,
128 const Date
& rEndDate
,
131 Date aStartDate
= rStartDate
;
132 Date aEndDate
= rEndDate
;
133 if ( aStartDate
> aEndDate
)
135 Date aTempDate
= aStartDate
;
136 aStartDate
= aEndDate
;
137 aEndDate
= aTempDate
;
142 while ( aStartDate
<= aEndDate
)
144 pTable
->Insert( aStartDate
.GetDate(), TABLE_DATE_SELECTED
);
150 void* p
= pTable
->First();
153 Date
aDate( pTable
->GetCurKey() );
154 if ( aDate
> aEndDate
)
157 if ( aDate
>= aStartDate
)
158 pTable
->Remove( aDate
.GetDate() );
165 // -----------------------------------------------------------------------
167 static void ImplCalendarUnSelectDateRange( Table
* pTable
,
169 const Date
& rStartDate
,
170 const Date
& rEndDate
)
172 Date aStartDate
= rStartDate
;
173 Date aEndDate
= rEndDate
;
174 if ( aStartDate
> aEndDate
)
176 Date aTempDate
= aStartDate
;
177 aStartDate
= aEndDate
;
178 aEndDate
= aTempDate
;
181 void* p
= pTable
->First();
184 Date
aDate( pTable
->GetCurKey() );
185 if ( aDate
> aEndDate
)
188 if ( aDate
>= aStartDate
)
189 pTable
->Remove( aDate
.GetDate() );
194 p
= pOldTable
->First();
197 Date
aDate( pOldTable
->GetCurKey() );
198 if ( aDate
> aEndDate
)
200 if ( aDate
>= aStartDate
)
201 pTable
->Insert( aDate
.GetDate(), TABLE_DATE_SELECTED
);
203 p
= pOldTable
->Next();
207 // -----------------------------------------------------------------------
209 inline void ImplCalendarClearSelectDate( Table
* pTable
)
214 // =======================================================================
216 void Calendar::ImplInit( WinBits nWinStyle
)
219 mpSelectTable
= new Table
;
220 mpOldSelectTable
= NULL
;
221 mpRestoreSelectTable
= NULL
;
222 mpStandardColor
= NULL
;
223 mpSaturdayColor
= NULL
;
224 mpSundayColor
= NULL
;
226 mnWinStyle
= nWinStyle
;
234 mbMultiSelection
= FALSE
;
242 mbInSelChange
= FALSE
;
243 mbTravelSelect
= FALSE
;
244 mbScrollDateRange
= FALSE
;
249 ::rtl::OUString
aGregorian( RTL_CONSTASCII_USTRINGPARAM( "gregorian"));
250 maCalendarWrapper
.loadCalendar( aGregorian
,
251 Application::GetAppLocaleDataWrapper().getLocale());
252 if (maCalendarWrapper
.getUniqueID() != aGregorian
)
255 ByteString
aMsg( "Calendar::ImplInit: No ``gregorian'' calendar available for locale ``");
256 lang::Locale
aLoc( Application::GetAppLocaleDataWrapper().getLocale());
257 aMsg
+= ByteString( String( aLoc
.Language
), RTL_TEXTENCODING_UTF8
);
259 aMsg
+= ByteString( String( aLoc
.Country
), RTL_TEXTENCODING_UTF8
);
260 aMsg
+= "'' and other calendars aren't supported. Using en-US fallback.";
261 DBG_ERRORFILE( aMsg
.GetBuffer());
263 /* If we ever wanted to support other calendars than Gregorian a lot of
264 * rewrite would be necessary to internally replace use of class Date
265 * with proper class CalendarWrapper methods, get rid of fixed 12
266 * months, fixed 7 days, ... */
267 maCalendarWrapper
.loadCalendar( aGregorian
, lang::Locale(
268 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "en")),
269 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "US")),
273 SetFirstDate( maCurDate
);
274 ImplCalendarSelectDate( mpSelectTable
, maCurDate
, TRUE
);
276 // Sonstige Strings erzeugen
277 maDayText
= XubString( SvtResId( STR_SVT_CALENDAR_DAY
) );
278 maWeekText
= XubString( SvtResId( STR_SVT_CALENDAR_WEEK
) );
280 // Tagestexte anlegen
281 for ( USHORT i
= 0; i
< 31; i
++ )
282 mpDayText
[i
] = new UniString( UniString::CreateFromInt32( i
+1 ) );
284 maDragScrollTimer
.SetTimeoutHdl( STATIC_LINK( this, Calendar
, ScrollHdl
) );
285 maDragScrollTimer
.SetTimeout( GetSettings().GetMouseSettings().GetScrollRepeat() );
286 mnDragScrollHitTest
= 0;
291 // -----------------------------------------------------------------------
293 void Calendar::ImplInitSettings()
295 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
296 maSelColor
= rStyleSettings
.GetHighlightTextColor();
297 SetPointFont( rStyleSettings
.GetToolFont() );
298 SetTextColor( rStyleSettings
.GetFieldTextColor() );
299 SetBackground( Wallpaper( rStyleSettings
.GetFieldColor() ) );
302 // -----------------------------------------------------------------------
304 Calendar::Calendar( Window
* pParent
, WinBits nWinStyle
) :
305 Control( pParent
, nWinStyle
& (WB_TABSTOP
| WB_GROUP
| WB_BORDER
| WB_3DLOOK
| WB_RANGESELECT
| WB_MULTISELECT
) ),
306 maCalendarWrapper( Application::GetAppLocaleDataWrapper().getServiceFactory() ),
307 maOldFormatFirstDate( 0, 0, 1900 ),
308 maOldFormatLastDate( 0, 0, 1900 ),
309 maFirstDate( 0, 0, 1900 ),
310 maOldFirstDate( 0, 0, 1900 ),
311 maOldCurDate( 0, 0, 1900 ),
312 maAnchorDate( maCurDate
),
313 maDropDate( 0, 0, 1900 )
315 ImplInit( nWinStyle
);
318 // -----------------------------------------------------------------------
320 Calendar::Calendar( Window
* pParent
, const ResId
& rResId
) :
321 Control( pParent
, rResId
),
322 maCalendarWrapper( Application::GetAppLocaleDataWrapper().getServiceFactory() ),
323 maOldFormatFirstDate( 0, 0, 1900 ),
324 maOldFormatLastDate( 0, 0, 1900 ),
325 maFirstDate( 0, 0, 1900 ),
326 maOldFirstDate( 0, 0, 1900 ),
327 maOldCurDate( 0, 0, 1900 ),
328 maAnchorDate( maCurDate
),
329 maDropDate( 0, 0, 1900 )
331 ImplInit( rResId
.GetWinBits() );
334 // -----------------------------------------------------------------------
336 Calendar::~Calendar()
338 delete mpStandardColor
;
339 delete mpSaturdayColor
;
340 delete mpSundayColor
;
344 ImplDateInfo
* pDateInfo
= mpDateTable
->First();
348 pDateInfo
= mpDateTable
->Next();
354 delete mpSelectTable
;
355 if ( mpOldSelectTable
)
356 delete mpOldSelectTable
;
357 if ( mpRestoreSelectTable
)
358 delete mpRestoreSelectTable
;
360 for ( USHORT i
= 0; i
< 31; i
++ )
364 // -----------------------------------------------------------------------
366 void Calendar::SetMinimumNumberOfDaysInWeek( sal_Int16 nDays
)
369 maCalendarWrapper
.setMinimumNumberOfDaysForFirstWeek( nDays
);
372 // -----------------------------------------------------------------------
374 void Calendar::SetWeekStart( sal_Int16 nDay
)
379 case i18n::Weekdays::SUNDAY
:
380 case i18n::Weekdays::MONDAY
:
381 case i18n::Weekdays::TUESDAY
:
382 case i18n::Weekdays::WEDNESDAY
:
383 case i18n::Weekdays::THURSDAY
:
384 case i18n::Weekdays::FRIDAY
:
385 case i18n::Weekdays::SATURDAY
:
388 DBG_ERRORFILE("Calendar::SetWeekStart: unknown value for setFirstDayOfWeek() of a Gregorian calendar");
389 nDay
= i18n::Weekdays::SUNDAY
;
391 maCalendarWrapper
.setFirstDayOfWeek( nDay
);
394 // -----------------------------------------------------------------------
396 DayOfWeek
Calendar::ImplGetWeekStart() const
398 // Map i18n::Weekdays to Date DayOfWeek
400 sal_Int16 nDay
= maCalendarWrapper
.getFirstDayOfWeek();
403 case i18n::Weekdays::SUNDAY
:
406 case i18n::Weekdays::MONDAY
:
409 case i18n::Weekdays::TUESDAY
:
412 case i18n::Weekdays::WEDNESDAY
:
415 case i18n::Weekdays::THURSDAY
:
418 case i18n::Weekdays::FRIDAY
:
421 case i18n::Weekdays::SATURDAY
:
425 DBG_ERRORFILE("Calendar::ImplGetWeekStart: broken i18n Gregorian calendar (getFirstDayOfWeek())");
431 // -----------------------------------------------------------------------
433 void Calendar::ImplGetWeekFont( Font
& rFont
) const
435 // Wochennummer geben wir in WEEKNUMBER_HEIGHT%-Fonthoehe aus
436 Size aFontSize
= rFont
.GetSize();
437 aFontSize
.Height() *= WEEKNUMBER_HEIGHT
;
438 aFontSize
.Height() /= 100;
439 rFont
.SetSize( aFontSize
);
440 rFont
.SetWeight( WEIGHT_NORMAL
);
443 // -----------------------------------------------------------------------
445 void Calendar::ImplFormat()
452 Size aOutSize
= GetOutputSizePixel();
454 if ( (aOutSize
.Width() <= 1) || (aOutSize
.Height() <= 1) )
457 XubString
a99Text( XubString( RTL_CONSTASCII_USTRINGPARAM( "99" ) ) );
459 Font aOldFont
= GetFont();
461 // Wochenanzeige beruecksichtigen
462 if ( mnWinStyle
& WB_WEEKNUMBER
)
464 Font aTempFont
= aOldFont
;
465 ImplGetWeekFont( aTempFont
);
466 SetFont( aTempFont
);
467 mnWeekWidth
= GetTextWidth( a99Text
)+WEEKNUMBER_OFFX
;
473 if ( mnWinStyle
& WB_BOLDTEXT
)
475 Font aFont
= aOldFont
;
476 if ( aFont
.GetWeight() < WEIGHT_BOLD
)
477 aFont
.SetWeight( WEIGHT_BOLD
);
479 aFont
.SetWeight( WEIGHT_NORMAL
);
483 long n99TextWidth
= GetTextWidth( a99Text
);
484 long nTextHeight
= GetTextHeight();
486 // Breiten und X-Positionen berechnen
487 mnDayWidth
= n99TextWidth
+DAY_OFFX
;
488 mnMonthWidth
= mnDayWidth
*7;
489 mnMonthWidth
+= mnWeekWidth
;
490 mnMonthWidth
+= MONTH_BORDERX
*2;
491 mnMonthPerLine
= aOutSize
.Width() / mnMonthWidth
;
492 if ( !mnMonthPerLine
)
494 long nOver
= ((aOutSize
.Width()-(mnMonthPerLine
*mnMonthWidth
)) / mnMonthPerLine
);
495 mnMonthWidth
+= nOver
;
496 mnDaysOffX
= MONTH_BORDERX
;
497 mnDaysOffX
+= nOver
/2;
498 mnDaysOffX
+= mnWeekWidth
;
500 // Hoehen und Y-Positionen berechnen
501 mnDayHeight
= nTextHeight
+ DAY_OFFY
;
502 mnWeekDayOffY
= nTextHeight
+ TITLE_OFFY
+ (TITLE_BORDERY
*2);
503 mnDaysOffY
= mnWeekDayOffY
+ nTextHeight
+ WEEKDAY_OFFY
;
504 mnMonthHeight
= (mnDayHeight
*6) + mnDaysOffY
;
505 mnMonthHeight
+= MONTH_OFFY
;
506 mnLines
= aOutSize
.Height() / mnMonthHeight
;
509 mnMonthHeight
+= (aOutSize
.Height()-(mnLines
*mnMonthHeight
)) / mnLines
;
511 // Spinfelder berechnen
512 long nSpinSize
= nTextHeight
+TITLE_BORDERY
-SPIN_OFFY
;
513 maPrevRect
.Left() = SPIN_OFFX
;
514 maPrevRect
.Top() = SPIN_OFFY
;
515 maPrevRect
.Right() = maPrevRect
.Left()+nSpinSize
;
516 maPrevRect
.Bottom() = maPrevRect
.Top()+nSpinSize
;
517 maNextRect
.Left() = aOutSize
.Width()-SPIN_OFFX
-nSpinSize
-1;
518 maNextRect
.Top() = SPIN_OFFY
;
519 maNextRect
.Right() = maNextRect
.Left()+nSpinSize
;
520 maNextRect
.Bottom() = maNextRect
.Top()+nSpinSize
;
522 if ( mnWinStyle
& WB_BOLDTEXT
)
525 // Calculate DayOfWeekText (gets displayed in a narrow font)
526 maDayOfWeekText
.Erase();
528 sal_Int16 nDay
= maCalendarWrapper
.getFirstDayOfWeek();
529 for ( sal_Int16 nDayOfWeek
= 0; nDayOfWeek
< 7; nDayOfWeek
++ )
531 // Use first character of full name, since the abbreviated name may
532 // be roman digits or similar in some locales. Proper
533 // implementation would need narrow one letter month names defined
535 String
aDayOfWeek( maCalendarWrapper
.getDisplayName(
536 i18n::CalendarDisplayIndex::DAY
, nDay
, 1).GetChar(0));
537 long nOffX
= (mnDayWidth
-GetTextWidth( aDayOfWeek
))/2;
538 if ( mnWinStyle
& WB_BOLDTEXT
)
544 nOffX
+= nDayOfWeek
* mnDayWidth
;
545 mnDayOfWeekAry
[nDayOfWeek
] = nOffX
;
546 maDayOfWeekText
+= aDayOfWeek
;
554 // Anzahl Tage berechnen
556 DayOfWeek eStartDay
= ImplGetWeekStart();
559 Date aTempDate
= GetFirstMonth();
560 maFirstDate
= aTempDate
;
561 nWeekDay
= (USHORT
)aTempDate
.GetDayOfWeek();
562 nWeekDay
= (nWeekDay
+(7-(USHORT
)eStartDay
)) % 7;
563 maFirstDate
-= (ULONG
)nWeekDay
;
564 mnDayCount
= nWeekDay
;
566 USHORT nMonthCount
= (USHORT
)(mnMonthPerLine
*mnLines
);
567 for ( USHORT i
= 0; i
< nMonthCount
; i
++ )
569 nDaysInMonth
= aTempDate
.GetDaysInMonth();
570 mnDayCount
+= nDaysInMonth
;
571 aTempDate
+= nDaysInMonth
;
573 Date aTempDate2
= aTempDate
;
575 nDaysInMonth
= aTempDate2
.GetDaysInMonth();
576 aTempDate2
-= nDaysInMonth
-1;
577 nWeekDay
= (USHORT
)aTempDate2
.GetDayOfWeek();
578 nWeekDay
= (nWeekDay
+(7-(USHORT
)eStartDay
)) % 7;
579 mnDayCount
+= 42-nDaysInMonth
-nWeekDay
;
582 maOtherColor
= Color( COL_LIGHTGRAY
);
583 if ( maOtherColor
.IsRGBEqual( GetBackground().GetColor() ) )
584 maOtherColor
.SetColor( COL_GRAY
);
586 Date aLastDate
= GetLastDate();
587 if ( (maOldFormatLastDate
!= aLastDate
) ||
588 (maOldFormatFirstDate
!= maFirstDate
) )
590 maOldFormatFirstDate
= maFirstDate
;
591 maOldFormatLastDate
= aLastDate
;
596 USHORT nNewFirstYear
= maFirstDate
.GetYear();
597 USHORT nNewLastYear
= GetLastDate().GetYear();
600 if ( nNewFirstYear
< mnFirstYear
)
602 for ( mnRequestYear
= nNewFirstYear
; mnRequestYear
< mnFirstYear
; mnRequestYear
++ )
604 mnFirstYear
= nNewFirstYear
;
606 if ( nNewLastYear
> mnLastYear
)
608 for ( mnRequestYear
= mnLastYear
; mnRequestYear
< nNewLastYear
; mnRequestYear
++ )
610 mnLastYear
= nNewLastYear
;
615 for ( mnRequestYear
= nNewFirstYear
; mnRequestYear
< nNewLastYear
; mnRequestYear
++ )
617 mnFirstYear
= nNewFirstYear
;
618 mnLastYear
= nNewLastYear
;
625 // -----------------------------------------------------------------------
627 USHORT
Calendar::ImplHitTest( const Point
& rPos
, Date
& rDate
) const
632 if ( maPrevRect
.IsInside( rPos
) )
633 return CALENDAR_HITTEST_PREV
;
634 else if ( maNextRect
.IsInside( rPos
) )
635 return CALENDAR_HITTEST_NEXT
;
642 DayOfWeek eStartDay
= ImplGetWeekStart();
644 rDate
= GetFirstMonth();
646 for ( long i
= 0; i
< mnLines
; i
++ )
652 nYMonth
= nY
+mnMonthHeight
;
653 for ( long j
= 0; j
< mnMonthPerLine
; j
++ )
655 if ( (rPos
.X() < nX
) && (rPos
.Y() < nYMonth
) )
658 USHORT nDaysInMonth
= rDate
.GetDaysInMonth();
660 // Entsprechender Monat gefunden
661 if ( (rPos
.X() > nX
) && (rPos
.Y() < nYMonth
) &&
662 (rPos
.X() < nX
+mnMonthWidth
) )
664 if ( rPos
.Y() < (nY
+(TITLE_BORDERY
*2)+mnDayHeight
))
665 return CALENDAR_HITTEST_MONTHTITLE
;
668 long nDayX
= nX
+mnDaysOffX
;
669 long nDayY
= nY
+mnDaysOffY
;
670 if ( rPos
.Y() < nDayY
)
672 USHORT nDayIndex
= (USHORT
)rDate
.GetDayOfWeek();
673 nDayIndex
= (nDayIndex
+(7-(USHORT
)eStartDay
)) % 7;
674 if ( (i
== 0) && (j
== 0) )
676 Date aTempDate
= rDate
;
677 aTempDate
-= nDayIndex
;
678 for ( nDay
= 0; nDay
< nDayIndex
; nDay
++ )
680 nOffX
= nDayX
+ (nDay
*mnDayWidth
);
681 if ( (rPos
.Y() >= nDayY
) && (rPos
.Y() < nDayY
+mnDayHeight
) &&
682 (rPos
.X() >= nOffX
) && (rPos
.X() < nOffX
+mnDayWidth
) )
686 return CALENDAR_HITTEST_DAY
;
690 for ( nDay
= 1; nDay
<= nDaysInMonth
; nDay
++ )
692 if ( rPos
.Y() < nDayY
)
697 nOffX
= nDayX
+ (nDayIndex
*mnDayWidth
);
698 if ( (rPos
.Y() >= nDayY
) && (rPos
.Y() < nDayY
+mnDayHeight
) &&
699 (rPos
.X() >= nOffX
) && (rPos
.X() < nOffX
+mnDayWidth
) )
702 return CALENDAR_HITTEST_DAY
;
704 if ( nDayIndex
== 6 )
707 nDayY
+= mnDayHeight
;
712 if ( (i
== mnLines
-1) && (j
== mnMonthPerLine
-1) )
714 USHORT nWeekDay
= (USHORT
)rDate
.GetDayOfWeek();
715 nWeekDay
= (nWeekDay
+(7-(USHORT
)eStartDay
)) % 7;
716 USHORT nDayCount
= 42-nDaysInMonth
-nWeekDay
;
717 Date aTempDate
= rDate
;
718 aTempDate
+= nDaysInMonth
;
719 for ( nDay
= 1; nDay
<= nDayCount
; nDay
++ )
721 if ( rPos
.Y() < nDayY
)
726 nOffX
= nDayX
+ (nDayIndex
*mnDayWidth
);
727 if ( (rPos
.Y() >= nDayY
) && (rPos
.Y() < nDayY
+mnDayHeight
) &&
728 (rPos
.X() >= nOffX
) && (rPos
.X() < nOffX
+mnDayWidth
) )
732 return CALENDAR_HITTEST_DAY
;
734 if ( nDayIndex
== 6 )
737 nDayY
+= mnDayHeight
;
746 rDate
+= nDaysInMonth
;
756 // -----------------------------------------------------------------------
758 static void ImplDrawSpinArrow( OutputDevice
* pDev
, const Rectangle
& rRect
,
764 long nHeight
= rRect
.GetHeight();
765 long nWidth
= rRect
.GetWidth();
766 if ( nWidth
< nHeight
)
774 Rectangle
aRect( Point( rRect
.Left()+(nWidth
/2)-(nLines
/2),
775 rRect
.Top()+(nHeight
/2) ),
779 aRect
.Left() += nLines
;
780 aRect
.Right() += nLines
;
783 pDev
->DrawRect( aRect
);
784 for ( i
= 0; i
< nLines
; i
++ )
798 pDev
->DrawRect( aRect
);
802 // -----------------------------------------------------------------------
804 void Calendar::ImplDrawSpin( BOOL bDrawPrev
, BOOL bDrawNext
)
806 if ( !bDrawPrev
&& !bDrawNext
)
810 SetFillColor( GetSettings().GetStyleSettings().GetButtonTextColor() );
813 Rectangle aOutRect
= maPrevRect
;
814 aOutRect
.Left() += 3;
816 aOutRect
.Right() -= 3;
817 aOutRect
.Bottom() -= 3;
818 ImplDrawSpinArrow( this, aOutRect
, TRUE
);
822 Rectangle aOutRect
= maNextRect
;
823 aOutRect
.Left() += 3;
825 aOutRect
.Right() -= 3;
826 aOutRect
.Bottom() -= 3;
827 ImplDrawSpinArrow( this, aOutRect
, FALSE
);
831 // -----------------------------------------------------------------------
833 void Calendar::ImplDrawDate( long nX
, long nY
,
834 USHORT nDay
, USHORT nMonth
, USHORT nYear
,
835 DayOfWeek eDayOfWeek
,
836 BOOL bBack
, BOOL bOther
, ULONG nToday
)
838 ImplDateInfo
* pDateInfo
;
839 Color
* pTextColor
= NULL
;
840 const String
& rDay
= *(mpDayText
[nDay
-1]);
841 Rectangle
aDateRect( nX
, nY
, nX
+mnDayWidth
-1, nY
+mnDayHeight
-1 );
846 if ( (nDay
== maCurDate
.GetDay()) &&
847 (nMonth
== maCurDate
.GetMonth()) &&
848 (nYear
== maCurDate
.GetYear()) )
852 if ( mpSelectTable
->IsKeyValid( Date( nDay
, nMonth
, nYear
).GetDate() ) )
856 // Dateinfo ermitteln
859 pDateInfo
= mpDateTable
->Get( Date( nDay
, nMonth
, nYear
).GetDate() );
861 pDateInfo
= mpDateTable
->Get( Date( nDay
, nMonth
, 0 ).GetDate() );
866 // Textfarbe ermitteln
868 pTextColor
= &maSelColor
;
870 pTextColor
= &maOtherColor
;
873 if ( pDateInfo
&& pDateInfo
->mpTextColor
)
874 pTextColor
= pDateInfo
->mpTextColor
;
877 if ( eDayOfWeek
== SATURDAY
)
878 pTextColor
= mpSaturdayColor
;
879 else if ( eDayOfWeek
== SUNDAY
)
880 pTextColor
= mpSundayColor
;
882 pTextColor
= mpStandardColor
;
890 Font aOldFont
= GetFont();
891 BOOL bBoldFont
= FALSE
;
892 if ( (mnWinStyle
& WB_BOLDTEXT
) &&
893 pDateInfo
&& (pDateInfo
->mnFlags
& DIB_BOLD
) )
896 Font aFont
= aOldFont
;
897 if ( aFont
.GetWeight() < WEIGHT_BOLD
)
898 aFont
.SetWeight( WEIGHT_BOLD
);
900 aFont
.SetWeight( WEIGHT_NORMAL
);
904 // Hintergrund ausgeben
905 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
911 SetFillColor( rStyleSettings
.GetHighlightColor() );
912 DrawRect( aDateRect
);
919 long nTextX
= nX
+(mnDayWidth
-GetTextWidth( rDay
))-(DAY_OFFX
/2);
920 long nTextY
= nY
+(mnDayHeight
-GetTextHeight())/2;
923 Color aOldColor
= GetTextColor();
924 SetTextColor( *pTextColor
);
925 DrawText( Point( nTextX
, nTextY
), rDay
);
926 SetTextColor( aOldColor
);
929 DrawText( Point( nTextX
, nTextY
), rDay
);
932 Date
aTodayDate( maCurDate
);
934 aTodayDate
.SetDate( nToday
);
937 if ( (nDay
== aTodayDate
.GetDay()) &&
938 (nMonth
== aTodayDate
.GetMonth()) &&
939 (nYear
== aTodayDate
.GetYear()) )
941 SetLineColor( rStyleSettings
.GetWindowTextColor() );
943 DrawRect( aDateRect
);
946 // Evt. DateInfo ausgeben
947 if ( (mnWinStyle
& WB_FRAMEINFO
) && pDateInfo
&& pDateInfo
->mpFrameColor
)
949 SetLineColor( *(pDateInfo
->mpFrameColor
) );
951 Rectangle
aFrameRect( aDateRect
);
954 long nFrameWidth
= aFrameRect
.GetWidth();
955 long nFrameHeight
= aFrameRect
.GetHeight();
957 if ( nFrameWidth
< nFrameHeight
)
959 nFrameOff
= nFrameHeight
-nFrameWidth
;
960 aFrameRect
.Top() += nFrameOff
/2;
962 aFrameRect
.Bottom() -= nFrameOff
;
964 else if ( nFrameWidth
> nFrameHeight
)
966 nFrameOff
= nFrameWidth
-nFrameHeight
;
967 aFrameRect
.Left() += nFrameOff
/2;
969 aFrameRect
.Right() -= nFrameOff
;
971 DrawEllipse( aFrameRect
);
974 // Evt. noch FocusRect
975 if ( bFocus
&& HasFocus() )
976 ShowFocus( aDateRect
);
978 if( mbDropPos
&& maDropDate
== Date( nDay
, nMonth
, nYear
) )
985 // -----------------------------------------------------------------------
987 void Calendar::ImplDraw( BOOL bPaint
)
991 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
992 Size aOutSize
= GetOutputSizePixel();
1001 ULONG nToday
= Date().GetDate();
1005 Date aDate
= GetFirstMonth();
1006 DayOfWeek eStartDay
= ImplGetWeekStart();
1011 for ( i
= 0; i
< mnLines
; i
++ )
1013 // Titleleiste ausgeben
1015 SetFillColor( rStyleSettings
.GetFaceColor() );
1016 Rectangle
aTitleRect( 0, nY
, aOutSize
.Width()-1, nY
+mnDayHeight
-DAY_OFFY
+TITLE_BORDERY
*2 );
1019 Rectangle
aTempRect( 1, aTitleRect
.Top()+TITLE_BORDERY
,
1021 aTitleRect
.Bottom()-TITLE_BORDERY
);
1024 aTempRect
.Left() = maPrevRect
.Right()+1;
1025 aTempRect
.Right() = maNextRect
.Left()-1;
1027 DrawRect( aTempRect
);
1031 DrawRect( aTitleRect
);
1032 Point
aTopLeft1( aTitleRect
.Left(), aTitleRect
.Top() );
1033 Point
aTopLeft2( aTitleRect
.Left(), aTitleRect
.Top()+1 );
1034 Point
aBottomRight1( aTitleRect
.Right(), aTitleRect
.Bottom() );
1035 Point
aBottomRight2( aTitleRect
.Right(), aTitleRect
.Bottom()-1 );
1036 SetLineColor( rStyleSettings
.GetDarkShadowColor() );
1037 DrawLine( aTopLeft1
, Point( aBottomRight1
.X(), aTopLeft1
.Y() ) );
1038 SetLineColor( rStyleSettings
.GetLightColor() );
1039 DrawLine( aTopLeft2
, Point( aBottomRight2
.X(), aTopLeft2
.Y() ) );
1040 DrawLine( aTopLeft2
, Point( aTopLeft2
.X(), aBottomRight2
.Y() ) );
1041 SetLineColor( rStyleSettings
.GetShadowColor() );
1042 DrawLine( Point( aTopLeft2
.X(), aBottomRight2
.Y() ), aBottomRight2
);
1043 DrawLine( Point( aBottomRight2
.X(), aTopLeft2
.Y() ), aBottomRight2
);
1044 SetLineColor( rStyleSettings
.GetDarkShadowColor() );
1045 DrawLine( Point( aTopLeft1
.X(), aBottomRight1
.Y() ), aBottomRight1
);
1047 Point
aSepPos1( 0, aTitleRect
.Top()+TITLE_BORDERY
);
1048 Point
aSepPos2( 0, aTitleRect
.Bottom()-TITLE_BORDERY
);
1049 for ( j
= 0; j
< mnMonthPerLine
-1; j
++ )
1051 aSepPos1
.X() += mnMonthWidth
-1;
1052 aSepPos2
.X() = aSepPos1
.X();
1053 SetLineColor( rStyleSettings
.GetShadowColor() );
1054 DrawLine( aSepPos1
, aSepPos2
);
1056 aSepPos2
.X() = aSepPos1
.X();
1057 SetLineColor( rStyleSettings
.GetLightColor() );
1058 DrawLine( aSepPos1
, aSepPos2
);
1062 for ( j
= 0; j
< mnMonthPerLine
; j
++ )
1064 nMonth
= aDate
.GetMonth();
1065 nYear
= aDate
.GetYear();
1067 // Monat in der Titleleiste ausgeben
1069 nDeltaY
= nY
+TITLE_BORDERY
;
1070 String
aMonthText( maCalendarWrapper
.getDisplayName(
1071 i18n::CalendarDisplayIndex::MONTH
, nMonth
-1, 1));
1073 aMonthText
+= String::CreateFromInt64( nYear
);
1074 long nMonthTextWidth
= GetTextWidth( aMonthText
);
1075 long nMonthOffX1
= 0;
1076 long nMonthOffX2
= 0;
1080 nMonthOffX1
= maPrevRect
.Right()+1;
1081 if ( j
== mnMonthPerLine
-1 )
1082 nMonthOffX2
= aOutSize
.Width()-maNextRect
.Left()+1;
1084 long nMaxMonthWidth
= mnMonthWidth
-nMonthOffX1
-nMonthOffX2
-4;
1085 if ( nMonthTextWidth
> nMaxMonthWidth
)
1087 // Abbreviated month name.
1088 aMonthText
= maCalendarWrapper
.getDisplayName(
1089 i18n::CalendarDisplayIndex::MONTH
, nMonth
-1, 0);
1091 aMonthText
+= String::CreateFromInt64( nYear
);
1092 nMonthTextWidth
= GetTextWidth( aMonthText
);
1094 long nTempOff
= (mnMonthWidth
-nMonthTextWidth
+1)/2;
1095 if ( nTempOff
< nMonthOffX1
)
1096 nDeltaX
+= nMonthOffX1
+1;
1099 if ( nTempOff
+nMonthTextWidth
> mnMonthWidth
-nMonthOffX2
)
1100 nDeltaX
+= mnMonthWidth
-nMonthOffX2
-nMonthTextWidth
;
1102 nDeltaX
+= nTempOff
;
1104 SetTextColor( rStyleSettings
.GetButtonTextColor() );
1105 DrawText( Point( nDeltaX
, nDeltaY
), aMonthText
);
1106 SetTextColor( rStyleSettings
.GetWindowTextColor() );
1108 // Weekleiste ausgeben
1111 nDayX
= nX
+mnDaysOffX
;
1112 nDayY
= nY
+mnWeekDayOffY
;
1113 nDeltaY
= nDayY
+ mnDayHeight
;
1114 SetLineColor( rStyleSettings
.GetWindowTextColor() );
1115 Point
aStartPos( nDayX
, nDeltaY
);
1116 if ( mnWinStyle
& WB_WEEKNUMBER
)
1117 aStartPos
.X() -= WEEKNUMBER_OFFX
-2;
1118 DrawLine( aStartPos
, Point( nDayX
+(7*mnDayWidth
), nDeltaY
) );
1119 DrawTextArray( Point( nDayX
+mnDayOfWeekAry
[0], nDayY
), maDayOfWeekText
, &(mnDayOfWeekAry
[1]) );
1122 // Week-Numbers ausgeben
1123 if ( mnWinStyle
& WB_WEEKNUMBER
)
1125 nDayX
= nX
+mnDaysOffX
;
1126 nDayY
= nY
+mnWeekDayOffY
;
1127 nDeltaY
= nDayY
+ mnDayHeight
;
1128 long nMonthHeight
= mnDayHeight
*6;
1130 DrawLine( Point( nDayX
-WEEKNUMBER_OFFX
+2, nDeltaY
), Point( nDayX
-WEEKNUMBER_OFFX
+2, nDeltaY
+nMonthHeight
) );
1132 Erase( Rectangle( nDayX
-mnWeekWidth
-WEEKNUMBER_OFFX
, nDeltaY
, nDayX
-WEEKNUMBER_OFFX
-1, nDeltaY
+nMonthHeight
) );
1134 Font aOldFont
= GetFont();
1135 Font aTempFont
= aOldFont
;
1136 ImplGetWeekFont( aTempFont
);
1137 SetFont( aTempFont
);
1138 nDayX
-= mnWeekWidth
;
1139 nDayY
= nY
+mnDaysOffY
;
1140 maCalendarWrapper
.setGregorianDateTime( aDate
);
1141 for ( USHORT nWeekCount
= 0; nWeekCount
< 6; nWeekCount
++ )
1143 sal_Int16 nWeek
= maCalendarWrapper
.getValue( i18n::CalendarFieldIndex::WEEK_OF_YEAR
);
1144 String
aWeekText( String::CreateFromInt32( nWeek
));
1145 long nOffX
= (mnWeekWidth
-WEEKNUMBER_OFFX
)-GetTextWidth( aWeekText
);
1146 long nOffY
= (mnDayHeight
-GetTextHeight())/2;
1147 DrawText( Point( nDayX
+nOffX
, nDayY
+nOffY
), aWeekText
);
1148 nDayY
+= mnDayHeight
;
1149 maCalendarWrapper
.addValue( i18n::CalendarFieldIndex::DAY_OF_MONTH
, 7);
1151 SetFont( aOldFont
);
1155 USHORT nDaysInMonth
= aDate
.GetDaysInMonth();
1156 nDayX
= nX
+mnDaysOffX
;
1157 nDayY
= nY
+mnDaysOffY
;
1160 Rectangle
aClearRect( nDayX
, nDayY
,
1161 nDayX
+(7*mnDayWidth
)-1, nDayY
+(6*mnDayHeight
)-1 );
1162 Erase( aClearRect
);
1164 USHORT nDayIndex
= (USHORT
)aDate
.GetDayOfWeek();
1165 nDayIndex
= (nDayIndex
+(7-(USHORT
)eStartDay
)) % 7;
1166 if ( (i
== 0) && (j
== 0) )
1168 Date aTempDate
= aDate
;
1169 aTempDate
-= nDayIndex
;
1170 for ( nDay
= 0; nDay
< nDayIndex
; nDay
++ )
1172 nDeltaX
= nDayX
+ (nDay
*mnDayWidth
);
1173 ImplDrawDate( nDeltaX
, nDayY
, nDay
+aTempDate
.GetDay(),
1174 aTempDate
.GetMonth(), aTempDate
.GetYear(),
1175 (DayOfWeek
)((nDay
+(USHORT
)eStartDay
)%7), FALSE
, TRUE
, nToday
);
1178 for ( nDay
= 1; nDay
<= nDaysInMonth
; nDay
++ )
1180 nDeltaX
= nDayX
+ (nDayIndex
*mnDayWidth
);
1181 ImplDrawDate( nDeltaX
, nDayY
, nDay
, nMonth
, nYear
,
1182 (DayOfWeek
)((nDayIndex
+(USHORT
)eStartDay
)%7),
1183 FALSE
, FALSE
, nToday
);
1184 if ( nDayIndex
== 6 )
1187 nDayY
+= mnDayHeight
;
1192 if ( (i
== mnLines
-1) && (j
== mnMonthPerLine
-1) )
1194 USHORT nWeekDay
= (USHORT
)aDate
.GetDayOfWeek();
1195 nWeekDay
= (nWeekDay
+(7-(USHORT
)eStartDay
)) % 7;
1196 USHORT nDayCount
= 42-nDaysInMonth
-nWeekDay
;
1197 Date aTempDate
= aDate
;
1198 aTempDate
+= nDaysInMonth
;
1199 for ( nDay
= 1; nDay
<= nDayCount
; nDay
++ )
1201 nDeltaX
= nDayX
+ (nDayIndex
*mnDayWidth
);
1202 ImplDrawDate( nDeltaX
, nDayY
, nDay
,
1203 aTempDate
.GetMonth(), aTempDate
.GetYear(),
1204 (DayOfWeek
)((nDayIndex
+(USHORT
)eStartDay
)%7),
1205 FALSE
, TRUE
, nToday
);
1206 if ( nDayIndex
== 6 )
1209 nDayY
+= mnDayHeight
;
1216 aDate
+= nDaysInMonth
;
1220 nY
+= mnMonthHeight
;
1223 // Spin-Buttons zeichnen
1228 // -----------------------------------------------------------------------
1230 void Calendar::ImplUpdateDate( const Date
& rDate
)
1232 if ( IsReallyVisible() && IsUpdateMode() )
1234 Rectangle
aDateRect( GetDateRect( rDate
) );
1235 if ( !aDateRect
.IsEmpty() )
1237 BOOL bOther
= (rDate
< GetFirstMonth()) || (rDate
> GetLastMonth());
1238 ImplDrawDate( aDateRect
.Left(), aDateRect
.Top(),
1239 rDate
.GetDay(), rDate
.GetMonth(), rDate
.GetYear(),
1240 rDate
.GetDayOfWeek(), TRUE
, bOther
);
1245 // -----------------------------------------------------------------------
1247 void Calendar::ImplUpdateSelection( Table
* pOld
)
1249 Table
* pNew
= mpSelectTable
;
1256 nKey
= pOld
->GetCurKey();
1257 if ( !pNew
->Get( nKey
) )
1259 Date
aTempDate( nKey
);
1260 ImplUpdateDate( aTempDate
);
1269 nKey
= pNew
->GetCurKey();
1270 if ( !pOld
->Get( nKey
) )
1272 Date
aTempDate( nKey
);
1273 ImplUpdateDate( aTempDate
);
1280 // -----------------------------------------------------------------------
1282 void Calendar::ImplMouseSelect( const Date
& rDate
, USHORT nHitTest
,
1283 BOOL bMove
, BOOL bExpand
, BOOL bExtended
)
1285 Table
* pOldSel
= new Table( *mpSelectTable
);
1286 Date aOldDate
= maCurDate
;
1287 Date aTempDate
= rDate
;
1289 if ( !(nHitTest
& CALENDAR_HITTEST_DAY
) )
1292 if ( mbMultiSelection
)
1294 maCurDate
= aTempDate
;
1295 mbSelLeft
= aTempDate
< maAnchorDate
;
1301 ImplCalendarUnSelectDateRange( mpSelectTable
, mpRestoreSelectTable
, Date( 1, 1, 0 ), aTempDate
);
1302 ImplCalendarUnSelectDateRange( mpSelectTable
, mpRestoreSelectTable
, maAnchorDate
, Date( 31, 12, 9999 ) );
1306 ImplCalendarUnSelectDateRange( mpSelectTable
, mpRestoreSelectTable
, Date( 1, 1, 0 ), maAnchorDate
);
1307 ImplCalendarUnSelectDateRange( mpSelectTable
, mpRestoreSelectTable
, aTempDate
, Date( 31, 12, 9999 ) );
1309 ImplCalendarSelectDateRange( mpSelectTable
, aTempDate
, maAnchorDate
, !mbUnSel
);
1319 ImplCalendarSelectDateRange( mpSelectTable
, Date( 1, 1, 0 ), aTempDate
, FALSE
);
1320 ImplCalendarSelectDateRange( mpSelectTable
, maAnchorDate
, Date( 31, 12, 9999 ), FALSE
);
1324 ImplCalendarSelectDateRange( mpSelectTable
, Date( 1, 1, 0 ), maAnchorDate
, FALSE
);
1325 ImplCalendarSelectDateRange( mpSelectTable
, aTempDate
, Date( 31, 12, 9999 ), FALSE
);
1328 ImplCalendarSelectDateRange( mpSelectTable
, aTempDate
, maAnchorDate
, TRUE
);
1330 else if ( bExtended
&& !(mnWinStyle
& WB_RANGESELECT
) )
1332 maAnchorDate
= aTempDate
;
1333 if ( IsDateSelected( aTempDate
) )
1336 ImplCalendarSelectDate( mpSelectTable
, aTempDate
, FALSE
);
1340 ImplCalendarSelectDate( mpSelectTable
, aTempDate
, TRUE
);
1345 maAnchorDate
= aTempDate
;
1346 ImplCalendarClearSelectDate( mpSelectTable
);
1347 ImplCalendarSelectDate( mpSelectTable
, aTempDate
, TRUE
);
1350 mpRestoreSelectTable
= new Table( *mpSelectTable
);
1355 if ( aTempDate
< maCurDate
)
1359 if ( !(nHitTest
& CALENDAR_HITTEST_DAY
) )
1360 aTempDate
= maOldCurDate
;
1362 maAnchorDate
= aTempDate
;
1363 if ( aTempDate
!= maCurDate
)
1365 maCurDate
= aTempDate
;
1366 ImplCalendarSelectDate( mpSelectTable
, aOldDate
, FALSE
);
1367 ImplCalendarSelectDate( mpSelectTable
, maCurDate
, TRUE
);
1371 BOOL bNewSel
= *pOldSel
!= *mpSelectTable
;
1372 if ( (maCurDate
!= aOldDate
) || bNewSel
)
1376 mbInSelChange
= TRUE
;
1377 SelectionChanging();
1378 mbInSelChange
= FALSE
;
1382 ImplUpdateSelection( pOldSel
);
1383 if ( !bNewSel
|| !pOldSel
->Get( aOldDate
.GetDate() ) )
1384 ImplUpdateDate( aOldDate
);
1385 // Damit Focus-Rechteck auch wieder neu ausgegeben wird
1386 if ( HasFocus() || !bNewSel
|| !mpSelectTable
->Get( maCurDate
.GetDate() ) )
1387 ImplUpdateDate( maCurDate
);
1392 // -----------------------------------------------------------------------
1394 void Calendar::ImplUpdate( BOOL bCalcNew
)
1396 if ( IsReallyVisible() && IsUpdateMode() )
1398 if ( bCalcNew
&& !mbCalc
)
1400 else if ( !mbFormat
&& !mbCalc
)
1418 // -----------------------------------------------------------------------
1420 void Calendar::ImplInvertDropPos()
1422 Rectangle aRect
= GetDateRect( maDropDate
);//this is one Pixel to width and one to heigh
1423 aRect
.Bottom() = aRect
.Top()+mnDayHeight
-1;
1424 aRect
.Right() = aRect
.Left()+mnDayWidth
-1;
1428 // -----------------------------------------------------------------------
1430 void Calendar::ImplScroll( BOOL bPrev
)
1432 Date aNewFirstMonth
= GetFirstMonth();
1436 aNewFirstMonth
-= aNewFirstMonth
.GetDaysInMonth()-1;
1439 aNewFirstMonth
+= aNewFirstMonth
.GetDaysInMonth();
1441 SetFirstDate( aNewFirstMonth
);
1445 // -----------------------------------------------------------------------
1447 void Calendar::ImplShowMenu( const Point
& rPos
, const Date
& rDate
)
1451 Date aOldFirstDate
= GetFirstMonth();
1452 PopupMenu aPopupMenu
;
1453 PopupMenu
* pYearPopupMenus
[MENU_YEAR_COUNT
];
1456 USHORT nYear
= rDate
.GetYear()-1;
1459 USHORT nYearIdCount
= 1000;
1461 nMonthOff
= (rDate
.GetYear()-aOldFirstDate
.GetYear())*12;
1462 if ( aOldFirstDate
.GetMonth() < rDate
.GetMonth() )
1463 nMonthOff
+= rDate
.GetMonth()-aOldFirstDate
.GetMonth();
1465 nMonthOff
-= aOldFirstDate
.GetMonth()-rDate
.GetMonth();
1467 // Menu aufbauen (Jahre mit verschiedenen Monaten aufnehmen)
1468 for ( i
= 0; i
< MENU_YEAR_COUNT
; i
++ )
1470 pYearPopupMenus
[i
] = new PopupMenu
;
1471 for ( j
= 1; j
<= 12; j
++ )
1472 pYearPopupMenus
[i
]->InsertItem( nYearIdCount
+j
,
1473 maCalendarWrapper
.getDisplayName(
1474 i18n::CalendarDisplayIndex::MONTH
, j
-1, 1));
1475 aPopupMenu
.InsertItem( 10+i
, UniString::CreateFromInt32( nYear
+i
) );
1476 aPopupMenu
.SetPopupMenu( 10+i
, pYearPopupMenus
[i
] );
1477 nYearIdCount
+= 1000;
1481 nCurItemId
= aPopupMenu
.Execute( this, rPos
);
1485 aPopupMenu
.SetPopupMenu( 2, NULL
);
1486 for ( i
= 0; i
< MENU_YEAR_COUNT
; i
++ )
1488 aPopupMenu
.SetPopupMenu( 10+i
, NULL
);
1489 delete pYearPopupMenus
[i
];
1494 USHORT nTempMonthOff
= nMonthOff
% 12;
1495 USHORT nTempYearOff
= nMonthOff
/ 12;
1496 USHORT nNewMonth
= nCurItemId
% 1000;
1497 USHORT nNewYear
= nYear
+((nCurItemId
-1000)/1000);
1498 if ( nTempMonthOff
< nNewMonth
)
1499 nNewMonth
= nNewMonth
- nTempMonthOff
;
1503 nNewMonth
= 12-(nTempMonthOff
-nNewMonth
);
1505 nNewYear
= nNewYear
- nTempYearOff
;
1506 SetFirstDate( Date( 1, nNewMonth
, nNewYear
) );
1510 // -----------------------------------------------------------------------
1512 void Calendar::ImplTracking( const Point
& rPos
, BOOL bRepeat
)
1514 Date aTempDate
= maCurDate
;
1515 USHORT nHitTest
= ImplHitTest( rPos
, aTempDate
);
1519 mbPrevIn
= (nHitTest
& CALENDAR_HITTEST_PREV
) != 0;
1520 mbNextIn
= (nHitTest
& CALENDAR_HITTEST_NEXT
) != 0;
1522 if ( bRepeat
&& (mbPrevIn
|| mbNextIn
) )
1524 mbScrollDateRange
= TRUE
;
1525 ImplScroll( mbPrevIn
);
1526 mbScrollDateRange
= FALSE
;
1530 ImplMouseSelect( aTempDate
, nHitTest
, TRUE
, FALSE
, FALSE
);
1533 // -----------------------------------------------------------------------
1535 void Calendar::ImplEndTracking( BOOL bCancel
)
1537 BOOL bSelection
= mbSelection
;
1538 BOOL bSpinDown
= mbSpinDown
;
1541 mbSelection
= FALSE
;
1542 mbMultiSelection
= FALSE
;
1550 if ( maOldFirstDate
!= maFirstDate
)
1551 SetFirstDate( maOldFirstDate
);
1555 Table
* pOldSel
= new Table( *mpSelectTable
);
1556 Date aOldDate
= maCurDate
;
1557 maCurDate
= maOldCurDate
;
1558 *mpSelectTable
= *mpOldSelectTable
;
1560 ImplUpdateSelection( pOldSel
);
1561 if ( !pOldSel
->Get( aOldDate
.GetDate() ) )
1562 ImplUpdateDate( aOldDate
);
1563 // Damit Focus-Rechteck auch wieder neu ausgegeben wird
1564 if ( HasFocus() || !mpSelectTable
->Get( maCurDate
.GetDate() ) )
1565 ImplUpdateDate( maCurDate
);
1574 // Feststellen, ob wir sichtbaren Bereich scrollen sollen
1575 ULONG nSelCount
= mpSelectTable
->Count();
1578 Date
aFirstSelDate( mpSelectTable
->GetObjectKey( 0 ) );
1579 Date
aLastSelDate( mpSelectTable
->GetObjectKey( nSelCount
-1 ) );
1580 if ( aLastSelDate
< GetFirstMonth() )
1582 else if ( GetLastMonth() < aFirstSelDate
)
1583 ImplScroll( FALSE
);
1588 (!bCancel
&& ((maCurDate
!= maOldCurDate
) || (*mpOldSelectTable
!= *mpSelectTable
))) )
1591 if ( !bSelection
&& (mnWinStyle
& WB_TABSTOP
) && !bCancel
)
1594 delete mpOldSelectTable
;
1595 mpOldSelectTable
= NULL
;
1596 delete mpRestoreSelectTable
;
1597 mpRestoreSelectTable
= NULL
;
1601 // -----------------------------------------------------------------------
1603 IMPL_STATIC_LINK( Calendar
, ScrollHdl
, Timer
*, EMPTYARG
)
1605 BOOL bPrevIn
= (pThis
->mnDragScrollHitTest
& CALENDAR_HITTEST_PREV
) != 0;
1606 BOOL bNextIn
= (pThis
->mnDragScrollHitTest
& CALENDAR_HITTEST_NEXT
) != 0;
1607 if( bNextIn
|| bPrevIn
)
1609 pThis
->mbScrollDateRange
= TRUE
;
1610 pThis
->ImplScroll( bPrevIn
);
1611 pThis
->mbScrollDateRange
= FALSE
;
1616 // -----------------------------------------------------------------------
1618 void Calendar::MouseButtonDown( const MouseEvent
& rMEvt
)
1620 if ( rMEvt
.IsLeft() && !mbMenuDown
)
1622 Date aTempDate
= maCurDate
;
1623 USHORT nHitTest
= ImplHitTest( rMEvt
.GetPosPixel(), aTempDate
);
1626 if ( nHitTest
& CALENDAR_HITTEST_MONTHTITLE
)
1627 ImplShowMenu( rMEvt
.GetPosPixel(), aTempDate
);
1630 maOldFirstDate
= maFirstDate
;
1632 mbPrevIn
= (nHitTest
& CALENDAR_HITTEST_PREV
) != 0;
1633 mbNextIn
= (nHitTest
& CALENDAR_HITTEST_NEXT
) != 0;
1634 if ( mbPrevIn
|| mbNextIn
)
1637 mbScrollDateRange
= TRUE
;
1638 ImplScroll( mbPrevIn
);
1639 mbScrollDateRange
= FALSE
;
1640 // Hier muss BUTTONREPEAT stehen, also nicht wieder
1641 // auf SCROLLREPEAT aendern, sondern mit TH abklaeren,
1642 // warum es evtl. anders sein sollte (71775)
1643 StartTracking( STARTTRACK_BUTTONREPEAT
);
1647 if ( (rMEvt
.GetClicks() == 2) && (nHitTest
& CALENDAR_HITTEST_DAY
) )
1651 if ( mpOldSelectTable
)
1652 delete mpOldSelectTable
;
1653 maOldCurDate
= maCurDate
;
1654 mpOldSelectTable
= new Table( *mpSelectTable
);
1662 mbMultiSelection
= (mnWinStyle
& (WB_MULTISELECT
| WB_RANGESELECT
)) != 0;
1663 if ( (nHitTest
& CALENDAR_HITTEST_DAY
) && mbMultiSelection
)
1667 ImplMouseSelect( aTempDate
, nHitTest
, FALSE
, rMEvt
.IsShift(), rMEvt
.IsMod1() );
1676 Control::MouseButtonDown( rMEvt
);
1679 // -----------------------------------------------------------------------
1681 void Calendar::MouseButtonUp( const MouseEvent
& rMEvt
)
1683 if ( rMEvt
.IsLeft() && mbSelection
)
1684 ImplEndTracking( FALSE
);
1686 Control::MouseButtonUp( rMEvt
);
1689 // -----------------------------------------------------------------------
1691 void Calendar::MouseMove( const MouseEvent
& rMEvt
)
1693 if ( mbSelection
&& rMEvt
.GetButtons() )
1694 ImplTracking( rMEvt
.GetPosPixel(), FALSE
);
1696 Control::MouseMove( rMEvt
);
1699 // -----------------------------------------------------------------------
1701 void Calendar::Tracking( const TrackingEvent
& rTEvt
)
1703 Point aMousePos
= rTEvt
.GetMouseEvent().GetPosPixel();
1705 if ( rTEvt
.IsTrackingEnded() )
1706 ImplEndTracking( rTEvt
.IsTrackingCanceled() );
1708 ImplTracking( aMousePos
, rTEvt
.IsTrackingRepeat() );
1711 // -----------------------------------------------------------------------
1713 void Calendar::KeyInput( const KeyEvent
& rKEvt
)
1715 Date aNewDate
= maCurDate
;
1716 BOOL bMultiSel
= (mnWinStyle
& (WB_RANGESELECT
| WB_MULTISELECT
)) != 0;
1717 BOOL bExpand
= rKEvt
.GetKeyCode().IsShift();
1718 BOOL bExtended
= rKEvt
.GetKeyCode().IsMod1();
1720 switch ( rKEvt
.GetKeyCode().GetCode() )
1723 aNewDate
.SetDay( 1 );
1727 aNewDate
.SetDay( aNewDate
.GetDaysInMonth() );
1748 Date aTempDate
= aNewDate
;
1749 aTempDate
-= aNewDate
.GetDay()+1;
1750 aNewDate
-= aTempDate
.GetDaysInMonth();
1755 aNewDate
+= aNewDate
.GetDaysInMonth();
1759 if ( bMultiSel
&& !(mnWinStyle
& WB_RANGESELECT
) )
1763 BOOL bDateSel
= IsDateSelected( maCurDate
);
1764 SelectDate( maCurDate
, !bDateSel
);
1766 SelectionChanging();
1767 mbTravelSelect
= TRUE
;
1769 mbTravelSelect
= FALSE
;
1773 Control::KeyInput( rKEvt
);
1777 Control::KeyInput( rKEvt
);
1781 if ( aNewDate
!= maCurDate
)
1783 if ( bMultiSel
&& bExpand
)
1785 Table
* pOldSel
= new Table( *mpSelectTable
);
1786 Date aOldAnchorDate
= maAnchorDate
;
1787 mbSelLeft
= aNewDate
< maAnchorDate
;
1792 ImplCalendarSelectDateRange( mpSelectTable
, Date( 1, 1, 0 ), aNewDate
, FALSE
);
1793 ImplCalendarSelectDateRange( mpSelectTable
, maAnchorDate
, Date( 31, 12, 9999 ), FALSE
);
1797 ImplCalendarSelectDateRange( mpSelectTable
, Date( 1, 1, 0 ), maAnchorDate
, FALSE
);
1798 ImplCalendarSelectDateRange( mpSelectTable
, aNewDate
, Date( 31, 12, 9999 ), FALSE
);
1801 ImplCalendarSelectDateRange( mpSelectTable
, aNewDate
, maAnchorDate
, TRUE
);
1803 SetCurDate( aNewDate
);
1805 maAnchorDate
= aOldAnchorDate
;
1806 mbInSelChange
= TRUE
;
1807 SelectionChanging();
1808 mbInSelChange
= FALSE
;
1809 ImplUpdateSelection( pOldSel
);
1814 if ( mnWinStyle
& WB_RANGESELECT
)
1817 SelectDate( aNewDate
, TRUE
);
1820 SetCurDate( aNewDate
);
1823 mbTravelSelect
= TRUE
;
1825 mbTravelSelect
= FALSE
;
1829 // -----------------------------------------------------------------------
1831 void Calendar::Paint( const Rectangle
& )
1836 // -----------------------------------------------------------------------
1838 void Calendar::GetFocus()
1840 ImplUpdateDate( maCurDate
);
1841 Control::GetFocus();
1844 // -----------------------------------------------------------------------
1846 void Calendar::LoseFocus()
1849 Control::LoseFocus();
1852 // -----------------------------------------------------------------------
1854 void Calendar::Resize()
1860 // -----------------------------------------------------------------------
1862 void Calendar::RequestHelp( const HelpEvent
& rHEvt
)
1864 if ( rHEvt
.GetMode() & (HELPMODE_QUICK
| HELPMODE_BALLOON
) )
1866 Date aDate
= maCurDate
;
1867 if ( GetDate( ScreenToOutputPixel( rHEvt
.GetMousePosPixel() ), aDate
) )
1869 Rectangle aDateRect
= GetDateRect( aDate
);
1870 Point aPt
= OutputToScreenPixel( aDateRect
.TopLeft() );
1871 aDateRect
.Left() = aPt
.X();
1872 aDateRect
.Top() = aPt
.Y();
1873 aPt
= OutputToScreenPixel( aDateRect
.BottomRight() );
1874 aDateRect
.Right() = aPt
.X();
1875 aDateRect
.Bottom() = aPt
.Y();
1877 if ( (rHEvt
.GetMode() & HELPMODE_BALLOON
) || (mnWinStyle
& WB_QUICKHELPSHOWSDATEINFO
) )
1879 ImplDateInfo
* pInfo
;
1882 pInfo
= mpDateTable
->Get( aDate
.GetDate() );
1884 pInfo
= mpDateTable
->Get( Date( aDate
.GetDay(), aDate
.GetMonth(), 0 ).GetDate() );
1890 XubString aStr
= pInfo
->maText
;
1893 Help::ShowBalloon( this, rHEvt
.GetMousePosPixel(), aDateRect
, aStr
);
1899 if ( rHEvt
.GetMode() & HELPMODE_QUICK
)
1901 maCalendarWrapper
.setGregorianDateTime( aDate
);
1902 USHORT nWeek
= (USHORT
) maCalendarWrapper
.getValue( i18n::CalendarFieldIndex::WEEK_OF_YEAR
);
1903 USHORT nMonth
= aDate
.GetMonth();
1904 XubString
aStr( maDayText
);
1905 aStr
.AppendAscii( ": " );
1906 aStr
.Append( XubString::CreateFromInt32( aDate
.GetDayOfYear() ) );
1907 aStr
.AppendAscii( " / " );
1908 aStr
.Append( maWeekText
);
1909 aStr
.AppendAscii( ": " );
1910 aStr
.Append( XubString::CreateFromInt32( nWeek
) );
1911 // Evt. noch Jahr hinzufuegen, wenn es nicht das gleiche ist
1912 if ( (nMonth
== 12) && (nWeek
== 1) )
1914 aStr
.AppendAscii( ", " );
1915 aStr
.Append( XubString::CreateFromInt32( aDate
.GetYear()+1 ) );
1917 else if ( (nMonth
== 1) && (nWeek
> 50) )
1919 aStr
.AppendAscii( ", " );
1920 aStr
.Append( XubString::CreateFromInt32( aDate
.GetYear()-1 ) );
1922 Help::ShowQuickHelp( this, aDateRect
, aStr
);
1928 Control::RequestHelp( rHEvt
);
1931 // -----------------------------------------------------------------------
1933 void Calendar::Command( const CommandEvent
& rCEvt
)
1935 if ( rCEvt
.GetCommand() == COMMAND_CONTEXTMENU
)
1937 if ( !mbSelection
&& rCEvt
.IsMouseEvent() )
1939 Date aTempDate
= maCurDate
;
1940 USHORT nHitTest
= ImplHitTest( rCEvt
.GetMousePosPixel(), aTempDate
);
1941 if ( nHitTest
& CALENDAR_HITTEST_MONTHTITLE
)
1943 ImplShowMenu( rCEvt
.GetMousePosPixel(), aTempDate
);
1948 else if ( rCEvt
.GetCommand() == COMMAND_WHEEL
)
1950 const CommandWheelData
* pData
= rCEvt
.GetWheelData();
1951 if ( pData
->GetMode() == COMMAND_WHEEL_SCROLL
)
1953 long nNotchDelta
= pData
->GetNotchDelta();
1954 if ( nNotchDelta
< 0 )
1956 while ( nNotchDelta
< 0 )
1964 while ( nNotchDelta
> 0 )
1966 ImplScroll( FALSE
);
1975 Control::Command( rCEvt
);
1978 // -----------------------------------------------------------------------
1980 void Calendar::StateChanged( StateChangedType nType
)
1982 Control::StateChanged( nType
);
1984 if ( nType
== STATE_CHANGE_INITSHOW
)
1988 // -----------------------------------------------------------------------
1990 void Calendar::DataChanged( const DataChangedEvent
& rDCEvt
)
1992 Control::DataChanged( rDCEvt
);
1994 if ( (rDCEvt
.GetType() == DATACHANGED_FONTS
) ||
1995 (rDCEvt
.GetType() == DATACHANGED_FONTSUBSTITUTION
) ||
1996 ((rDCEvt
.GetType() == DATACHANGED_SETTINGS
) &&
1997 (rDCEvt
.GetFlags() & SETTINGS_STYLE
)) )
2004 // -----------------------------------------------------------------------
2006 void Calendar::SelectionChanging()
2008 maSelectionChangingHdl
.Call( this );
2011 // -----------------------------------------------------------------------
2013 void Calendar::DateRangeChanged()
2015 maDateRangeChangedHdl
.Call( this );
2018 // -----------------------------------------------------------------------
2020 void Calendar::RequestDateInfo()
2022 maRequestDateInfoHdl
.Call( this );
2025 // -----------------------------------------------------------------------
2027 void Calendar::DoubleClick()
2029 maDoubleClickHdl
.Call( this );
2032 // -----------------------------------------------------------------------
2034 void Calendar::Select()
2036 maSelectHdl
.Call( this );
2039 // -----------------------------------------------------------------------
2041 void Calendar::SelectDate( const Date
& rDate
, BOOL bSelect
)
2043 if ( !rDate
.IsValid() )
2048 if ( !mbInSelChange
)
2049 pOldSel
= new Table( *mpSelectTable
);
2053 ImplCalendarSelectDate( mpSelectTable
, rDate
, bSelect
);
2057 ImplUpdateSelection( pOldSel
);
2062 // -----------------------------------------------------------------------
2064 void Calendar::SelectDateRange( const Date
& rStartDate
, const Date
& rEndDate
,
2067 if ( !rStartDate
.IsValid() || !rEndDate
.IsValid() )
2072 if ( !mbInSelChange
)
2073 pOldSel
= new Table( *mpSelectTable
);
2077 ImplCalendarSelectDateRange( mpSelectTable
, rStartDate
, rEndDate
, bSelect
);
2081 ImplUpdateSelection( pOldSel
);
2086 // -----------------------------------------------------------------------
2088 void Calendar::SetNoSelection()
2092 if ( !mbInSelChange
)
2093 pOldSel
= new Table( *mpSelectTable
);
2097 ImplCalendarClearSelectDate( mpSelectTable
);
2101 ImplUpdateSelection( pOldSel
);
2106 // -----------------------------------------------------------------------
2108 BOOL
Calendar::IsDateSelected( const Date
& rDate
) const
2110 return mpSelectTable
->IsKeyValid( rDate
.GetDate() );
2113 // -----------------------------------------------------------------------
2115 ULONG
Calendar::GetSelectDateCount() const
2117 return mpSelectTable
->Count();
2120 // -----------------------------------------------------------------------
2122 Date
Calendar::GetSelectDate( ULONG nIndex
) const
2124 if ( nIndex
< mpSelectTable
->Count() )
2125 return Date( mpSelectTable
->GetObjectKey( nIndex
) );
2128 Date
aDate( 0, 0, 0 );
2133 // -----------------------------------------------------------------------
2135 void Calendar::SetCurDate( const Date
& rNewDate
)
2137 if ( !rNewDate
.IsValid() )
2140 if ( maCurDate
!= rNewDate
)
2142 BOOL bUpdate
= IsVisible() && IsUpdateMode();
2143 Date aOldDate
= maCurDate
;
2144 maCurDate
= rNewDate
;
2145 maAnchorDate
= maCurDate
;
2147 if ( !(mnWinStyle
& (WB_RANGESELECT
| WB_MULTISELECT
)) )
2149 ImplCalendarSelectDate( mpSelectTable
, aOldDate
, FALSE
);
2150 ImplCalendarSelectDate( mpSelectTable
, maCurDate
, TRUE
);
2152 else if ( !HasFocus() )
2155 // Aktuelles Datum noch in den sichtbaren Bereich verschieben
2156 if ( mbFormat
|| (maCurDate
< GetFirstMonth()) )
2157 SetFirstDate( maCurDate
);
2158 else if ( maCurDate
> GetLastMonth() )
2160 Date aTempDate
= GetLastMonth();
2161 long nDateOff
= maCurDate
-aTempDate
;
2162 if ( nDateOff
< 365 )
2164 Date aFirstDate
= GetFirstMonth();
2165 aFirstDate
+= aFirstDate
.GetDaysInMonth();
2167 while ( nDateOff
> aTempDate
.GetDaysInMonth() )
2169 aFirstDate
+= aFirstDate
.GetDaysInMonth();
2170 long nDaysInMonth
= aTempDate
.GetDaysInMonth();
2171 aTempDate
+= nDaysInMonth
;
2172 nDateOff
-= nDaysInMonth
;
2174 SetFirstDate( aFirstDate
);
2177 SetFirstDate( maCurDate
);
2184 ImplUpdateDate( aOldDate
);
2185 ImplUpdateDate( maCurDate
);
2191 // -----------------------------------------------------------------------
2193 void Calendar::SetFirstDate( const Date
& rNewFirstDate
)
2195 if ( maFirstDate
!= rNewFirstDate
)
2197 maFirstDate
= Date( 1, rNewFirstDate
.GetMonth(), rNewFirstDate
.GetYear() );
2203 // -----------------------------------------------------------------------
2205 Date
Calendar::GetFirstMonth() const
2207 if ( maFirstDate
.GetDay() > 1 )
2209 if ( maFirstDate
.GetMonth() == 12 )
2210 return Date( 1, 1, maFirstDate
.GetYear()+1 );
2212 return Date( 1, maFirstDate
.GetMonth()+1, maFirstDate
.GetYear() );
2218 // -----------------------------------------------------------------------
2220 Date
Calendar::GetLastMonth() const
2222 Date aDate
= GetFirstMonth();
2223 USHORT nMonthCount
= GetMonthCount();
2224 for ( USHORT i
= 0; i
< nMonthCount
; i
++ )
2225 aDate
+= aDate
.GetDaysInMonth();
2230 // -----------------------------------------------------------------------
2232 USHORT
Calendar::GetMonthCount() const
2237 return (USHORT
)(mnMonthPerLine
*mnLines
);
2240 // -----------------------------------------------------------------------
2242 BOOL
Calendar::GetDropDate( Date
& rDate
) const
2252 // -----------------------------------------------------------------------
2254 BOOL
Calendar::GetDate( const Point
& rPos
, Date
& rDate
) const
2256 Date aDate
= maCurDate
;
2257 USHORT nHitTest
= ImplHitTest( rPos
, aDate
);
2258 if ( nHitTest
& CALENDAR_HITTEST_DAY
)
2267 // -----------------------------------------------------------------------
2269 Rectangle
Calendar::GetDateRect( const Date
& rDate
) const
2273 if ( mbFormat
|| (rDate
< maFirstDate
) || (rDate
> (maFirstDate
+mnDayCount
)) )
2280 Date aDate
= GetFirstMonth();
2282 if ( rDate
< aDate
)
2284 aRect
= GetDateRect( aDate
);
2285 nDaysOff
= aDate
-rDate
;
2286 nX
= (long)(nDaysOff
*mnDayWidth
);
2288 aRect
.Right() -= nX
;
2293 Date aLastDate
= GetLastMonth();
2294 if ( rDate
> aLastDate
)
2296 USHORT nWeekDay
= (USHORT
)aLastDate
.GetDayOfWeek();
2297 nWeekDay
= (nWeekDay
+(7-(USHORT
)ImplGetWeekStart())) % 7;
2298 aLastDate
-= nWeekDay
;
2299 aRect
= GetDateRect( aLastDate
);
2300 nDaysOff
= rDate
-aLastDate
;
2302 for ( USHORT i
= 0; i
<= nDaysOff
; i
++ )
2304 if ( aLastDate
== rDate
)
2306 aRect
.Left() += nDayIndex
*mnDayWidth
;
2307 aRect
.Right() = aRect
.Left()+mnDayWidth
;
2310 if ( nDayIndex
== 6 )
2313 aRect
.Top() += mnDayHeight
;
2314 aRect
.Bottom() += mnDayHeight
;
2324 for ( long i
= 0; i
< mnLines
; i
++ )
2327 for ( long j
= 0; j
< mnMonthPerLine
; j
++ )
2329 USHORT nDaysInMonth
= aDate
.GetDaysInMonth();
2332 if ( (aDate
.GetMonth() == rDate
.GetMonth()) &&
2333 (aDate
.GetYear() == rDate
.GetYear()) )
2335 long nDayX
= nX
+mnDaysOffX
;
2336 long nDayY
= nY
+mnDaysOffY
;
2337 nDayIndex
= (USHORT
)aDate
.GetDayOfWeek();
2338 nDayIndex
= (nDayIndex
+(7-(USHORT
)ImplGetWeekStart())) % 7;
2339 for ( USHORT nDay
= 1; nDay
<= nDaysInMonth
; nDay
++ )
2341 if ( nDay
== rDate
.GetDay() )
2343 aRect
.Left() = nDayX
+ (nDayIndex
*mnDayWidth
);
2344 aRect
.Top() = nDayY
;
2345 aRect
.Right() = aRect
.Left()+mnDayWidth
;
2346 aRect
.Bottom() = aRect
.Top()+mnDayHeight
;
2349 if ( nDayIndex
== 6 )
2352 nDayY
+= mnDayHeight
;
2359 aDate
+= nDaysInMonth
;
2363 nY
+= mnMonthHeight
;
2369 // -----------------------------------------------------------------------
2371 void Calendar::SetStandardColor( const Color
& rColor
)
2373 if ( mpStandardColor
)
2374 *mpStandardColor
= rColor
;
2376 mpStandardColor
= new Color( rColor
);
2380 // -----------------------------------------------------------------------
2382 void Calendar::SetSaturdayColor( const Color
& rColor
)
2384 if ( mpSaturdayColor
)
2385 *mpSaturdayColor
= rColor
;
2387 mpSaturdayColor
= new Color( rColor
);
2391 // -----------------------------------------------------------------------
2393 void Calendar::SetSundayColor( const Color
& rColor
)
2395 if ( mpSundayColor
)
2396 *mpSundayColor
= rColor
;
2398 mpSundayColor
= new Color( rColor
);
2402 // -----------------------------------------------------------------------
2404 void Calendar::AddDateInfo( const Date
& rDate
, const String
& rText
,
2405 const Color
* pTextColor
, const Color
* pFrameColor
,
2409 mpDateTable
= new ImplDateTable( 256, 256 );
2411 BOOL bChanged
= FALSE
;
2412 ULONG nKey
= rDate
.GetDate();
2413 ImplDateInfo
* pDateInfo
= mpDateTable
->Get( nKey
);
2415 pDateInfo
->maText
= rText
;
2418 pDateInfo
= new ImplDateInfo( rText
);
2419 mpDateTable
->Insert( nKey
, pDateInfo
);
2423 if ( pDateInfo
->mpTextColor
)
2425 if ( *(pDateInfo
->mpTextColor
) != *pTextColor
)
2427 *(pDateInfo
->mpTextColor
) = *pTextColor
;
2433 pDateInfo
->mpTextColor
= new Color( *pTextColor
);
2439 if ( pDateInfo
->mpTextColor
)
2441 delete pDateInfo
->mpTextColor
;
2442 pDateInfo
->mpTextColor
= NULL
;
2448 if ( pDateInfo
->mpFrameColor
)
2450 if ( *(pDateInfo
->mpFrameColor
) != *pFrameColor
)
2452 *(pDateInfo
->mpFrameColor
) = *pFrameColor
;
2458 pDateInfo
->mpFrameColor
= new Color( *pFrameColor
);
2464 if ( pDateInfo
->mpFrameColor
)
2466 delete pDateInfo
->mpFrameColor
;
2467 pDateInfo
->mpFrameColor
= NULL
;
2471 if ( pDateInfo
->mnFlags
!= nFlags
)
2473 pDateInfo
->mnFlags
= nFlags
;
2478 ImplUpdateDate( rDate
);
2481 // -----------------------------------------------------------------------
2483 void Calendar::RemoveDateInfo( const Date
& rDate
)
2487 ImplDateInfo
* pDateInfo
= mpDateTable
->Remove( rDate
.GetDate() );
2491 ImplUpdateDate( rDate
);
2496 // -----------------------------------------------------------------------
2498 void Calendar::ClearDateInfo()
2502 ImplDateInfo
* pDateInfo
= mpDateTable
->First();
2505 ULONG nKey
= mpDateTable
->GetCurKey();
2506 mpDateTable
->Remove( nKey
);
2508 ImplUpdateDate( aDate
);
2510 pDateInfo
= mpDateTable
->First();
2517 // -----------------------------------------------------------------------
2519 XubString
Calendar::GetDateInfoText( const Date
& rDate
)
2524 ULONG nKey
= rDate
.GetDate();
2525 ImplDateInfo
* pDateInfo
= mpDateTable
->Get( nKey
);
2527 aRet
= pDateInfo
->maText
;
2532 // -----------------------------------------------------------------------
2534 BOOL
Calendar::ShowDropPos( const Point
& rPos
, Date
& rDate
)
2536 Date aTempDate
= maCurDate
;
2537 mnDragScrollHitTest
= ImplHitTest( rPos
, aTempDate
);
2539 if ( mnDragScrollHitTest
)
2541 if ( mnDragScrollHitTest
& (CALENDAR_HITTEST_PREV
| CALENDAR_HITTEST_NEXT
) )
2543 if ( !maDragScrollTimer
.IsActive() )
2544 maDragScrollTimer
.Start();
2548 maDragScrollTimer
.Stop();
2549 if ( mnDragScrollHitTest
& CALENDAR_HITTEST_DAY
)
2551 if ( !mbDropPos
|| (aTempDate
!= maDropDate
) )
2554 ImplInvertDropPos();
2555 maDropDate
= aTempDate
;
2557 ImplInvertDropPos();
2566 maDragScrollTimer
.Stop();
2572 // -----------------------------------------------------------------------
2574 void Calendar::HideDropPos()
2578 ImplInvertDropPos();
2583 // -----------------------------------------------------------------------
2585 void Calendar::StartSelection()
2587 if ( mpOldSelectTable
)
2588 delete mpOldSelectTable
;
2589 maOldCurDate
= maCurDate
;
2590 mpOldSelectTable
= new Table( *mpSelectTable
);
2595 // -----------------------------------------------------------------------
2597 void Calendar::EndSelection()
2599 if ( mbDrag
|| mbSpinDown
|| mbSelection
)
2605 mbSelection
= FALSE
;
2606 mbMultiSelection
= FALSE
;
2613 // -----------------------------------------------------------------------
2615 Size
Calendar::CalcWindowSizePixel( long nCalcMonthPerLine
,
2616 long nCalcLines
) const
2618 XubString
a99Text( XubString( RTL_CONSTASCII_USTRINGPARAM( "99" ) ) );
2619 Font aOldFont
= GetFont();
2621 // Wochenanzeige beruecksichtigen
2623 if ( mnWinStyle
& WB_WEEKNUMBER
)
2625 Font aTempFont
= aOldFont
;
2626 ImplGetWeekFont( aTempFont
);
2627 ((Calendar
*)this)->SetFont( aTempFont
);
2628 nWeekWidth
= GetTextWidth( a99Text
)+WEEKNUMBER_OFFX
;
2629 ((Calendar
*)this)->SetFont( aOldFont
);
2634 if ( mnWinStyle
& WB_BOLDTEXT
)
2636 Font aFont
= aOldFont
;
2637 if ( aFont
.GetWeight() < WEIGHT_BOLD
)
2638 aFont
.SetWeight( WEIGHT_BOLD
);
2640 aFont
.SetWeight( WEIGHT_NORMAL
);
2641 ((Calendar
*)this)->SetFont( aFont
);
2645 long n99TextWidth
= GetTextWidth( a99Text
);
2646 long nTextHeight
= GetTextHeight();
2648 if ( mnWinStyle
& WB_BOLDTEXT
)
2649 ((Calendar
*)this)->SetFont( aOldFont
);
2651 aSize
.Width() += ((n99TextWidth
+DAY_OFFX
)*7) + nWeekWidth
;
2652 aSize
.Width() += MONTH_BORDERX
*2;
2653 aSize
.Width() *= nCalcMonthPerLine
;
2655 aSize
.Height() = nTextHeight
+ TITLE_OFFY
+ (TITLE_BORDERY
*2);
2656 aSize
.Height() += nTextHeight
+ WEEKDAY_OFFY
;
2657 aSize
.Height() += ((nTextHeight
+DAY_OFFY
)*6);
2658 aSize
.Height() += MONTH_OFFY
;
2659 aSize
.Height() *= nCalcLines
;
2664 // =======================================================================
2666 #define CALFIELD_EXTRA_BUTTON_WIDTH 14
2667 #define CALFIELD_EXTRA_BUTTON_HEIGHT 8
2668 #define CALFIELD_SEP_X 6
2669 #define CALFIELD_BORDERLINE_X 5
2670 #define CALFIELD_BORDER_YTOP 4
2671 #define CALFIELD_BORDER_Y 5
2673 // =======================================================================
2675 class ImplCFieldFloatWin
: public FloatingWindow
2678 Calendar
* mpCalendar
;
2679 PushButton
* mpTodayBtn
;
2680 PushButton
* mpNoneBtn
;
2681 FixedLine
* mpFixedLine
;
2684 ImplCFieldFloatWin( Window
* pParent
);
2685 ~ImplCFieldFloatWin();
2687 void SetCalendar( Calendar
* pCalendar
)
2688 { mpCalendar
= pCalendar
; }
2690 PushButton
* EnableTodayBtn( BOOL bEnable
);
2691 PushButton
* EnableNoneBtn( BOOL bEnable
);
2692 void ArrangeButtons();
2694 long Notify( NotifyEvent
& rNEvt
);
2697 // -----------------------------------------------------------------------
2699 ImplCFieldFloatWin::ImplCFieldFloatWin( Window
* pParent
) :
2700 FloatingWindow( pParent
, WB_BORDER
| WB_SYSTEMWINDOW
| WB_NOSHADOW
)
2708 // -----------------------------------------------------------------------
2710 ImplCFieldFloatWin::~ImplCFieldFloatWin()
2717 // -----------------------------------------------------------------------
2719 PushButton
* ImplCFieldFloatWin::EnableTodayBtn( BOOL bEnable
)
2725 mpTodayBtn
= new PushButton( this, WB_NOPOINTERFOCUS
);
2726 XubString
aTodayText( SvtResId( STR_SVT_CALENDAR_TODAY
) );
2727 mpTodayBtn
->SetText( aTodayText
);
2729 aSize
.Width() = mpTodayBtn
->GetCtrlTextWidth( mpTodayBtn
->GetText() );
2730 aSize
.Height() = mpTodayBtn
->GetTextHeight();
2731 aSize
.Width() += CALFIELD_EXTRA_BUTTON_WIDTH
;
2732 aSize
.Height() += CALFIELD_EXTRA_BUTTON_HEIGHT
;
2733 mpTodayBtn
->SetSizePixel( aSize
);
2749 // -----------------------------------------------------------------------
2751 PushButton
* ImplCFieldFloatWin::EnableNoneBtn( BOOL bEnable
)
2757 mpNoneBtn
= new PushButton( this, WB_NOPOINTERFOCUS
);
2758 XubString
aNoneText( SvtResId( STR_SVT_CALENDAR_NONE
) );
2759 mpNoneBtn
->SetText( aNoneText
);
2761 aSize
.Width() = mpNoneBtn
->GetCtrlTextWidth( mpNoneBtn
->GetText() );
2762 aSize
.Height() = mpNoneBtn
->GetTextHeight();
2763 aSize
.Width() += CALFIELD_EXTRA_BUTTON_WIDTH
;
2764 aSize
.Height() += CALFIELD_EXTRA_BUTTON_HEIGHT
;
2765 mpNoneBtn
->SetSizePixel( aSize
);
2781 // -----------------------------------------------------------------------
2783 void ImplCFieldFloatWin::ArrangeButtons()
2785 long nBtnHeight
= 0;
2787 Size aOutSize
= GetOutputSizePixel();
2788 if ( mpTodayBtn
&& mpNoneBtn
)
2790 Size aTodayBtnSize
= mpTodayBtn
->GetSizePixel();
2791 Size aNoneBtnSize
= mpNoneBtn
->GetSizePixel();
2792 if ( aTodayBtnSize
.Width() < aNoneBtnSize
.Width() )
2793 aTodayBtnSize
.Width() = aNoneBtnSize
.Width();
2795 aNoneBtnSize
.Width() = aTodayBtnSize
.Width();
2796 if ( aTodayBtnSize
.Height() < aNoneBtnSize
.Height() )
2797 aTodayBtnSize
.Height() = aNoneBtnSize
.Height();
2799 aNoneBtnSize
.Height() = aTodayBtnSize
.Height();
2801 nBtnWidth
= aTodayBtnSize
.Width() + aNoneBtnSize
.Width() + CALFIELD_SEP_X
;
2802 nBtnHeight
= aTodayBtnSize
.Height();
2803 long nX
= (aOutSize
.Width()-nBtnWidth
)/2;
2804 long nY
= aOutSize
.Height()+CALFIELD_BORDER_Y
+CALFIELD_BORDER_YTOP
;
2805 mpTodayBtn
->SetPosSizePixel( Point( nX
, nY
), aTodayBtnSize
);
2806 nX
+= aTodayBtnSize
.Width() + CALFIELD_SEP_X
;
2807 mpNoneBtn
->SetPosSizePixel( Point( nX
, nY
), aNoneBtnSize
);
2809 else if ( mpTodayBtn
)
2811 Size aTodayBtnSize
= mpTodayBtn
->GetSizePixel();
2812 nBtnWidth
= aTodayBtnSize
.Width();
2813 nBtnHeight
= aTodayBtnSize
.Height();
2814 mpTodayBtn
->SetPosPixel( Point( (aOutSize
.Width()-nBtnWidth
)/2, aOutSize
.Height()+CALFIELD_BORDER_Y
+CALFIELD_BORDER_YTOP
) );
2816 else if ( mpNoneBtn
)
2818 Size aNoneBtnSize
= mpNoneBtn
->GetSizePixel();
2819 nBtnWidth
= aNoneBtnSize
.Width();
2820 nBtnHeight
= aNoneBtnSize
.Height();
2821 mpNoneBtn
->SetPosPixel( Point( (aOutSize
.Width()-nBtnWidth
)/2, aOutSize
.Height()+CALFIELD_BORDER_Y
+CALFIELD_BORDER_YTOP
) );
2828 mpFixedLine
= new FixedLine( this );
2829 mpFixedLine
->Show();
2831 long nLineWidth
= aOutSize
.Width()-(CALFIELD_BORDERLINE_X
*2);
2832 mpFixedLine
->SetPosSizePixel( (aOutSize
.Width()-nLineWidth
)/2, aOutSize
.Height()+((CALFIELD_BORDER_YTOP
-2)/2),
2833 nLineWidth
, 2, WINDOW_POSSIZE_POSSIZE
);
2834 aOutSize
.Height() += nBtnHeight
+ (CALFIELD_BORDER_Y
*2) + CALFIELD_BORDER_YTOP
;
2835 SetOutputSizePixel( aOutSize
);
2847 // -----------------------------------------------------------------------
2849 long ImplCFieldFloatWin::Notify( NotifyEvent
& rNEvt
)
2851 if ( rNEvt
.GetType() == EVENT_KEYINPUT
)
2853 const KeyEvent
* pKEvt
= rNEvt
.GetKeyEvent();
2854 if ( pKEvt
->GetKeyCode().GetCode() == KEY_RETURN
)
2855 mpCalendar
->Select();
2858 return FloatingWindow::Notify( rNEvt
);
2861 // =======================================================================
2863 CalendarField::CalendarField( Window
* pParent
, WinBits nWinStyle
) :
2864 DateField( pParent
, nWinStyle
),
2865 maDefaultDate( 0, 0, 0 )
2869 mnCalendarStyle
= 0;
2874 // -----------------------------------------------------------------------
2876 CalendarField::CalendarField( Window
* pParent
, const ResId
& rResId
) :
2877 DateField( pParent
, rResId
),
2878 maDefaultDate( 0, 0, 0 )
2882 mnCalendarStyle
= 0;
2887 // -----------------------------------------------------------------------
2889 CalendarField::~CalendarField()
2898 // -----------------------------------------------------------------------
2900 IMPL_LINK( CalendarField
, ImplSelectHdl
, Calendar
*, pCalendar
)
2902 if ( !pCalendar
->IsTravelSelect() )
2904 mpFloatWin
->EndPopupMode();
2907 Date aNewDate
= mpCalendar
->GetSelectDate( 0 );
2908 if ( IsEmptyDate() || ( aNewDate
!= GetDate() ) )
2910 SetDate( aNewDate
);
2919 // -----------------------------------------------------------------------
2921 IMPL_LINK( CalendarField
, ImplClickHdl
, PushButton
*, pBtn
)
2923 mpFloatWin
->EndPopupMode();
2927 if ( pBtn
== mpTodayBtn
)
2930 if ( (aToday
!= GetDate()) || IsEmptyDate() )
2937 else if ( pBtn
== mpNoneBtn
)
2939 if ( !IsEmptyDate() )
2951 // -----------------------------------------------------------------------
2953 IMPL_LINK( CalendarField
, ImplPopupModeEndHdl
, FloatingWindow
*, EMPTYARG
)
2957 mpCalendar
->EndSelection();
2961 // -----------------------------------------------------------------------
2963 void CalendarField::Select()
2965 maSelectHdl
.Call( this );
2968 // -----------------------------------------------------------------------
2970 BOOL
CalendarField::ShowDropDown( BOOL bShow
)
2974 Calendar
* pCalendar
= GetCalendar();
2976 Date aDate
= GetDate();
2977 if ( IsEmptyDate() || !aDate
.IsValid() )
2979 if ( maDefaultDate
.IsValid() )
2980 aDate
= maDefaultDate
;
2984 if ( pCalendar
->GetStyle() & (WB_RANGESELECT
| WB_MULTISELECT
) )
2986 pCalendar
->SetNoSelection();
2987 pCalendar
->SelectDate( aDate
);
2989 pCalendar
->SetCurDate( aDate
);
2990 Point
aPos( GetParent()->OutputToScreenPixel( GetPosPixel() ) );
2991 Rectangle
aRect( aPos
, GetSizePixel() );
2992 aRect
.Bottom() -= 1;
2993 mpCalendar
->SetOutputSizePixel( mpCalendar
->CalcWindowSizePixel() );
2994 mpFloatWin
->SetOutputSizePixel( mpCalendar
->GetSizePixel() );
2995 mpFloatWin
->SetCalendar( mpCalendar
);
2996 mpTodayBtn
= mpFloatWin
->EnableTodayBtn( mbToday
);
2997 mpNoneBtn
= mpFloatWin
->EnableNoneBtn( mbNone
);
2999 mpTodayBtn
->SetClickHdl( LINK( this, CalendarField
, ImplClickHdl
) );
3001 mpNoneBtn
->SetClickHdl( LINK( this, CalendarField
, ImplClickHdl
) );
3002 mpFloatWin
->ArrangeButtons();
3003 mpCalendar
->EnableCallEverySelect();
3004 mpCalendar
->StartSelection();
3005 mpCalendar
->GrabFocus();
3007 mpFloatWin
->StartPopupMode( aRect
, FLOATWIN_POPUPMODE_NOFOCUSCLOSE
|FLOATWIN_POPUPMODE_DOWN
);
3011 mpFloatWin
->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL
);
3012 mpCalendar
->EndSelection();
3018 // -----------------------------------------------------------------------
3020 Calendar
* CalendarField::CreateCalendar( Window
* pParent
)
3022 return new Calendar( pParent
, mnCalendarStyle
| WB_TABSTOP
);
3025 // -----------------------------------------------------------------------
3027 Calendar
* CalendarField::GetCalendar()
3031 mpFloatWin
= new ImplCFieldFloatWin( this );
3032 mpFloatWin
->SetPopupModeEndHdl( LINK( this, CalendarField
, ImplPopupModeEndHdl
) );
3033 mpCalendar
= CreateCalendar( mpFloatWin
);
3034 mpCalendar
->SetPosPixel( Point() );
3035 mpCalendar
->SetSelectHdl( LINK( this, CalendarField
, ImplSelectHdl
) );
3041 // -----------------------------------------------------------------------
3043 void CalendarField::StateChanged( StateChangedType nStateChange
)
3045 DateField::StateChanged( nStateChange
);
3047 if ( ( nStateChange
== STATE_CHANGE_STYLE
) && GetSubEdit() )
3049 WinBits nAllAlignmentBits
= ( WB_LEFT
| WB_CENTER
| WB_RIGHT
| WB_TOP
| WB_VCENTER
| WB_BOTTOM
);
3050 WinBits nMyAlignment
= GetStyle() & nAllAlignmentBits
;
3051 GetSubEdit()->SetStyle( ( GetSubEdit()->GetStyle() & ~nAllAlignmentBits
) | nMyAlignment
);