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