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