build fix: no comphelper/profilezone.hxx in this branch
[LibreOffice.git] / vcl / source / window / status.cxx
blobd541d888cfe8c7d5ab66c2d36841bd21442e4279
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <tools/debug.hxx>
21 #include <tools/rc.h>
23 #include <vcl/event.hxx>
24 #include <vcl/decoview.hxx>
25 #include <vcl/svapp.hxx>
26 #include <vcl/help.hxx>
27 #include <vcl/status.hxx>
28 #include <vcl/virdev.hxx>
29 #include <vcl/settings.hxx>
30 #include <config_features.h>
31 #if HAVE_FEATURE_OPENGL
32 #include <vcl/opengl/OpenGLWrapper.hxx>
33 #endif
34 #include <svdata.hxx>
35 #include <window.h>
37 #define STATUSBAR_OFFSET_X STATUSBAR_OFFSET
38 #define STATUSBAR_OFFSET_Y 2
39 #define STATUSBAR_OFFSET_TEXTY 3
41 #define STATUSBAR_PRGS_OFFSET 3
42 #define STATUSBAR_PRGS_COUNT 100
43 #define STATUSBAR_PRGS_MIN 5
45 class StatusBar::ImplData
47 public:
48 ImplData();
50 VclPtr<VirtualDevice> mpVirDev;
51 long mnItemBorderWidth;
52 bool mbDrawItemFrames:1;
55 StatusBar::ImplData::ImplData()
57 mpVirDev = nullptr;
58 mbDrawItemFrames = false;
59 mnItemBorderWidth = 0;
62 struct ImplStatusItem
64 sal_uInt16 mnId;
65 StatusBarItemBits mnBits;
66 long mnWidth;
67 long mnOffset;
68 long mnExtraWidth;
69 long mnX;
70 OUString maText;
71 OUString maHelpText;
72 OUString maQuickHelpText;
73 OString maHelpId;
74 void* mpUserData;
75 bool mbVisible;
76 OUString maAccessibleName;
77 OUString maCommand;
80 inline long ImplCalcProgessWidth( sal_uInt16 nMax, long nSize )
82 return ((nMax*(nSize+(nSize/2)))-(nSize/2)+(STATUSBAR_PRGS_OFFSET*2));
85 static Point ImplGetItemTextPos( const Size& rRectSize, const Size& rTextSize,
86 StatusBarItemBits nStyle )
88 long nX;
89 long nY;
90 long delta = (rTextSize.Height()/4) + 1;
91 if( delta + rTextSize.Width() > rRectSize.Width() )
92 delta = 0;
94 if ( nStyle & StatusBarItemBits::Left )
95 nX = delta;
96 else if ( nStyle & StatusBarItemBits::Right )
97 nX = rRectSize.Width()-rTextSize.Width()-delta;
98 else // StatusBarItemBits::Center
99 nX = (rRectSize.Width()-rTextSize.Width())/2;
100 nY = (rRectSize.Height()-rTextSize.Height())/2 + 1;
101 return Point( nX, nY );
104 bool StatusBar::ImplIsItemUpdate()
106 if ( !mbProgressMode && mbVisibleItems && IsReallyVisible() && IsUpdateMode() )
107 return true;
108 else
109 return false;
112 void StatusBar::ImplInit( vcl::Window* pParent, WinBits nStyle )
114 mpImplData = new ImplData;
116 // default: RightAlign
117 if ( !(nStyle & (WB_LEFT | WB_RIGHT)) )
118 nStyle |= WB_RIGHT;
120 Window::ImplInit( pParent, nStyle & ~WB_BORDER, nullptr );
122 // remember WinBits
123 mpImplData->mpVirDev = VclPtr<VirtualDevice>::Create( *this );
124 mnCurItemId = 0;
125 mbFormat = true;
126 mbVisibleItems = true;
127 mbProgressMode = false;
128 mbInUserDraw = false;
129 mbAdjustHiDPI = false;
130 mnItemsWidth = STATUSBAR_OFFSET_X;
131 mnDX = 0;
132 mnDY = 0;
133 mnCalcHeight = 0;
134 mnItemY = STATUSBAR_OFFSET_Y;
135 mnTextY = STATUSBAR_OFFSET_TEXTY;
137 ImplInitSettings();
139 SetOutputSizePixel( CalcWindowSizePixel() );
142 StatusBar::StatusBar( vcl::Window* pParent, WinBits nStyle ) :
143 Window( WINDOW_STATUSBAR )
145 ImplInit( pParent, nStyle );
148 StatusBar::~StatusBar()
150 disposeOnce();
153 void StatusBar::dispose()
155 // delete all items
156 for (ImplStatusItem* i : mpItemList) {
157 delete i;
159 mpItemList.clear();
161 // delete VirtualDevice
162 mpImplData->mpVirDev.disposeAndClear();
163 delete mpImplData;
164 Window::dispose();
167 void StatusBar::AdjustItemWidthsForHiDPI()
169 mbAdjustHiDPI = true;
172 void StatusBar::ApplySettings(vcl::RenderContext& rRenderContext)
174 rRenderContext.SetLineColor();
176 const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
177 vcl::Font aFont = rStyleSettings.GetToolFont();
178 if (IsControlFont())
179 aFont.Merge(GetControlFont());
180 SetZoomedPointFont(rRenderContext, aFont);
182 Color aColor;
183 if (IsControlForeground())
184 aColor = GetControlForeground();
185 else if (GetStyle() & WB_3DLOOK)
186 aColor = rStyleSettings.GetButtonTextColor();
187 else
188 aColor = rStyleSettings.GetWindowTextColor();
190 rRenderContext.SetTextColor(aColor);
191 rRenderContext.SetTextFillColor();
193 if (IsControlBackground())
194 aColor = GetControlBackground();
195 else if (GetStyle() & WB_3DLOOK)
196 aColor = rStyleSettings.GetFaceColor();
197 else
198 aColor = rStyleSettings.GetWindowColor();
199 rRenderContext.SetBackground(aColor);
201 // NWF background
202 if (!IsControlBackground() &&
203 rRenderContext.IsNativeControlSupported(ControlType::WindowBackground, ControlPart::BackgroundWindow))
205 ImplGetWindowImpl()->mnNativeBackground = ControlPart::BackgroundWindow;
206 EnableChildTransparentMode();
210 void StatusBar::ImplInitSettings()
212 ApplySettings(*this);
214 mpImplData->mpVirDev->SetFont(GetFont());
215 mpImplData->mpVirDev->SetTextColor(GetTextColor());
216 mpImplData->mpVirDev->SetTextAlign(GetTextAlign());
217 mpImplData->mpVirDev->SetTextFillColor();
218 mpImplData->mpVirDev->SetBackground(GetBackground());
221 void StatusBar::ImplFormat()
223 ImplStatusItem* pItem;
224 long nExtraWidth;
225 long nExtraWidth2;
226 long nX;
227 sal_uInt16 nAutoSizeItems = 0;
229 // sum up widths
230 mnItemsWidth = STATUSBAR_OFFSET_X;
231 long nOffset = 0;
232 for (ImplStatusItem* i : mpItemList) {
233 pItem = i;
234 if ( pItem->mbVisible )
236 if ( pItem->mnBits & StatusBarItemBits::AutoSize ) {
237 nAutoSizeItems++;
240 mnItemsWidth += pItem->mnWidth + nOffset;
241 nOffset = pItem->mnOffset;
245 if ( GetStyle() & WB_RIGHT )
247 // AutoSize isn't computed for right-alignment,
248 // because we show the text that is declared by SetText on the left side
249 nX = mnDX - mnItemsWidth;
250 nExtraWidth = 0;
251 nExtraWidth2 = 0;
253 else
255 mnItemsWidth += STATUSBAR_OFFSET_X;
257 // calling AutoSize is potentially necessary for left-aligned text,
258 if ( nAutoSizeItems && (mnDX > (mnItemsWidth - STATUSBAR_OFFSET)) )
260 nExtraWidth = (mnDX - mnItemsWidth - 1) / nAutoSizeItems;
261 nExtraWidth2 = (mnDX - mnItemsWidth - 1) % nAutoSizeItems;
263 else
265 nExtraWidth = 0;
266 nExtraWidth2 = 0;
268 nX = STATUSBAR_OFFSET_X;
270 if( HasMirroredGraphics() && IsRTLEnabled() )
271 nX += ImplGetSVData()->maNWFData.mnStatusBarLowerRightOffset;
274 for (ImplStatusItem* i : mpItemList) {
275 pItem = i;
276 if ( pItem->mbVisible ) {
277 if ( pItem->mnBits & StatusBarItemBits::AutoSize ) {
278 pItem->mnExtraWidth = nExtraWidth;
279 if ( nExtraWidth2 ) {
280 pItem->mnExtraWidth++;
281 nExtraWidth2--;
283 } else {
284 pItem->mnExtraWidth = 0;
287 pItem->mnX = nX;
288 nX += pItem->mnWidth + pItem->mnExtraWidth + pItem->mnOffset;
292 mbFormat = false;
295 Rectangle StatusBar::ImplGetItemRectPos( sal_uInt16 nPos ) const
297 Rectangle aRect;
298 ImplStatusItem* pItem;
299 pItem = ( nPos < mpItemList.size() ) ? mpItemList[ nPos ] : nullptr;
300 if ( pItem )
302 if ( pItem->mbVisible )
304 aRect.Left() = pItem->mnX;
305 aRect.Right() = aRect.Left() + pItem->mnWidth + pItem->mnExtraWidth;
306 aRect.Top() = mnItemY;
307 aRect.Bottom() = mnCalcHeight - STATUSBAR_OFFSET_Y;
311 return aRect;
314 sal_uInt16 StatusBar::ImplGetFirstVisiblePos() const
316 for( size_t nPos = 0; nPos < mpItemList.size(); nPos++ )
318 ImplStatusItem* pItem = mpItemList[ nPos ];
319 if ( pItem )
321 if ( pItem->mbVisible )
322 return sal_uInt16(nPos);
326 return SAL_MAX_UINT16;
329 void StatusBar::ImplDrawText(vcl::RenderContext& rRenderContext)
331 // prevent item box from being overwritten
332 Rectangle aTextRect;
333 aTextRect.Left() = STATUSBAR_OFFSET_X + 1;
334 aTextRect.Top() = mnTextY;
335 if (mbVisibleItems && (GetStyle() & WB_RIGHT))
336 aTextRect.Right() = mnDX - mnItemsWidth - 1;
337 else
338 aTextRect.Right() = mnDX - 1;
339 if (aTextRect.Right() > aTextRect.Left())
341 // compute position
342 OUString aStr = GetText();
343 sal_Int32 nPos = aStr.indexOf('\n');
344 if (nPos != -1)
345 aStr = aStr.copy(0, nPos);
347 aTextRect.Bottom() = aTextRect.Top()+GetTextHeight()+1;
349 rRenderContext.DrawText(aTextRect, aStr, DrawTextFlags::Left | DrawTextFlags::Top | DrawTextFlags::Clip | DrawTextFlags::EndEllipsis);
353 void StatusBar::ImplDrawItem(vcl::RenderContext& rRenderContext, bool bOffScreen, sal_uInt16 nPos)
355 Rectangle aRect = ImplGetItemRectPos(nPos);
357 if (aRect.IsEmpty())
358 return;
360 // compute output region
361 ImplStatusItem* pItem = mpItemList[nPos];
362 long nW = mpImplData->mnItemBorderWidth + 1;
363 Rectangle aTextRect(aRect.Left() + nW, aRect.Top() + nW,
364 aRect.Right() - nW, aRect.Bottom() - nW);
366 Size aTextRectSize(aTextRect.GetSize());
368 if (bOffScreen)
370 mpImplData->mpVirDev->SetOutputSizePixel(aTextRectSize);
372 else
374 vcl::Region aRegion(aTextRect);
375 rRenderContext.SetClipRegion(aRegion);
378 // print text
379 Size aTextSize(rRenderContext.GetTextWidth(pItem->maText), rRenderContext.GetTextHeight());
380 Point aTextPos = ImplGetItemTextPos(aTextRectSize, aTextSize, pItem->mnBits);
381 if (bOffScreen)
383 mpImplData->mpVirDev->DrawText(aTextPos, pItem->maText);
385 else
387 aTextPos.X() += aTextRect.Left();
388 aTextPos.Y() += aTextRect.Top();
389 rRenderContext.DrawText(aTextPos, pItem->maText);
392 // call DrawItem if necessary
393 if (pItem->mnBits & StatusBarItemBits::UserDraw)
395 if (bOffScreen)
397 mbInUserDraw = true;
398 mpImplData->mpVirDev->EnableRTL( IsRTLEnabled() );
399 UserDrawEvent aODEvt(this, mpImplData->mpVirDev, Rectangle(Point(), aTextRectSize), pItem->mnId);
400 UserDraw(aODEvt);
401 mpImplData->mpVirDev->EnableRTL(false);
402 mbInUserDraw = false;
404 else
406 UserDrawEvent aODEvt(this, &rRenderContext, aTextRect, pItem->mnId);
407 UserDraw(aODEvt);
411 if (bOffScreen)
412 rRenderContext.DrawOutDev(aTextRect.TopLeft(), aTextRectSize, Point(), aTextRectSize, *mpImplData->mpVirDev);
413 else
414 rRenderContext.SetClipRegion();
416 // show frame
417 if (mpImplData->mbDrawItemFrames)
419 if (!(pItem->mnBits & StatusBarItemBits::Flat))
421 DrawFrameStyle nStyle;
423 if (pItem->mnBits & StatusBarItemBits::In)
424 nStyle = DrawFrameStyle::In;
425 else
426 nStyle = DrawFrameStyle::Out;
428 DecorationView aDecoView(&rRenderContext);
429 aDecoView.DrawFrame(aRect, nStyle);
432 else if (nPos != ImplGetFirstVisiblePos())
434 // draw separator
435 Point aFrom(aRect.TopLeft());
436 aFrom.X() -= 4;
437 aFrom.Y()++;
438 Point aTo(aRect.BottomLeft());
439 aTo.X() -= 4;
440 aTo.Y()--;
442 DecorationView aDecoView(&rRenderContext);
443 aDecoView.DrawSeparator(aFrom, aTo);
446 if (!rRenderContext.ImplIsRecordLayout())
447 CallEventListeners(VCLEVENT_STATUSBAR_DRAWITEM, reinterpret_cast<void*>(pItem->mnId));
450 void DrawProgress(vcl::Window* pWindow, vcl::RenderContext& rRenderContext, const Point& rPos,
451 long nOffset, long nPrgsWidth, long nPrgsHeight,
452 sal_uInt16 nPercent1, sal_uInt16 nPercent2, sal_uInt16 nPercentCount,
453 const Rectangle& rFramePosSize)
455 if (rRenderContext.IsNativeControlSupported(ControlType::Progress, ControlPart::Entire))
457 bool bNeedErase = ImplGetSVData()->maNWFData.mbProgressNeedsErase;
459 long nFullWidth = (nPrgsWidth + nOffset) * (10000 / nPercentCount);
460 long nPerc = (nPercent2 > 10000) ? 10000 : nPercent2;
461 ImplControlValue aValue(nFullWidth * long(nPerc) / 10000);
462 Rectangle aDrawRect(rPos, Size(nFullWidth, nPrgsHeight));
463 Rectangle aControlRegion(aDrawRect);
465 if(bNeedErase)
467 vcl::Window* pEraseWindow = pWindow;
468 while (pEraseWindow->IsPaintTransparent() && !pEraseWindow->ImplGetWindowImpl()->mbFrame)
470 pEraseWindow = pEraseWindow->ImplGetWindowImpl()->mpParent;
473 if (pEraseWindow == pWindow)
475 // restore background of pWindow
476 rRenderContext.Erase(rFramePosSize);
478 else
480 // restore transparent background
481 Point aTL(pWindow->OutputToAbsoluteScreenPixel(rFramePosSize.TopLeft()));
482 aTL = pEraseWindow->AbsoluteScreenToOutputPixel(aTL);
483 Rectangle aRect(aTL, rFramePosSize.GetSize());
484 pEraseWindow->Invalidate(aRect, InvalidateFlags::NoChildren |
485 InvalidateFlags::NoClipChildren |
486 InvalidateFlags::Transparent);
487 pEraseWindow->Update();
489 rRenderContext.Push(PushFlags::CLIPREGION);
490 rRenderContext.IntersectClipRegion(rFramePosSize);
493 bool bNativeOK = rRenderContext.DrawNativeControl(ControlType::Progress, ControlPart::Entire, aControlRegion,
494 ControlState::ENABLED, aValue, OUString());
495 if (bNeedErase)
496 rRenderContext.Pop();
497 if (bNativeOK)
498 return;
501 // precompute values
502 sal_uInt16 nPerc1 = nPercent1 / nPercentCount;
503 sal_uInt16 nPerc2 = nPercent2 / nPercentCount;
505 if (nPerc1 > nPerc2)
507 // support progress that can also decrease
509 // compute rectangle
510 long nDX = nPrgsWidth + nOffset;
511 long nLeft = rPos.X() + ((nPerc1 - 1) * nDX);
512 Rectangle aRect(nLeft, rPos.Y(), nLeft + nPrgsWidth, rPos.Y() + nPrgsHeight);
516 rRenderContext.Erase(aRect);
517 aRect.Left() -= nDX;
518 aRect.Right() -= nDX;
519 nPerc1--;
521 while (nPerc1 > nPerc2);
523 else if (nPerc1 < nPerc2)
525 // draw Percent rectangle
526 // if Percent2 greater than 100%, adapt values
527 if (nPercent2 > 10000)
529 nPerc2 = 10000 / nPercentCount;
530 if (nPerc1 >= nPerc2)
531 nPerc1 = nPerc2 - 1;
534 // compute rectangle
535 long nDX = nPrgsWidth + nOffset;
536 long nLeft = rPos.X() + (nPerc1 * nDX);
537 Rectangle aRect(nLeft, rPos.Y(), nLeft + nPrgsWidth, rPos.Y() + nPrgsHeight);
541 rRenderContext.DrawRect(aRect);
542 aRect.Left() += nDX;
543 aRect.Right() += nDX;
544 nPerc1++;
546 while (nPerc1 < nPerc2);
548 // if greater than 100%, set rectangle to blink
549 if (nPercent2 > 10000)
551 // define on/off status
552 if (((nPercent2 / nPercentCount) & 0x01) == (nPercentCount & 0x01))
554 aRect.Left() -= nDX;
555 aRect.Right() -= nDX;
556 rRenderContext.Erase(aRect);
562 void StatusBar::ImplDrawProgress(vcl::RenderContext& rRenderContext, sal_uInt16 nPercent2)
564 bool bNative = rRenderContext.IsNativeControlSupported(ControlType::Progress, ControlPart::Entire);
565 // bPaint: draw text also, else only update progress
566 rRenderContext.DrawText(maPrgsTxtPos, maPrgsTxt);
567 if (!bNative)
569 DecorationView aDecoView(&rRenderContext);
570 aDecoView.DrawFrame(maPrgsFrameRect, DrawFrameStyle::In);
573 Point aPos(maPrgsFrameRect.Left() + STATUSBAR_PRGS_OFFSET,
574 maPrgsFrameRect.Top() + STATUSBAR_PRGS_OFFSET);
575 long nPrgsHeight = mnPrgsSize;
576 if (bNative)
578 aPos = maPrgsFrameRect.TopLeft();
579 nPrgsHeight = maPrgsFrameRect.GetHeight();
581 DrawProgress(this, rRenderContext, aPos, mnPrgsSize / 2, mnPrgsSize, nPrgsHeight,
582 0, nPercent2 * 100, mnPercentCount, maPrgsFrameRect);
585 void StatusBar::ImplCalcProgressRect()
587 // calculate text size
588 Size aPrgsTxtSize( GetTextWidth( maPrgsTxt ), GetTextHeight() );
589 maPrgsTxtPos.X() = STATUSBAR_OFFSET_X+1;
591 // calculate progress frame
592 maPrgsFrameRect.Left() = maPrgsTxtPos.X()+aPrgsTxtSize.Width()+STATUSBAR_OFFSET;
593 maPrgsFrameRect.Top() = mnItemY;
594 maPrgsFrameRect.Bottom() = mnCalcHeight - STATUSBAR_OFFSET_Y;
596 // calculate size of progress rects
597 mnPrgsSize = maPrgsFrameRect.Bottom()-maPrgsFrameRect.Top()-(STATUSBAR_PRGS_OFFSET*2);
598 sal_uInt16 nMaxPercent = STATUSBAR_PRGS_COUNT;
600 long nMaxWidth = mnDX-STATUSBAR_OFFSET-1;
602 // make smaller if there are too many rects
603 while ( maPrgsFrameRect.Left()+ImplCalcProgessWidth( nMaxPercent, mnPrgsSize ) > nMaxWidth )
605 nMaxPercent--;
606 if ( nMaxPercent <= STATUSBAR_PRGS_MIN )
607 break;
609 maPrgsFrameRect.Right() = maPrgsFrameRect.Left() + ImplCalcProgessWidth( nMaxPercent, mnPrgsSize );
611 // save the divisor for later
612 mnPercentCount = 10000 / nMaxPercent;
613 bool bNativeOK = false;
614 if( IsNativeControlSupported( ControlType::Progress, ControlPart::Entire ) )
616 ImplControlValue aValue;
617 Rectangle aControlRegion( Rectangle( (const Point&)Point(), maPrgsFrameRect.GetSize() ) );
618 Rectangle aNativeControlRegion, aNativeContentRegion;
619 if( (bNativeOK = GetNativeControlRegion( ControlType::Progress, ControlPart::Entire, aControlRegion,
620 ControlState::ENABLED, aValue, OUString(),
621 aNativeControlRegion, aNativeContentRegion ) ) )
623 long nProgressHeight = aNativeControlRegion.GetHeight();
624 if( nProgressHeight > maPrgsFrameRect.GetHeight() )
626 long nDelta = nProgressHeight - maPrgsFrameRect.GetHeight();
627 maPrgsFrameRect.Top() -= (nDelta - nDelta/2);
628 maPrgsFrameRect.Bottom() += nDelta/2;
630 maPrgsTxtPos.Y() = maPrgsFrameRect.Top() + (nProgressHeight - GetTextHeight())/2;
633 if( ! bNativeOK )
634 maPrgsTxtPos.Y() = mnTextY;
637 void StatusBar::MouseButtonDown( const MouseEvent& rMEvt )
639 // trigger toolbox only for left mouse button
640 if ( rMEvt.IsLeft() )
642 if ( mbVisibleItems )
644 Point aMousePos = rMEvt.GetPosPixel();
646 // search for clicked item
647 for ( size_t i = 0; i < mpItemList.size(); ++i )
649 ImplStatusItem* pItem = mpItemList[ i ];
650 // check item for being clicked
651 if ( ImplGetItemRectPos( sal_uInt16(i) ).IsInside( aMousePos ) )
653 mnCurItemId = pItem->mnId;
654 if ( rMEvt.GetClicks() == 2 )
655 DoubleClick();
656 else
657 Click();
658 mnCurItemId = 0;
660 // Item found
661 return;
666 // if there's no item, trigger Click or DoubleClick
667 if ( rMEvt.GetClicks() == 2 )
668 DoubleClick();
669 else
670 Click();
674 void StatusBar::Paint(vcl::RenderContext& rRenderContext, const Rectangle& rRect)
676 if (mbFormat)
677 ImplFormat();
679 sal_uInt16 nItemCount = sal_uInt16( mpItemList.size() );
681 if (mbProgressMode)
683 rRenderContext.Push(PushFlags::FILLCOLOR | PushFlags::LINECOLOR);
685 const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
686 Color aProgressColor = rStyleSettings.GetHighlightColor();
687 if (aProgressColor == rStyleSettings.GetFaceColor())
688 aProgressColor = rStyleSettings.GetDarkShadowColor();
689 rRenderContext.SetLineColor();
690 rRenderContext.SetFillColor(aProgressColor);
692 ImplDrawProgress(rRenderContext, mnPercent);
694 rRenderContext.Pop();
696 else
698 // draw text
699 if (!mbVisibleItems || (GetStyle() & WB_RIGHT))
700 ImplDrawText(rRenderContext);
702 // draw items
703 if (mbVisibleItems)
705 // Do offscreen only when we are not recording layout..
706 bool bOffscreen = !rRenderContext.ImplIsRecordLayout();
708 // tdf#94213 - un-necessary virtual-device in GL mode
709 // causes context switch & hence flicker during sizing.
710 #if HAVE_FEATURE_OPENGL
711 if( OpenGLWrapper::isVCLOpenGLEnabled() )
712 bOffscreen = false;
713 #endif
715 if (!bOffscreen)
716 rRenderContext.Erase(rRect);
718 for (sal_uInt16 i = 0; i < nItemCount; i++)
719 ImplDrawItem(rRenderContext, bOffscreen, i);
723 // draw line at the top of the status bar (to visually distinguish it from
724 // shell / docking area)
725 const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
726 rRenderContext.SetLineColor(rStyleSettings.GetShadowColor());
727 rRenderContext.DrawLine(Point(0, 0), Point(mnDX-1, 0));
730 void StatusBar::Resize()
732 // save width and height
733 Size aSize = GetOutputSizePixel();
734 mnDX = aSize.Width() - ImplGetSVData()->maNWFData.mnStatusBarLowerRightOffset;
735 mnDY = aSize.Height();
736 mnCalcHeight = mnDY;
738 mnItemY = STATUSBAR_OFFSET_Y;
739 mnTextY = (mnCalcHeight-GetTextHeight())/2;
741 // provoke re-formatting
742 mbFormat = true;
744 if ( mbProgressMode )
745 ImplCalcProgressRect();
747 Invalidate();
750 void StatusBar::RequestHelp( const HelpEvent& rHEvt )
752 // no keyboard help in status bar
753 if( rHEvt.KeyboardActivated() )
754 return;
756 sal_uInt16 nItemId = GetItemId( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ) );
758 if ( nItemId )
760 Rectangle aItemRect = GetItemRect( nItemId );
761 Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
762 aItemRect.Left() = aPt.X();
763 aItemRect.Top() = aPt.Y();
764 aPt = OutputToScreenPixel( aItemRect.BottomRight() );
765 aItemRect.Right() = aPt.X();
766 aItemRect.Bottom() = aPt.Y();
768 if ( rHEvt.GetMode() & HelpEventMode::BALLOON )
770 OUString aStr = GetHelpText( nItemId );
771 Help::ShowBalloon( this, aItemRect.Center(), aItemRect, aStr );
772 return;
774 else if ( rHEvt.GetMode() & HelpEventMode::QUICK )
776 OUString aStr(GetQuickHelpText(nItemId));
777 // show quickhelp if available
778 if (!aStr.isEmpty())
780 Help::ShowQuickHelp( this, aItemRect, aStr );
781 return;
783 aStr = GetItemText( nItemId );
784 // show a quick help if item text doesn't fit
785 if ( GetTextWidth( aStr ) > aItemRect.GetWidth() )
787 Help::ShowQuickHelp( this, aItemRect, aStr );
788 return;
791 else if ( rHEvt.GetMode() & HelpEventMode::EXTENDED )
793 OUString aCommand = GetItemCommand( nItemId );
794 OString aHelpId( GetHelpId( nItemId ) );
796 if ( !aCommand.isEmpty() || !aHelpId.isEmpty() )
798 // show help text if there is one
799 Help* pHelp = Application::GetHelp();
800 if ( pHelp )
802 if ( !aCommand.isEmpty() )
803 pHelp->Start( aCommand, this );
804 else if ( !aHelpId.isEmpty() )
805 pHelp->Start( OStringToOUString( aHelpId, RTL_TEXTENCODING_UTF8 ), this );
807 return;
812 Window::RequestHelp( rHEvt );
815 void StatusBar::StateChanged( StateChangedType nType )
817 Window::StateChanged( nType );
819 if ( nType == StateChangedType::InitShow )
820 ImplFormat();
821 else if ( nType == StateChangedType::UpdateMode )
822 Invalidate();
823 else if ( (nType == StateChangedType::Zoom) ||
824 (nType == StateChangedType::ControlFont) )
826 mbFormat = true;
827 ImplInitSettings();
828 Invalidate();
830 else if ( nType == StateChangedType::ControlForeground )
832 ImplInitSettings();
833 Invalidate();
835 else if ( nType == StateChangedType::ControlBackground )
837 ImplInitSettings();
838 Invalidate();
842 void StatusBar::DataChanged( const DataChangedEvent& rDCEvt )
844 Window::DataChanged( rDCEvt );
846 if ( (rDCEvt.GetType() == DataChangedEventType::DISPLAY )
847 || (rDCEvt.GetType() == DataChangedEventType::FONTS )
848 || (rDCEvt.GetType() == DataChangedEventType::FONTSUBSTITUTION)
849 || ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS)
850 && (rDCEvt.GetFlags() & AllSettingsFlags::STYLE )
854 mbFormat = true;
855 ImplInitSettings();
856 long nFudge = GetTextHeight() / 4;
857 for (ImplStatusItem* pItem : mpItemList)
859 long nWidth = GetTextWidth( pItem->maText ) + nFudge;
860 if( nWidth > pItem->mnWidth + STATUSBAR_OFFSET )
861 pItem->mnWidth = nWidth + STATUSBAR_OFFSET;
863 Size aSize = GetSizePixel();
864 // do not disturb current width, since
865 // CalcWindowSizePixel calculates a minimum width
866 aSize.Height() = CalcWindowSizePixel().Height();
867 SetSizePixel( aSize );
868 Invalidate();
872 void StatusBar::Click()
874 CallEventListeners( VCLEVENT_STATUSBAR_CLICK );
875 maClickHdl.Call( this );
878 void StatusBar::DoubleClick()
880 CallEventListeners( VCLEVENT_STATUSBAR_DOUBLECLICK );
881 maDoubleClickHdl.Call( this );
884 void StatusBar::UserDraw( const UserDrawEvent& )
888 void StatusBar::InsertItem( sal_uInt16 nItemId, sal_uLong nWidth,
889 StatusBarItemBits nBits,
890 long nOffset, sal_uInt16 nPos )
892 SAL_WARN_IF( !nItemId, "vcl", "StatusBar::InsertItem(): ItemId == 0" );
893 SAL_WARN_IF( GetItemPos( nItemId ) != STATUSBAR_ITEM_NOTFOUND, "vcl",
894 "StatusBar::InsertItem(): ItemId already exists" );
896 // default: IN and CENTER
897 if ( !(nBits & (StatusBarItemBits::In | StatusBarItemBits::Out | StatusBarItemBits::Flat)) )
898 nBits |= StatusBarItemBits::In;
899 if ( !(nBits & (StatusBarItemBits::Left | StatusBarItemBits::Right | StatusBarItemBits::Center)) )
900 nBits |= StatusBarItemBits::Center;
902 // create item
903 if (mbAdjustHiDPI)
905 nWidth *= GetDPIScaleFactor();
907 long nFudge = GetTextHeight()/4;
908 ImplStatusItem* pItem = new ImplStatusItem;
909 pItem->mnId = nItemId;
910 pItem->mnBits = nBits;
911 pItem->mnWidth = (long)nWidth+nFudge+STATUSBAR_OFFSET;
912 pItem->mnOffset = nOffset;
913 pItem->mpUserData = nullptr;
914 pItem->mbVisible = true;
916 // add item to list
917 if ( nPos < mpItemList.size() ) {
918 mpItemList.insert( mpItemList.begin() + nPos, pItem );
919 } else {
920 mpItemList.push_back( pItem );
923 mbFormat = true;
924 if ( ImplIsItemUpdate() )
925 Invalidate();
927 CallEventListeners( VCLEVENT_STATUSBAR_ITEMADDED, reinterpret_cast<void*>(nItemId) );
930 void StatusBar::RemoveItem( sal_uInt16 nItemId )
932 sal_uInt16 nPos = GetItemPos( nItemId );
933 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
935 delete mpItemList[ nPos ];
936 mpItemList.erase( mpItemList.begin() + nPos );
938 mbFormat = true;
939 if ( ImplIsItemUpdate() )
940 Invalidate();
942 CallEventListeners( VCLEVENT_STATUSBAR_ITEMREMOVED, reinterpret_cast<void*>(nItemId) );
946 void StatusBar::ShowItem( sal_uInt16 nItemId )
948 sal_uInt16 nPos = GetItemPos( nItemId );
950 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
952 ImplStatusItem* pItem = mpItemList[ nPos ];
953 if ( !pItem->mbVisible )
955 pItem->mbVisible = true;
957 mbFormat = true;
958 if ( ImplIsItemUpdate() )
959 Invalidate();
961 CallEventListeners( VCLEVENT_STATUSBAR_SHOWITEM, reinterpret_cast<void*>(nItemId) );
966 void StatusBar::HideItem( sal_uInt16 nItemId )
968 sal_uInt16 nPos = GetItemPos( nItemId );
970 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
972 ImplStatusItem* pItem = mpItemList[ nPos ];
973 if ( pItem->mbVisible )
975 pItem->mbVisible = false;
977 mbFormat = true;
978 if ( ImplIsItemUpdate() )
979 Invalidate();
981 CallEventListeners( VCLEVENT_STATUSBAR_HIDEITEM, reinterpret_cast<void*>(nItemId) );
986 bool StatusBar::IsItemVisible( sal_uInt16 nItemId ) const
988 sal_uInt16 nPos = GetItemPos( nItemId );
990 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
991 return mpItemList[ nPos ]->mbVisible;
992 else
993 return false;
996 void StatusBar::Clear()
998 // delete all items
999 for (ImplStatusItem* i : mpItemList) {
1000 delete i;
1002 mpItemList.clear();
1004 mbFormat = true;
1005 if ( ImplIsItemUpdate() )
1006 Invalidate();
1008 CallEventListeners( VCLEVENT_STATUSBAR_ALLITEMSREMOVED );
1011 sal_uInt16 StatusBar::GetItemCount() const
1013 return (sal_uInt16)mpItemList.size();
1016 sal_uInt16 StatusBar::GetItemId( sal_uInt16 nPos ) const
1018 if ( nPos < mpItemList.size() )
1019 return mpItemList[ nPos ]->mnId;
1020 return 0;
1023 sal_uInt16 StatusBar::GetItemPos( sal_uInt16 nItemId ) const
1025 for ( size_t i = 0, n = mpItemList.size(); i < n; ++i ) {
1026 if ( mpItemList[ i ]->mnId == nItemId ) {
1027 return sal_uInt16( i );
1031 return STATUSBAR_ITEM_NOTFOUND;
1034 sal_uInt16 StatusBar::GetItemId( const Point& rPos ) const
1036 if ( AreItemsVisible() && !mbFormat )
1038 sal_uInt16 nItemCount = GetItemCount();
1039 sal_uInt16 nPos;
1040 for ( nPos = 0; nPos < nItemCount; nPos++ )
1042 // get rectangle
1043 Rectangle aRect = ImplGetItemRectPos( nPos );
1044 if ( aRect.IsInside( rPos ) )
1045 return mpItemList[ nPos ]->mnId;
1049 return 0;
1052 Rectangle StatusBar::GetItemRect( sal_uInt16 nItemId ) const
1054 Rectangle aRect;
1056 if ( AreItemsVisible() && !mbFormat )
1058 sal_uInt16 nPos = GetItemPos( nItemId );
1059 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1061 // get rectangle and subtract frame
1062 aRect = ImplGetItemRectPos( nPos );
1063 long nW = mpImplData->mnItemBorderWidth+1;
1064 aRect.Top() += nW-1;
1065 aRect.Bottom() -= nW-1;
1066 aRect.Left() += nW;
1067 aRect.Right() -= nW;
1068 return aRect;
1072 return aRect;
1075 Point StatusBar::GetItemTextPos( sal_uInt16 nItemId ) const
1077 if ( !mbFormat )
1079 sal_uInt16 nPos = GetItemPos( nItemId );
1080 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1082 // get rectangle
1083 ImplStatusItem* pItem = mpItemList[ nPos ];
1084 Rectangle aRect = ImplGetItemRectPos( nPos );
1085 long nW = mpImplData->mnItemBorderWidth + 1;
1086 Rectangle aTextRect( aRect.Left()+nW, aRect.Top()+nW,
1087 aRect.Right()-nW, aRect.Bottom()-nW );
1088 Point aPos = ImplGetItemTextPos( aTextRect.GetSize(),
1089 Size( GetTextWidth( pItem->maText ), GetTextHeight() ),
1090 pItem->mnBits );
1091 if ( !mbInUserDraw )
1093 aPos.X() += aTextRect.Left();
1094 aPos.Y() += aTextRect.Top();
1096 return aPos;
1100 return Point();
1103 sal_uLong StatusBar::GetItemWidth( sal_uInt16 nItemId ) const
1105 sal_uInt16 nPos = GetItemPos( nItemId );
1107 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1108 return mpItemList[ nPos ]->mnWidth;
1110 return 0;
1113 StatusBarItemBits StatusBar::GetItemBits( sal_uInt16 nItemId ) const
1115 sal_uInt16 nPos = GetItemPos( nItemId );
1117 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1118 return mpItemList[ nPos ]->mnBits;
1120 return StatusBarItemBits::NONE;
1123 long StatusBar::GetItemOffset( sal_uInt16 nItemId ) const
1125 sal_uInt16 nPos = GetItemPos( nItemId );
1127 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1128 return mpItemList[ nPos ]->mnOffset;
1130 return 0;
1133 void StatusBar::SetItemText( sal_uInt16 nItemId, const OUString& rText )
1135 sal_uInt16 nPos = GetItemPos( nItemId );
1137 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1139 ImplStatusItem* pItem = mpItemList[ nPos ];
1141 if ( pItem->maText != rText )
1143 pItem->maText = rText;
1145 // adjust item width - see also DataChanged()
1146 long nFudge = GetTextHeight()/4;
1147 long nWidth = GetTextWidth( pItem->maText ) + nFudge;
1148 if( (nWidth > pItem->mnWidth + STATUSBAR_OFFSET) ||
1149 ((nWidth < pItem->mnWidth) && (mnDX - STATUSBAR_OFFSET) < mnItemsWidth ))
1151 pItem->mnWidth = nWidth + STATUSBAR_OFFSET;
1152 ImplFormat();
1153 Invalidate();
1156 // re-draw item if StatusBar is visible and UpdateMode active
1157 if ( pItem->mbVisible && !mbFormat && ImplIsItemUpdate() )
1159 Rectangle aRect = ImplGetItemRectPos(nPos);
1160 Invalidate(aRect);
1161 Update();
1167 const OUString& StatusBar::GetItemText( sal_uInt16 nItemId ) const
1169 sal_uInt16 nPos = GetItemPos( nItemId );
1171 assert( nPos != STATUSBAR_ITEM_NOTFOUND );
1173 return mpItemList[ nPos ]->maText;
1176 void StatusBar::SetItemCommand( sal_uInt16 nItemId, const OUString& rCommand )
1178 sal_uInt16 nPos = GetItemPos( nItemId );
1180 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1182 ImplStatusItem* pItem = mpItemList[ nPos ];
1184 if ( pItem->maCommand != rCommand )
1185 pItem->maCommand = rCommand;
1189 const OUString StatusBar::GetItemCommand( sal_uInt16 nItemId )
1191 sal_uInt16 nPos = GetItemPos( nItemId );
1193 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1194 return mpItemList[ nPos ]->maCommand;
1196 return OUString();
1199 void StatusBar::SetItemData( sal_uInt16 nItemId, void* pNewData )
1201 sal_uInt16 nPos = GetItemPos( nItemId );
1203 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1205 ImplStatusItem* pItem = mpItemList[ nPos ];
1206 pItem->mpUserData = pNewData;
1208 // call Draw-Item if it's a User-Item
1209 if ( (pItem->mnBits & StatusBarItemBits::UserDraw) && pItem->mbVisible &&
1210 !mbFormat && ImplIsItemUpdate() )
1212 Rectangle aRect = ImplGetItemRectPos(nPos);
1213 Invalidate(aRect, InvalidateFlags::NoErase);
1214 Update();
1219 void* StatusBar::GetItemData( sal_uInt16 nItemId ) const
1221 sal_uInt16 nPos = GetItemPos( nItemId );
1223 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1224 return mpItemList[ nPos ]->mpUserData;
1226 return nullptr;
1229 void StatusBar::RedrawItem(sal_uInt16 nItemId)
1231 if ( mbFormat )
1232 return;
1234 sal_uInt16 nPos = GetItemPos(nItemId);
1235 if ( nPos == STATUSBAR_ITEM_NOTFOUND )
1236 return;
1238 ImplStatusItem* pItem = mpItemList[ nPos ];
1239 if (pItem && (pItem->mnBits & StatusBarItemBits::UserDraw) &&
1240 pItem->mbVisible && ImplIsItemUpdate())
1242 Rectangle aRect = ImplGetItemRectPos(nPos);
1243 Invalidate(aRect);
1244 Update();
1248 void StatusBar::SetHelpText( sal_uInt16 nItemId, const OUString& rText )
1250 sal_uInt16 nPos = GetItemPos( nItemId );
1252 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1253 mpItemList[ nPos ]->maHelpText = rText;
1256 const OUString& StatusBar::GetHelpText( sal_uInt16 nItemId ) const
1258 sal_uInt16 nPos = GetItemPos( nItemId );
1260 assert ( nPos != STATUSBAR_ITEM_NOTFOUND );
1262 ImplStatusItem* pItem = mpItemList[ nPos ];
1263 if ( pItem->maHelpText.isEmpty() && ( !pItem->maHelpId.isEmpty() || !pItem->maCommand.isEmpty() ))
1265 Help* pHelp = Application::GetHelp();
1266 if ( pHelp )
1268 if ( !pItem->maCommand.isEmpty() )
1269 pItem->maHelpText = pHelp->GetHelpText( pItem->maCommand, this );
1270 if ( pItem->maHelpText.isEmpty() && !pItem->maHelpId.isEmpty() )
1271 pItem->maHelpText = pHelp->GetHelpText( OStringToOUString( pItem->maHelpId, RTL_TEXTENCODING_UTF8 ), this );
1275 return pItem->maHelpText;
1278 void StatusBar::SetQuickHelpText( sal_uInt16 nItemId, const OUString& rText )
1280 sal_uInt16 nPos = GetItemPos( nItemId );
1282 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1283 mpItemList[ nPos ]->maQuickHelpText = rText;
1286 const OUString& StatusBar::GetQuickHelpText( sal_uInt16 nItemId ) const
1288 sal_uInt16 nPos = GetItemPos( nItemId );
1290 assert ( nPos != STATUSBAR_ITEM_NOTFOUND );
1292 ImplStatusItem* pItem = mpItemList[ nPos ];
1293 return pItem->maQuickHelpText;
1296 void StatusBar::SetHelpId( sal_uInt16 nItemId, const OString& rHelpId )
1298 sal_uInt16 nPos = GetItemPos( nItemId );
1300 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1301 mpItemList[ nPos ]->maHelpId = rHelpId;
1304 OString StatusBar::GetHelpId( sal_uInt16 nItemId ) const
1306 sal_uInt16 nPos = GetItemPos( nItemId );
1308 OString aRet;
1309 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1311 ImplStatusItem* pItem = mpItemList[ nPos ];
1312 if ( !pItem->maHelpId.isEmpty() )
1313 aRet = pItem->maHelpId;
1314 else
1315 aRet = OUStringToOString( pItem->maCommand, RTL_TEXTENCODING_UTF8 );
1318 return aRet;
1321 void StatusBar::StartProgressMode( const OUString& rText )
1323 SAL_WARN_IF( mbProgressMode, "vcl", "StatusBar::StartProgressMode(): progress mode is active" );
1325 mbProgressMode = true;
1326 mnPercent = 0;
1327 maPrgsTxt = rText;
1329 // compute size
1330 ImplCalcProgressRect();
1332 // trigger Paint, which draws text and frame
1333 if ( IsReallyVisible() )
1335 Invalidate();
1336 Update();
1340 void StatusBar::SetProgressValue( sal_uInt16 nNewPercent )
1342 SAL_WARN_IF( !mbProgressMode, "vcl", "StatusBar::SetProgressValue(): no progress mode" );
1343 SAL_WARN_IF( nNewPercent > 100, "vcl", "StatusBar::SetProgressValue(): nPercent > 100" );
1345 if ( mbProgressMode
1346 && IsReallyVisible()
1347 && (!mnPercent || (mnPercent != nNewPercent)) )
1349 bool bNeedErase = ImplGetSVData()->maNWFData.mbProgressNeedsErase;
1350 Invalidate(maPrgsFrameRect, bNeedErase ? InvalidateFlags::NONE : InvalidateFlags::NoErase);
1351 Update();
1353 mnPercent = nNewPercent;
1356 void StatusBar::EndProgressMode()
1358 SAL_WARN_IF( !mbProgressMode, "vcl", "StatusBar::EndProgressMode(): no progress mode" );
1360 mbProgressMode = false;
1361 maPrgsTxt.clear();
1363 if ( IsReallyVisible() )
1365 Invalidate();
1366 Update();
1370 void StatusBar::SetText(const OUString& rText)
1372 if ((!mbVisibleItems || (GetStyle() & WB_RIGHT)) && !mbProgressMode && IsReallyVisible() && IsUpdateMode())
1374 if (mbFormat)
1376 Invalidate();
1377 Window::SetText(rText);
1379 else
1381 Invalidate();
1382 Window::SetText(rText);
1383 Update();
1386 else if (mbProgressMode)
1388 maPrgsTxt = rText;
1389 if (IsReallyVisible())
1391 Invalidate();
1392 Update();
1395 else
1397 Window::SetText(rText);
1401 Size StatusBar::CalcWindowSizePixel() const
1403 size_t i = 0;
1404 size_t nCount = mpItemList.size();
1405 long nOffset = 0;
1406 long nCalcWidth = (STATUSBAR_OFFSET_X*2);
1407 long nCalcHeight;
1409 while ( i < nCount )
1411 ImplStatusItem* pItem = mpItemList[ i ];
1412 nCalcWidth += pItem->mnWidth + nOffset;
1413 nOffset = pItem->mnOffset;
1414 i++;
1417 long nMinHeight = GetTextHeight();
1418 const long nBarTextOffset = STATUSBAR_OFFSET_TEXTY*2;
1419 long nProgressHeight = nMinHeight + nBarTextOffset;
1421 if( IsNativeControlSupported( ControlType::Progress, ControlPart::Entire ) )
1423 ImplControlValue aValue;
1424 Rectangle aControlRegion( (const Point&)Point(), Size( nCalcWidth, nMinHeight ) );
1425 Rectangle aNativeControlRegion, aNativeContentRegion;
1426 if( GetNativeControlRegion( ControlType::Progress, ControlPart::Entire,
1427 aControlRegion, ControlState::ENABLED, aValue, OUString(),
1428 aNativeControlRegion, aNativeContentRegion ) )
1430 nProgressHeight = aNativeControlRegion.GetHeight();
1434 if( mpImplData->mbDrawItemFrames &&
1435 IsNativeControlSupported( ControlType::Frame, ControlPart::Border ) )
1437 ImplControlValue aControlValue( static_cast<long>(DrawFrameFlags::NoDraw) );
1438 Rectangle aBound, aContent;
1439 Rectangle aNatRgn( Point( 0, 0 ), Size( 150, 50 ) );
1440 if( GetNativeControlRegion(ControlType::Frame, ControlPart::Border,
1441 aNatRgn, ControlState::NONE, aControlValue, OUString(), aBound, aContent) )
1443 mpImplData->mnItemBorderWidth =
1444 ( aBound.GetHeight() - aContent.GetHeight() ) / 2;
1448 nCalcHeight = nMinHeight+nBarTextOffset + 2*mpImplData->mnItemBorderWidth;
1449 if( nCalcHeight < nProgressHeight+2 )
1450 nCalcHeight = nProgressHeight+2;
1452 return Size( nCalcWidth, nCalcHeight );
1455 void StatusBar::SetAccessibleName( sal_uInt16 nItemId, const OUString& rName )
1457 sal_uInt16 nPos = GetItemPos( nItemId );
1459 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1461 ImplStatusItem* pItem = mpItemList[ nPos ];
1463 if ( pItem->maAccessibleName != rName )
1465 pItem->maAccessibleName = rName;
1466 CallEventListeners( VCLEVENT_STATUSBAR_NAMECHANGED, reinterpret_cast<void*>(pItem->mnId) );
1471 const OUString& StatusBar::GetAccessibleName( sal_uInt16 nItemId ) const
1473 sal_uInt16 nPos = GetItemPos( nItemId );
1475 assert ( nPos != STATUSBAR_ITEM_NOTFOUND );
1477 return mpItemList[ nPos ]->maAccessibleName;
1480 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */