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