1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_svtools.hxx" 30 31 #define _SV_HEADBAR_CXX 32 #include <svtools/headbar.hxx> 33 #include <tools/debug.hxx> 34 #ifndef _TOOLS_LIST_HXX 35 #include <tools/list.hxx> 36 #endif 37 38 #ifndef _VCL_APP_HXX 39 #include <vcl/svapp.hxx> 40 #endif 41 #ifndef _VCL_HELP_HXX 42 #include <vcl/help.hxx> 43 #endif 44 #ifndef _VCL_IMAGE_HXX 45 #include <vcl/image.hxx> 46 #endif 47 #include <com/sun/star/accessibility/XAccessible.hpp> 48 49 // ======================================================================= 50 51 struct ImplHeadItem 52 { 53 sal_uInt16 mnId; 54 HeaderBarItemBits mnBits; 55 long mnSize; 56 rtl::OString maHelpId; 57 Image maImage; 58 XubString maOutText; 59 XubString maText; 60 XubString maHelpText; 61 void* mpUserData; 62 }; 63 64 DECLARE_LIST( ImplHeadItemList, ImplHeadItem* ) 65 66 // ======================================================================= 67 68 #define HEAD_ARROWSIZE1 4 69 #define HEAD_ARROWSIZE2 7 70 71 #define HEADERBAR_TEXTOFF 2 72 #define HEADERBAR_ARROWOFF 5 73 #define HEADERBAR_SPLITOFF 3 74 75 #define HEADERBAR_DRAGOFF 4 76 #define HEADERBAR_DRAGOUTOFF 15 77 78 #define HEAD_HITTEST_ITEM ((sal_uInt16)0x0001) 79 #define HEAD_HITTEST_DIVIDER ((sal_uInt16)0x0002) 80 81 // ======================================================================= 82 83 void HeaderBar::ImplInit( WinBits nWinStyle ) 84 { 85 mpItemList = new ImplHeadItemList; 86 mnBorderOff1 = 0; 87 mnBorderOff2 = 0; 88 mnOffset = 0; 89 mnDX = 0; 90 mnDY = 0; 91 mnDragSize = 0; 92 mnStartPos = 0; 93 mnDragPos = 0; 94 mnMouseOff = 0; 95 mnCurItemId = 0; 96 mnItemDragPos = HEADERBAR_ITEM_NOTFOUND; 97 mbDrag = sal_False; 98 mbItemDrag = sal_False; 99 mbOutDrag = sal_False; 100 mbItemMode = sal_False; 101 102 // StyleBits auswerten 103 if ( nWinStyle & WB_DRAG ) 104 mbDragable = sal_True; 105 else 106 mbDragable = sal_False; 107 if ( nWinStyle & WB_BUTTONSTYLE ) 108 mbButtonStyle = sal_True; 109 else 110 mbButtonStyle = sal_False; 111 if ( nWinStyle & WB_BORDER ) 112 { 113 mnBorderOff1 = 1; 114 mnBorderOff2 = 1; 115 } 116 else 117 { 118 if ( nWinStyle & WB_BOTTOMBORDER ) 119 mnBorderOff2 = 1; 120 } 121 122 ImplInitSettings( sal_True, sal_True, sal_True ); 123 } 124 125 // ----------------------------------------------------------------------- 126 127 HeaderBar::HeaderBar( Window* pParent, WinBits nWinStyle ) : 128 Window( pParent, nWinStyle & WB_3DLOOK ) 129 { 130 ImplInit( nWinStyle ); 131 SetSizePixel( CalcWindowSizePixel() ); 132 } 133 134 // ----------------------------------------------------------------------- 135 136 HeaderBar::HeaderBar( Window* pParent, const ResId& rResId ) : 137 Window( pParent, rResId ) 138 { 139 ImplInit( rResId.GetWinBits() ); 140 } 141 142 // ----------------------------------------------------------------------- 143 144 HeaderBar::~HeaderBar() 145 { 146 // Alle Items loeschen 147 ImplHeadItem* pItem = mpItemList->First(); 148 while ( pItem ) 149 { 150 delete pItem; 151 pItem = mpItemList->Next(); 152 } 153 154 delete mpItemList; 155 } 156 157 // ----------------------------------------------------------------------- 158 159 void HeaderBar::ImplInitSettings( sal_Bool bFont, 160 sal_Bool bForeground, sal_Bool bBackground ) 161 { 162 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); 163 164 if ( bFont ) 165 { 166 Font aFont; 167 aFont = rStyleSettings.GetToolFont(); 168 if ( IsControlFont() ) 169 aFont.Merge( GetControlFont() ); 170 SetZoomedPointFont( aFont ); 171 } 172 173 if ( bForeground || bFont ) 174 { 175 Color aColor; 176 if ( IsControlForeground() ) 177 aColor = GetControlForeground(); 178 else 179 aColor = rStyleSettings.GetButtonTextColor(); 180 SetTextColor( aColor ); 181 SetTextFillColor(); 182 } 183 184 if ( bBackground ) 185 { 186 Color aColor; 187 if ( IsControlBackground() ) 188 aColor = GetControlBackground(); 189 else 190 aColor = rStyleSettings.GetFaceColor(); 191 SetBackground( aColor ); 192 } 193 } 194 195 // ----------------------------------------------------------------------- 196 197 long HeaderBar::ImplGetItemPos( sal_uInt16 nPos ) const 198 { 199 long nX = -mnOffset; 200 for ( sal_uInt16 i = 0; i < nPos; i++ ) 201 nX += mpItemList->GetObject( i )->mnSize; 202 return nX; 203 } 204 205 // ----------------------------------------------------------------------- 206 207 Rectangle HeaderBar::ImplGetItemRect( sal_uInt16 nPos ) const 208 { 209 Rectangle aRect( ImplGetItemPos( nPos ), 0, 0, mnDY-1 ); 210 aRect.Right() = aRect.Left() + mpItemList->GetObject( nPos )->mnSize - 1; 211 // Gegen Ueberlauf auf einigen Systemen testen 212 if ( aRect.Right() > 16000 ) 213 aRect.Right() = 16000; 214 return aRect; 215 } 216 217 // ----------------------------------------------------------------------- 218 219 sal_uInt16 HeaderBar::ImplHitTest( const Point& rPos, 220 long& nMouseOff, sal_uInt16& nPos ) const 221 { 222 ImplHeadItem* pItem; 223 sal_uInt16 nCount = (sal_uInt16)mpItemList->Count(); 224 sal_Bool bLastFixed = sal_True; 225 long nX = -mnOffset; 226 227 for ( sal_uInt16 i = 0; i < nCount; i++ ) 228 { 229 pItem = mpItemList->GetObject( i ); 230 231 if ( rPos.X() < (nX+pItem->mnSize) ) 232 { 233 sal_uInt16 nMode; 234 235 if ( !bLastFixed && (rPos.X() < (nX+HEADERBAR_SPLITOFF)) ) 236 { 237 nMode = HEAD_HITTEST_DIVIDER; 238 nPos = i-1; 239 nMouseOff = rPos.X()-nX+1; 240 } 241 else 242 { 243 nPos = i; 244 245 if ( !(pItem->mnBits & HIB_FIXED) && (rPos.X() >= (nX+pItem->mnSize-HEADERBAR_SPLITOFF)) ) 246 { 247 nMode = HEAD_HITTEST_DIVIDER; 248 nMouseOff = rPos.X()-(nX+pItem->mnSize); 249 } 250 else 251 { 252 nMode = HEAD_HITTEST_ITEM; 253 nMouseOff = rPos.X()-nX; 254 } 255 } 256 257 return nMode; 258 } 259 260 if ( pItem->mnBits & HIB_FIXED ) 261 bLastFixed = sal_True; 262 else 263 bLastFixed = sal_False; 264 265 nX += pItem->mnSize; 266 } 267 268 if ( !bLastFixed ) 269 { 270 pItem = mpItemList->GetObject( nCount-1 ); 271 if ( (pItem->mnSize < 4) && (rPos.X() < (nX+HEADERBAR_SPLITOFF)) ) 272 { 273 nPos = nCount-1; 274 nMouseOff = rPos.X()-nX+1; 275 return HEAD_HITTEST_DIVIDER; 276 } 277 } 278 279 return 0; 280 } 281 282 // ----------------------------------------------------------------------- 283 284 void HeaderBar::ImplInvertDrag( sal_uInt16 nStartPos, sal_uInt16 nEndPos ) 285 { 286 Rectangle aRect1 = ImplGetItemRect( nStartPos ); 287 Rectangle aRect2 = ImplGetItemRect( nEndPos ); 288 Point aStartPos = aRect1.Center(); 289 Point aEndPos = aStartPos; 290 Rectangle aStartRect( aStartPos.X()-2, aStartPos.Y()-2, 291 aStartPos.X()+2, aStartPos.Y()+2 ); 292 293 if ( nEndPos > nStartPos ) 294 { 295 aStartPos.X() += 3; 296 aEndPos.X() = aRect2.Right()-6; 297 } 298 else 299 { 300 aStartPos.X() -= 3; 301 aEndPos.X() = aRect2.Left()+6; 302 } 303 304 SetRasterOp( ROP_INVERT ); 305 DrawRect( aStartRect ); 306 DrawLine( aStartPos, aEndPos ); 307 if ( nEndPos > nStartPos ) 308 { 309 DrawLine( Point( aEndPos.X()+1, aEndPos.Y()-3 ), 310 Point( aEndPos.X()+1, aEndPos.Y()+3 ) ); 311 DrawLine( Point( aEndPos.X()+2, aEndPos.Y()-2 ), 312 Point( aEndPos.X()+2, aEndPos.Y()+2 ) ); 313 DrawLine( Point( aEndPos.X()+3, aEndPos.Y()-1 ), 314 Point( aEndPos.X()+3, aEndPos.Y()+1 ) ); 315 DrawPixel( Point( aEndPos.X()+4, aEndPos.Y() ) ); 316 } 317 else 318 { 319 DrawLine( Point( aEndPos.X()-1, aEndPos.Y()-3 ), 320 Point( aEndPos.X()-1, aEndPos.Y()+3 ) ); 321 DrawLine( Point( aEndPos.X()-2, aEndPos.Y()-2 ), 322 Point( aEndPos.X()-2, aEndPos.Y()+2 ) ); 323 DrawLine( Point( aEndPos.X()-3, aEndPos.Y()-1 ), 324 Point( aEndPos.X()-3, aEndPos.Y()+1 ) ); 325 DrawPixel( Point( aEndPos.X()-4, aEndPos.Y() ) ); 326 } 327 SetRasterOp( ROP_OVERPAINT ); 328 } 329 330 // ----------------------------------------------------------------------- 331 332 void HeaderBar::ImplDrawItem( OutputDevice* pDev, 333 sal_uInt16 nPos, sal_Bool bHigh, sal_Bool bDrag, 334 const Rectangle& rItemRect, 335 const Rectangle* pRect, 336 sal_uLong ) 337 { 338 Rectangle aRect = rItemRect; 339 340 // Wenn kein Platz, dann brauchen wir auch nichts ausgeben 341 if ( aRect.GetWidth() <= 1 ) 342 return; 343 344 // Feststellen, ob Rectangle ueberhaupt sichtbar 345 if ( pRect ) 346 { 347 if ( aRect.Right() < pRect->Left() ) 348 return; 349 else if ( aRect.Left() > pRect->Right() ) 350 return; 351 } 352 else 353 { 354 if ( aRect.Right() < 0 ) 355 return; 356 else if ( aRect.Left() > mnDX ) 357 return; 358 } 359 360 ImplHeadItem* pItem = mpItemList->GetObject( nPos ); 361 HeaderBarItemBits nBits = pItem->mnBits; 362 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); 363 364 // Border muss nicht gemalt werden 365 aRect.Top() += mnBorderOff1; 366 aRect.Bottom() -= mnBorderOff2; 367 368 // Hintergrund loeschen 369 if ( !pRect || bDrag ) 370 { 371 if ( bDrag ) 372 { 373 pDev->SetLineColor(); 374 pDev->SetFillColor( rStyleSettings.GetCheckedColor() ); 375 pDev->DrawRect( aRect ); 376 } 377 else 378 pDev->DrawWallpaper( aRect, GetBackground() ); 379 } 380 381 // Trennlinie malen 382 pDev->SetLineColor( rStyleSettings.GetDarkShadowColor() ); 383 pDev->DrawLine( Point( aRect.Right(), aRect.Top() ), 384 Point( aRect.Right(), aRect.Bottom() ) ); 385 386 // ButtonStyle malen 387 // avoid 3D borders 388 Color aSelectionTextColor( COL_TRANSPARENT ); 389 if( bHigh ) 390 DrawSelectionBackground( aRect, 1, sal_True, sal_False, sal_False, &aSelectionTextColor ); 391 else if ( !mbButtonStyle || (nBits & HIB_FLAT) ) 392 DrawSelectionBackground( aRect, 0, sal_True, sal_False, sal_False, &aSelectionTextColor ); 393 394 // Wenn kein Platz, dann brauchen wir auch nichts ausgeben 395 if ( aRect.GetWidth() < 1 ) 396 return; 397 398 // Positionen und Groessen berechnen und Inhalt ausgeben 399 pItem->maOutText = pItem->maText; 400 Size aImageSize = pItem->maImage.GetSizePixel(); 401 Size aTxtSize( pDev->GetTextWidth( pItem->maOutText ), 0 ); 402 if ( pItem->maOutText.Len() ) 403 aTxtSize.Height() = pDev->GetTextHeight(); 404 long nArrowWidth = 0; 405 if ( nBits & (HIB_UPARROW | HIB_DOWNARROW) ) 406 nArrowWidth = HEAD_ARROWSIZE2+HEADERBAR_ARROWOFF; 407 408 // Wenn kein Platz fuer Image, dann nicht ausgeben 409 long nTestHeight = aImageSize.Height(); 410 if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) ) 411 nTestHeight += aTxtSize.Height(); 412 if ( (aImageSize.Width() > aRect.GetWidth()) || (nTestHeight > aRect.GetHeight()) ) 413 { 414 aImageSize.Width() = 0; 415 aImageSize.Height() = 0; 416 } 417 418 // Text auf entsprechende Laenge kuerzen 419 sal_Bool bLeftText = sal_False; 420 long nMaxTxtWidth = aRect.GetWidth()-(HEADERBAR_TEXTOFF*2)-nArrowWidth; 421 if ( nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE) ) 422 nMaxTxtWidth -= aImageSize.Width(); 423 long nTxtWidth = aTxtSize.Width(); 424 if ( nTxtWidth > nMaxTxtWidth ) 425 { 426 bLeftText = sal_True; 427 // 3 == Len of "..." 428 pItem->maOutText.AppendAscii( "..." ); 429 do 430 { 431 pItem->maOutText.Erase( pItem->maOutText.Len()-3-1, 1 ); 432 nTxtWidth = pDev->GetTextWidth( pItem->maOutText ); 433 } 434 while ( (nTxtWidth > nMaxTxtWidth) && (pItem->maOutText.Len() > 3) ); 435 if ( pItem->maOutText.Len() == 3 ) 436 { 437 nTxtWidth = 0; 438 pItem->maOutText.Erase(); 439 } 440 } 441 442 // Text/Imageposition berechnen 443 long nTxtPos; 444 if ( !bLeftText && (nBits & HIB_RIGHT) ) 445 { 446 nTxtPos = aRect.Right()-nTxtWidth-HEADERBAR_TEXTOFF; 447 if ( nBits & HIB_RIGHTIMAGE ) 448 nTxtPos -= aImageSize.Width(); 449 } 450 else if ( !bLeftText && (nBits & HIB_CENTER) ) 451 { 452 long nTempWidth = nTxtWidth; 453 if ( nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE) ) 454 nTempWidth += aImageSize.Width(); 455 nTxtPos = aRect.Left()+(aRect.GetWidth()-nTempWidth)/2; 456 if ( nBits & HIB_LEFTIMAGE ) 457 nTxtPos += aImageSize.Width(); 458 if ( nArrowWidth ) 459 { 460 if ( nTxtPos+nTxtWidth+nArrowWidth >= aRect.Right() ) 461 { 462 nTxtPos = aRect.Left()+HEADERBAR_TEXTOFF; 463 if ( nBits & HIB_LEFTIMAGE ) 464 nTxtPos += aImageSize.Width(); 465 } 466 } 467 } 468 else 469 { 470 nTxtPos = aRect.Left()+HEADERBAR_TEXTOFF; 471 if ( nBits & HIB_LEFTIMAGE ) 472 nTxtPos += aImageSize.Width(); 473 if ( nBits & HIB_RIGHT ) 474 nTxtPos += nArrowWidth; 475 } 476 477 // TextPosition berechnen 478 long nTxtPosY = 0; 479 if ( pItem->maOutText.Len() || (nArrowWidth && aTxtSize.Height()) ) 480 { 481 if ( nBits & HIB_TOP ) 482 { 483 nTxtPosY = aRect.Top(); 484 if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) ) 485 nTxtPosY += aImageSize.Height(); 486 } 487 else if ( nBits & HIB_BOTTOM ) 488 nTxtPosY = aRect.Bottom()-aTxtSize.Height(); 489 else 490 { 491 long nTempHeight = aTxtSize.Height(); 492 if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) ) 493 nTempHeight += aImageSize.Height(); 494 nTxtPosY = aRect.Top()+((aRect.GetHeight()-nTempHeight)/2); 495 if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) ) 496 nTxtPosY += aImageSize.Height(); 497 } 498 } 499 500 // Text ausgebeben 501 if ( pItem->maOutText.Len() ) 502 { 503 if( aSelectionTextColor != Color( COL_TRANSPARENT ) ) 504 { 505 pDev->Push( PUSH_TEXTCOLOR ); 506 pDev->SetTextColor( aSelectionTextColor ); 507 } 508 if ( IsEnabled() ) 509 pDev->DrawText( Point( nTxtPos, nTxtPosY ), pItem->maOutText ); 510 else 511 pDev->DrawCtrlText( Point( nTxtPos, nTxtPosY ), pItem->maOutText, 0, STRING_LEN, TEXT_DRAW_DISABLE ); 512 if( aSelectionTextColor != Color( COL_TRANSPARENT ) ) 513 pDev->Pop(); 514 } 515 516 // Wenn Image vorhanden, Position berechnen und ausgeben 517 long nImagePosY = 0; 518 if ( aImageSize.Width() && aImageSize.Height() ) 519 { 520 long nImagePos = nTxtPos; 521 if ( nBits & HIB_LEFTIMAGE ) 522 { 523 nImagePos -= aImageSize.Width(); 524 if ( nBits & HIB_RIGHT ) 525 nImagePos -= nArrowWidth; 526 } 527 else if ( nBits & HIB_RIGHTIMAGE ) 528 { 529 nImagePos += nTxtWidth; 530 if ( !(nBits & HIB_RIGHT) ) 531 nImagePos += nArrowWidth; 532 } 533 else 534 { 535 if ( nBits & HIB_RIGHT ) 536 nImagePos = aRect.Right()-aImageSize.Width(); 537 else if ( nBits & HIB_CENTER ) 538 nImagePos = aRect.Left()+(aRect.GetWidth()-aImageSize.Width())/2; 539 else 540 nImagePos = aRect.Left()+HEADERBAR_TEXTOFF; 541 } 542 543 if ( nBits & HIB_TOP ) 544 nImagePosY = aRect.Top(); 545 else if ( nBits & HIB_BOTTOM ) 546 { 547 nImagePosY = aRect.Bottom()-aImageSize.Height(); 548 if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) ) 549 nImagePosY -= aTxtSize.Height(); 550 } 551 else 552 { 553 long nTempHeight = aImageSize.Height(); 554 if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) ) 555 nTempHeight += aTxtSize.Height(); 556 nImagePosY = aRect.Top()+((aRect.GetHeight()-nTempHeight)/2); 557 } 558 if ( nImagePos+aImageSize.Width() <= aRect.Right() ) 559 { 560 sal_uInt16 nStyle = 0; 561 if ( !IsEnabled() ) 562 nStyle |= IMAGE_DRAW_DISABLE; 563 pDev->DrawImage( Point( nImagePos, nImagePosY ), pItem->maImage, nStyle ); 564 } 565 } 566 567 if ( nBits & (HIB_UPARROW | HIB_DOWNARROW) ) 568 { 569 long nArrowX = nTxtPos; 570 if ( nBits & HIB_RIGHT ) 571 nArrowX -= nArrowWidth; 572 else 573 nArrowX += nTxtWidth+HEADERBAR_ARROWOFF; 574 if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) && !pItem->maText.Len() ) 575 { 576 if ( nBits & HIB_RIGHT ) 577 nArrowX -= aImageSize.Width(); 578 else 579 nArrowX += aImageSize.Width(); 580 } 581 582 // Feststellen, ob Platz genug ist, das Item zu malen 583 sal_Bool bDraw = sal_True; 584 if ( nArrowX < aRect.Left()+HEADERBAR_TEXTOFF ) 585 bDraw = sal_False; 586 else if ( nArrowX+HEAD_ARROWSIZE2 > aRect.Right() ) 587 bDraw = sal_False; 588 589 if ( bDraw ) 590 { 591 long nArrowY; 592 if ( aTxtSize.Height() ) 593 nArrowY = nTxtPosY+(aTxtSize.Height()/2); 594 else if ( aImageSize.Width() && aImageSize.Height() ) 595 nArrowY = nImagePosY+(aImageSize.Height()/2); 596 else 597 { 598 if ( nBits & HIB_TOP ) 599 nArrowY = aRect.Top()+1; 600 else if ( nBits & HIB_BOTTOM ) 601 nArrowY = aRect.Bottom()-HEAD_ARROWSIZE2-1; 602 else 603 nArrowY = aRect.Top()+((aRect.GetHeight()-HEAD_ARROWSIZE2)/2);; 604 } 605 nArrowY -= HEAD_ARROWSIZE1-1; 606 if ( nBits & HIB_DOWNARROW ) 607 { 608 pDev->SetLineColor( rStyleSettings.GetLightColor() ); 609 pDev->DrawLine( Point( nArrowX, nArrowY ), 610 Point( nArrowX+HEAD_ARROWSIZE2, nArrowY ) ); 611 pDev->DrawLine( Point( nArrowX, nArrowY ), 612 Point( nArrowX+HEAD_ARROWSIZE1, nArrowY+HEAD_ARROWSIZE2 ) ); 613 pDev->SetLineColor( rStyleSettings.GetShadowColor() ); 614 pDev->DrawLine( Point( nArrowX+HEAD_ARROWSIZE1, nArrowY+HEAD_ARROWSIZE2 ), 615 Point( nArrowX+HEAD_ARROWSIZE2, nArrowY ) ); 616 } 617 else 618 { 619 pDev->SetLineColor( rStyleSettings.GetLightColor() ); 620 pDev->DrawLine( Point( nArrowX, nArrowY+HEAD_ARROWSIZE2 ), 621 Point( nArrowX+HEAD_ARROWSIZE1, nArrowY ) ); 622 pDev->SetLineColor( rStyleSettings.GetShadowColor() ); 623 pDev->DrawLine( Point( nArrowX, nArrowY+HEAD_ARROWSIZE2 ), 624 Point( nArrowX+HEAD_ARROWSIZE2, nArrowY+HEAD_ARROWSIZE2 ) ); 625 pDev->DrawLine( Point( nArrowX+HEAD_ARROWSIZE2, nArrowY+HEAD_ARROWSIZE2 ), 626 Point( nArrowX+HEAD_ARROWSIZE1, nArrowY ) ); 627 } 628 } 629 } 630 631 // Gegebenenfalls auch UserDraw aufrufen 632 if ( nBits & HIB_USERDRAW ) 633 { 634 Region aRegion( aRect ); 635 if ( pRect ) 636 aRegion.Intersect( *pRect ); 637 pDev->SetClipRegion( aRegion ); 638 UserDrawEvent aODEvt( pDev, aRect, pItem->mnId ); 639 UserDraw( aODEvt ); 640 pDev->SetClipRegion(); 641 } 642 } 643 644 // ----------------------------------------------------------------------- 645 646 void HeaderBar::ImplDrawItem( sal_uInt16 nPos, sal_Bool bHigh, sal_Bool bDrag, 647 const Rectangle* pRect ) 648 { 649 Rectangle aRect = ImplGetItemRect( nPos ); 650 ImplDrawItem( this, nPos, bHigh, bDrag, aRect, pRect, 0 ); 651 } 652 653 // ----------------------------------------------------------------------- 654 655 void HeaderBar::ImplUpdate( sal_uInt16 nPos, sal_Bool bEnd, sal_Bool bDirect ) 656 { 657 if ( IsVisible() && IsUpdateMode() ) 658 { 659 if ( !bDirect ) 660 { 661 Rectangle aRect; 662 sal_uInt16 nItemCount = (sal_uInt16)(mpItemList->Count()); 663 if ( nPos < nItemCount ) 664 aRect = ImplGetItemRect( nPos ); 665 else 666 { 667 aRect.Bottom() = mnDY-1; 668 if ( nItemCount ) 669 aRect.Left() = ImplGetItemRect( nItemCount-1 ).Right(); 670 } 671 if ( bEnd ) 672 aRect.Right() = mnDX-1; 673 aRect.Top() += mnBorderOff1; 674 aRect.Bottom() -= mnBorderOff2; 675 Invalidate( aRect ); 676 } 677 else 678 { 679 for ( sal_uInt16 i = nPos; i < mpItemList->Count(); i++ ) 680 ImplDrawItem( i ); 681 if ( bEnd ) 682 { 683 Rectangle aRect = ImplGetItemRect( (sal_uInt16)mpItemList->Count() ); 684 aRect.Left() = aRect.Right(); 685 aRect.Right() = mnDX-1; 686 if ( aRect.Left() < aRect.Right() ) 687 { 688 aRect.Top() += mnBorderOff1; 689 aRect.Bottom() -= mnBorderOff2; 690 Erase( aRect ); 691 } 692 } 693 } 694 } 695 } 696 697 // ----------------------------------------------------------------------- 698 699 void HeaderBar::ImplStartDrag( const Point& rMousePos, sal_Bool bCommand ) 700 { 701 sal_uInt16 nPos; 702 sal_uInt16 nHitTest = ImplHitTest( rMousePos, mnMouseOff, nPos ); 703 if ( nHitTest ) 704 { 705 mbDrag = sal_False; 706 ImplHeadItem* pItem = mpItemList->GetObject( nPos ); 707 if ( nHitTest & HEAD_HITTEST_DIVIDER ) 708 mbDrag = sal_True; 709 else 710 { 711 if ( ((pItem->mnBits & HIB_CLICKABLE) && !(pItem->mnBits & HIB_FLAT)) || 712 (mbDragable && !(pItem->mnBits & HIB_FIXEDPOS)) ) 713 { 714 mbItemMode = sal_True; 715 mbDrag = sal_True; 716 if ( bCommand ) 717 { 718 if ( mbDragable ) 719 mbItemDrag = sal_True; 720 else 721 { 722 mbItemMode = sal_False; 723 mbDrag = sal_False; 724 } 725 } 726 } 727 else 728 { 729 if ( !bCommand ) 730 { 731 mnCurItemId = pItem->mnId; 732 Select(); 733 mnCurItemId = 0; 734 } 735 } 736 } 737 738 if ( mbDrag ) 739 { 740 mbOutDrag = sal_False; 741 mnCurItemId = pItem->mnId; 742 mnItemDragPos = nPos; 743 StartTracking(); 744 mnStartPos = rMousePos.X()-mnMouseOff; 745 mnDragPos = mnStartPos; 746 StartDrag(); 747 if ( mbItemMode ) 748 ImplDrawItem( nPos, sal_True, mbItemDrag ); 749 else 750 { 751 Rectangle aSizeRect( mnDragPos, 0, mnDragPos, mnDragSize+mnDY ); 752 ShowTracking( aSizeRect, SHOWTRACK_SPLIT ); 753 } 754 } 755 else 756 mnMouseOff = 0; 757 } 758 } 759 760 // ----------------------------------------------------------------------- 761 762 void HeaderBar::ImplDrag( const Point& rMousePos ) 763 { 764 sal_Bool bNewOutDrag; 765 sal_uInt16 nPos = GetItemPos( mnCurItemId ); 766 767 mnDragPos = rMousePos.X()-mnMouseOff; 768 if ( mbItemMode ) 769 { 770 Rectangle aItemRect = ImplGetItemRect( nPos ); 771 if ( aItemRect.IsInside( rMousePos ) ) 772 bNewOutDrag = sal_False; 773 else 774 bNewOutDrag = sal_True; 775 776 // Evt. ItemDrag anschalten 777 if ( bNewOutDrag && mbDragable && !mbItemDrag && 778 !(mpItemList->GetObject(nPos)->mnBits & HIB_FIXEDPOS) ) 779 { 780 if ( (rMousePos.Y() >= aItemRect.Top()) && (rMousePos.Y() <= aItemRect.Bottom()) ) 781 { 782 mbItemDrag = sal_True; 783 ImplDrawItem( nPos, sal_True, mbItemDrag ); 784 } 785 } 786 787 sal_uInt16 nOldItemDragPos = mnItemDragPos; 788 if ( mbItemDrag ) 789 { 790 if ( (rMousePos.Y() < -HEADERBAR_DRAGOUTOFF) || (rMousePos.Y() > mnDY+HEADERBAR_DRAGOUTOFF) ) 791 bNewOutDrag = sal_True; 792 else 793 bNewOutDrag = sal_False; 794 795 if ( bNewOutDrag ) 796 mnItemDragPos = HEADERBAR_ITEM_NOTFOUND; 797 else 798 { 799 sal_uInt16 nTempId = GetItemId( Point( rMousePos.X(), 2 ) ); 800 if ( nTempId ) 801 mnItemDragPos = GetItemPos( nTempId ); 802 else 803 { 804 if ( rMousePos.X() <= 0 ) 805 mnItemDragPos = 0; 806 else 807 mnItemDragPos = GetItemCount()-1; 808 } 809 810 // Nicht verschiebbare Items aussparen 811 if ( mnItemDragPos < nPos ) 812 { 813 while ( (mpItemList->GetObject(mnItemDragPos)->mnBits & HIB_FIXEDPOS) && 814 (mnItemDragPos < nPos) ) 815 mnItemDragPos++; 816 } 817 else if ( mnItemDragPos > nPos ) 818 { 819 while ( (mpItemList->GetObject(mnItemDragPos)->mnBits & HIB_FIXEDPOS) && 820 (mnItemDragPos > nPos) ) 821 mnItemDragPos--; 822 } 823 } 824 825 if ( (mnItemDragPos != nOldItemDragPos) && 826 (nOldItemDragPos != nPos) && 827 (nOldItemDragPos != HEADERBAR_ITEM_NOTFOUND) ) 828 { 829 ImplInvertDrag( nPos, nOldItemDragPos ); 830 ImplDrawItem( nOldItemDragPos ); 831 } 832 } 833 834 if ( bNewOutDrag != mbOutDrag ) 835 ImplDrawItem( nPos, !bNewOutDrag, mbItemDrag ); 836 837 if ( mbItemDrag ) 838 { 839 if ( (mnItemDragPos != nOldItemDragPos) && 840 (mnItemDragPos != nPos) && 841 (mnItemDragPos != HEADERBAR_ITEM_NOTFOUND) ) 842 { 843 ImplDrawItem( mnItemDragPos, sal_False, sal_True ); 844 ImplInvertDrag( nPos, mnItemDragPos ); 845 } 846 } 847 848 mbOutDrag = bNewOutDrag; 849 } 850 else 851 { 852 Rectangle aItemRect = ImplGetItemRect( nPos ); 853 if ( mnDragPos < aItemRect.Left() ) 854 mnDragPos = aItemRect.Left(); 855 if ( (mnDragPos < 0) || (mnDragPos > mnDX-1) ) 856 HideTracking(); 857 else 858 { 859 Rectangle aSizeRect( mnDragPos, 0, mnDragPos, mnDragSize+mnDY ); 860 ShowTracking( aSizeRect, SHOWTRACK_SPLIT ); 861 } 862 } 863 864 Drag(); 865 } 866 867 // ----------------------------------------------------------------------- 868 869 void HeaderBar::ImplEndDrag( sal_Bool bCancel ) 870 { 871 HideTracking(); 872 873 if ( bCancel || mbOutDrag ) 874 { 875 if ( mbItemMode && (!mbOutDrag || mbItemDrag) ) 876 { 877 sal_uInt16 nPos = GetItemPos( mnCurItemId ); 878 ImplDrawItem( nPos ); 879 } 880 881 mnCurItemId = 0; 882 } 883 else 884 { 885 sal_uInt16 nPos = GetItemPos( mnCurItemId ); 886 if ( mbItemMode ) 887 { 888 if ( mbItemDrag ) 889 { 890 Pointer aPointer( POINTER_ARROW ); 891 SetPointer( aPointer ); 892 if ( (mnItemDragPos != nPos) && 893 (mnItemDragPos != HEADERBAR_ITEM_NOTFOUND) ) 894 { 895 ImplInvertDrag( nPos, mnItemDragPos ); 896 MoveItem( mnCurItemId, mnItemDragPos ); 897 } 898 else 899 ImplDrawItem( nPos ); 900 } 901 else 902 { 903 Select(); 904 ImplUpdate( nPos ); 905 } 906 } 907 else 908 { 909 long nDelta = mnDragPos - mnStartPos; 910 if ( nDelta ) 911 { 912 ImplHeadItem* pItem = mpItemList->GetObject( nPos ); 913 pItem->mnSize += nDelta; 914 ImplUpdate( nPos, sal_True ); 915 } 916 } 917 } 918 919 mbDrag = sal_False; 920 EndDrag(); 921 mnCurItemId = 0; 922 mnItemDragPos = HEADERBAR_ITEM_NOTFOUND; 923 mbOutDrag = sal_False; 924 mbItemMode = sal_False; 925 mbItemDrag = sal_False; 926 } 927 928 // ----------------------------------------------------------------------- 929 930 void HeaderBar::MouseButtonDown( const MouseEvent& rMEvt ) 931 { 932 if ( rMEvt.IsLeft() ) 933 { 934 if ( rMEvt.GetClicks() == 2 ) 935 { 936 long nTemp; 937 sal_uInt16 nPos; 938 sal_uInt16 nHitTest = ImplHitTest( rMEvt.GetPosPixel(), nTemp, nPos ); 939 if ( nHitTest ) 940 { 941 ImplHeadItem* pItem = mpItemList->GetObject( nPos ); 942 if ( nHitTest & HEAD_HITTEST_DIVIDER ) 943 mbItemMode = sal_False; 944 else 945 mbItemMode = sal_True; 946 mnCurItemId = pItem->mnId; 947 DoubleClick(); 948 mbItemMode = sal_False; 949 mnCurItemId = 0; 950 } 951 } 952 else 953 ImplStartDrag( rMEvt.GetPosPixel(), sal_False ); 954 } 955 } 956 957 // ----------------------------------------------------------------------- 958 959 void HeaderBar::MouseMove( const MouseEvent& rMEvt ) 960 { 961 long nTemp1; 962 sal_uInt16 nTemp2; 963 PointerStyle eStyle = POINTER_ARROW; 964 sal_uInt16 nHitTest = ImplHitTest( rMEvt.GetPosPixel(), nTemp1, nTemp2 ); 965 966 if ( nHitTest & HEAD_HITTEST_DIVIDER ) 967 eStyle = POINTER_HSIZEBAR; 968 Pointer aPtr( eStyle ); 969 SetPointer( aPtr ); 970 } 971 972 // ----------------------------------------------------------------------- 973 974 void HeaderBar::Tracking( const TrackingEvent& rTEvt ) 975 { 976 Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel(); 977 978 if ( rTEvt.IsTrackingEnded() ) 979 ImplEndDrag( rTEvt.IsTrackingCanceled() ); 980 else 981 ImplDrag( aMousePos ); 982 } 983 984 // ----------------------------------------------------------------------- 985 986 void HeaderBar::Paint( const Rectangle& rRect ) 987 { 988 if ( mnBorderOff1 || mnBorderOff2 ) 989 { 990 SetLineColor( GetSettings().GetStyleSettings().GetDarkShadowColor() ); 991 if ( mnBorderOff1 ) 992 DrawLine( Point( 0, 0 ), Point( mnDX-1, 0 ) ); 993 if ( mnBorderOff2 ) 994 DrawLine( Point( 0, mnDY-1 ), Point( mnDX-1, mnDY-1 ) ); 995 // #i40393# draw left and right border, if WB_BORDER was set in ImplInit() 996 if ( mnBorderOff1 && mnBorderOff2 ) 997 { 998 DrawLine( Point( 0, 0 ), Point( 0, mnDY-1 ) ); 999 DrawLine( Point( mnDX-1, 0 ), Point( mnDX-1, mnDY-1 ) ); 1000 } 1001 } 1002 1003 sal_uInt16 nCurItemPos; 1004 if ( mbDrag ) 1005 nCurItemPos = GetItemPos( mnCurItemId ); 1006 else 1007 nCurItemPos = HEADERBAR_ITEM_NOTFOUND; 1008 sal_uInt16 nItemCount = (sal_uInt16)mpItemList->Count(); 1009 for ( sal_uInt16 i = 0; i < nItemCount; i++ ) 1010 ImplDrawItem( i, (i == nCurItemPos) ? sal_True : sal_False, sal_False, &rRect ); 1011 } 1012 1013 // ----------------------------------------------------------------------- 1014 1015 void HeaderBar::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, 1016 sal_uLong nFlags ) 1017 { 1018 Point aPos = pDev->LogicToPixel( rPos ); 1019 Size aSize = pDev->LogicToPixel( rSize ); 1020 Rectangle aRect( aPos, aSize ); 1021 Font aFont = GetDrawPixelFont( pDev ); 1022 1023 pDev->Push(); 1024 pDev->SetMapMode(); 1025 pDev->SetFont( aFont ); 1026 if ( nFlags & WINDOW_DRAW_MONO ) 1027 pDev->SetTextColor( Color( COL_BLACK ) ); 1028 else 1029 pDev->SetTextColor( GetTextColor() ); 1030 pDev->SetTextFillColor(); 1031 1032 if ( !(nFlags & WINDOW_DRAW_NOBACKGROUND) ) 1033 { 1034 pDev->DrawWallpaper( aRect, GetBackground() ); 1035 if ( mnBorderOff1 || mnBorderOff2 ) 1036 { 1037 pDev->SetLineColor( GetSettings().GetStyleSettings().GetDarkShadowColor() ); 1038 if ( mnBorderOff1 ) 1039 pDev->DrawLine( aRect.TopLeft(), Point( aRect.Right(), aRect.Top() ) ); 1040 if ( mnBorderOff2 ) 1041 pDev->DrawLine( Point( aRect.Left(), aRect.Bottom() ), Point( aRect.Right(), aRect.Bottom() ) ); 1042 // #i40393# draw left and right border, if WB_BORDER was set in ImplInit() 1043 if ( mnBorderOff1 && mnBorderOff2 ) 1044 { 1045 pDev->DrawLine( aRect.TopLeft(), Point( aRect.Left(), aRect.Bottom() ) ); 1046 pDev->DrawLine( Point( aRect.Right(), aRect.Top() ), Point( aRect.Right(), aRect.Bottom() ) ); 1047 } 1048 } 1049 } 1050 1051 Rectangle aItemRect( aRect ); 1052 // aItemRect.Bottom()--; 1053 sal_uInt16 nItemCount = (sal_uInt16)mpItemList->Count(); 1054 for ( sal_uInt16 i = 0; i < nItemCount; i++ ) 1055 { 1056 aItemRect.Left() = aRect.Left()+ImplGetItemPos( i ); 1057 aItemRect.Right() = aItemRect.Left() + mpItemList->GetObject( i )->mnSize - 1; 1058 // Gegen Ueberlauf auf einigen Systemen testen 1059 if ( aItemRect.Right() > 16000 ) 1060 aItemRect.Right() = 16000; 1061 Region aRegion( aRect ); 1062 pDev->SetClipRegion( aRegion ); 1063 ImplDrawItem( pDev, i, sal_False, sal_False, aItemRect, &aRect, nFlags ); 1064 pDev->SetClipRegion(); 1065 } 1066 1067 pDev->Pop(); 1068 } 1069 1070 // ----------------------------------------------------------------------- 1071 1072 void HeaderBar::Resize() 1073 { 1074 Size aSize = GetOutputSizePixel(); 1075 if ( IsVisible() && (mnDY != aSize.Height()) ) 1076 Invalidate(); 1077 mnDX = aSize.Width(); 1078 mnDY = aSize.Height(); 1079 } 1080 1081 // ----------------------------------------------------------------------- 1082 1083 void HeaderBar::Command( const CommandEvent& rCEvt ) 1084 { 1085 if ( rCEvt.IsMouseEvent() && (rCEvt.GetCommand() == COMMAND_STARTDRAG) && !mbDrag ) 1086 { 1087 ImplStartDrag( rCEvt.GetMousePosPixel(), sal_True ); 1088 return; 1089 } 1090 1091 Window::Command( rCEvt ); 1092 } 1093 1094 // ----------------------------------------------------------------------- 1095 1096 void HeaderBar::RequestHelp( const HelpEvent& rHEvt ) 1097 { 1098 sal_uInt16 nItemId = GetItemId( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ) ); 1099 if ( nItemId ) 1100 { 1101 if ( rHEvt.GetMode() & (HELPMODE_QUICK | HELPMODE_BALLOON) ) 1102 { 1103 Rectangle aItemRect = GetItemRect( nItemId ); 1104 Point aPt = OutputToScreenPixel( aItemRect.TopLeft() ); 1105 aItemRect.Left() = aPt.X(); 1106 aItemRect.Top() = aPt.Y(); 1107 aPt = OutputToScreenPixel( aItemRect.BottomRight() ); 1108 aItemRect.Right() = aPt.X(); 1109 aItemRect.Bottom() = aPt.Y(); 1110 1111 XubString aStr = GetHelpText( nItemId ); 1112 if ( !aStr.Len() || !(rHEvt.GetMode() & HELPMODE_BALLOON) ) 1113 { 1114 ImplHeadItem* pItem = mpItemList->GetObject( GetItemPos( nItemId ) ); 1115 // Wir zeigen die Quick-Hilfe nur an, wenn Text nicht 1116 // vollstaendig sichtbar, ansonsten zeigen wir den Hilfetext 1117 // an, wenn das Item keinen Text besitzt 1118 if ( pItem->maOutText != pItem->maText ) 1119 aStr = pItem->maText; 1120 else if ( pItem->maText.Len() ) 1121 aStr.Erase(); 1122 } 1123 1124 if ( aStr.Len() ) 1125 { 1126 if ( rHEvt.GetMode() & HELPMODE_BALLOON ) 1127 Help::ShowBalloon( this, aItemRect.Center(), aItemRect, aStr ); 1128 else 1129 Help::ShowQuickHelp( this, aItemRect, aStr ); 1130 return; 1131 } 1132 } 1133 else if ( rHEvt.GetMode() & HELPMODE_EXTENDED ) 1134 { 1135 rtl::OUString aHelpId( rtl::OStringToOUString( GetHelpId( nItemId ), RTL_TEXTENCODING_UTF8 ) ); 1136 if ( aHelpId.getLength() ) 1137 { 1138 // Wenn eine Hilfe existiert, dann ausloesen 1139 Help* pHelp = Application::GetHelp(); 1140 if ( pHelp ) 1141 pHelp->Start( aHelpId, this ); 1142 return; 1143 } 1144 } 1145 } 1146 1147 Window::RequestHelp( rHEvt ); 1148 } 1149 1150 // ----------------------------------------------------------------------- 1151 1152 void HeaderBar::StateChanged( StateChangedType nType ) 1153 { 1154 Window::StateChanged( nType ); 1155 1156 if ( nType == STATE_CHANGE_ENABLE ) 1157 Invalidate(); 1158 else if ( (nType == STATE_CHANGE_ZOOM) || 1159 (nType == STATE_CHANGE_CONTROLFONT) ) 1160 { 1161 ImplInitSettings( sal_True, sal_False, sal_False ); 1162 Invalidate(); 1163 } 1164 else if ( nType == STATE_CHANGE_CONTROLFOREGROUND ) 1165 { 1166 ImplInitSettings( sal_False, sal_True, sal_False ); 1167 Invalidate(); 1168 } 1169 else if ( nType == STATE_CHANGE_CONTROLBACKGROUND ) 1170 { 1171 ImplInitSettings( sal_False, sal_False, sal_True ); 1172 Invalidate(); 1173 } 1174 } 1175 1176 // ----------------------------------------------------------------------- 1177 1178 void HeaderBar::DataChanged( const DataChangedEvent& rDCEvt ) 1179 { 1180 Window::DataChanged( rDCEvt ); 1181 1182 if ( (rDCEvt.GetType() == DATACHANGED_FONTS) || 1183 (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) || 1184 ((rDCEvt.GetType() == DATACHANGED_SETTINGS) && 1185 (rDCEvt.GetFlags() & SETTINGS_STYLE)) ) 1186 { 1187 ImplInitSettings( sal_True, sal_True, sal_True ); 1188 Invalidate(); 1189 } 1190 } 1191 1192 // ----------------------------------------------------------------------- 1193 1194 void HeaderBar::UserDraw( const UserDrawEvent& ) 1195 { 1196 } 1197 1198 // ----------------------------------------------------------------------- 1199 1200 void HeaderBar::StartDrag() 1201 { 1202 maStartDragHdl.Call( this ); 1203 } 1204 1205 // ----------------------------------------------------------------------- 1206 1207 void HeaderBar::Drag() 1208 { 1209 maDragHdl.Call( this ); 1210 } 1211 1212 // ----------------------------------------------------------------------- 1213 1214 void HeaderBar::EndDrag() 1215 { 1216 maEndDragHdl.Call( this ); 1217 } 1218 1219 // ----------------------------------------------------------------------- 1220 1221 void HeaderBar::Select() 1222 { 1223 maSelectHdl.Call( this ); 1224 } 1225 1226 // ----------------------------------------------------------------------- 1227 1228 void HeaderBar::DoubleClick() 1229 { 1230 maDoubleClickHdl.Call( this ); 1231 } 1232 1233 // ----------------------------------------------------------------------- 1234 1235 void HeaderBar::InsertItem( sal_uInt16 nItemId, const Image& rImage, 1236 long nSize, HeaderBarItemBits nBits, sal_uInt16 nPos ) 1237 { 1238 DBG_ASSERT( nItemId, "HeaderBar::InsertItem(): ItemId == 0" ); 1239 DBG_ASSERT( GetItemPos( nItemId ) == HEADERBAR_ITEM_NOTFOUND, 1240 "HeaderBar::InsertItem(): ItemId already exists" ); 1241 1242 // Item anlegen und in die Liste einfuegen 1243 ImplHeadItem* pItem = new ImplHeadItem; 1244 pItem->mnId = nItemId; 1245 pItem->mnBits = nBits; 1246 pItem->mnSize = nSize; 1247 pItem->maImage = rImage; 1248 pItem->mpUserData = 0; 1249 mpItemList->Insert( pItem, nPos ); 1250 1251 // Ausgabe updaten 1252 ImplUpdate( nPos, sal_True ); 1253 } 1254 1255 // ----------------------------------------------------------------------- 1256 1257 void HeaderBar::InsertItem( sal_uInt16 nItemId, const XubString& rText, 1258 long nSize, HeaderBarItemBits nBits, sal_uInt16 nPos ) 1259 { 1260 DBG_ASSERT( nItemId, "HeaderBar::InsertItem(): ItemId == 0" ); 1261 DBG_ASSERT( GetItemPos( nItemId ) == HEADERBAR_ITEM_NOTFOUND, 1262 "HeaderBar::InsertItem(): ItemId already exists" ); 1263 1264 // Item anlegen und in die Liste einfuegen 1265 ImplHeadItem* pItem = new ImplHeadItem; 1266 pItem->mnId = nItemId; 1267 pItem->mnBits = nBits; 1268 pItem->mnSize = nSize; 1269 pItem->maText = rText; 1270 pItem->mpUserData = 0; 1271 mpItemList->Insert( pItem, nPos ); 1272 1273 // Ausgabe updaten 1274 ImplUpdate( nPos, sal_True ); 1275 } 1276 1277 // ----------------------------------------------------------------------- 1278 1279 void HeaderBar::InsertItem( sal_uInt16 nItemId, 1280 const Image& rImage, const XubString& rText, 1281 long nSize, HeaderBarItemBits nBits, 1282 sal_uInt16 nPos ) 1283 { 1284 DBG_ASSERT( nItemId, "HeaderBar::InsertItem(): ItemId == 0" ); 1285 DBG_ASSERT( GetItemPos( nItemId ) == HEADERBAR_ITEM_NOTFOUND, 1286 "HeaderBar::InsertItem(): ItemId already exists" ); 1287 1288 // Item anlegen und in die Liste einfuegen 1289 ImplHeadItem* pItem = new ImplHeadItem; 1290 pItem->mnId = nItemId; 1291 pItem->mnBits = nBits; 1292 pItem->mnSize = nSize; 1293 pItem->maImage = rImage; 1294 pItem->maText = rText; 1295 pItem->mpUserData = 0; 1296 mpItemList->Insert( pItem, nPos ); 1297 1298 // Ausgabe updaten 1299 ImplUpdate( nPos, sal_True ); 1300 } 1301 1302 // ----------------------------------------------------------------------- 1303 1304 void HeaderBar::RemoveItem( sal_uInt16 nItemId ) 1305 { 1306 sal_uInt16 nPos = GetItemPos( nItemId ); 1307 if ( nPos != HEADERBAR_ITEM_NOTFOUND ) 1308 { 1309 ImplHeadItem* pItem = mpItemList->Remove( nPos ); 1310 delete pItem; 1311 ImplUpdate( nPos, sal_True ); 1312 } 1313 } 1314 1315 // ----------------------------------------------------------------------- 1316 1317 void HeaderBar::MoveItem( sal_uInt16 nItemId, sal_uInt16 nNewPos ) 1318 { 1319 sal_uInt16 nPos = GetItemPos( nItemId ); 1320 if ( nPos != HEADERBAR_ITEM_NOTFOUND ) 1321 { 1322 if ( nPos != nNewPos ) 1323 { 1324 ImplHeadItem* pItem = mpItemList->Remove( nPos ); 1325 if ( nNewPos < nPos ) 1326 nPos = nNewPos; 1327 mpItemList->Insert( pItem, nNewPos ); 1328 ImplUpdate( nPos, sal_True ); 1329 } 1330 } 1331 } 1332 1333 // ----------------------------------------------------------------------- 1334 1335 void HeaderBar::Clear() 1336 { 1337 // Alle Items loeschen 1338 ImplHeadItem* pItem = mpItemList->First(); 1339 while ( pItem ) 1340 { 1341 delete pItem; 1342 pItem = mpItemList->Next(); 1343 } 1344 mpItemList->Clear(); 1345 1346 ImplUpdate( 0, sal_True ); 1347 } 1348 1349 // ----------------------------------------------------------------------- 1350 1351 void HeaderBar::SetOffset( long nNewOffset ) 1352 { 1353 // Hier erstmal neu zeichnen, damit mit alten Offset noch das 1354 // richtige gemalt wird 1355 //Update(); 1356 1357 // Bereich verschieben 1358 Rectangle aRect( 0, mnBorderOff1, mnDX-1, mnDY-mnBorderOff1-mnBorderOff2-1 ); 1359 long nDelta = mnOffset-nNewOffset; 1360 mnOffset = nNewOffset; 1361 Scroll( nDelta, 0, aRect ); 1362 } 1363 1364 // ----------------------------------------------------------------------- 1365 1366 sal_uInt16 HeaderBar::GetItemCount() const 1367 { 1368 return (sal_uInt16)mpItemList->Count(); 1369 } 1370 1371 // ----------------------------------------------------------------------- 1372 1373 sal_uInt16 HeaderBar::GetItemPos( sal_uInt16 nItemId ) const 1374 { 1375 ImplHeadItem* pItem = mpItemList->First(); 1376 while ( pItem ) 1377 { 1378 if ( pItem->mnId == nItemId ) 1379 return (sal_uInt16)mpItemList->GetCurPos(); 1380 pItem = mpItemList->Next(); 1381 } 1382 1383 return HEADERBAR_ITEM_NOTFOUND; 1384 } 1385 1386 // ----------------------------------------------------------------------- 1387 1388 sal_uInt16 HeaderBar::GetItemId( sal_uInt16 nPos ) const 1389 { 1390 ImplHeadItem* pItem = mpItemList->GetObject( nPos ); 1391 if ( pItem ) 1392 return pItem->mnId; 1393 else 1394 return 0; 1395 } 1396 1397 // ----------------------------------------------------------------------- 1398 1399 sal_uInt16 HeaderBar::GetItemId( const Point& rPos ) const 1400 { 1401 sal_uInt16 nPos = 0; 1402 while ( nPos < mpItemList->Count() ) 1403 { 1404 if ( ImplGetItemRect( nPos ).IsInside( rPos ) ) 1405 return GetItemId( nPos ); 1406 1407 nPos++; 1408 } 1409 1410 return 0; 1411 } 1412 1413 // ----------------------------------------------------------------------- 1414 1415 Rectangle HeaderBar::GetItemRect( sal_uInt16 nItemId ) const 1416 { 1417 Rectangle aRect; 1418 sal_uInt16 nPos = GetItemPos( nItemId ); 1419 if ( nPos != HEADERBAR_ITEM_NOTFOUND ) 1420 aRect = ImplGetItemRect( nPos ); 1421 return aRect; 1422 } 1423 1424 // ----------------------------------------------------------------------- 1425 1426 void HeaderBar::SetItemSize( sal_uInt16 nItemId, long nNewSize ) 1427 { 1428 sal_uInt16 nPos = GetItemPos( nItemId ); 1429 if ( nPos != HEADERBAR_ITEM_NOTFOUND ) 1430 { 1431 ImplHeadItem* pItem = mpItemList->GetObject( nPos ); 1432 if ( pItem->mnSize != nNewSize ) 1433 { 1434 pItem->mnSize = nNewSize; 1435 ImplUpdate( nPos, sal_True ); 1436 } 1437 } 1438 } 1439 1440 // ----------------------------------------------------------------------- 1441 1442 long HeaderBar::GetItemSize( sal_uInt16 nItemId ) const 1443 { 1444 sal_uInt16 nPos = GetItemPos( nItemId ); 1445 if ( nPos != HEADERBAR_ITEM_NOTFOUND ) 1446 return mpItemList->GetObject( nPos )->mnSize; 1447 else 1448 return 0; 1449 } 1450 1451 // ----------------------------------------------------------------------- 1452 1453 void HeaderBar::SetItemBits( sal_uInt16 nItemId, HeaderBarItemBits nNewBits ) 1454 { 1455 sal_uInt16 nPos = GetItemPos( nItemId ); 1456 if ( nPos != HEADERBAR_ITEM_NOTFOUND ) 1457 { 1458 ImplHeadItem* pItem = mpItemList->GetObject( nPos ); 1459 if ( pItem->mnBits != nNewBits ) 1460 { 1461 pItem->mnBits = nNewBits; 1462 ImplUpdate( nPos ); 1463 } 1464 } 1465 } 1466 1467 // ----------------------------------------------------------------------- 1468 1469 HeaderBarItemBits HeaderBar::GetItemBits( sal_uInt16 nItemId ) const 1470 { 1471 sal_uInt16 nPos = GetItemPos( nItemId ); 1472 if ( nPos != HEADERBAR_ITEM_NOTFOUND ) 1473 return mpItemList->GetObject( nPos )->mnBits; 1474 else 1475 return 0; 1476 } 1477 1478 // ----------------------------------------------------------------------- 1479 1480 void HeaderBar::SetItemData( sal_uInt16 nItemId, void* pNewData ) 1481 { 1482 sal_uInt16 nPos = GetItemPos( nItemId ); 1483 if ( nPos != HEADERBAR_ITEM_NOTFOUND ) 1484 { 1485 mpItemList->GetObject( nPos )->mpUserData = pNewData; 1486 ImplUpdate( nPos ); 1487 } 1488 } 1489 1490 // ----------------------------------------------------------------------- 1491 1492 void* HeaderBar::GetItemData( sal_uInt16 nItemId ) const 1493 { 1494 sal_uInt16 nPos = GetItemPos( nItemId ); 1495 if ( nPos != HEADERBAR_ITEM_NOTFOUND ) 1496 return mpItemList->GetObject( nPos )->mpUserData; 1497 else 1498 return NULL; 1499 } 1500 1501 // ----------------------------------------------------------------------- 1502 1503 void HeaderBar::SetItemImage( sal_uInt16 nItemId, const Image& rImage ) 1504 { 1505 sal_uInt16 nPos = GetItemPos( nItemId ); 1506 if ( nPos != HEADERBAR_ITEM_NOTFOUND ) 1507 { 1508 mpItemList->GetObject( nPos )->maImage = rImage; 1509 ImplUpdate( nPos ); 1510 } 1511 } 1512 1513 // ----------------------------------------------------------------------- 1514 1515 Image HeaderBar::GetItemImage( sal_uInt16 nItemId ) const 1516 { 1517 sal_uInt16 nPos = GetItemPos( nItemId ); 1518 if ( nPos != HEADERBAR_ITEM_NOTFOUND ) 1519 return mpItemList->GetObject( nPos )->maImage; 1520 else 1521 return Image(); 1522 } 1523 1524 // ----------------------------------------------------------------------- 1525 1526 void HeaderBar::SetItemText( sal_uInt16 nItemId, const XubString& rText ) 1527 { 1528 sal_uInt16 nPos = GetItemPos( nItemId ); 1529 if ( nPos != HEADERBAR_ITEM_NOTFOUND ) 1530 { 1531 mpItemList->GetObject( nPos )->maText = rText; 1532 ImplUpdate( nPos ); 1533 } 1534 } 1535 1536 // ----------------------------------------------------------------------- 1537 1538 XubString HeaderBar::GetItemText( sal_uInt16 nItemId ) const 1539 { 1540 sal_uInt16 nPos = GetItemPos( nItemId ); 1541 if ( nPos != HEADERBAR_ITEM_NOTFOUND ) 1542 return mpItemList->GetObject( nPos )->maText; 1543 else 1544 return String(); 1545 } 1546 1547 // ----------------------------------------------------------------------- 1548 1549 void HeaderBar::SetHelpText( sal_uInt16 nItemId, const XubString& rText ) 1550 { 1551 sal_uInt16 nPos = GetItemPos( nItemId ); 1552 if ( nPos != HEADERBAR_ITEM_NOTFOUND ) 1553 mpItemList->GetObject( nPos )->maHelpText = rText; 1554 } 1555 1556 // ----------------------------------------------------------------------- 1557 1558 XubString HeaderBar::GetHelpText( sal_uInt16 nItemId ) const 1559 { 1560 sal_uInt16 nPos = GetItemPos( nItemId ); 1561 if ( nPos != HEADERBAR_ITEM_NOTFOUND ) 1562 { 1563 ImplHeadItem* pItem = mpItemList->GetObject( nPos ); 1564 if ( !pItem->maHelpText.Len() && pItem->maHelpId.getLength() ) 1565 { 1566 Help* pHelp = Application::GetHelp(); 1567 if ( pHelp ) 1568 pItem->maHelpText = pHelp->GetHelpText( rtl::OStringToOUString( pItem->maHelpId, RTL_TEXTENCODING_UTF8 ), this ); 1569 } 1570 1571 return pItem->maHelpText; 1572 } 1573 else 1574 return XubString(); 1575 } 1576 1577 // ----------------------------------------------------------------------- 1578 1579 void HeaderBar::SetHelpId( sal_uInt16 nItemId, const rtl::OString& rHelpId ) 1580 { 1581 sal_uInt16 nPos = GetItemPos( nItemId ); 1582 if ( nPos != HEADERBAR_ITEM_NOTFOUND ) 1583 mpItemList->GetObject( nPos )->maHelpId = rHelpId; 1584 } 1585 1586 // ----------------------------------------------------------------------- 1587 1588 rtl::OString HeaderBar::GetHelpId( sal_uInt16 nItemId ) const 1589 { 1590 sal_uInt16 nPos = GetItemPos( nItemId ); 1591 rtl::OString aRet; 1592 if ( nPos != HEADERBAR_ITEM_NOTFOUND ) 1593 aRet = mpItemList->GetObject( nPos )->maHelpId; 1594 return aRet; 1595 } 1596 1597 // ----------------------------------------------------------------------- 1598 1599 Size HeaderBar::CalcWindowSizePixel() const 1600 { 1601 long nMaxImageSize = 0; 1602 Size aSize( 0, GetTextHeight() ); 1603 1604 ImplHeadItem* pItem = mpItemList->First(); 1605 while ( pItem ) 1606 { 1607 // Image-Groessen beruecksichtigen 1608 long nImageHeight = pItem->maImage.GetSizePixel().Height(); 1609 if ( !(pItem->mnBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) && pItem->maText.Len() ) 1610 nImageHeight += aSize.Height(); 1611 if ( nImageHeight > nMaxImageSize ) 1612 nMaxImageSize = nImageHeight; 1613 1614 // Breite aufaddieren 1615 aSize.Width() += pItem->mnSize; 1616 1617 pItem = mpItemList->Next(); 1618 } 1619 1620 if ( nMaxImageSize > aSize.Height() ) 1621 aSize.Height() = nMaxImageSize; 1622 1623 // Border aufaddieren 1624 if ( mbButtonStyle ) 1625 aSize.Height() += 4; 1626 else 1627 aSize.Height() += 2; 1628 aSize.Height() += mnBorderOff1+mnBorderOff2; 1629 1630 return aSize; 1631 } 1632 1633 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > HeaderBar::CreateAccessible() 1634 { 1635 if ( !mxAccessible.is() ) 1636 { 1637 if ( maCreateAccessibleHdl.IsSet() ) 1638 maCreateAccessibleHdl.Call( this ); 1639 1640 if ( !mxAccessible.is() ) 1641 mxAccessible = Window::CreateAccessible(); 1642 } 1643 1644 return mxAccessible; 1645 } 1646 1647 void HeaderBar::SetAccessible( ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > _xAccessible ) 1648 { 1649 mxAccessible = _xAccessible; 1650 } 1651 1652