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 : #include <boost/scoped_ptr.hpp>
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( vcl::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( vcl::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 : vcl::Font aOldFont = GetFont();
335 :
336 : // Wochenanzeige beruecksichtigen
337 0 : if ( mnWinStyle & WB_WEEKNUMBER )
338 : {
339 0 : vcl::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 : vcl::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 : vcl::Font aOldFont = GetFont();
945 0 : vcl::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 : boost::scoped_ptr<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.get() );
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 0 : }
1192 0 : }
1193 :
1194 :
1195 :
1196 0 : void Calendar::ImplUpdate( bool bCalcNew )
1197 : {
1198 0 : if ( IsReallyVisible() && IsUpdateMode() )
1199 : {
1200 0 : if ( bCalcNew && !mbCalc )
1201 0 : Invalidate();
1202 0 : else if ( !mbFormat && !mbCalc )
1203 : {
1204 0 : if ( mbDirect )
1205 : {
1206 0 : mbFormat = true;
1207 0 : ImplDraw( false );
1208 0 : return;
1209 : }
1210 : else
1211 0 : Invalidate();
1212 : }
1213 : }
1214 :
1215 0 : if ( bCalcNew )
1216 0 : mbCalc = true;
1217 0 : mbFormat = true;
1218 : }
1219 :
1220 :
1221 :
1222 0 : void Calendar::ImplInvertDropPos()
1223 : {
1224 0 : Rectangle aRect = GetDateRect( maDropDate );//this is one Pixel to width and one to heigh
1225 0 : aRect.Bottom() = aRect.Top()+mnDayHeight-1;
1226 0 : aRect.Right() = aRect.Left()+mnDayWidth-1;
1227 0 : Invert( aRect );
1228 0 : }
1229 :
1230 :
1231 :
1232 0 : void Calendar::ImplScroll( bool bPrev )
1233 : {
1234 0 : Date aNewFirstMonth = GetFirstMonth();
1235 0 : if ( bPrev )
1236 : {
1237 0 : aNewFirstMonth--;
1238 0 : aNewFirstMonth -= aNewFirstMonth.GetDaysInMonth()-1;
1239 : }
1240 : else
1241 0 : aNewFirstMonth += aNewFirstMonth.GetDaysInMonth();
1242 0 : mbDirect = true;
1243 0 : SetFirstDate( aNewFirstMonth );
1244 0 : mbDirect = false;
1245 0 : }
1246 :
1247 :
1248 :
1249 0 : void Calendar::ImplShowMenu( const Point& rPos, const Date& rDate )
1250 : {
1251 0 : EndSelection();
1252 :
1253 0 : Date aOldFirstDate = GetFirstMonth();
1254 0 : PopupMenu aPopupMenu;
1255 : PopupMenu* pYearPopupMenus[MENU_YEAR_COUNT];
1256 : sal_uInt16 nMonthOff;
1257 : sal_uInt16 nCurItemId;
1258 0 : sal_uInt16 nYear = rDate.GetYear()-1;
1259 : sal_uInt16 i;
1260 : sal_uInt16 j;
1261 0 : sal_uInt16 nYearIdCount = 1000;
1262 :
1263 0 : nMonthOff = (rDate.GetYear()-aOldFirstDate.GetYear())*12;
1264 0 : if ( aOldFirstDate.GetMonth() < rDate.GetMonth() )
1265 0 : nMonthOff += rDate.GetMonth()-aOldFirstDate.GetMonth();
1266 : else
1267 0 : nMonthOff -= aOldFirstDate.GetMonth()-rDate.GetMonth();
1268 :
1269 : // construct menu (include years with different months)
1270 0 : for ( i = 0; i < MENU_YEAR_COUNT; i++ )
1271 : {
1272 0 : pYearPopupMenus[i] = new PopupMenu;
1273 0 : for ( j = 1; j <= 12; j++ )
1274 0 : pYearPopupMenus[i]->InsertItem( nYearIdCount+j,
1275 : maCalendarWrapper.getDisplayName(
1276 0 : i18n::CalendarDisplayIndex::MONTH, j-1, 1));
1277 0 : aPopupMenu.InsertItem( 10+i, OUString::number( nYear+i ) );
1278 0 : aPopupMenu.SetPopupMenu( 10+i, pYearPopupMenus[i] );
1279 0 : nYearIdCount += 1000;
1280 : }
1281 :
1282 0 : mbMenuDown = true;
1283 0 : nCurItemId = aPopupMenu.Execute( this, rPos );
1284 0 : mbMenuDown = false;
1285 :
1286 : // destroy menu
1287 0 : aPopupMenu.SetPopupMenu( 2, NULL );
1288 0 : for ( i = 0; i < MENU_YEAR_COUNT; i++ )
1289 : {
1290 0 : aPopupMenu.SetPopupMenu( 10+i, NULL );
1291 0 : delete pYearPopupMenus[i];
1292 : }
1293 :
1294 0 : if ( nCurItemId )
1295 : {
1296 0 : sal_uInt16 nTempMonthOff = nMonthOff % 12;
1297 0 : sal_uInt16 nTempYearOff = nMonthOff / 12;
1298 0 : sal_uInt16 nNewMonth = nCurItemId % 1000;
1299 0 : sal_uInt16 nNewYear = nYear+((nCurItemId-1000)/1000);
1300 0 : if ( nTempMonthOff < nNewMonth )
1301 0 : nNewMonth = nNewMonth - nTempMonthOff;
1302 : else
1303 : {
1304 0 : nNewYear--;
1305 0 : nNewMonth = 12-(nTempMonthOff-nNewMonth);
1306 : }
1307 0 : nNewYear = nNewYear - nTempYearOff;
1308 0 : SetFirstDate( Date( 1, nNewMonth, nNewYear ) );
1309 0 : }
1310 0 : }
1311 :
1312 :
1313 :
1314 0 : void Calendar::ImplTracking( const Point& rPos, bool bRepeat )
1315 : {
1316 0 : Date aTempDate = maCurDate;
1317 0 : sal_uInt16 nHitTest = ImplHitTest( rPos, aTempDate );
1318 :
1319 0 : if ( mbSpinDown )
1320 : {
1321 0 : mbPrevIn = (nHitTest & CALENDAR_HITTEST_PREV) != 0;
1322 0 : mbNextIn = (nHitTest & CALENDAR_HITTEST_NEXT) != 0;
1323 :
1324 0 : if ( bRepeat && (mbPrevIn || mbNextIn) )
1325 : {
1326 0 : mbScrollDateRange = true;
1327 0 : ImplScroll( mbPrevIn );
1328 0 : mbScrollDateRange = false;
1329 : }
1330 : }
1331 : else
1332 0 : ImplMouseSelect( aTempDate, nHitTest, true, false, false );
1333 0 : }
1334 :
1335 :
1336 :
1337 0 : void Calendar::ImplEndTracking( bool bCancel )
1338 : {
1339 0 : bool bSelection = mbSelection;
1340 0 : bool bSpinDown = mbSpinDown;
1341 :
1342 0 : mbDrag = false;
1343 0 : mbSelection = false;
1344 0 : mbMultiSelection = false;
1345 0 : mbUnSel = false;
1346 0 : mbSpinDown = false;
1347 0 : mbPrevIn = false;
1348 0 : mbNextIn = false;
1349 :
1350 0 : if ( bCancel )
1351 : {
1352 0 : if ( maOldFirstDate != maFirstDate )
1353 0 : SetFirstDate( maOldFirstDate );
1354 :
1355 0 : if ( !bSpinDown )
1356 : {
1357 0 : boost::scoped_ptr<IntDateSet> pOldSel(new IntDateSet( *mpSelectTable ));
1358 0 : Date aOldDate = maCurDate;
1359 0 : maCurDate = maOldCurDate;
1360 0 : *mpSelectTable = *mpOldSelectTable;
1361 0 : HideFocus();
1362 0 : ImplUpdateSelection( pOldSel.get() );
1363 0 : if ( pOldSel->find( aOldDate.GetDate() ) == pOldSel->end() )
1364 0 : ImplUpdateDate( aOldDate );
1365 : // assure focus rectangle is displayed again
1366 0 : if ( HasFocus() || mpSelectTable->find( maCurDate.GetDate() ) == mpSelectTable->end() )
1367 0 : ImplUpdateDate( maCurDate );
1368 : }
1369 : }
1370 :
1371 0 : if ( !bSpinDown )
1372 : {
1373 0 : if ( !bCancel )
1374 : {
1375 : // determine if we should scroll the visible area
1376 0 : sal_uLong nSelCount = mpSelectTable->size();
1377 0 : if ( nSelCount )
1378 : {
1379 0 : Date aFirstSelDate( *mpSelectTable->begin() );
1380 0 : Date aLastSelDate( *mpSelectTable->rbegin() );
1381 0 : if ( aLastSelDate < GetFirstMonth() )
1382 0 : ImplScroll( true );
1383 0 : else if ( GetLastMonth() < aFirstSelDate )
1384 0 : ImplScroll( false );
1385 : }
1386 : }
1387 :
1388 0 : if ( mbAllSel ||
1389 0 : (!bCancel && ((maCurDate != maOldCurDate) || (*mpOldSelectTable != *mpSelectTable))) )
1390 0 : Select();
1391 :
1392 0 : if ( !bSelection && (mnWinStyle & WB_TABSTOP) && !bCancel )
1393 0 : GrabFocus();
1394 :
1395 0 : delete mpOldSelectTable;
1396 0 : mpOldSelectTable = NULL;
1397 0 : delete mpRestoreSelectTable;
1398 0 : mpRestoreSelectTable = NULL;
1399 : }
1400 0 : }
1401 :
1402 :
1403 :
1404 0 : IMPL_STATIC_LINK( Calendar, ScrollHdl, Timer*, EMPTYARG )
1405 : {
1406 0 : bool bPrevIn = (pThis->mnDragScrollHitTest & CALENDAR_HITTEST_PREV) != 0;
1407 0 : bool bNextIn = (pThis->mnDragScrollHitTest & CALENDAR_HITTEST_NEXT) != 0;
1408 0 : if( bNextIn || bPrevIn )
1409 : {
1410 0 : pThis->mbScrollDateRange = true;
1411 0 : pThis->ImplScroll( bPrevIn );
1412 0 : pThis->mbScrollDateRange = false;
1413 : }
1414 0 : return 0;
1415 : }
1416 :
1417 :
1418 :
1419 0 : void Calendar::MouseButtonDown( const MouseEvent& rMEvt )
1420 : {
1421 0 : if ( rMEvt.IsLeft() && !mbMenuDown )
1422 : {
1423 0 : Date aTempDate = maCurDate;
1424 0 : sal_uInt16 nHitTest = ImplHitTest( rMEvt.GetPosPixel(), aTempDate );
1425 0 : if ( nHitTest )
1426 : {
1427 0 : if ( nHitTest & CALENDAR_HITTEST_MONTHTITLE )
1428 0 : ImplShowMenu( rMEvt.GetPosPixel(), aTempDate );
1429 : else
1430 : {
1431 0 : maOldFirstDate = maFirstDate;
1432 :
1433 0 : mbPrevIn = (nHitTest & CALENDAR_HITTEST_PREV) != 0;
1434 0 : mbNextIn = (nHitTest & CALENDAR_HITTEST_NEXT) != 0;
1435 0 : if ( mbPrevIn || mbNextIn )
1436 : {
1437 0 : mbSpinDown = true;
1438 0 : mbScrollDateRange = true;
1439 0 : ImplScroll( mbPrevIn );
1440 0 : mbScrollDateRange = false;
1441 : // it should really read BUTTONREPEAT, therefore do not
1442 : // change it to SCROLLREPEAT, check with TH,
1443 : // why it could be different (71775)
1444 0 : StartTracking( STARTTRACK_BUTTONREPEAT );
1445 : }
1446 : else
1447 : {
1448 0 : if ( (rMEvt.GetClicks() == 2) && (nHitTest & CALENDAR_HITTEST_DAY) )
1449 0 : DoubleClick();
1450 : else
1451 : {
1452 0 : if ( mpOldSelectTable )
1453 0 : delete mpOldSelectTable;
1454 0 : maOldCurDate = maCurDate;
1455 0 : mpOldSelectTable = new IntDateSet( *mpSelectTable );
1456 :
1457 0 : if ( !mbSelection )
1458 : {
1459 0 : mbDrag = true;
1460 0 : StartTracking();
1461 : }
1462 :
1463 0 : mbMultiSelection = (mnWinStyle & (WB_MULTISELECT | WB_RANGESELECT)) != 0;
1464 0 : if ( (nHitTest & CALENDAR_HITTEST_DAY) && mbMultiSelection )
1465 0 : mbWeekSel = true;
1466 : else
1467 0 : mbWeekSel = false;
1468 0 : ImplMouseSelect( aTempDate, nHitTest, false, rMEvt.IsShift(), rMEvt.IsMod1() );
1469 : }
1470 : }
1471 : }
1472 : }
1473 :
1474 0 : return;
1475 : }
1476 :
1477 0 : Control::MouseButtonDown( rMEvt );
1478 : }
1479 :
1480 :
1481 :
1482 0 : void Calendar::MouseButtonUp( const MouseEvent& rMEvt )
1483 : {
1484 0 : if ( rMEvt.IsLeft() && mbSelection )
1485 0 : ImplEndTracking( false );
1486 : else
1487 0 : Control::MouseButtonUp( rMEvt );
1488 0 : }
1489 :
1490 :
1491 :
1492 0 : void Calendar::MouseMove( const MouseEvent& rMEvt )
1493 : {
1494 0 : if ( mbSelection && rMEvt.GetButtons() )
1495 0 : ImplTracking( rMEvt.GetPosPixel(), false );
1496 : else
1497 0 : Control::MouseMove( rMEvt );
1498 0 : }
1499 :
1500 :
1501 :
1502 0 : void Calendar::Tracking( const TrackingEvent& rTEvt )
1503 : {
1504 0 : Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel();
1505 :
1506 0 : if ( rTEvt.IsTrackingEnded() )
1507 0 : ImplEndTracking( rTEvt.IsTrackingCanceled() );
1508 : else
1509 0 : ImplTracking( aMousePos, rTEvt.IsTrackingRepeat() );
1510 0 : }
1511 :
1512 :
1513 :
1514 0 : void Calendar::KeyInput( const KeyEvent& rKEvt )
1515 : {
1516 0 : Date aNewDate = maCurDate;
1517 0 : bool bMultiSel = (mnWinStyle & (WB_RANGESELECT | WB_MULTISELECT)) != 0;
1518 0 : bool bExpand = rKEvt.GetKeyCode().IsShift();
1519 0 : bool bExtended = rKEvt.GetKeyCode().IsMod1();
1520 :
1521 0 : switch ( rKEvt.GetKeyCode().GetCode() )
1522 : {
1523 : case KEY_HOME:
1524 0 : aNewDate.SetDay( 1 );
1525 0 : break;
1526 :
1527 : case KEY_END:
1528 0 : aNewDate.SetDay( aNewDate.GetDaysInMonth() );
1529 0 : break;
1530 :
1531 : case KEY_LEFT:
1532 0 : aNewDate--;
1533 0 : break;
1534 :
1535 : case KEY_RIGHT:
1536 0 : aNewDate++;
1537 0 : break;
1538 :
1539 : case KEY_UP:
1540 0 : aNewDate -= 7;
1541 0 : break;
1542 :
1543 : case KEY_DOWN:
1544 0 : aNewDate += 7;
1545 0 : break;
1546 :
1547 : case KEY_PAGEUP:
1548 : {
1549 0 : Date aTempDate = aNewDate;
1550 0 : aTempDate -= aNewDate.GetDay()+1;
1551 0 : aNewDate -= aTempDate.GetDaysInMonth();
1552 : }
1553 0 : break;
1554 :
1555 : case KEY_PAGEDOWN:
1556 0 : aNewDate += aNewDate.GetDaysInMonth();
1557 0 : break;
1558 :
1559 : case KEY_SPACE:
1560 0 : if ( bMultiSel && !(mnWinStyle & WB_RANGESELECT) )
1561 : {
1562 0 : if ( !bExpand )
1563 : {
1564 0 : bool bDateSel = IsDateSelected( maCurDate );
1565 0 : SelectDate( maCurDate, !bDateSel );
1566 0 : mbSelLeft = false;
1567 0 : SelectionChanging();
1568 0 : mbTravelSelect = true;
1569 0 : Select();
1570 0 : mbTravelSelect = false;
1571 0 : }
1572 : }
1573 : else
1574 0 : Control::KeyInput( rKEvt );
1575 0 : break;
1576 :
1577 : default:
1578 0 : Control::KeyInput( rKEvt );
1579 0 : break;
1580 : }
1581 :
1582 0 : if ( aNewDate != maCurDate )
1583 : {
1584 0 : if ( bMultiSel && bExpand )
1585 : {
1586 0 : boost::scoped_ptr<IntDateSet> pOldSel(new IntDateSet( *mpSelectTable ));
1587 0 : Date aOldAnchorDate = maAnchorDate;
1588 0 : mbSelLeft = aNewDate < maAnchorDate;
1589 0 : if ( !bExtended )
1590 : {
1591 0 : if ( mbSelLeft )
1592 : {
1593 0 : ImplCalendarSelectDateRange( mpSelectTable, Date( 1, 1, 0 ), aNewDate, false );
1594 0 : ImplCalendarSelectDateRange( mpSelectTable, maAnchorDate, Date( 31, 12, 9999 ), false );
1595 : }
1596 : else
1597 : {
1598 0 : ImplCalendarSelectDateRange( mpSelectTable, Date( 1, 1, 0 ), maAnchorDate, false );
1599 0 : ImplCalendarSelectDateRange( mpSelectTable, aNewDate, Date( 31, 12, 9999 ), false );
1600 : }
1601 : }
1602 0 : ImplCalendarSelectDateRange( mpSelectTable, aNewDate, maAnchorDate, true );
1603 0 : mbDirect = true;
1604 0 : SetCurDate( aNewDate );
1605 0 : mbDirect = false;
1606 0 : maAnchorDate = aOldAnchorDate;
1607 0 : mbInSelChange = true;
1608 0 : SelectionChanging();
1609 0 : mbInSelChange = false;
1610 0 : ImplUpdateSelection( pOldSel.get() );
1611 : }
1612 : else
1613 : {
1614 0 : if ( mnWinStyle & WB_RANGESELECT )
1615 : {
1616 0 : SetNoSelection();
1617 0 : SelectDate( aNewDate, true );
1618 : }
1619 0 : mbDirect = true;
1620 0 : SetCurDate( aNewDate );
1621 0 : mbDirect = false;
1622 : }
1623 0 : mbTravelSelect = true;
1624 0 : Select();
1625 0 : mbTravelSelect = false;
1626 : }
1627 0 : }
1628 :
1629 :
1630 :
1631 0 : void Calendar::Paint( const Rectangle& )
1632 : {
1633 0 : ImplDraw( true );
1634 0 : }
1635 :
1636 :
1637 :
1638 0 : void Calendar::GetFocus()
1639 : {
1640 0 : ImplUpdateDate( maCurDate );
1641 0 : Control::GetFocus();
1642 0 : }
1643 :
1644 :
1645 :
1646 0 : void Calendar::LoseFocus()
1647 : {
1648 0 : HideFocus();
1649 0 : Control::LoseFocus();
1650 0 : }
1651 :
1652 :
1653 :
1654 0 : void Calendar::Resize()
1655 : {
1656 0 : ImplUpdate( true );
1657 0 : Control::Resize();
1658 0 : }
1659 :
1660 :
1661 :
1662 0 : void Calendar::RequestHelp( const HelpEvent& rHEvt )
1663 : {
1664 0 : if ( rHEvt.GetMode() & (HELPMODE_QUICK | HELPMODE_BALLOON) )
1665 : {
1666 0 : Date aDate = maCurDate;
1667 0 : if ( GetDate( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ), aDate ) )
1668 : {
1669 0 : Rectangle aDateRect = GetDateRect( aDate );
1670 0 : Point aPt = OutputToScreenPixel( aDateRect.TopLeft() );
1671 0 : aDateRect.Left() = aPt.X();
1672 0 : aDateRect.Top() = aPt.Y();
1673 0 : aPt = OutputToScreenPixel( aDateRect.BottomRight() );
1674 0 : aDateRect.Right() = aPt.X();
1675 0 : aDateRect.Bottom() = aPt.Y();
1676 :
1677 0 : if ( rHEvt.GetMode() & HELPMODE_QUICK )
1678 : {
1679 0 : maCalendarWrapper.setGregorianDateTime( aDate);
1680 0 : sal_uInt16 nWeek = (sal_uInt16) maCalendarWrapper.getValue( i18n::CalendarFieldIndex::WEEK_OF_YEAR);
1681 0 : sal_uInt16 nMonth = aDate.GetMonth();
1682 0 : OUString aStr( maDayText );
1683 0 : aStr += ": ";
1684 0 : aStr += OUString::number(aDate.GetDayOfYear());
1685 0 : aStr += " / ";
1686 0 : aStr += maWeekText;
1687 0 : aStr += ": ";
1688 0 : aStr += OUString::number(nWeek);
1689 : // if year is not the same, add it
1690 0 : if ( (nMonth == 12) && (nWeek == 1) )
1691 : {
1692 0 : aStr += ", ";
1693 0 : aStr += OUString::number(aDate.GetYear()+1);
1694 : }
1695 0 : else if ( (nMonth == 1) && (nWeek > 50) )
1696 : {
1697 0 : aStr += ", ";
1698 0 : aStr += OUString::number(aDate.GetYear()-1);
1699 : }
1700 0 : Help::ShowQuickHelp( this, aDateRect, aStr );
1701 0 : return;
1702 : }
1703 : }
1704 : }
1705 :
1706 0 : Control::RequestHelp( rHEvt );
1707 : }
1708 :
1709 :
1710 :
1711 0 : void Calendar::Command( const CommandEvent& rCEvt )
1712 : {
1713 0 : if ( rCEvt.GetCommand() == COMMAND_CONTEXTMENU )
1714 : {
1715 0 : if ( !mbSelection && rCEvt.IsMouseEvent() )
1716 : {
1717 0 : Date aTempDate = maCurDate;
1718 0 : sal_uInt16 nHitTest = ImplHitTest( rCEvt.GetMousePosPixel(), aTempDate );
1719 0 : if ( nHitTest & CALENDAR_HITTEST_MONTHTITLE )
1720 : {
1721 0 : ImplShowMenu( rCEvt.GetMousePosPixel(), aTempDate );
1722 0 : return;
1723 : }
1724 : }
1725 : }
1726 0 : else if ( rCEvt.GetCommand() == COMMAND_WHEEL )
1727 : {
1728 0 : const CommandWheelData* pData = rCEvt.GetWheelData();
1729 0 : if ( pData->GetMode() == CommandWheelMode::SCROLL )
1730 : {
1731 0 : long nNotchDelta = pData->GetNotchDelta();
1732 0 : if ( nNotchDelta < 0 )
1733 : {
1734 0 : while ( nNotchDelta < 0 )
1735 : {
1736 0 : ImplScroll( true );
1737 0 : nNotchDelta++;
1738 : }
1739 : }
1740 : else
1741 : {
1742 0 : while ( nNotchDelta > 0 )
1743 : {
1744 0 : ImplScroll( false );
1745 0 : nNotchDelta--;
1746 : }
1747 : }
1748 :
1749 0 : return;
1750 : }
1751 : }
1752 :
1753 0 : Control::Command( rCEvt );
1754 : }
1755 :
1756 :
1757 :
1758 0 : void Calendar::StateChanged( StateChangedType nType )
1759 : {
1760 0 : Control::StateChanged( nType );
1761 :
1762 0 : if ( nType == StateChangedType::INITSHOW )
1763 0 : ImplFormat();
1764 0 : }
1765 :
1766 :
1767 :
1768 0 : void Calendar::DataChanged( const DataChangedEvent& rDCEvt )
1769 : {
1770 0 : Control::DataChanged( rDCEvt );
1771 :
1772 0 : if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
1773 0 : (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
1774 0 : ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
1775 0 : (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
1776 : {
1777 0 : ImplInitSettings();
1778 0 : Invalidate();
1779 : }
1780 0 : }
1781 :
1782 :
1783 :
1784 0 : void Calendar::SelectionChanging()
1785 : {
1786 0 : maSelectionChangingHdl.Call( this );
1787 0 : }
1788 :
1789 :
1790 :
1791 0 : void Calendar::DateRangeChanged()
1792 : {
1793 0 : maDateRangeChangedHdl.Call( this );
1794 0 : }
1795 :
1796 :
1797 :
1798 0 : void Calendar::RequestDateInfo()
1799 : {
1800 0 : maRequestDateInfoHdl.Call( this );
1801 0 : }
1802 :
1803 :
1804 :
1805 0 : void Calendar::DoubleClick()
1806 : {
1807 0 : maDoubleClickHdl.Call( this );
1808 0 : }
1809 :
1810 :
1811 :
1812 0 : void Calendar::Select()
1813 : {
1814 0 : maSelectHdl.Call( this );
1815 0 : }
1816 :
1817 :
1818 :
1819 0 : void Calendar::SelectDate( const Date& rDate, bool bSelect )
1820 : {
1821 0 : if ( !rDate.IsValidAndGregorian() )
1822 0 : return;
1823 :
1824 0 : boost::scoped_ptr<IntDateSet> pOldSel;
1825 :
1826 0 : if ( !mbInSelChange )
1827 0 : pOldSel.reset(new IntDateSet( *mpSelectTable ));
1828 :
1829 0 : ImplCalendarSelectDate( mpSelectTable, rDate, bSelect );
1830 :
1831 0 : if ( pOldSel )
1832 0 : ImplUpdateSelection( pOldSel.get() );
1833 : }
1834 :
1835 :
1836 :
1837 0 : void Calendar::SetNoSelection()
1838 : {
1839 0 : boost::scoped_ptr<IntDateSet> pOldSel;
1840 :
1841 0 : if ( !mbInSelChange )
1842 0 : pOldSel.reset(new IntDateSet( *mpSelectTable ));
1843 :
1844 0 : ImplCalendarClearSelectDate( mpSelectTable );
1845 :
1846 0 : if ( pOldSel )
1847 0 : ImplUpdateSelection( pOldSel.get() );
1848 0 : }
1849 :
1850 :
1851 :
1852 0 : bool Calendar::IsDateSelected( const Date& rDate ) const
1853 : {
1854 0 : return mpSelectTable->find( rDate.GetDate() ) != mpSelectTable->end();
1855 : }
1856 :
1857 :
1858 :
1859 0 : Date Calendar::GetFirstSelectedDate() const
1860 : {
1861 0 : if ( !mpSelectTable->empty() )
1862 0 : return Date( *mpSelectTable->begin() );
1863 : else
1864 : {
1865 0 : Date aDate( 0, 0, 0 );
1866 0 : return aDate;
1867 : }
1868 : }
1869 :
1870 :
1871 :
1872 0 : void Calendar::SetCurDate( const Date& rNewDate )
1873 : {
1874 0 : if ( !rNewDate.IsValidAndGregorian() )
1875 0 : return;
1876 :
1877 0 : if ( maCurDate != rNewDate )
1878 : {
1879 0 : bool bUpdate = IsVisible() && IsUpdateMode();
1880 0 : Date aOldDate = maCurDate;
1881 0 : maCurDate = rNewDate;
1882 0 : maAnchorDate = maCurDate;
1883 :
1884 0 : if ( !(mnWinStyle & (WB_RANGESELECT | WB_MULTISELECT)) )
1885 : {
1886 0 : ImplCalendarSelectDate( mpSelectTable, aOldDate, false );
1887 0 : ImplCalendarSelectDate( mpSelectTable, maCurDate, true );
1888 : }
1889 0 : else if ( !HasFocus() )
1890 0 : bUpdate = false;
1891 :
1892 : // shift actual date in the visible area
1893 0 : if ( mbFormat || (maCurDate < GetFirstMonth()) )
1894 0 : SetFirstDate( maCurDate );
1895 0 : else if ( maCurDate > GetLastMonth() )
1896 : {
1897 0 : Date aTempDate = GetLastMonth();
1898 0 : long nDateOff = maCurDate-aTempDate;
1899 0 : if ( nDateOff < 365 )
1900 : {
1901 0 : Date aFirstDate = GetFirstMonth();
1902 0 : aFirstDate += aFirstDate.GetDaysInMonth();
1903 0 : aTempDate++;
1904 0 : while ( nDateOff > aTempDate.GetDaysInMonth() )
1905 : {
1906 0 : aFirstDate += aFirstDate.GetDaysInMonth();
1907 0 : long nDaysInMonth = aTempDate.GetDaysInMonth();
1908 0 : aTempDate += nDaysInMonth;
1909 0 : nDateOff -= nDaysInMonth;
1910 : }
1911 0 : SetFirstDate( aFirstDate );
1912 : }
1913 : else
1914 0 : SetFirstDate( maCurDate );
1915 : }
1916 : else
1917 : {
1918 0 : if ( bUpdate )
1919 : {
1920 0 : HideFocus();
1921 0 : ImplUpdateDate( aOldDate );
1922 0 : ImplUpdateDate( maCurDate );
1923 : }
1924 : }
1925 : }
1926 : }
1927 :
1928 :
1929 :
1930 0 : void Calendar::SetFirstDate( const Date& rNewFirstDate )
1931 : {
1932 0 : if ( maFirstDate != rNewFirstDate )
1933 : {
1934 0 : maFirstDate = Date( 1, rNewFirstDate.GetMonth(), rNewFirstDate.GetYear() );
1935 0 : mbDropPos = false;
1936 0 : ImplUpdate();
1937 : }
1938 0 : }
1939 :
1940 :
1941 :
1942 0 : Date Calendar::GetFirstMonth() const
1943 : {
1944 0 : if ( maFirstDate.GetDay() > 1 )
1945 : {
1946 0 : if ( maFirstDate.GetMonth() == 12 )
1947 0 : return Date( 1, 1, maFirstDate.GetYear()+1 );
1948 : else
1949 0 : return Date( 1, maFirstDate.GetMonth()+1, maFirstDate.GetYear() );
1950 : }
1951 : else
1952 0 : return maFirstDate;
1953 : }
1954 :
1955 :
1956 :
1957 0 : Date Calendar::GetLastMonth() const
1958 : {
1959 0 : Date aDate = GetFirstMonth();
1960 0 : sal_uInt16 nMonthCount = GetMonthCount();
1961 0 : for ( sal_uInt16 i = 0; i < nMonthCount; i++ )
1962 0 : aDate += aDate.GetDaysInMonth();
1963 0 : aDate--;
1964 0 : return aDate;
1965 : }
1966 :
1967 :
1968 :
1969 0 : sal_uInt16 Calendar::GetMonthCount() const
1970 : {
1971 0 : if ( mbFormat )
1972 0 : return 1;
1973 : else
1974 0 : return (sal_uInt16)(mnMonthPerLine*mnLines);
1975 : }
1976 :
1977 :
1978 :
1979 0 : bool Calendar::GetDate( const Point& rPos, Date& rDate ) const
1980 : {
1981 0 : Date aDate = maCurDate;
1982 0 : sal_uInt16 nHitTest = ImplHitTest( rPos, aDate );
1983 0 : if ( nHitTest & CALENDAR_HITTEST_DAY )
1984 : {
1985 0 : rDate = aDate;
1986 0 : return true;
1987 : }
1988 : else
1989 0 : return false;
1990 : }
1991 :
1992 :
1993 :
1994 0 : Rectangle Calendar::GetDateRect( const Date& rDate ) const
1995 : {
1996 0 : Rectangle aRect;
1997 :
1998 0 : if ( mbFormat || (rDate < maFirstDate) || (rDate > (maFirstDate+mnDayCount)) )
1999 0 : return aRect;
2000 :
2001 : long nX;
2002 : long nY;
2003 : sal_uLong nDaysOff;
2004 : sal_uInt16 nDayIndex;
2005 0 : Date aDate = GetFirstMonth();
2006 :
2007 0 : if ( rDate < aDate )
2008 : {
2009 0 : aRect = GetDateRect( aDate );
2010 0 : nDaysOff = aDate-rDate;
2011 0 : nX = (long)(nDaysOff*mnDayWidth);
2012 0 : aRect.Left() -= nX;
2013 0 : aRect.Right() -= nX;
2014 0 : return aRect;
2015 : }
2016 : else
2017 : {
2018 0 : Date aLastDate = GetLastMonth();
2019 0 : if ( rDate > aLastDate )
2020 : {
2021 0 : sal_uInt16 nWeekDay = (sal_uInt16)aLastDate.GetDayOfWeek();
2022 0 : nWeekDay = (nWeekDay+(7-(sal_uInt16)ImplGetWeekStart())) % 7;
2023 0 : aLastDate -= nWeekDay;
2024 0 : aRect = GetDateRect( aLastDate );
2025 0 : nDaysOff = rDate-aLastDate;
2026 0 : nDayIndex = 0;
2027 0 : for ( sal_uInt16 i = 0; i <= nDaysOff; i++ )
2028 : {
2029 0 : if ( aLastDate == rDate )
2030 : {
2031 0 : aRect.Left() += nDayIndex*mnDayWidth;
2032 0 : aRect.Right() = aRect.Left()+mnDayWidth;
2033 0 : return aRect;
2034 : }
2035 0 : if ( nDayIndex == 6 )
2036 : {
2037 0 : nDayIndex = 0;
2038 0 : aRect.Top() += mnDayHeight;
2039 0 : aRect.Bottom() += mnDayHeight;
2040 : }
2041 : else
2042 0 : nDayIndex++;
2043 0 : aLastDate++;
2044 : }
2045 : }
2046 : }
2047 :
2048 0 : nY = 0;
2049 0 : for ( long i = 0; i < mnLines; i++ )
2050 : {
2051 0 : nX = 0;
2052 0 : for ( long j = 0; j < mnMonthPerLine; j++ )
2053 : {
2054 0 : sal_uInt16 nDaysInMonth = aDate.GetDaysInMonth();
2055 :
2056 : // month is called
2057 0 : if ( (aDate.GetMonth() == rDate.GetMonth()) &&
2058 0 : (aDate.GetYear() == rDate.GetYear()) )
2059 : {
2060 0 : long nDayX = nX+mnDaysOffX;
2061 0 : long nDayY = nY+mnDaysOffY;
2062 0 : nDayIndex = (sal_uInt16)aDate.GetDayOfWeek();
2063 0 : nDayIndex = (nDayIndex+(7-(sal_uInt16)ImplGetWeekStart())) % 7;
2064 0 : for ( sal_uInt16 nDay = 1; nDay <= nDaysInMonth; nDay++ )
2065 : {
2066 0 : if ( nDay == rDate.GetDay() )
2067 : {
2068 0 : aRect.Left() = nDayX + (nDayIndex*mnDayWidth);
2069 0 : aRect.Top() = nDayY;
2070 0 : aRect.Right() = aRect.Left()+mnDayWidth;
2071 0 : aRect.Bottom() = aRect.Top()+mnDayHeight;
2072 0 : break;
2073 : }
2074 0 : if ( nDayIndex == 6 )
2075 : {
2076 0 : nDayIndex = 0;
2077 0 : nDayY += mnDayHeight;
2078 : }
2079 : else
2080 0 : nDayIndex++;
2081 : }
2082 : }
2083 :
2084 0 : aDate += nDaysInMonth;
2085 0 : nX += mnMonthWidth;
2086 : }
2087 :
2088 0 : nY += mnMonthHeight;
2089 : }
2090 :
2091 0 : return aRect;
2092 : }
2093 :
2094 :
2095 :
2096 0 : void Calendar::StartSelection()
2097 : {
2098 0 : if ( mpOldSelectTable )
2099 0 : delete mpOldSelectTable;
2100 0 : maOldCurDate = maCurDate;
2101 0 : mpOldSelectTable = new IntDateSet( *mpSelectTable );
2102 :
2103 0 : mbSelection = true;
2104 0 : }
2105 :
2106 :
2107 :
2108 0 : void Calendar::EndSelection()
2109 : {
2110 0 : if ( mbDrag || mbSpinDown || mbSelection )
2111 : {
2112 0 : if ( !mbSelection )
2113 0 : ReleaseMouse();
2114 :
2115 0 : mbDrag = false;
2116 0 : mbSelection = false;
2117 0 : mbMultiSelection = false;
2118 0 : mbSpinDown = false;
2119 0 : mbPrevIn = false;
2120 0 : mbNextIn = false;
2121 : }
2122 0 : }
2123 :
2124 :
2125 :
2126 0 : Size Calendar::CalcWindowSizePixel( long nCalcMonthPerLine,
2127 : long nCalcLines ) const
2128 : {
2129 0 : OUString a99Text("99");
2130 0 : vcl::Font aOldFont = GetFont();
2131 :
2132 : // take display of week into account
2133 : long nWeekWidth;
2134 0 : if ( mnWinStyle & WB_WEEKNUMBER )
2135 : {
2136 0 : vcl::Font aTempFont = aOldFont;
2137 0 : ImplGetWeekFont( aTempFont );
2138 0 : ((Calendar*)this)->SetFont( aTempFont );
2139 0 : nWeekWidth = GetTextWidth( a99Text )+WEEKNUMBER_OFFX;
2140 0 : ((Calendar*)this)->SetFont( aOldFont );
2141 : }
2142 : else
2143 0 : nWeekWidth = 0;
2144 :
2145 0 : if ( mnWinStyle & WB_BOLDTEXT )
2146 : {
2147 0 : vcl::Font aFont = aOldFont;
2148 0 : if ( aFont.GetWeight() < WEIGHT_BOLD )
2149 0 : aFont.SetWeight( WEIGHT_BOLD );
2150 : else
2151 0 : aFont.SetWeight( WEIGHT_NORMAL );
2152 0 : ((Calendar*)this)->SetFont( aFont );
2153 : }
2154 :
2155 0 : Size aSize;
2156 0 : long n99TextWidth = GetTextWidth( a99Text );
2157 0 : long nTextHeight = GetTextHeight();
2158 :
2159 0 : if ( mnWinStyle & WB_BOLDTEXT )
2160 0 : ((Calendar*)this)->SetFont( aOldFont );
2161 :
2162 0 : aSize.Width() += ((n99TextWidth+DAY_OFFX)*7) + nWeekWidth;
2163 0 : aSize.Width() += MONTH_BORDERX*2;
2164 0 : aSize.Width() *= nCalcMonthPerLine;
2165 :
2166 0 : aSize.Height() = nTextHeight + TITLE_OFFY + (TITLE_BORDERY*2);
2167 0 : aSize.Height() += nTextHeight + WEEKDAY_OFFY;
2168 0 : aSize.Height() += ((nTextHeight+DAY_OFFY)*6);
2169 0 : aSize.Height() += MONTH_OFFY;
2170 0 : aSize.Height() *= nCalcLines;
2171 :
2172 0 : return aSize;
2173 : }
2174 :
2175 :
2176 :
2177 : #define CALFIELD_EXTRA_BUTTON_WIDTH 14
2178 : #define CALFIELD_EXTRA_BUTTON_HEIGHT 8
2179 : #define CALFIELD_SEP_X 6
2180 : #define CALFIELD_BORDERLINE_X 5
2181 : #define CALFIELD_BORDER_YTOP 4
2182 : #define CALFIELD_BORDER_Y 5
2183 :
2184 :
2185 :
2186 : class ImplCFieldFloatWin : public FloatingWindow
2187 : {
2188 : private:
2189 : Calendar* mpCalendar;
2190 : PushButton* mpTodayBtn;
2191 : PushButton* mpNoneBtn;
2192 : FixedLine* mpFixedLine;
2193 :
2194 : public:
2195 : ImplCFieldFloatWin( vcl::Window* pParent );
2196 : virtual ~ImplCFieldFloatWin();
2197 :
2198 0 : void SetCalendar( Calendar* pCalendar )
2199 0 : { mpCalendar = pCalendar; }
2200 :
2201 : PushButton* EnableTodayBtn( bool bEnable );
2202 : PushButton* EnableNoneBtn( bool bEnable );
2203 : void ArrangeButtons();
2204 :
2205 : virtual bool Notify( NotifyEvent& rNEvt ) SAL_OVERRIDE;
2206 : };
2207 :
2208 :
2209 :
2210 0 : ImplCFieldFloatWin::ImplCFieldFloatWin( vcl::Window* pParent ) :
2211 0 : FloatingWindow( pParent, WB_BORDER | WB_SYSTEMWINDOW | WB_NOSHADOW )
2212 : {
2213 0 : mpCalendar = NULL;
2214 0 : mpTodayBtn = NULL;
2215 0 : mpNoneBtn = NULL;
2216 0 : mpFixedLine = NULL;
2217 0 : }
2218 :
2219 :
2220 :
2221 0 : ImplCFieldFloatWin::~ImplCFieldFloatWin()
2222 : {
2223 0 : delete mpTodayBtn;
2224 0 : delete mpNoneBtn;
2225 0 : delete mpFixedLine;
2226 0 : }
2227 :
2228 :
2229 :
2230 0 : PushButton* ImplCFieldFloatWin::EnableTodayBtn( bool bEnable )
2231 : {
2232 0 : if ( bEnable )
2233 : {
2234 0 : if ( !mpTodayBtn )
2235 : {
2236 0 : mpTodayBtn = new PushButton( this, WB_NOPOINTERFOCUS );
2237 0 : OUString aTodayText(SVT_RESSTR(STR_SVT_CALENDAR_TODAY));
2238 0 : mpTodayBtn->SetText( aTodayText );
2239 0 : Size aSize;
2240 0 : aSize.Width() = mpTodayBtn->GetCtrlTextWidth( mpTodayBtn->GetText() );
2241 0 : aSize.Height() = mpTodayBtn->GetTextHeight();
2242 0 : aSize.Width() += CALFIELD_EXTRA_BUTTON_WIDTH;
2243 0 : aSize.Height() += CALFIELD_EXTRA_BUTTON_HEIGHT;
2244 0 : mpTodayBtn->SetSizePixel( aSize );
2245 0 : mpTodayBtn->Show();
2246 : }
2247 : }
2248 : else
2249 : {
2250 0 : if ( mpTodayBtn )
2251 : {
2252 0 : delete mpTodayBtn;
2253 0 : mpTodayBtn = NULL;
2254 : }
2255 : }
2256 :
2257 0 : return mpTodayBtn;
2258 : }
2259 :
2260 :
2261 :
2262 0 : PushButton* ImplCFieldFloatWin::EnableNoneBtn( bool bEnable )
2263 : {
2264 0 : if ( bEnable )
2265 : {
2266 0 : if ( !mpNoneBtn )
2267 : {
2268 0 : mpNoneBtn = new PushButton( this, WB_NOPOINTERFOCUS );
2269 0 : OUString aNoneText(SVT_RESSTR(STR_SVT_CALENDAR_NONE));
2270 0 : mpNoneBtn->SetText( aNoneText );
2271 0 : Size aSize;
2272 0 : aSize.Width() = mpNoneBtn->GetCtrlTextWidth( mpNoneBtn->GetText() );
2273 0 : aSize.Height() = mpNoneBtn->GetTextHeight();
2274 0 : aSize.Width() += CALFIELD_EXTRA_BUTTON_WIDTH;
2275 0 : aSize.Height() += CALFIELD_EXTRA_BUTTON_HEIGHT;
2276 0 : mpNoneBtn->SetSizePixel( aSize );
2277 0 : mpNoneBtn->Show();
2278 : }
2279 : }
2280 : else
2281 : {
2282 0 : if ( mpNoneBtn )
2283 : {
2284 0 : delete mpNoneBtn;
2285 0 : mpNoneBtn = NULL;
2286 : }
2287 : }
2288 :
2289 0 : return mpNoneBtn;
2290 : }
2291 :
2292 :
2293 :
2294 0 : void ImplCFieldFloatWin::ArrangeButtons()
2295 : {
2296 0 : long nBtnHeight = 0;
2297 0 : long nBtnWidth = 0;
2298 0 : Size aOutSize = GetOutputSizePixel();
2299 0 : if ( mpTodayBtn && mpNoneBtn )
2300 : {
2301 0 : Size aTodayBtnSize = mpTodayBtn->GetSizePixel();
2302 0 : Size aNoneBtnSize = mpNoneBtn->GetSizePixel();
2303 0 : if ( aTodayBtnSize.Width() < aNoneBtnSize.Width() )
2304 0 : aTodayBtnSize.Width() = aNoneBtnSize.Width();
2305 : else
2306 0 : aNoneBtnSize.Width() = aTodayBtnSize.Width();
2307 0 : if ( aTodayBtnSize.Height() < aNoneBtnSize.Height() )
2308 0 : aTodayBtnSize.Height() = aNoneBtnSize.Height();
2309 : else
2310 0 : aNoneBtnSize.Height() = aTodayBtnSize.Height();
2311 :
2312 0 : nBtnWidth = aTodayBtnSize.Width() + aNoneBtnSize.Width() + CALFIELD_SEP_X;
2313 0 : nBtnHeight = aTodayBtnSize.Height();
2314 0 : long nX = (aOutSize.Width()-nBtnWidth)/2;
2315 0 : long nY = aOutSize.Height()+CALFIELD_BORDER_Y+CALFIELD_BORDER_YTOP;
2316 0 : mpTodayBtn->SetPosSizePixel( Point( nX, nY ), aTodayBtnSize );
2317 0 : nX += aTodayBtnSize.Width() + CALFIELD_SEP_X;
2318 0 : mpNoneBtn->SetPosSizePixel( Point( nX, nY ), aNoneBtnSize );
2319 : }
2320 0 : else if ( mpTodayBtn )
2321 : {
2322 0 : Size aTodayBtnSize = mpTodayBtn->GetSizePixel();
2323 0 : nBtnWidth = aTodayBtnSize.Width();
2324 0 : nBtnHeight = aTodayBtnSize.Height();
2325 0 : mpTodayBtn->SetPosPixel( Point( (aOutSize.Width()-nBtnWidth)/2, aOutSize.Height()+CALFIELD_BORDER_Y+CALFIELD_BORDER_YTOP ) );
2326 : }
2327 0 : else if ( mpNoneBtn )
2328 : {
2329 0 : Size aNoneBtnSize = mpNoneBtn->GetSizePixel();
2330 0 : nBtnWidth = aNoneBtnSize.Width();
2331 0 : nBtnHeight = aNoneBtnSize.Height();
2332 0 : mpNoneBtn->SetPosPixel( Point( (aOutSize.Width()-nBtnWidth)/2, aOutSize.Height()+CALFIELD_BORDER_Y+CALFIELD_BORDER_YTOP ) );
2333 : }
2334 :
2335 0 : if ( nBtnHeight )
2336 : {
2337 0 : if ( !mpFixedLine )
2338 : {
2339 0 : mpFixedLine = new FixedLine( this );
2340 0 : mpFixedLine->Show();
2341 : }
2342 0 : long nLineWidth = aOutSize.Width()-(CALFIELD_BORDERLINE_X*2);
2343 0 : mpFixedLine->setPosSizePixel( (aOutSize.Width()-nLineWidth)/2, aOutSize.Height()+((CALFIELD_BORDER_YTOP-2)/2),
2344 0 : nLineWidth, 2, WINDOW_POSSIZE_POSSIZE );
2345 0 : aOutSize.Height() += nBtnHeight + (CALFIELD_BORDER_Y*2) + CALFIELD_BORDER_YTOP;
2346 0 : SetOutputSizePixel( aOutSize );
2347 : }
2348 : else
2349 : {
2350 0 : if ( mpFixedLine )
2351 : {
2352 0 : delete mpFixedLine;
2353 0 : mpFixedLine = NULL;
2354 : }
2355 : }
2356 0 : }
2357 :
2358 :
2359 :
2360 0 : bool ImplCFieldFloatWin::Notify( NotifyEvent& rNEvt )
2361 : {
2362 0 : if ( rNEvt.GetType() == EVENT_KEYINPUT )
2363 : {
2364 0 : const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
2365 0 : if ( pKEvt->GetKeyCode().GetCode() == KEY_RETURN )
2366 0 : mpCalendar->Select();
2367 : }
2368 :
2369 0 : return FloatingWindow::Notify( rNEvt );
2370 : }
2371 :
2372 60 : CalendarField::CalendarField(vcl::Window* pParent, WinBits nWinStyle)
2373 : : DateField(pParent, nWinStyle)
2374 : , mpFloatWin(NULL)
2375 : , mpCalendar(NULL)
2376 : , mnCalendarStyle(0)
2377 : , mpTodayBtn(NULL)
2378 : , mpNoneBtn(NULL)
2379 : , maDefaultDate( 0, 0, 0 )
2380 : , mbToday(false)
2381 60 : , mbNone(false)
2382 : {
2383 60 : }
2384 :
2385 180 : CalendarField::~CalendarField()
2386 : {
2387 60 : if ( mpFloatWin )
2388 : {
2389 0 : delete mpCalendar;
2390 0 : delete mpFloatWin;
2391 : }
2392 120 : }
2393 :
2394 :
2395 :
2396 0 : IMPL_LINK( CalendarField, ImplSelectHdl, Calendar*, pCalendar )
2397 : {
2398 0 : if ( !pCalendar->IsTravelSelect() )
2399 : {
2400 0 : mpFloatWin->EndPopupMode();
2401 0 : EndDropDown();
2402 0 : GrabFocus();
2403 0 : Date aNewDate = mpCalendar->GetFirstSelectedDate();
2404 0 : if ( IsEmptyDate() || ( aNewDate != GetDate() ) )
2405 : {
2406 0 : SetDate( aNewDate );
2407 0 : SetModifyFlag();
2408 0 : Modify();
2409 : }
2410 0 : Select();
2411 : }
2412 0 : return 0;
2413 : }
2414 :
2415 :
2416 :
2417 0 : IMPL_LINK( CalendarField, ImplClickHdl, PushButton*, pBtn )
2418 : {
2419 0 : mpFloatWin->EndPopupMode();
2420 0 : EndDropDown();
2421 0 : GrabFocus();
2422 :
2423 0 : if ( pBtn == mpTodayBtn )
2424 : {
2425 0 : Date aToday( Date::SYSTEM );
2426 0 : if ( (aToday != GetDate()) || IsEmptyDate() )
2427 : {
2428 0 : SetDate( aToday );
2429 0 : SetModifyFlag();
2430 0 : Modify();
2431 : }
2432 : }
2433 0 : else if ( pBtn == mpNoneBtn )
2434 : {
2435 0 : if ( !IsEmptyDate() )
2436 : {
2437 0 : SetEmptyDate();
2438 0 : SetModifyFlag();
2439 0 : Modify();
2440 : }
2441 : }
2442 0 : Select();
2443 :
2444 0 : return 0;
2445 : }
2446 :
2447 :
2448 :
2449 0 : IMPL_LINK_NOARG(CalendarField, ImplPopupModeEndHdl)
2450 : {
2451 0 : EndDropDown();
2452 0 : GrabFocus();
2453 0 : mpCalendar->EndSelection();
2454 0 : return 0;
2455 : }
2456 :
2457 :
2458 :
2459 0 : void CalendarField::Select()
2460 : {
2461 0 : maSelectHdl.Call( this );
2462 0 : }
2463 :
2464 :
2465 :
2466 0 : bool CalendarField::ShowDropDown( bool bShow )
2467 : {
2468 0 : if ( bShow )
2469 : {
2470 0 : Calendar* pCalendar = GetCalendar();
2471 :
2472 0 : Date aDate = GetDate();
2473 0 : if ( IsEmptyDate() || !aDate.IsValidAndGregorian() )
2474 : {
2475 0 : if ( maDefaultDate.IsValidAndGregorian() )
2476 0 : aDate = maDefaultDate;
2477 : else
2478 0 : aDate = Date( Date::SYSTEM );
2479 : }
2480 0 : if ( pCalendar->GetStyle() & (WB_RANGESELECT | WB_MULTISELECT) )
2481 : {
2482 0 : pCalendar->SetNoSelection();
2483 0 : pCalendar->SelectDate( aDate );
2484 : }
2485 0 : pCalendar->SetCurDate( aDate );
2486 0 : Point aPos( GetParent()->OutputToScreenPixel( GetPosPixel() ) );
2487 0 : Rectangle aRect( aPos, GetSizePixel() );
2488 0 : aRect.Bottom() -= 1;
2489 0 : mpCalendar->SetOutputSizePixel( mpCalendar->CalcWindowSizePixel() );
2490 0 : mpFloatWin->SetOutputSizePixel( mpCalendar->GetSizePixel() );
2491 0 : mpFloatWin->SetCalendar( mpCalendar );
2492 0 : mpTodayBtn = mpFloatWin->EnableTodayBtn( mbToday );
2493 0 : mpNoneBtn = mpFloatWin->EnableNoneBtn( mbNone );
2494 0 : if ( mpTodayBtn )
2495 0 : mpTodayBtn->SetClickHdl( LINK( this, CalendarField, ImplClickHdl ) );
2496 0 : if ( mpNoneBtn )
2497 0 : mpNoneBtn->SetClickHdl( LINK( this, CalendarField, ImplClickHdl ) );
2498 0 : mpFloatWin->ArrangeButtons();
2499 0 : mpCalendar->EnableCallEverySelect();
2500 0 : mpCalendar->StartSelection();
2501 0 : mpCalendar->GrabFocus();
2502 0 : mpCalendar->Show();
2503 0 : mpFloatWin->StartPopupMode( aRect, FLOATWIN_POPUPMODE_NOFOCUSCLOSE|FLOATWIN_POPUPMODE_DOWN );
2504 : }
2505 : else
2506 : {
2507 0 : mpFloatWin->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL );
2508 0 : mpCalendar->EndSelection();
2509 0 : EndDropDown();
2510 : }
2511 0 : return true;
2512 : }
2513 :
2514 :
2515 :
2516 0 : Calendar* CalendarField::CreateCalendar( vcl::Window* pParent )
2517 : {
2518 0 : return new Calendar( pParent, mnCalendarStyle | WB_TABSTOP );
2519 : }
2520 :
2521 :
2522 :
2523 0 : Calendar* CalendarField::GetCalendar()
2524 : {
2525 0 : if ( !mpFloatWin )
2526 : {
2527 0 : mpFloatWin = new ImplCFieldFloatWin( this );
2528 0 : mpFloatWin->SetPopupModeEndHdl( LINK( this, CalendarField, ImplPopupModeEndHdl ) );
2529 0 : mpCalendar = CreateCalendar( mpFloatWin );
2530 0 : mpCalendar->SetPosPixel( Point() );
2531 0 : mpCalendar->SetSelectHdl( LINK( this, CalendarField, ImplSelectHdl ) );
2532 : }
2533 :
2534 0 : return mpCalendar;
2535 : }
2536 :
2537 :
2538 :
2539 1156 : void CalendarField::StateChanged( StateChangedType nStateChange )
2540 : {
2541 1156 : DateField::StateChanged( nStateChange );
2542 :
2543 1156 : if ( ( nStateChange == StateChangedType::STYLE ) && GetSubEdit() )
2544 : {
2545 148 : WinBits nAllAlignmentBits = ( WB_LEFT | WB_CENTER | WB_RIGHT | WB_TOP | WB_VCENTER | WB_BOTTOM );
2546 148 : WinBits nMyAlignment = GetStyle() & nAllAlignmentBits;
2547 148 : GetSubEdit()->SetStyle( ( GetSubEdit()->GetStyle() & ~nAllAlignmentBits ) | nMyAlignment );
2548 : }
2549 2383 : }
2550 :
2551 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|