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