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