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_vcl.hxx" 30 31 #include <tools/list.hxx> 32 #include <tools/debug.hxx> 33 #include <tools/rc.h> 34 35 #include <vcl/event.hxx> 36 #include <vcl/decoview.hxx> 37 #include <vcl/svapp.hxx> 38 #include <vcl/help.hxx> 39 #include <vcl/status.hxx> 40 #include <vcl/virdev.hxx> 41 42 #include <svdata.hxx> 43 #include <window.h> 44 45 // ======================================================================= 46 47 #define STATUSBAR_OFFSET_X STATUSBAR_OFFSET 48 #define STATUSBAR_OFFSET_Y 2 49 #define STATUSBAR_OFFSET_TEXTY 3 50 51 #define STATUSBAR_PRGS_OFFSET 3 52 #define STATUSBAR_PRGS_COUNT 100 53 #define STATUSBAR_PRGS_MIN 5 54 55 // ----------------------------------------------------------------------- 56 57 class StatusBar::ImplData 58 { 59 public: 60 ImplData(); 61 ~ImplData(); 62 63 VirtualDevice* mpVirDev; 64 long mnItemBorderWidth; 65 bool mbTopBorder:1; 66 bool mbDrawItemFrames:1; 67 }; 68 69 StatusBar::ImplData::ImplData() 70 { 71 mpVirDev = NULL; 72 mbTopBorder = false; 73 mbDrawItemFrames = false; 74 mnItemBorderWidth = 0; 75 } 76 77 StatusBar::ImplData::~ImplData() 78 { 79 } 80 81 struct ImplStatusItem 82 { 83 sal_uInt16 mnId; 84 StatusBarItemBits mnBits; 85 long mnWidth; 86 long mnOffset; 87 long mnExtraWidth; 88 long mnX; 89 XubString maText; 90 XubString maHelpText; 91 XubString maQuickHelpText; 92 rtl::OString maHelpId; 93 void* mpUserData; 94 sal_Bool mbVisible; 95 XubString maAccessibleName; 96 XubString maCommand; 97 }; 98 99 DECLARE_LIST( ImplStatusItemList, ImplStatusItem* ) 100 101 // ======================================================================= 102 103 inline long ImplCalcProgessWidth( sal_uInt16 nMax, long nSize ) 104 { 105 return ((nMax*(nSize+(nSize/2)))-(nSize/2)+(STATUSBAR_PRGS_OFFSET*2)); 106 } 107 108 // ----------------------------------------------------------------------- 109 110 static Point ImplGetItemTextPos( const Size& rRectSize, const Size& rTextSize, 111 sal_uInt16 nStyle ) 112 { 113 long nX; 114 long nY; 115 long delta = (rTextSize.Height()/4) + 1; 116 if( delta + rTextSize.Width() > rRectSize.Width() ) 117 delta = 0; 118 119 if ( nStyle & SIB_LEFT ) 120 nX = delta; 121 else if ( nStyle & SIB_RIGHT ) 122 nX = rRectSize.Width()-rTextSize.Width()-delta; 123 else // SIB_CENTER 124 nX = (rRectSize.Width()-rTextSize.Width())/2; 125 nY = (rRectSize.Height()-rTextSize.Height())/2 + 1; 126 return Point( nX, nY ); 127 } 128 129 // ----------------------------------------------------------------------- 130 131 sal_Bool StatusBar::ImplIsItemUpdate() 132 { 133 if ( !mbProgressMode && mbVisibleItems && IsReallyVisible() && IsUpdateMode() ) 134 return sal_True; 135 else 136 return sal_False; 137 } 138 139 // ----------------------------------------------------------------------- 140 141 void StatusBar::ImplInit( Window* pParent, WinBits nStyle ) 142 { 143 mpImplData = new ImplData; 144 145 // Default ist RightAlign 146 if ( !(nStyle & (WB_LEFT | WB_RIGHT)) ) 147 nStyle |= WB_RIGHT; 148 149 Window::ImplInit( pParent, nStyle & ~WB_BORDER, NULL ); 150 151 // WinBits merken 152 mpItemList = new ImplStatusItemList; 153 mpImplData->mpVirDev = new VirtualDevice( *this ); 154 mnCurItemId = 0; 155 mbFormat = sal_True; 156 mbVisibleItems = sal_True; 157 mbProgressMode = sal_False; 158 mbInUserDraw = sal_False; 159 mbBottomBorder = sal_False; 160 mnItemsWidth = STATUSBAR_OFFSET_X; 161 mnDX = 0; 162 mnDY = 0; 163 mnCalcHeight = 0; 164 mnItemY = STATUSBAR_OFFSET_Y; 165 mnTextY = STATUSBAR_OFFSET_TEXTY; 166 167 ImplInitSettings( sal_True, sal_True, sal_True ); 168 SetLineColor(); 169 170 SetOutputSizePixel( CalcWindowSizePixel() ); 171 } 172 173 // ----------------------------------------------------------------------- 174 175 StatusBar::StatusBar( Window* pParent, WinBits nStyle ) : 176 Window( WINDOW_STATUSBAR ) 177 { 178 ImplInit( pParent, nStyle ); 179 } 180 181 // ----------------------------------------------------------------------- 182 183 StatusBar::StatusBar( Window* pParent, const ResId& rResId ) : 184 Window( WINDOW_STATUSBAR ) 185 { 186 rResId.SetRT( RSC_STATUSBAR ); 187 WinBits nStyle = ImplInitRes( rResId ); 188 ImplInit( pParent, nStyle ); 189 ImplLoadRes( rResId ); 190 191 if ( !(nStyle & WB_HIDE) ) 192 Show(); 193 } 194 195 // ----------------------------------------------------------------------- 196 197 StatusBar::~StatusBar() 198 { 199 // Alle Items loeschen 200 ImplStatusItem* pItem = mpItemList->First(); 201 while ( pItem ) 202 { 203 delete pItem; 204 pItem = mpItemList->Next(); 205 } 206 207 delete mpItemList; 208 209 // VirtualDevice loeschen 210 delete mpImplData->mpVirDev; 211 212 delete mpImplData; 213 } 214 215 // ----------------------------------------------------------------------- 216 217 void StatusBar::ImplInitSettings( sal_Bool bFont, 218 sal_Bool bForeground, sal_Bool bBackground ) 219 { 220 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); 221 222 if ( bFont ) 223 { 224 Font aFont = rStyleSettings.GetToolFont(); 225 if ( IsControlFont() ) 226 aFont.Merge( GetControlFont() ); 227 SetZoomedPointFont( aFont ); 228 } 229 230 if ( bForeground || bFont ) 231 { 232 Color aColor; 233 if ( IsControlForeground() ) 234 aColor = GetControlForeground(); 235 else if ( GetStyle() & WB_3DLOOK ) 236 aColor = rStyleSettings.GetButtonTextColor(); 237 else 238 aColor = rStyleSettings.GetWindowTextColor(); 239 SetTextColor( aColor ); 240 SetTextFillColor(); 241 242 mpImplData->mpVirDev->SetFont( GetFont() ); 243 mpImplData->mpVirDev->SetTextColor( GetTextColor() ); 244 mpImplData->mpVirDev->SetTextAlign( GetTextAlign() ); 245 mpImplData->mpVirDev->SetTextFillColor(); 246 } 247 248 if ( bBackground ) 249 { 250 Color aColor; 251 if ( IsControlBackground() ) 252 aColor = GetControlBackground(); 253 else if ( GetStyle() & WB_3DLOOK ) 254 aColor = rStyleSettings.GetFaceColor(); 255 else 256 aColor = rStyleSettings.GetWindowColor(); 257 SetBackground( aColor ); 258 mpImplData->mpVirDev->SetBackground( GetBackground() ); 259 260 // NWF background 261 if( ! IsControlBackground() && 262 IsNativeControlSupported( CTRL_WINDOW_BACKGROUND, PART_BACKGROUND_WINDOW ) ) 263 { 264 ImplGetWindowImpl()->mnNativeBackground = PART_BACKGROUND_WINDOW; 265 EnableChildTransparentMode( sal_True ); 266 } 267 } 268 } 269 270 // ----------------------------------------------------------------------- 271 272 void StatusBar::ImplFormat() 273 { 274 ImplStatusItem* pItem; 275 long nExtraWidth; 276 long nExtraWidth2; 277 long nX; 278 sal_uInt16 nAutoSizeItems = 0; 279 280 // Breiten zusammenrechnen 281 mnItemsWidth = STATUSBAR_OFFSET_X; 282 long nOffset = 0; 283 pItem = mpItemList->First(); 284 while ( pItem ) 285 { 286 if ( pItem->mbVisible ) 287 { 288 if ( pItem->mnBits & SIB_AUTOSIZE ) 289 nAutoSizeItems++; 290 291 mnItemsWidth += pItem->mnWidth + nOffset; 292 nOffset = pItem->mnOffset; 293 } 294 295 pItem = mpItemList->Next(); 296 } 297 298 if ( GetStyle() & WB_RIGHT ) 299 { 300 // Bei rechtsbuendiger Ausrichtung wird kein AutoSize ausgewertet, 301 // da wir links den Text anzeigen, der mit SetText gesetzt wird 302 nX = mnDX - mnItemsWidth; 303 nExtraWidth = 0; 304 nExtraWidth2 = 0; 305 } 306 else 307 { 308 mnItemsWidth += STATUSBAR_OFFSET_X; 309 310 // Bei linksbuendiger Ausrichtung muessen wir gegebenenfalls noch 311 // AutoSize auswerten 312 if ( nAutoSizeItems && (mnDX > (mnItemsWidth - STATUSBAR_OFFSET)) ) 313 { 314 nExtraWidth = (mnDX - mnItemsWidth - 1) / nAutoSizeItems; 315 nExtraWidth2 = (mnDX - mnItemsWidth - 1) % nAutoSizeItems; 316 } 317 else 318 { 319 nExtraWidth = 0; 320 nExtraWidth2 = 0; 321 } 322 nX = STATUSBAR_OFFSET_X; 323 if( ImplHasMirroredGraphics() && IsRTLEnabled() ) 324 nX += ImplGetSVData()->maNWFData.mnStatusBarLowerRightOffset; 325 } 326 327 pItem = mpItemList->First(); 328 while ( pItem ) 329 { 330 if ( pItem->mbVisible ) 331 { 332 if ( pItem->mnBits & SIB_AUTOSIZE ) 333 { 334 pItem->mnExtraWidth = nExtraWidth; 335 if ( nExtraWidth2 ) 336 { 337 pItem->mnExtraWidth++; 338 nExtraWidth2--; 339 } 340 } 341 else 342 pItem->mnExtraWidth = 0; 343 344 pItem->mnX = nX; 345 nX += pItem->mnWidth + pItem->mnExtraWidth + pItem->mnOffset; 346 } 347 348 pItem = mpItemList->Next(); 349 } 350 351 mbFormat = sal_False; 352 } 353 354 // ----------------------------------------------------------------------- 355 356 Rectangle StatusBar::ImplGetItemRectPos( sal_uInt16 nPos ) const 357 { 358 Rectangle aRect; 359 ImplStatusItem* pItem; 360 pItem = mpItemList->GetObject( nPos ); 361 if ( pItem ) 362 { 363 if ( pItem->mbVisible ) 364 { 365 aRect.Left() = pItem->mnX; 366 aRect.Right() = aRect.Left() + pItem->mnWidth + pItem->mnExtraWidth; 367 aRect.Top() = mnItemY; 368 aRect.Bottom() = mnCalcHeight - STATUSBAR_OFFSET_Y; 369 if( IsTopBorder() ) 370 aRect.Bottom()+=2; 371 } 372 } 373 374 return aRect; 375 } 376 377 // ----------------------------------------------------------------------- 378 379 sal_uInt16 StatusBar::ImplGetFirstVisiblePos() const 380 { 381 ImplStatusItem* pItem; 382 383 for( sal_uInt16 nPos = 0; nPos < mpItemList->Count(); nPos++ ) 384 { 385 pItem = mpItemList->GetObject( nPos ); 386 if ( pItem ) 387 { 388 if ( pItem->mbVisible ) 389 return nPos; 390 } 391 } 392 393 return ~0; 394 } 395 396 // ----------------------------------------------------------------------- 397 398 void StatusBar::ImplDrawText( sal_Bool bOffScreen, long nOldTextWidth ) 399 { 400 // Das ueberschreiben der Item-Box verhindern 401 Rectangle aTextRect; 402 aTextRect.Left() = STATUSBAR_OFFSET_X+1; 403 aTextRect.Top() = mnTextY; 404 if ( mbVisibleItems && (GetStyle() & WB_RIGHT) ) 405 aTextRect.Right() = mnDX - mnItemsWidth - 1; 406 else 407 aTextRect.Right() = mnDX - 1; 408 if ( aTextRect.Right() > aTextRect.Left() ) 409 { 410 // Position ermitteln 411 XubString aStr = GetText(); 412 sal_uInt16 nPos = aStr.Search( _LF ); 413 if ( nPos != STRING_NOTFOUND ) 414 aStr.Erase( nPos ); 415 416 aTextRect.Bottom() = aTextRect.Top()+GetTextHeight()+1; 417 418 if ( bOffScreen ) 419 { 420 long nMaxWidth = Max( nOldTextWidth, GetTextWidth( aStr ) ); 421 Size aVirDevSize( nMaxWidth, aTextRect.GetHeight() ); 422 mpImplData->mpVirDev->SetOutputSizePixel( aVirDevSize ); 423 Rectangle aTempRect = aTextRect; 424 aTempRect.SetPos( Point( 0, 0 ) ); 425 mpImplData->mpVirDev->DrawText( aTempRect, aStr, TEXT_DRAW_LEFT | TEXT_DRAW_TOP | TEXT_DRAW_CLIP | TEXT_DRAW_ENDELLIPSIS ); 426 DrawOutDev( aTextRect.TopLeft(), aVirDevSize, Point(), aVirDevSize, *mpImplData->mpVirDev ); 427 } 428 else 429 DrawText( aTextRect, aStr, TEXT_DRAW_LEFT | TEXT_DRAW_TOP | TEXT_DRAW_CLIP | TEXT_DRAW_ENDELLIPSIS ); 430 } 431 } 432 433 // ----------------------------------------------------------------------- 434 435 void StatusBar::ImplDrawItem( sal_Bool bOffScreen, sal_uInt16 nPos, sal_Bool bDrawText, sal_Bool bDrawFrame ) 436 { 437 Rectangle aRect = ImplGetItemRectPos( nPos ); 438 439 if ( aRect.IsEmpty() ) 440 return; 441 442 // Ausgabebereich berechnen 443 ImplStatusItem* pItem = mpItemList->GetObject( nPos ); 444 long nW = mpImplData->mnItemBorderWidth + 1; 445 Rectangle aTextRect( aRect.Left()+nW, aRect.Top()+nW, 446 aRect.Right()-nW, aRect.Bottom()-nW ); 447 Size aTextRectSize( aTextRect.GetSize() ); 448 449 if ( bOffScreen ) 450 mpImplData->mpVirDev->SetOutputSizePixel( aTextRectSize ); 451 else 452 { 453 Region aRegion( aTextRect ); 454 SetClipRegion( aRegion ); 455 } 456 457 // Text ausgeben 458 if ( bDrawText ) 459 { 460 Size aTextSize( GetTextWidth( pItem->maText ), GetTextHeight() ); 461 Point aTextPos = ImplGetItemTextPos( aTextRectSize, aTextSize, pItem->mnBits ); 462 if ( bOffScreen ) 463 mpImplData->mpVirDev->DrawText( aTextPos, pItem->maText ); 464 else 465 { 466 aTextPos.X() += aTextRect.Left(); 467 aTextPos.Y() += aTextRect.Top(); 468 DrawText( aTextPos, pItem->maText ); 469 } 470 } 471 472 // Gegebenenfalls auch DrawItem aufrufen 473 if ( pItem->mnBits & SIB_USERDRAW ) 474 { 475 if ( bOffScreen ) 476 { 477 mbInUserDraw = sal_True; 478 mpImplData->mpVirDev->EnableRTL( IsRTLEnabled() ); 479 UserDrawEvent aODEvt( mpImplData->mpVirDev, Rectangle( Point(), aTextRectSize ), pItem->mnId ); 480 UserDraw( aODEvt ); 481 mpImplData->mpVirDev->EnableRTL( sal_False ); 482 mbInUserDraw = sal_False; 483 } 484 else 485 { 486 UserDrawEvent aODEvt( this, aTextRect, pItem->mnId ); 487 UserDraw( aODEvt ); 488 } 489 } 490 491 if ( bOffScreen ) 492 DrawOutDev( aTextRect.TopLeft(), aTextRectSize, Point(), aTextRectSize, *mpImplData->mpVirDev ); 493 else 494 SetClipRegion(); 495 496 // Frame ausgeben 497 if ( bDrawFrame ) 498 { 499 if( mpImplData->mbDrawItemFrames ) 500 { 501 if( !(pItem->mnBits & SIB_FLAT) ) 502 { 503 sal_uInt16 nStyle; 504 505 if ( pItem->mnBits & SIB_IN ) 506 nStyle = FRAME_DRAW_IN; 507 else 508 nStyle = FRAME_DRAW_OUT; 509 510 DecorationView aDecoView( this ); 511 aDecoView.DrawFrame( aRect, nStyle ); 512 } 513 } 514 else if( nPos != ImplGetFirstVisiblePos() ) 515 { 516 // draw separator 517 Point aFrom( aRect.TopLeft() ); 518 aFrom.X()--; 519 aFrom.Y()++; 520 Point aTo( aRect.BottomLeft() ); 521 aTo.X()--; 522 aTo.Y()--; 523 524 DecorationView aDecoView( this ); 525 aDecoView.DrawSeparator( aFrom, aTo ); 526 } 527 } 528 529 if ( !ImplIsRecordLayout() ) 530 ImplCallEventListeners( VCLEVENT_STATUSBAR_DRAWITEM, (void*) sal_IntPtr(pItem->mnId) ); 531 } 532 533 // ----------------------------------------------------------------------- 534 535 void DrawProgress( Window* pWindow, const Point& rPos, 536 long nOffset, long nPrgsWidth, long nPrgsHeight, 537 sal_uInt16 nPercent1, sal_uInt16 nPercent2, sal_uInt16 nPercentCount, 538 const Rectangle& rFramePosSize 539 ) 540 { 541 if( pWindow->IsNativeControlSupported( CTRL_PROGRESS, PART_ENTIRE_CONTROL ) ) 542 { 543 bool bNeedErase = ImplGetSVData()->maNWFData.mbProgressNeedsErase; 544 545 long nFullWidth = (nPrgsWidth + nOffset) * (10000 / nPercentCount); 546 long nPerc = (nPercent2 > 10000) ? 10000 : nPercent2; 547 ImplControlValue aValue( nFullWidth * (long)nPerc / 10000 ); 548 Rectangle aDrawRect( rPos, Size( nFullWidth, nPrgsHeight ) ); 549 Rectangle aControlRegion( aDrawRect ); 550 if( bNeedErase ) 551 { 552 Window* pEraseWindow = pWindow; 553 while( pEraseWindow->IsPaintTransparent() && 554 ! pEraseWindow->ImplGetWindowImpl()->mbFrame ) 555 { 556 pEraseWindow = pEraseWindow->ImplGetWindowImpl()->mpParent; 557 } 558 if( pEraseWindow == pWindow ) 559 // restore background of pWindow 560 pEraseWindow->Erase( rFramePosSize ); 561 else 562 { 563 // restore transparent background 564 Point aTL( pWindow->OutputToAbsoluteScreenPixel( rFramePosSize.TopLeft() ) ); 565 aTL = pEraseWindow->AbsoluteScreenToOutputPixel( aTL ); 566 Rectangle aRect( aTL, rFramePosSize.GetSize() ); 567 pEraseWindow->Invalidate( aRect, INVALIDATE_NOCHILDREN | 568 INVALIDATE_NOCLIPCHILDREN | 569 INVALIDATE_TRANSPARENT ); 570 pEraseWindow->Update(); 571 } 572 pWindow->Push( PUSH_CLIPREGION ); 573 pWindow->IntersectClipRegion( rFramePosSize ); 574 } 575 sal_Bool bNativeOK = pWindow->DrawNativeControl( CTRL_PROGRESS, PART_ENTIRE_CONTROL, aControlRegion, 576 CTRL_STATE_ENABLED, aValue, rtl::OUString() ); 577 if( bNeedErase ) 578 pWindow->Pop(); 579 if( bNativeOK ) 580 { 581 pWindow->Flush(); 582 return; 583 } 584 } 585 586 // Werte vorberechnen 587 sal_uInt16 nPerc1 = nPercent1 / nPercentCount; 588 sal_uInt16 nPerc2 = nPercent2 / nPercentCount; 589 590 if ( nPerc1 > nPerc2 ) 591 { 592 // Support progress that can also decrease 593 594 // Rechteck berechnen 595 long nDX = nPrgsWidth + nOffset; 596 long nLeft = rPos.X()+((nPerc1-1)*nDX); 597 Rectangle aRect( nLeft, rPos.Y(), nLeft+nPrgsWidth, rPos.Y()+nPrgsHeight ); 598 599 do 600 { 601 pWindow->Erase( aRect ); 602 aRect.Left() -= nDX; 603 aRect.Right() -= nDX; 604 nPerc1--; 605 } 606 while ( nPerc1 > nPerc2 ); 607 608 pWindow->Flush(); 609 } 610 else if ( nPerc1 < nPerc2 ) 611 { 612 // Percent-Rechtecke malen 613 // Wenn Percent2 ueber 100%, Werte anpassen 614 if ( nPercent2 > 10000 ) 615 { 616 nPerc2 = 10000 / nPercentCount; 617 if ( nPerc1 >= nPerc2 ) 618 nPerc1 = nPerc2-1; 619 } 620 621 // Rechteck berechnen 622 long nDX = nPrgsWidth + nOffset; 623 long nLeft = rPos.X()+(nPerc1*nDX); 624 Rectangle aRect( nLeft, rPos.Y(), nLeft+nPrgsWidth, rPos.Y()+nPrgsHeight ); 625 626 do 627 { 628 pWindow->DrawRect( aRect ); 629 aRect.Left() += nDX; 630 aRect.Right() += nDX; 631 nPerc1++; 632 } 633 while ( nPerc1 < nPerc2 ); 634 635 // Bei mehr als 100%, lassen wir das Rechteck blinken 636 if ( nPercent2 > 10000 ) 637 { 638 // an/aus-Status festlegen 639 if ( ((nPercent2 / nPercentCount) & 0x01) == (nPercentCount & 0x01) ) 640 { 641 aRect.Left() -= nDX; 642 aRect.Right() -= nDX; 643 pWindow->Erase( aRect ); 644 } 645 } 646 647 pWindow->Flush(); 648 } 649 } 650 651 // ----------------------------------------------------------------------- 652 653 void StatusBar::ImplDrawProgress( sal_Bool bPaint, 654 sal_uInt16 nPercent1, sal_uInt16 nPercent2 ) 655 { 656 bool bNative = IsNativeControlSupported( CTRL_PROGRESS, PART_ENTIRE_CONTROL ); 657 // bPaint: draw text also, else only update progress 658 if ( bPaint ) 659 { 660 DrawText( maPrgsTxtPos, maPrgsTxt ); 661 if( ! bNative ) 662 { 663 DecorationView aDecoView( this ); 664 aDecoView.DrawFrame( maPrgsFrameRect, FRAME_DRAW_IN ); 665 } 666 } 667 668 Point aPos( maPrgsFrameRect.Left()+STATUSBAR_PRGS_OFFSET, 669 maPrgsFrameRect.Top()+STATUSBAR_PRGS_OFFSET ); 670 long nPrgsHeight = mnPrgsSize; 671 if( bNative ) 672 { 673 aPos = maPrgsFrameRect.TopLeft(); 674 nPrgsHeight = maPrgsFrameRect.GetHeight(); 675 } 676 DrawProgress( this, aPos, mnPrgsSize/2, mnPrgsSize, nPrgsHeight, 677 nPercent1*100, nPercent2*100, mnPercentCount, maPrgsFrameRect ); 678 } 679 680 // ----------------------------------------------------------------------- 681 682 void StatusBar::ImplCalcProgressRect() 683 { 684 // calculate text size 685 Size aPrgsTxtSize( GetTextWidth( maPrgsTxt ), GetTextHeight() ); 686 maPrgsTxtPos.X() = STATUSBAR_OFFSET_X+1; 687 688 // calculate progress frame 689 maPrgsFrameRect.Left() = maPrgsTxtPos.X()+aPrgsTxtSize.Width()+STATUSBAR_OFFSET; 690 maPrgsFrameRect.Top() = mnItemY; 691 maPrgsFrameRect.Bottom() = mnCalcHeight - STATUSBAR_OFFSET_Y; 692 if( IsTopBorder() ) 693 maPrgsFrameRect.Bottom()+=2; 694 695 // calculate size of progress rects 696 mnPrgsSize = maPrgsFrameRect.Bottom()-maPrgsFrameRect.Top()-(STATUSBAR_PRGS_OFFSET*2); 697 sal_uInt16 nMaxPercent = STATUSBAR_PRGS_COUNT; 698 699 long nMaxWidth = mnDX-STATUSBAR_OFFSET-1; 700 701 // make smaller if there are too many rects 702 while ( maPrgsFrameRect.Left()+ImplCalcProgessWidth( nMaxPercent, mnPrgsSize ) > nMaxWidth ) 703 { 704 nMaxPercent--; 705 if ( nMaxPercent <= STATUSBAR_PRGS_MIN ) 706 break; 707 } 708 maPrgsFrameRect.Right() = maPrgsFrameRect.Left() + ImplCalcProgessWidth( nMaxPercent, mnPrgsSize ); 709 710 // save the divisor for later 711 mnPercentCount = 10000 / nMaxPercent; 712 sal_Bool bNativeOK = sal_False; 713 if( IsNativeControlSupported( CTRL_PROGRESS, PART_ENTIRE_CONTROL ) ) 714 { 715 ImplControlValue aValue; 716 Rectangle aControlRegion( Rectangle( (const Point&)Point(), maPrgsFrameRect.GetSize() ) ); 717 Rectangle aNativeControlRegion, aNativeContentRegion; 718 if( (bNativeOK = GetNativeControlRegion( CTRL_PROGRESS, PART_ENTIRE_CONTROL, aControlRegion, 719 CTRL_STATE_ENABLED, aValue, rtl::OUString(), 720 aNativeControlRegion, aNativeContentRegion ) ) != sal_False ) 721 { 722 long nProgressHeight = aNativeControlRegion.GetHeight(); 723 if( nProgressHeight > maPrgsFrameRect.GetHeight() ) 724 { 725 long nDelta = nProgressHeight - maPrgsFrameRect.GetHeight(); 726 maPrgsFrameRect.Top() -= (nDelta - nDelta/2); 727 maPrgsFrameRect.Bottom() += nDelta/2; 728 } 729 maPrgsTxtPos.Y() = maPrgsFrameRect.Top() + (nProgressHeight - GetTextHeight())/2; 730 } 731 } 732 if( ! bNativeOK ) 733 maPrgsTxtPos.Y() = mnTextY; 734 } 735 736 // ----------------------------------------------------------------------- 737 738 void StatusBar::MouseButtonDown( const MouseEvent& rMEvt ) 739 { 740 // Nur bei linker Maustaste ToolBox ausloesen 741 if ( rMEvt.IsLeft() ) 742 { 743 if ( mbVisibleItems ) 744 { 745 Point aMousePos = rMEvt.GetPosPixel(); 746 sal_uInt16 i = 0; 747 748 // Item suchen, das geklickt wurde 749 ImplStatusItem* pItem = mpItemList->First(); 750 while ( pItem ) 751 { 752 // Ist es dieses Item 753 if ( ImplGetItemRectPos( i ).IsInside( aMousePos ) ) 754 { 755 mnCurItemId = pItem->mnId; 756 if ( rMEvt.GetClicks() == 2 ) 757 DoubleClick(); 758 else 759 Click(); 760 mnCurItemId = 0; 761 762 // Item wurde gefunden 763 return; 764 } 765 766 i++; 767 pItem = mpItemList->Next(); 768 } 769 } 770 771 // Kein Item, dann nur Click oder DoubleClick 772 if ( rMEvt.GetClicks() == 2 ) 773 DoubleClick(); 774 else 775 Click(); 776 } 777 } 778 779 // ----------------------------------------------------------------------- 780 781 void StatusBar::Paint( const Rectangle& ) 782 { 783 if ( mbFormat ) 784 ImplFormat(); 785 786 sal_uInt16 nItemCount = (sal_uInt16)mpItemList->Count(); 787 788 if ( mbProgressMode ) 789 ImplDrawProgress( sal_True, 0, mnPercent ); 790 else 791 { 792 // Text zeichen 793 if ( !mbVisibleItems || (GetStyle() & WB_RIGHT) ) 794 ImplDrawText( sal_False, 0 ); 795 796 // Items zeichnen 797 if ( mbVisibleItems ) 798 { 799 // Items zeichnen 800 for ( sal_uInt16 i = 0; i < nItemCount; i++ ) 801 ImplDrawItem( sal_False, i, sal_True, sal_True ); 802 } 803 } 804 805 // draw borders 806 if( IsTopBorder() ) 807 { 808 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); 809 SetLineColor( rStyleSettings.GetShadowColor() ); 810 DrawLine( Point( 0, 0 ), Point( mnDX-1, 0 ) ); 811 SetLineColor( rStyleSettings.GetLightColor() ); 812 DrawLine( Point( 0, 1 ), Point( mnDX-1, 1 ) ); 813 } 814 815 if ( IsBottomBorder() ) 816 { 817 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); 818 SetLineColor( rStyleSettings.GetShadowColor() ); 819 DrawLine( Point( 0, mnDY-2 ), Point( mnDX-1, mnDY-2 ) ); 820 SetLineColor( rStyleSettings.GetLightColor() ); 821 DrawLine( Point( 0, mnDY-1 ), Point( mnDX-1, mnDY-1 ) ); 822 } 823 } 824 825 // ----------------------------------------------------------------------- 826 827 void StatusBar::Move() 828 { 829 Window::Move(); 830 } 831 832 // ----------------------------------------------------------------------- 833 834 void StatusBar::Resize() 835 { 836 // Breite und Hoehe abfragen und merken 837 Size aSize = GetOutputSizePixel(); 838 mnDX = aSize.Width() - ImplGetSVData()->maNWFData.mnStatusBarLowerRightOffset; 839 mnDY = aSize.Height(); 840 mnCalcHeight = mnDY; 841 // subtract border 842 if( IsTopBorder() ) 843 mnCalcHeight -= 2; 844 if ( IsBottomBorder() ) 845 mnCalcHeight -= 2; 846 847 mnItemY = STATUSBAR_OFFSET_Y; 848 if( IsTopBorder() ) 849 mnItemY += 2; 850 mnTextY = (mnCalcHeight-GetTextHeight())/2; 851 if( IsTopBorder() ) 852 mnTextY += 2; 853 854 // Formatierung neu ausloesen 855 mbFormat = sal_True; 856 857 if ( mbProgressMode ) 858 ImplCalcProgressRect(); 859 860 Invalidate(); 861 } 862 863 // ----------------------------------------------------------------------- 864 865 void StatusBar::RequestHelp( const HelpEvent& rHEvt ) 866 { 867 // no keyboard help in status bar 868 if( rHEvt.KeyboardActivated() ) 869 return; 870 871 sal_uInt16 nItemId = GetItemId( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ) ); 872 873 if ( nItemId ) 874 { 875 Rectangle aItemRect = GetItemRect( nItemId ); 876 Point aPt = OutputToScreenPixel( aItemRect.TopLeft() ); 877 aItemRect.Left() = aPt.X(); 878 aItemRect.Top() = aPt.Y(); 879 aPt = OutputToScreenPixel( aItemRect.BottomRight() ); 880 aItemRect.Right() = aPt.X(); 881 aItemRect.Bottom() = aPt.Y(); 882 883 if ( rHEvt.GetMode() & HELPMODE_BALLOON ) 884 { 885 XubString aStr = GetHelpText( nItemId ); 886 Help::ShowBalloon( this, aItemRect.Center(), aItemRect, aStr ); 887 return; 888 } 889 else if ( rHEvt.GetMode() & HELPMODE_QUICK ) 890 { 891 XubString aStr = GetQuickHelpText( nItemId ); 892 // Show quickhelp if available 893 if( aStr.Len() ) 894 { 895 Help::ShowQuickHelp( this, aItemRect, aStr ); 896 return; 897 } 898 aStr = GetItemText( nItemId ); 899 // show a quick help if item text doesn't fit 900 if ( GetTextWidth( aStr ) > aItemRect.GetWidth() ) 901 { 902 Help::ShowQuickHelp( this, aItemRect, aStr ); 903 return; 904 } 905 } 906 else if ( rHEvt.GetMode() & HELPMODE_EXTENDED ) 907 { 908 String aCommand = GetItemCommand( nItemId ); 909 rtl::OString aHelpId( GetHelpId( nItemId ) ); 910 911 if ( aCommand.Len() || aHelpId.getLength() ) 912 { 913 // Wenn eine Hilfe existiert, dann ausloesen 914 Help* pHelp = Application::GetHelp(); 915 if ( pHelp ) 916 { 917 if ( aCommand.Len() ) 918 pHelp->Start( aCommand, this ); 919 else if ( aHelpId.getLength() ) 920 pHelp->Start( rtl::OStringToOUString( aHelpId, RTL_TEXTENCODING_UTF8 ), this ); 921 } 922 return; 923 } 924 } 925 } 926 927 Window::RequestHelp( rHEvt ); 928 } 929 930 // ----------------------------------------------------------------------- 931 932 void StatusBar::StateChanged( StateChangedType nType ) 933 { 934 Window::StateChanged( nType ); 935 936 if ( nType == STATE_CHANGE_INITSHOW ) 937 ImplFormat(); 938 else if ( nType == STATE_CHANGE_UPDATEMODE ) 939 Invalidate(); 940 else if ( (nType == STATE_CHANGE_ZOOM) || 941 (nType == STATE_CHANGE_CONTROLFONT) ) 942 { 943 mbFormat = sal_True; 944 ImplInitSettings( sal_True, sal_False, sal_False ); 945 Invalidate(); 946 } 947 else if ( nType == STATE_CHANGE_CONTROLFOREGROUND ) 948 { 949 ImplInitSettings( sal_False, sal_True, sal_False ); 950 Invalidate(); 951 } 952 else if ( nType == STATE_CHANGE_CONTROLBACKGROUND ) 953 { 954 ImplInitSettings( sal_False, sal_False, sal_True ); 955 Invalidate(); 956 } 957 } 958 959 // ----------------------------------------------------------------------- 960 961 void StatusBar::DataChanged( const DataChangedEvent& rDCEvt ) 962 { 963 Window::DataChanged( rDCEvt ); 964 965 if ( (rDCEvt.GetType() == DATACHANGED_DISPLAY) || 966 (rDCEvt.GetType() == DATACHANGED_FONTS) || 967 (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) || 968 ((rDCEvt.GetType() == DATACHANGED_SETTINGS) && 969 (rDCEvt.GetFlags() & SETTINGS_STYLE)) ) 970 { 971 mbFormat = sal_True; 972 ImplInitSettings( sal_True, sal_True, sal_True ); 973 ImplStatusItem* pItem = mpItemList->First(); 974 long nFudge = GetTextHeight() / 4; 975 while ( pItem ) 976 { 977 long nWidth = GetTextWidth( pItem->maText ) + nFudge; 978 if( nWidth > pItem->mnWidth + STATUSBAR_OFFSET ) 979 pItem->mnWidth = nWidth + STATUSBAR_OFFSET; 980 pItem = mpItemList->Next(); 981 } 982 Size aSize = GetSizePixel(); 983 // do not disturb current width, since 984 // CalcWindowSizePixel calculates a minimum width 985 aSize.Height() = CalcWindowSizePixel().Height(); 986 SetSizePixel( aSize ); 987 Invalidate(); 988 } 989 } 990 991 // ----------------------------------------------------------------------- 992 993 void StatusBar::Click() 994 { 995 ImplCallEventListeners( VCLEVENT_STATUSBAR_CLICK ); 996 maClickHdl.Call( this ); 997 } 998 999 // ----------------------------------------------------------------------- 1000 1001 void StatusBar::DoubleClick() 1002 { 1003 ImplCallEventListeners( VCLEVENT_STATUSBAR_DOUBLECLICK ); 1004 maDoubleClickHdl.Call( this ); 1005 } 1006 1007 // ----------------------------------------------------------------------- 1008 1009 void StatusBar::UserDraw( const UserDrawEvent& ) 1010 { 1011 } 1012 1013 // ----------------------------------------------------------------------- 1014 1015 void StatusBar::InsertItem( sal_uInt16 nItemId, sal_uLong nWidth, 1016 StatusBarItemBits nBits, 1017 long nOffset, sal_uInt16 nPos ) 1018 { 1019 DBG_ASSERT( nItemId, "StatusBar::InsertItem(): ItemId == 0" ); 1020 DBG_ASSERT( GetItemPos( nItemId ) == STATUSBAR_ITEM_NOTFOUND, 1021 "StatusBar::InsertItem(): ItemId already exists" ); 1022 1023 // IN und CENTER sind Default 1024 if ( !(nBits & (SIB_IN | SIB_OUT | SIB_FLAT)) ) 1025 nBits |= SIB_IN; 1026 if ( !(nBits & (SIB_LEFT | SIB_RIGHT | SIB_CENTER)) ) 1027 nBits |= SIB_CENTER; 1028 1029 // Item anlegen 1030 long nFudge = GetTextHeight()/4; 1031 ImplStatusItem* pItem = new ImplStatusItem; 1032 pItem->mnId = nItemId; 1033 pItem->mnBits = nBits; 1034 pItem->mnWidth = (long)nWidth+nFudge+STATUSBAR_OFFSET; 1035 pItem->mnOffset = nOffset; 1036 pItem->mpUserData = 0; 1037 pItem->mbVisible = sal_True; 1038 1039 // Item in die Liste einfuegen 1040 mpItemList->Insert( pItem, nPos ); 1041 1042 mbFormat = sal_True; 1043 if ( ImplIsItemUpdate() ) 1044 Invalidate(); 1045 1046 ImplCallEventListeners( VCLEVENT_STATUSBAR_ITEMADDED, (void*) sal_IntPtr(nItemId) ); 1047 } 1048 1049 // ----------------------------------------------------------------------- 1050 1051 void StatusBar::RemoveItem( sal_uInt16 nItemId ) 1052 { 1053 sal_uInt16 nPos = GetItemPos( nItemId ); 1054 if ( nPos != STATUSBAR_ITEM_NOTFOUND ) 1055 { 1056 ImplStatusItem* pItem = mpItemList->Remove( nPos ); 1057 delete pItem; 1058 1059 mbFormat = sal_True; 1060 if ( ImplIsItemUpdate() ) 1061 Invalidate(); 1062 1063 ImplCallEventListeners( VCLEVENT_STATUSBAR_ITEMREMOVED, (void*) sal_IntPtr(nItemId) ); 1064 } 1065 } 1066 1067 // ----------------------------------------------------------------------- 1068 1069 void StatusBar::ShowItem( sal_uInt16 nItemId ) 1070 { 1071 sal_uInt16 nPos = GetItemPos( nItemId ); 1072 1073 if ( nPos != STATUSBAR_ITEM_NOTFOUND ) 1074 { 1075 ImplStatusItem* pItem = mpItemList->GetObject( nPos ); 1076 if ( !pItem->mbVisible ) 1077 { 1078 pItem->mbVisible = sal_True; 1079 1080 mbFormat = sal_True; 1081 if ( ImplIsItemUpdate() ) 1082 Invalidate(); 1083 1084 ImplCallEventListeners( VCLEVENT_STATUSBAR_SHOWITEM, (void*) sal_IntPtr(nItemId) ); 1085 } 1086 } 1087 } 1088 1089 // ----------------------------------------------------------------------- 1090 1091 void StatusBar::HideItem( sal_uInt16 nItemId ) 1092 { 1093 sal_uInt16 nPos = GetItemPos( nItemId ); 1094 1095 if ( nPos != STATUSBAR_ITEM_NOTFOUND ) 1096 { 1097 ImplStatusItem* pItem = mpItemList->GetObject( nPos ); 1098 if ( pItem->mbVisible ) 1099 { 1100 pItem->mbVisible = sal_False; 1101 1102 mbFormat = sal_True; 1103 if ( ImplIsItemUpdate() ) 1104 Invalidate(); 1105 1106 ImplCallEventListeners( VCLEVENT_STATUSBAR_HIDEITEM, (void*) sal_IntPtr(nItemId) ); 1107 } 1108 } 1109 } 1110 1111 // ----------------------------------------------------------------------- 1112 1113 sal_Bool StatusBar::IsItemVisible( sal_uInt16 nItemId ) const 1114 { 1115 sal_uInt16 nPos = GetItemPos( nItemId ); 1116 1117 if ( nPos != STATUSBAR_ITEM_NOTFOUND ) 1118 return mpItemList->GetObject( nPos )->mbVisible; 1119 else 1120 return sal_False; 1121 } 1122 1123 // ----------------------------------------------------------------------- 1124 1125 void StatusBar::ShowItems() 1126 { 1127 if ( !mbVisibleItems ) 1128 { 1129 mbVisibleItems = sal_True; 1130 if ( !mbProgressMode ) 1131 Invalidate(); 1132 1133 ImplCallEventListeners( VCLEVENT_STATUSBAR_SHOWALLITEMS ); 1134 } 1135 } 1136 1137 // ----------------------------------------------------------------------- 1138 1139 void StatusBar::HideItems() 1140 { 1141 if ( mbVisibleItems ) 1142 { 1143 mbVisibleItems = sal_False; 1144 if ( !mbProgressMode ) 1145 Invalidate(); 1146 1147 ImplCallEventListeners( VCLEVENT_STATUSBAR_HIDEALLITEMS ); 1148 } 1149 } 1150 1151 // ----------------------------------------------------------------------- 1152 1153 void StatusBar::CopyItems( const StatusBar& rStatusBar ) 1154 { 1155 // Alle Items entfernen 1156 ImplStatusItem* pItem = mpItemList->First(); 1157 while ( pItem ) 1158 { 1159 delete pItem; 1160 pItem = mpItemList->Next(); 1161 } 1162 1163 // Items aus der Liste loeschen 1164 mpItemList->Clear(); 1165 1166 // Items kopieren 1167 sal_uLong i = 0; 1168 pItem = rStatusBar.mpItemList->GetObject( i ); 1169 while ( pItem ) 1170 { 1171 mpItemList->Insert( new ImplStatusItem( *pItem ), LIST_APPEND ); 1172 i++; 1173 pItem = rStatusBar.mpItemList->GetObject( i ); 1174 } 1175 1176 mbFormat = sal_True; 1177 if ( ImplIsItemUpdate() ) 1178 Invalidate(); 1179 } 1180 1181 // ----------------------------------------------------------------------- 1182 1183 void StatusBar::Clear() 1184 { 1185 // Alle Item loeschen 1186 ImplStatusItem* pItem = mpItemList->First(); 1187 while ( pItem ) 1188 { 1189 delete pItem; 1190 pItem = mpItemList->Next(); 1191 } 1192 1193 // Items aus der Liste loeschen 1194 mpItemList->Clear(); 1195 1196 mbFormat = sal_True; 1197 if ( ImplIsItemUpdate() ) 1198 Invalidate(); 1199 1200 ImplCallEventListeners( VCLEVENT_STATUSBAR_ALLITEMSREMOVED ); 1201 } 1202 1203 // ----------------------------------------------------------------------- 1204 1205 sal_uInt16 StatusBar::GetItemCount() const 1206 { 1207 return (sal_uInt16)mpItemList->Count(); 1208 } 1209 1210 // ----------------------------------------------------------------------- 1211 1212 sal_uInt16 StatusBar::GetItemId( sal_uInt16 nPos ) const 1213 { 1214 ImplStatusItem* pItem = mpItemList->GetObject( nPos ); 1215 if ( pItem ) 1216 return pItem->mnId; 1217 else 1218 return 0; 1219 } 1220 1221 // ----------------------------------------------------------------------- 1222 1223 sal_uInt16 StatusBar::GetItemPos( sal_uInt16 nItemId ) const 1224 { 1225 ImplStatusItem* pItem = mpItemList->First(); 1226 while ( pItem ) 1227 { 1228 if ( pItem->mnId == nItemId ) 1229 return (sal_uInt16)mpItemList->GetCurPos(); 1230 1231 pItem = mpItemList->Next(); 1232 } 1233 1234 return STATUSBAR_ITEM_NOTFOUND; 1235 } 1236 1237 // ----------------------------------------------------------------------- 1238 1239 sal_uInt16 StatusBar::GetItemId( const Point& rPos ) const 1240 { 1241 if ( AreItemsVisible() && !mbFormat ) 1242 { 1243 sal_uInt16 nItemCount = GetItemCount(); 1244 sal_uInt16 nPos; 1245 for ( nPos = 0; nPos < nItemCount; nPos++ ) 1246 { 1247 // Rechteck holen 1248 Rectangle aRect = ImplGetItemRectPos( nPos ); 1249 if ( aRect.IsInside( rPos ) ) 1250 return mpItemList->GetObject( nPos )->mnId; 1251 } 1252 } 1253 1254 return 0; 1255 } 1256 1257 // ----------------------------------------------------------------------- 1258 1259 Rectangle StatusBar::GetItemRect( sal_uInt16 nItemId ) const 1260 { 1261 Rectangle aRect; 1262 1263 if ( AreItemsVisible() && !mbFormat ) 1264 { 1265 sal_uInt16 nPos = GetItemPos( nItemId ); 1266 if ( nPos != STATUSBAR_ITEM_NOTFOUND ) 1267 { 1268 // Rechteck holen und Rahmen abziehen 1269 aRect = ImplGetItemRectPos( nPos ); 1270 long nW = mpImplData->mnItemBorderWidth+1; 1271 aRect.Top() += nW-1; 1272 aRect.Bottom() -= nW-1; 1273 aRect.Left() += nW; 1274 aRect.Right() -= nW; 1275 return aRect; 1276 } 1277 } 1278 1279 return aRect; 1280 } 1281 1282 // ----------------------------------------------------------------------- 1283 1284 Point StatusBar::GetItemTextPos( sal_uInt16 nItemId ) const 1285 { 1286 if ( !mbFormat ) 1287 { 1288 sal_uInt16 nPos = GetItemPos( nItemId ); 1289 if ( nPos != STATUSBAR_ITEM_NOTFOUND ) 1290 { 1291 // Rechteck holen 1292 ImplStatusItem* pItem = mpItemList->GetObject( nPos ); 1293 Rectangle aRect = ImplGetItemRectPos( nPos ); 1294 long nW = mpImplData->mnItemBorderWidth + 1; 1295 Rectangle aTextRect( aRect.Left()+nW, aRect.Top()+nW, 1296 aRect.Right()-nW, aRect.Bottom()-nW ); 1297 Point aPos = ImplGetItemTextPos( aTextRect.GetSize(), 1298 Size( GetTextWidth( pItem->maText ), GetTextHeight() ), 1299 pItem->mnBits ); 1300 if ( !mbInUserDraw ) 1301 { 1302 aPos.X() += aTextRect.Left(); 1303 aPos.Y() += aTextRect.Top(); 1304 } 1305 return aPos; 1306 } 1307 } 1308 1309 return Point(); 1310 } 1311 1312 // ----------------------------------------------------------------------- 1313 1314 sal_uLong StatusBar::GetItemWidth( sal_uInt16 nItemId ) const 1315 { 1316 sal_uInt16 nPos = GetItemPos( nItemId ); 1317 1318 if ( nPos != STATUSBAR_ITEM_NOTFOUND ) 1319 return mpItemList->GetObject( nPos )->mnWidth; 1320 else 1321 return 0; 1322 } 1323 1324 // ----------------------------------------------------------------------- 1325 1326 StatusBarItemBits StatusBar::GetItemBits( sal_uInt16 nItemId ) const 1327 { 1328 sal_uInt16 nPos = GetItemPos( nItemId ); 1329 1330 if ( nPos != STATUSBAR_ITEM_NOTFOUND ) 1331 return mpItemList->GetObject( nPos )->mnBits; 1332 else 1333 return 0; 1334 } 1335 1336 // ----------------------------------------------------------------------- 1337 1338 long StatusBar::GetItemOffset( sal_uInt16 nItemId ) const 1339 { 1340 sal_uInt16 nPos = GetItemPos( nItemId ); 1341 1342 if ( nPos != STATUSBAR_ITEM_NOTFOUND ) 1343 return mpItemList->GetObject( nPos )->mnOffset; 1344 else 1345 return 0; 1346 } 1347 1348 // ----------------------------------------------------------------------- 1349 1350 void StatusBar::SetItemText( sal_uInt16 nItemId, const XubString& rText ) 1351 { 1352 sal_uInt16 nPos = GetItemPos( nItemId ); 1353 1354 if ( nPos != STATUSBAR_ITEM_NOTFOUND ) 1355 { 1356 ImplStatusItem* pItem = mpItemList->GetObject( nPos ); 1357 1358 if ( pItem->maText != rText ) 1359 { 1360 pItem->maText = rText; 1361 1362 // adjust item width - see also DataChanged() 1363 long nFudge = GetTextHeight()/4; 1364 long nWidth = GetTextWidth( pItem->maText ) + nFudge; 1365 if( (nWidth > pItem->mnWidth + STATUSBAR_OFFSET) || 1366 ((nWidth < pItem->mnWidth) && (mnDX - STATUSBAR_OFFSET) < mnItemsWidth )) 1367 { 1368 pItem->mnWidth = nWidth + STATUSBAR_OFFSET; 1369 ImplFormat(); 1370 Invalidate(); 1371 } 1372 1373 // Item neu Zeichen, wenn StatusBar sichtbar und 1374 // UpdateMode gesetzt ist 1375 if ( pItem->mbVisible && !mbFormat && ImplIsItemUpdate() ) 1376 { 1377 Update(); 1378 ImplDrawItem( sal_True, nPos, sal_True, sal_False ); 1379 Flush(); 1380 } 1381 } 1382 } 1383 } 1384 1385 // ----------------------------------------------------------------------- 1386 1387 const XubString& StatusBar::GetItemText( sal_uInt16 nItemId ) const 1388 { 1389 sal_uInt16 nPos = GetItemPos( nItemId ); 1390 1391 if ( nPos != STATUSBAR_ITEM_NOTFOUND ) 1392 return mpItemList->GetObject( nPos )->maText; 1393 else 1394 return ImplGetSVEmptyStr(); 1395 } 1396 1397 // ----------------------------------------------------------------------- 1398 1399 void StatusBar::SetItemCommand( sal_uInt16 nItemId, const XubString& rCommand ) 1400 { 1401 sal_uInt16 nPos = GetItemPos( nItemId ); 1402 1403 if ( nPos != STATUSBAR_ITEM_NOTFOUND ) 1404 { 1405 ImplStatusItem* pItem = mpItemList->GetObject( nPos ); 1406 1407 if ( pItem->maCommand != rCommand ) 1408 pItem->maCommand = rCommand; 1409 } 1410 } 1411 1412 // ----------------------------------------------------------------------- 1413 1414 const XubString& StatusBar::GetItemCommand( sal_uInt16 nItemId ) 1415 { 1416 sal_uInt16 nPos = GetItemPos( nItemId ); 1417 1418 if ( nPos != STATUSBAR_ITEM_NOTFOUND ) 1419 return mpItemList->GetObject( nPos )->maCommand; 1420 else 1421 return ImplGetSVEmptyStr(); 1422 } 1423 1424 // ----------------------------------------------------------------------- 1425 1426 void StatusBar::SetItemData( sal_uInt16 nItemId, void* pNewData ) 1427 { 1428 sal_uInt16 nPos = GetItemPos( nItemId ); 1429 1430 if ( nPos != STATUSBAR_ITEM_NOTFOUND ) 1431 { 1432 ImplStatusItem* pItem = mpItemList->GetObject( nPos ); 1433 pItem->mpUserData = pNewData; 1434 1435 // Wenn es ein User-Item ist, DrawItem-Aufrufen 1436 if ( (pItem->mnBits & SIB_USERDRAW) && pItem->mbVisible && 1437 !mbFormat && ImplIsItemUpdate() ) 1438 { 1439 Update(); 1440 ImplDrawItem( sal_True, nPos, sal_False, sal_False ); 1441 Flush(); 1442 } 1443 } 1444 } 1445 1446 // ----------------------------------------------------------------------- 1447 1448 void* StatusBar::GetItemData( sal_uInt16 nItemId ) const 1449 { 1450 sal_uInt16 nPos = GetItemPos( nItemId ); 1451 1452 if ( nPos != STATUSBAR_ITEM_NOTFOUND ) 1453 return mpItemList->GetObject( nPos )->mpUserData; 1454 else 1455 return NULL; 1456 } 1457 1458 // ----------------------------------------------------------------------- 1459 1460 void StatusBar::SetHelpText( sal_uInt16 nItemId, const XubString& rText ) 1461 { 1462 sal_uInt16 nPos = GetItemPos( nItemId ); 1463 1464 if ( nPos != STATUSBAR_ITEM_NOTFOUND ) 1465 mpItemList->GetObject( nPos )->maHelpText = rText; 1466 } 1467 1468 // ----------------------------------------------------------------------- 1469 1470 const XubString& StatusBar::GetHelpText( sal_uInt16 nItemId ) const 1471 { 1472 sal_uInt16 nPos = GetItemPos( nItemId ); 1473 1474 if ( nPos != STATUSBAR_ITEM_NOTFOUND ) 1475 { 1476 ImplStatusItem* pItem = mpItemList->GetObject( nPos ); 1477 if ( !pItem->maHelpText.Len() && ( pItem->maHelpId.getLength() || pItem->maCommand.Len() )) 1478 { 1479 Help* pHelp = Application::GetHelp(); 1480 if ( pHelp ) 1481 { 1482 if ( pItem->maCommand.Len() ) 1483 pItem->maHelpText = pHelp->GetHelpText( pItem->maCommand, this ); 1484 if ( !pItem->maHelpText.Len() && pItem->maHelpId.getLength() ) 1485 pItem->maHelpText = pHelp->GetHelpText( rtl::OStringToOUString( pItem->maHelpId, RTL_TEXTENCODING_UTF8 ), this ); 1486 } 1487 } 1488 1489 return pItem->maHelpText; 1490 } 1491 else 1492 return ImplGetSVEmptyStr(); 1493 } 1494 1495 // ----------------------------------------------------------------------- 1496 1497 void StatusBar::SetQuickHelpText( sal_uInt16 nItemId, const XubString& rText ) 1498 { 1499 sal_uInt16 nPos = GetItemPos( nItemId ); 1500 1501 if ( nPos != STATUSBAR_ITEM_NOTFOUND ) 1502 mpItemList->GetObject( nPos )->maQuickHelpText = rText; 1503 } 1504 1505 // ----------------------------------------------------------------------- 1506 1507 const XubString& StatusBar::GetQuickHelpText( sal_uInt16 nItemId ) const 1508 { 1509 sal_uInt16 nPos = GetItemPos( nItemId ); 1510 1511 if ( nPos != STATUSBAR_ITEM_NOTFOUND ) 1512 { 1513 ImplStatusItem* pItem = mpItemList->GetObject( nPos ); 1514 return pItem->maQuickHelpText; 1515 } 1516 else 1517 return ImplGetSVEmptyStr(); 1518 } 1519 1520 // ----------------------------------------------------------------------- 1521 1522 void StatusBar::SetHelpId( sal_uInt16 nItemId, const rtl::OString& rHelpId ) 1523 { 1524 sal_uInt16 nPos = GetItemPos( nItemId ); 1525 1526 if ( nPos != STATUSBAR_ITEM_NOTFOUND ) 1527 mpItemList->GetObject( nPos )->maHelpId = rHelpId; 1528 } 1529 1530 // ----------------------------------------------------------------------- 1531 1532 rtl::OString StatusBar::GetHelpId( sal_uInt16 nItemId ) const 1533 { 1534 sal_uInt16 nPos = GetItemPos( nItemId ); 1535 1536 rtl::OString aRet; 1537 if ( nPos != STATUSBAR_ITEM_NOTFOUND ) 1538 { 1539 ImplStatusItem* pItem = mpItemList->GetObject( nPos ); 1540 if ( pItem->maHelpId.getLength() ) 1541 aRet = pItem->maHelpId; 1542 else 1543 aRet = ::rtl::OUStringToOString( pItem->maCommand, RTL_TEXTENCODING_UTF8 ); 1544 } 1545 1546 return aRet; 1547 } 1548 1549 // ----------------------------------------------------------------------- 1550 1551 void StatusBar::ImplCalcBorder( ) 1552 { 1553 mnCalcHeight = mnDY; 1554 // subtract border 1555 if( IsTopBorder() ) 1556 { 1557 mnCalcHeight -= 2; 1558 mnTextY += 2; 1559 mnItemY += 2; 1560 } 1561 if ( IsBottomBorder() ) 1562 mnCalcHeight -= 2; 1563 mbFormat = sal_True; 1564 Invalidate(); 1565 } 1566 1567 void StatusBar::SetBottomBorder( sal_Bool bBottomBorder ) 1568 { 1569 if ( mbBottomBorder != bBottomBorder ) 1570 { 1571 mbBottomBorder = bBottomBorder; 1572 ImplCalcBorder(); 1573 } 1574 } 1575 1576 void StatusBar::SetTopBorder( sal_Bool bTopBorder ) 1577 { 1578 if ( mpImplData->mbTopBorder != static_cast<bool>(bTopBorder) ) 1579 { 1580 mpImplData->mbTopBorder = static_cast<bool>(bTopBorder); 1581 ImplCalcBorder(); 1582 } 1583 } 1584 1585 sal_Bool StatusBar::IsTopBorder() const 1586 { 1587 return mpImplData->mbTopBorder; 1588 } 1589 1590 // ----------------------------------------------------------------------- 1591 1592 void StatusBar::StartProgressMode( const XubString& rText ) 1593 { 1594 DBG_ASSERT( !mbProgressMode, "StatusBar::StartProgressMode(): progress mode is active" ); 1595 1596 mbProgressMode = sal_True; 1597 mnPercent = 0; 1598 maPrgsTxt = rText; 1599 1600 // Groessen berechnen 1601 ImplCalcProgressRect(); 1602 1603 // Paint ausloesen (dort wird der Text und der Frame gemalt) 1604 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); 1605 Color aPrgsColor = rStyleSettings.GetHighlightColor(); 1606 if ( aPrgsColor == rStyleSettings.GetFaceColor() ) 1607 aPrgsColor = rStyleSettings.GetDarkShadowColor(); 1608 SetLineColor(); 1609 SetFillColor( aPrgsColor ); 1610 if ( IsReallyVisible() ) 1611 { 1612 Invalidate(); 1613 Update(); 1614 Flush(); 1615 } 1616 } 1617 1618 // ----------------------------------------------------------------------- 1619 1620 void StatusBar::SetProgressValue( sal_uInt16 nNewPercent ) 1621 { 1622 DBG_ASSERT( mbProgressMode, "StatusBar::SetProgressValue(): no progrss mode" ); 1623 DBG_ASSERTWARNING( nNewPercent <= 100, "StatusBar::SetProgressValue(): nPercent > 100" ); 1624 1625 if ( mbProgressMode 1626 && IsReallyVisible() 1627 && (!mnPercent || (mnPercent != nNewPercent)) ) 1628 { 1629 Update(); 1630 SetLineColor(); 1631 ImplDrawProgress( sal_False, mnPercent, nNewPercent ); 1632 Flush(); 1633 } 1634 mnPercent = nNewPercent; 1635 } 1636 1637 // ----------------------------------------------------------------------- 1638 1639 void StatusBar::EndProgressMode() 1640 { 1641 DBG_ASSERT( mbProgressMode, "StatusBar::EndProgressMode(): no progress mode" ); 1642 1643 mbProgressMode = sal_False; 1644 maPrgsTxt.Erase(); 1645 1646 // Paint neu ausloesen um StatusBar wieder herzustellen 1647 SetFillColor( GetSettings().GetStyleSettings().GetFaceColor() ); 1648 if ( IsReallyVisible() ) 1649 { 1650 Invalidate(); 1651 Update(); 1652 Flush(); 1653 } 1654 } 1655 1656 // ----------------------------------------------------------------------- 1657 1658 void StatusBar::ResetProgressMode() 1659 { 1660 if ( mbProgressMode ) 1661 { 1662 mnPercent = 0; 1663 maPrgsTxt.Erase(); 1664 if ( IsReallyVisible() ) 1665 { 1666 Invalidate(); 1667 Update(); 1668 Flush(); 1669 } 1670 } 1671 } 1672 1673 // ----------------------------------------------------------------------- 1674 1675 void StatusBar::SetText( const XubString& rText ) 1676 { 1677 if ( (!mbVisibleItems || (GetStyle() & WB_RIGHT)) && !mbProgressMode && 1678 IsReallyVisible() && IsUpdateMode() ) 1679 { 1680 if ( mbFormat ) 1681 { 1682 Invalidate(); 1683 Window::SetText( rText ); 1684 } 1685 else 1686 { 1687 Update(); 1688 long nOldTextWidth = GetTextWidth( GetText() ); 1689 Window::SetText( rText ); 1690 ImplDrawText( sal_True, nOldTextWidth ); 1691 Flush(); 1692 } 1693 } 1694 else if ( mbProgressMode ) 1695 { 1696 maPrgsTxt = rText; 1697 if ( IsReallyVisible() ) 1698 { 1699 Invalidate(); 1700 Update(); 1701 Flush(); 1702 } 1703 } 1704 else 1705 Window::SetText( rText ); 1706 } 1707 1708 // ----------------------------------------------------------------------- 1709 1710 Size StatusBar::CalcWindowSizePixel() const 1711 { 1712 sal_uLong i = 0; 1713 sal_uLong nCount = mpItemList->Count(); 1714 long nOffset = 0; 1715 long nCalcWidth = (STATUSBAR_OFFSET_X*2); 1716 long nCalcHeight; 1717 1718 while ( i < nCount ) 1719 { 1720 ImplStatusItem* pItem = mpItemList->GetObject( i ); 1721 nCalcWidth += pItem->mnWidth + nOffset; 1722 nOffset = pItem->mnOffset; 1723 i++; 1724 } 1725 1726 long nMinHeight = GetTextHeight(); 1727 const long nBarTextOffset = STATUSBAR_OFFSET_TEXTY*2; 1728 long nProgressHeight = nMinHeight + nBarTextOffset; 1729 // FIXME: IsNativeControlSupported and GetNativeControlRegion should be const ? 1730 StatusBar* pThis = const_cast<StatusBar*>( this ); 1731 if( pThis->IsNativeControlSupported( CTRL_PROGRESS, PART_ENTIRE_CONTROL ) ) 1732 { 1733 ImplControlValue aValue; 1734 Rectangle aControlRegion( (const Point&)Point(), Size( nCalcWidth, nMinHeight ) ); 1735 Rectangle aNativeControlRegion, aNativeContentRegion; 1736 if( pThis->GetNativeControlRegion( CTRL_PROGRESS, PART_ENTIRE_CONTROL, aControlRegion, 1737 CTRL_STATE_ENABLED, aValue, rtl::OUString(), 1738 aNativeControlRegion, aNativeContentRegion ) ) 1739 { 1740 nProgressHeight = aNativeControlRegion.GetHeight(); 1741 } 1742 } 1743 1744 if( mpImplData->mbDrawItemFrames && 1745 pThis->IsNativeControlSupported( CTRL_FRAME, PART_BORDER ) ) 1746 { 1747 ImplControlValue aControlValue( FRAME_DRAW_NODRAW ); 1748 Rectangle aBound, aContent; 1749 Rectangle aNatRgn( Point( 0, 0 ), Size( 150, 50 ) ); 1750 if( pThis->GetNativeControlRegion(CTRL_FRAME, PART_BORDER, 1751 aNatRgn, 0, aControlValue, rtl::OUString(), aBound, aContent) ) 1752 { 1753 mpImplData->mnItemBorderWidth = 1754 ( aBound.GetHeight() - aContent.GetHeight() ) / 2; 1755 } 1756 } 1757 1758 nCalcHeight = nMinHeight+nBarTextOffset + 2*mpImplData->mnItemBorderWidth; 1759 if( nCalcHeight < nProgressHeight+2 ) 1760 nCalcHeight = nProgressHeight+2; 1761 1762 // add border 1763 if( IsTopBorder() ) 1764 nCalcHeight += 2; 1765 if ( IsBottomBorder() ) 1766 nCalcHeight += 2; 1767 1768 return Size( nCalcWidth, nCalcHeight ); 1769 } 1770 1771 1772 // ----------------------------------------------------------------------- 1773 1774 void StatusBar::SetAccessibleName( sal_uInt16 nItemId, const XubString& rName ) 1775 { 1776 sal_uInt16 nPos = GetItemPos( nItemId ); 1777 1778 if ( nPos != STATUSBAR_ITEM_NOTFOUND ) 1779 { 1780 ImplStatusItem* pItem = mpItemList->GetObject( nPos ); 1781 1782 if ( pItem->maAccessibleName != rName ) 1783 { 1784 pItem->maAccessibleName = rName; 1785 ImplCallEventListeners( VCLEVENT_STATUSBAR_NAMECHANGED, (void*) sal_IntPtr(pItem->mnId) ); 1786 } 1787 } 1788 } 1789 1790 // ----------------------------------------------------------------------- 1791 1792 const XubString& StatusBar::GetAccessibleName( sal_uInt16 nItemId ) const 1793 { 1794 sal_uInt16 nPos = GetItemPos( nItemId ); 1795 1796 if ( nPos != STATUSBAR_ITEM_NOTFOUND ) 1797 return mpItemList->GetObject( nPos )->maAccessibleName; 1798 else 1799 return ImplGetSVEmptyStr(); 1800 } 1801 1802 // ----------------------------------------------------------------------- 1803