1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
21 #include <sal/log.hxx>
22 #include <comphelper/string.hxx>
23 #include <vcl/event.hxx>
24 #include <vcl/decoview.hxx>
25 #include <vcl/glyphitemcache.hxx>
26 #include <vcl/svapp.hxx>
27 #include <vcl/help.hxx>
28 #include <vcl/vcllayout.hxx>
29 #include <vcl/status.hxx>
30 #include <vcl/virdev.hxx>
31 #include <vcl/settings.hxx>
32 #include <config_features.h>
36 #define STATUSBAR_OFFSET_X STATUSBAR_OFFSET
37 #define STATUSBAR_OFFSET_Y 2
38 #define STATUSBAR_OFFSET_TEXTY 3
40 #define STATUSBAR_PRGS_OFFSET 3
41 #define STATUSBAR_PRGS_COUNT 100
42 #define STATUSBAR_PRGS_MIN 5
44 #define STATUSBAR_MIN_HEIGHT 16 // icons height, tdf#153344
46 class StatusBar::ImplData
51 VclPtr
<VirtualDevice
> mpVirDev
;
54 StatusBar::ImplData::ImplData()
62 StatusBarItemBits mnBits
;
65 tools::Long mnExtraWidth
;
69 OUString maQuickHelpText
;
73 OUString maAccessibleName
;
75 std::optional
<SalLayoutGlyphs
> mLayoutGlyphsCache
;
76 SalLayoutGlyphs
* GetTextGlyphs(const OutputDevice
* pOutputDevice
);
79 SalLayoutGlyphs
* ImplStatusItem::GetTextGlyphs(const OutputDevice
* outputDevice
)
81 if(!mLayoutGlyphsCache
.has_value())
83 std::unique_ptr
<SalLayout
> pSalLayout
= outputDevice
->ImplLayout(
84 maText
, 0, -1, Point(0, 0), 0, {}, {}, SalLayoutFlags::GlyphItemsOnly
);
85 mLayoutGlyphsCache
= pSalLayout
? pSalLayout
->GetGlyphs() : SalLayoutGlyphs();
87 return mLayoutGlyphsCache
->IsValid() ? &mLayoutGlyphsCache
.value() : nullptr;
90 static tools::Long
ImplCalcProgressWidth( sal_uInt16 nMax
, tools::Long nSize
)
92 return ((nMax
*(nSize
+(nSize
/2)))-(nSize
/2)+(STATUSBAR_PRGS_OFFSET
*2));
95 static Point
ImplGetItemTextPos( const Size
& rRectSize
, const Size
& rTextSize
,
96 StatusBarItemBits nStyle
)
100 tools::Long delta
= (rTextSize
.Height()/4) + 1;
101 if( delta
+ rTextSize
.Width() > rRectSize
.Width() )
104 if ( nStyle
& StatusBarItemBits::Left
)
106 else if ( nStyle
& StatusBarItemBits::Right
)
107 nX
= rRectSize
.Width()-rTextSize
.Width()-delta
;
108 else // StatusBarItemBits::Center
109 nX
= (rRectSize
.Width()-rTextSize
.Width())/2;
110 nY
= (rRectSize
.Height()-rTextSize
.Height())/2 + 1;
111 return Point( nX
, nY
);
114 bool StatusBar::ImplIsItemUpdate() const
116 return !mbProgressMode
&& IsReallyVisible() && IsUpdateMode();
119 void StatusBar::ImplInit( vcl::Window
* pParent
, WinBits nStyle
)
121 mpImplData
.reset(new ImplData
);
123 // default: RightAlign
124 if ( !(nStyle
& (WB_LEFT
| WB_RIGHT
)) )
127 Window::ImplInit( pParent
, nStyle
& ~WB_BORDER
, nullptr );
130 mpImplData
->mpVirDev
= VclPtr
<VirtualDevice
>::Create( *GetOutDev() );
133 mbProgressMode
= false;
134 mbInUserDraw
= false;
135 mbAdjustHiDPI
= false;
136 mnItemsWidth
= STATUSBAR_OFFSET_X
;
140 mnTextY
= STATUSBAR_OFFSET_TEXTY
;
144 SetOutputSizePixel( CalcWindowSizePixel() );
147 StatusBar::StatusBar( vcl::Window
* pParent
, WinBits nStyle
) :
148 Window( WindowType::STATUSBAR
),
149 mnLastProgressPaint_ms(osl_getGlobalTimer())
151 ImplInit( pParent
, nStyle
);
154 StatusBar::~StatusBar()
159 void StatusBar::dispose()
164 // delete VirtualDevice
165 mpImplData
->mpVirDev
.disposeAndClear();
170 void StatusBar::AdjustItemWidthsForHiDPI()
172 mbAdjustHiDPI
= true;
175 void StatusBar::ApplySettings(vcl::RenderContext
& rRenderContext
)
177 rRenderContext
.SetLineColor();
179 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
180 ApplyControlFont(rRenderContext
, rStyleSettings
.GetToolFont());
183 if (IsControlForeground())
184 aColor
= GetControlForeground();
185 else if (GetStyle() & WB_3DLOOK
)
186 aColor
= rStyleSettings
.GetButtonTextColor();
188 aColor
= rStyleSettings
.GetWindowTextColor();
189 rRenderContext
.SetTextColor(aColor
);
191 rRenderContext
.SetTextFillColor();
193 if (IsControlBackground())
194 aColor
= GetControlBackground();
195 else if (GetStyle() & WB_3DLOOK
)
196 aColor
= rStyleSettings
.GetFaceColor();
198 aColor
= rStyleSettings
.GetWindowColor();
199 rRenderContext
.SetBackground(aColor
);
202 if (!IsControlBackground() &&
203 rRenderContext
.IsNativeControlSupported(ControlType::WindowBackground
, ControlPart::BackgroundWindow
))
205 ImplGetWindowImpl()->mnNativeBackground
= ControlPart::BackgroundWindow
;
206 EnableChildTransparentMode();
210 void StatusBar::ImplInitSettings()
212 ApplySettings(*GetOutDev());
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 tools::Long nExtraWidth
;
224 tools::Long nExtraWidth2
;
226 sal_uInt16 nAutoSizeItems
;
232 mnItemsWidth
= STATUSBAR_OFFSET_X
;
234 tools::Long nOffset
= 0;
235 for ( const auto & pItem
: mvItemList
) {
236 if ( pItem
->mbVisible
)
238 if ( pItem
->mnBits
& StatusBarItemBits::AutoSize
) {
242 mnItemsWidth
+= pItem
->mnWidth
+ nOffset
;
243 nOffset
= pItem
->mnOffset
;
247 if ( mnDX
> 0 && mnDX
< mnItemsWidth
)
249 // Total width of items is more than available width
250 // Try to hide secondary elements, if any
251 for ( auto & pItem
: mvItemList
)
253 if ( pItem
->mbVisible
&& !(pItem
->mnBits
& StatusBarItemBits::Mandatory
) )
255 pItem
->mbVisible
= false;
261 else if ( mnDX
> mnItemsWidth
)
263 // Width of statusbar is sufficient.
264 // Try to restore hidden items, if any
265 for ( auto & pItem
: mvItemList
)
267 if ( !pItem
->mbVisible
&&
268 !(pItem
->mnBits
& StatusBarItemBits::Mandatory
) &&
269 pItem
->mnWidth
+ nOffset
+ mnItemsWidth
< mnDX
)
271 pItem
->mbVisible
= true;
277 } while ( bChanged
);
279 if ( GetStyle() & WB_RIGHT
)
281 // AutoSize isn't computed for right-alignment,
282 // because we show the text that is declared by SetText on the left side
283 nX
= mnDX
- mnItemsWidth
;
289 mnItemsWidth
+= STATUSBAR_OFFSET_X
;
291 // calling AutoSize is potentially necessary for left-aligned text,
292 if ( nAutoSizeItems
&& (mnDX
> (mnItemsWidth
- STATUSBAR_OFFSET
)) )
294 nExtraWidth
= (mnDX
- mnItemsWidth
- 1) / nAutoSizeItems
;
295 nExtraWidth2
= (mnDX
- mnItemsWidth
- 1) % nAutoSizeItems
;
302 nX
= STATUSBAR_OFFSET_X
;
304 if( GetOutDev()->HasMirroredGraphics() && IsRTLEnabled() )
305 nX
+= ImplGetSVData()->maNWFData
.mnStatusBarLowerRightOffset
;
308 for (auto & pItem
: mvItemList
) {
309 if ( pItem
->mbVisible
) {
310 if ( pItem
->mnBits
& StatusBarItemBits::AutoSize
) {
311 pItem
->mnExtraWidth
= nExtraWidth
;
312 if ( nExtraWidth2
) {
313 pItem
->mnExtraWidth
++;
317 pItem
->mnExtraWidth
= 0;
321 nX
+= pItem
->mnWidth
+ pItem
->mnExtraWidth
+ pItem
->mnOffset
;
328 tools::Rectangle
StatusBar::ImplGetItemRectPos( sal_uInt16 nPos
) const
330 tools::Rectangle aRect
;
331 ImplStatusItem
* pItem
= ( nPos
< mvItemList
.size() ) ? mvItemList
[ nPos
].get() : nullptr;
332 if ( pItem
&& pItem
->mbVisible
)
334 aRect
.SetLeft( pItem
->mnX
);
335 aRect
.SetRight( aRect
.Left() + pItem
->mnWidth
+ pItem
->mnExtraWidth
);
336 aRect
.SetTop( STATUSBAR_OFFSET_Y
);
337 aRect
.SetBottom( mnCalcHeight
- STATUSBAR_OFFSET_Y
);
343 sal_uInt16
StatusBar::ImplGetFirstVisiblePos() const
345 for( size_t nPos
= 0; nPos
< mvItemList
.size(); nPos
++ )
347 ImplStatusItem
* pItem
= mvItemList
[ nPos
].get();
348 if ( pItem
->mbVisible
)
349 return sal_uInt16(nPos
);
352 return SAL_MAX_UINT16
;
355 void StatusBar::ImplDrawText(vcl::RenderContext
& rRenderContext
)
357 // prevent item box from being overwritten
358 tools::Rectangle aTextRect
;
359 aTextRect
.SetLeft( STATUSBAR_OFFSET_X
+ 1 );
360 aTextRect
.SetTop( mnTextY
);
361 if (GetStyle() & WB_RIGHT
)
362 aTextRect
.SetRight( mnDX
- mnItemsWidth
- 1 );
364 aTextRect
.SetRight( mnDX
- 1 );
365 if (aTextRect
.Right() > aTextRect
.Left())
368 OUString aStr
= GetText();
369 sal_Int32 nPos
= aStr
.indexOf('\n');
371 aStr
= aStr
.copy(0, nPos
);
373 aTextRect
.SetBottom( aTextRect
.Top()+GetTextHeight()+1 );
375 rRenderContext
.DrawText(aTextRect
, aStr
, DrawTextFlags::Left
| DrawTextFlags::Top
| DrawTextFlags::Clip
| DrawTextFlags::EndEllipsis
);
379 void StatusBar::ImplDrawItem(vcl::RenderContext
& rRenderContext
, bool bOffScreen
, sal_uInt16 nPos
)
381 tools::Rectangle aRect
= ImplGetItemRectPos(nPos
);
386 // compute output region
387 ImplStatusItem
* pItem
= mvItemList
[nPos
].get();
389 tools::Rectangle
aTextRect(aRect
.Left() + nW
, aRect
.Top() + nW
,
390 aRect
.Right() - nW
, aRect
.Bottom() - nW
);
392 Size
aTextRectSize(aTextRect
.GetSize());
396 mpImplData
->mpVirDev
->SetOutputSizePixel(aTextRectSize
);
400 vcl::Region
aRegion(aTextRect
);
401 rRenderContext
.SetClipRegion(aRegion
);
404 // if the framework code is drawing status, let it do all the work
405 if (!(pItem
->mnBits
& StatusBarItemBits::UserDraw
))
407 SalLayoutGlyphs
* pGlyphs
= pItem
->GetTextGlyphs(&rRenderContext
);
408 Size
aTextSize(rRenderContext
.GetTextWidth(pItem
->maText
,0,-1,nullptr,pGlyphs
),
409 rRenderContext
.GetTextHeight());
410 Point aTextPos
= ImplGetItemTextPos(aTextRectSize
, aTextSize
, pItem
->mnBits
);
414 mpImplData
->mpVirDev
->DrawText(
417 0, -1, nullptr, nullptr,
422 aTextPos
.AdjustX(aTextRect
.Left() );
423 aTextPos
.AdjustY(aTextRect
.Top() );
424 rRenderContext
.DrawText(
427 0, -1, nullptr, nullptr,
432 // call DrawItem if necessary
433 if (pItem
->mnBits
& StatusBarItemBits::UserDraw
)
438 mpImplData
->mpVirDev
->EnableRTL( IsRTLEnabled() );
439 UserDrawEvent
aODEvt(mpImplData
->mpVirDev
, tools::Rectangle(Point(), aTextRectSize
), pItem
->mnId
);
441 mpImplData
->mpVirDev
->EnableRTL(false);
442 mbInUserDraw
= false;
446 UserDrawEvent
aODEvt(&rRenderContext
, aTextRect
, pItem
->mnId
);
452 rRenderContext
.DrawOutDev(aTextRect
.TopLeft(), aTextRectSize
, Point(), aTextRectSize
, *mpImplData
->mpVirDev
);
454 rRenderContext
.SetClipRegion();
456 if (nPos
!= ImplGetFirstVisiblePos())
459 Point
aFrom(aRect
.TopLeft());
462 Point
aTo(aRect
.BottomLeft());
466 DecorationView
aDecoView(&rRenderContext
);
467 aDecoView
.DrawSeparator(aFrom
, aTo
);
470 if (!rRenderContext
.ImplIsRecordLayout())
471 CallEventListeners(VclEventId::StatusbarDrawItem
, reinterpret_cast<void*>(pItem
->mnId
));
474 void DrawProgress(vcl::Window
* pWindow
, vcl::RenderContext
& rRenderContext
, const Point
& rPos
,
475 tools::Long nOffset
, tools::Long nPrgsWidth
, tools::Long nPrgsHeight
,
476 sal_uInt16 nPercent1
, sal_uInt16 nPercent2
, sal_uInt16 nPercentCount
,
477 const tools::Rectangle
& rFramePosSize
)
479 if (rRenderContext
.IsNativeControlSupported(ControlType::Progress
, ControlPart::Entire
))
481 bool bNeedErase
= ImplGetSVData()->maNWFData
.mbProgressNeedsErase
;
483 tools::Long nFullWidth
= (nPrgsWidth
+ nOffset
) * (10000 / nPercentCount
);
484 tools::Long nPerc
= std::min
<sal_uInt16
>(nPercent2
, 10000);
485 ImplControlValue
aValue(nFullWidth
* nPerc
/ 10000);
486 tools::Rectangle
aDrawRect(rPos
, Size(nFullWidth
, nPrgsHeight
));
487 tools::Rectangle
aControlRegion(aDrawRect
);
491 vcl::Window
* pEraseWindow
= pWindow
;
492 while (pEraseWindow
->IsPaintTransparent() && !pEraseWindow
->ImplGetWindowImpl()->mbFrame
)
494 pEraseWindow
= pEraseWindow
->ImplGetWindowImpl()->mpParent
;
497 if (pEraseWindow
== pWindow
)
499 // restore background of pWindow
500 rRenderContext
.Erase(rFramePosSize
);
504 // restore transparent background
505 Point
aTL(pWindow
->OutputToAbsoluteScreenPixel(rFramePosSize
.TopLeft()));
506 aTL
= pEraseWindow
->AbsoluteScreenToOutputPixel(aTL
);
507 tools::Rectangle
aRect(aTL
, rFramePosSize
.GetSize());
508 pEraseWindow
->Invalidate(aRect
, InvalidateFlags::NoChildren
|
509 InvalidateFlags::NoClipChildren
|
510 InvalidateFlags::Transparent
);
511 pEraseWindow
->PaintImmediately();
513 rRenderContext
.Push(vcl::PushFlags::CLIPREGION
);
514 rRenderContext
.IntersectClipRegion(rFramePosSize
);
517 bool bNativeOK
= rRenderContext
.DrawNativeControl(ControlType::Progress
, ControlPart::Entire
, aControlRegion
,
518 ControlState::ENABLED
, aValue
, OUString());
520 rRenderContext
.Pop();
526 sal_uInt16 nPerc1
= nPercent1
/ nPercentCount
;
527 sal_uInt16 nPerc2
= nPercent2
/ nPercentCount
;
531 // support progress that can also decrease
534 tools::Long nDX
= nPrgsWidth
+ nOffset
;
535 tools::Long nLeft
= rPos
.X() + ((nPerc1
- 1) * nDX
);
536 tools::Rectangle
aRect(nLeft
, rPos
.Y(), nLeft
+ nPrgsWidth
, rPos
.Y() + nPrgsHeight
);
540 rRenderContext
.Erase(aRect
);
541 aRect
.AdjustLeft( -nDX
);
542 aRect
.AdjustRight( -nDX
);
545 while (nPerc1
> nPerc2
);
547 else if (nPerc1
< nPerc2
)
549 // draw Percent rectangle
550 // if Percent2 greater than 100%, adapt values
551 if (nPercent2
> 10000)
553 nPerc2
= 10000 / nPercentCount
;
554 if (nPerc1
>= nPerc2
)
559 tools::Long nDX
= nPrgsWidth
+ nOffset
;
560 tools::Long nLeft
= rPos
.X() + (nPerc1
* nDX
);
561 tools::Rectangle
aRect(nLeft
, rPos
.Y(), nLeft
+ nPrgsWidth
, rPos
.Y() + nPrgsHeight
);
565 rRenderContext
.DrawRect(aRect
);
566 aRect
.AdjustLeft(nDX
);
567 aRect
.AdjustRight(nDX
);
570 while (nPerc1
< nPerc2
);
572 // if greater than 100%, set rectangle to blink
573 if (nPercent2
> 10000)
575 // define on/off status
576 if (((nPercent2
/ nPercentCount
) & 0x01) == (nPercentCount
& 0x01))
578 aRect
.AdjustLeft( -nDX
);
579 aRect
.AdjustRight( -nDX
);
580 rRenderContext
.Erase(aRect
);
586 void StatusBar::ImplDrawProgress(vcl::RenderContext
& rRenderContext
, sal_uInt16 nPercent2
)
588 bool bNative
= rRenderContext
.IsNativeControlSupported(ControlType::Progress
, ControlPart::Entire
);
589 // bPaint: draw text also, else only update progress
590 rRenderContext
.DrawText(maPrgsTxtPos
, maPrgsTxt
);
593 DecorationView
aDecoView(&rRenderContext
);
594 aDecoView
.DrawFrame(maPrgsFrameRect
, DrawFrameStyle::In
);
597 Point
aPos(maPrgsFrameRect
.Left() + STATUSBAR_PRGS_OFFSET
,
598 maPrgsFrameRect
.Top() + STATUSBAR_PRGS_OFFSET
);
599 tools::Long nPrgsHeight
= mnPrgsSize
;
602 aPos
= maPrgsFrameRect
.TopLeft();
603 nPrgsHeight
= maPrgsFrameRect
.GetHeight();
605 DrawProgress(this, rRenderContext
, aPos
, mnPrgsSize
/ 2, mnPrgsSize
, nPrgsHeight
,
606 0, nPercent2
* 100, mnPercentCount
, maPrgsFrameRect
);
609 void StatusBar::ImplCalcProgressRect()
611 // calculate text size
612 Size
aPrgsTxtSize( GetTextWidth( maPrgsTxt
), GetTextHeight() );
613 maPrgsTxtPos
.setX( STATUSBAR_OFFSET_X
+1 );
615 // calculate progress frame
616 maPrgsFrameRect
.SetLeft( maPrgsTxtPos
.X()+aPrgsTxtSize
.Width()+STATUSBAR_OFFSET
);
617 maPrgsFrameRect
.SetTop( STATUSBAR_OFFSET_Y
);
618 maPrgsFrameRect
.SetBottom( mnCalcHeight
- STATUSBAR_OFFSET_Y
);
620 // calculate size of progress rects
621 mnPrgsSize
= maPrgsFrameRect
.Bottom()-maPrgsFrameRect
.Top()-(STATUSBAR_PRGS_OFFSET
*2);
622 sal_uInt16 nMaxPercent
= STATUSBAR_PRGS_COUNT
;
624 tools::Long nMaxWidth
= mnDX
-STATUSBAR_OFFSET
-1;
626 // make smaller if there are too many rects
627 while ( maPrgsFrameRect
.Left()+ImplCalcProgressWidth( nMaxPercent
, mnPrgsSize
) > nMaxWidth
)
630 if ( nMaxPercent
<= STATUSBAR_PRGS_MIN
)
633 maPrgsFrameRect
.SetRight( maPrgsFrameRect
.Left() + ImplCalcProgressWidth( nMaxPercent
, mnPrgsSize
) );
635 // save the divisor for later
636 mnPercentCount
= 10000 / nMaxPercent
;
637 bool bNativeOK
= false;
638 if( IsNativeControlSupported( ControlType::Progress
, ControlPart::Entire
) )
640 ImplControlValue aValue
;
641 tools::Rectangle
aControlRegion( tools::Rectangle( Point(), maPrgsFrameRect
.GetSize() ) );
642 tools::Rectangle aNativeControlRegion
, aNativeContentRegion
;
643 if( (bNativeOK
= GetNativeControlRegion( ControlType::Progress
, ControlPart::Entire
, aControlRegion
,
644 ControlState::ENABLED
, aValue
,
645 aNativeControlRegion
, aNativeContentRegion
) ) )
647 tools::Long nProgressHeight
= aNativeControlRegion
.GetHeight();
648 if( nProgressHeight
> maPrgsFrameRect
.GetHeight() )
650 tools::Long nDelta
= nProgressHeight
- maPrgsFrameRect
.GetHeight();
651 maPrgsFrameRect
.AdjustTop( -(nDelta
- nDelta
/2) );
652 maPrgsFrameRect
.AdjustBottom(nDelta
/2 );
654 maPrgsTxtPos
.setY( maPrgsFrameRect
.Top() + (nProgressHeight
- GetTextHeight())/2 );
658 maPrgsTxtPos
.setY( mnTextY
);
661 void StatusBar::MouseButtonDown( const MouseEvent
& rMEvt
)
663 // trigger toolbox only for left mouse button
664 if ( !rMEvt
.IsLeft() )
667 Point aMousePos
= rMEvt
.GetPosPixel();
669 // search for clicked item
670 for ( size_t i
= 0; i
< mvItemList
.size(); ++i
)
672 ImplStatusItem
* pItem
= mvItemList
[ i
].get();
673 // check item for being clicked
674 if ( ImplGetItemRectPos( sal_uInt16(i
) ).Contains( aMousePos
) )
676 mnCurItemId
= pItem
->mnId
;
677 if ( rMEvt
.GetClicks() == 2 )
688 // if there's no item, trigger Click or DoubleClick
689 if ( rMEvt
.GetClicks() == 2 )
695 void StatusBar::Paint(vcl::RenderContext
& rRenderContext
, const tools::Rectangle
& rRect
)
700 sal_uInt16 nItemCount
= sal_uInt16( mvItemList
.size() );
704 rRenderContext
.Push(vcl::PushFlags::FILLCOLOR
| vcl::PushFlags::LINECOLOR
);
706 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
707 Color aProgressColor
= rStyleSettings
.GetHighlightColor();
708 if (aProgressColor
== rStyleSettings
.GetFaceColor())
709 aProgressColor
= rStyleSettings
.GetDarkShadowColor();
710 rRenderContext
.SetLineColor();
711 rRenderContext
.SetFillColor(aProgressColor
);
713 ImplDrawProgress(rRenderContext
, mnPercent
);
715 rRenderContext
.Pop();
720 if (GetStyle() & WB_RIGHT
)
721 ImplDrawText(rRenderContext
);
725 // Do offscreen only when we are not recording layout...
726 bool bOffscreen
= !rRenderContext
.ImplIsRecordLayout();
729 rRenderContext
.Erase(rRect
);
731 for (sal_uInt16 i
= 0; i
< nItemCount
; i
++)
732 ImplDrawItem(rRenderContext
, bOffscreen
, i
);
735 // draw line at the top of the status bar (to visually distinguish it from
736 // shell / docking area)
737 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
738 rRenderContext
.SetLineColor(rStyleSettings
.GetShadowColor());
739 rRenderContext
.DrawLine(Point(0, 0), Point(mnDX
-1, 0));
742 void StatusBar::Resize()
744 // save width and height
745 Size aSize
= GetOutputSizePixel();
746 mnDX
= aSize
.Width() - ImplGetSVData()->maNWFData
.mnStatusBarLowerRightOffset
;
747 mnDY
= aSize
.Height();
750 mnTextY
= (mnCalcHeight
-GetTextHeight())/2;
752 // provoke re-formatting
755 if ( mbProgressMode
)
756 ImplCalcProgressRect();
761 void StatusBar::RequestHelp( const HelpEvent
& rHEvt
)
763 // no keyboard help in status bar
764 if( rHEvt
.KeyboardActivated() )
767 sal_uInt16 nItemId
= GetItemId( ScreenToOutputPixel( rHEvt
.GetMousePosPixel() ) );
771 tools::Rectangle aItemRect
= GetItemRect( nItemId
);
772 Point aPt
= OutputToScreenPixel( aItemRect
.TopLeft() );
773 aItemRect
.SetLeft( aPt
.X() );
774 aItemRect
.SetTop( aPt
.Y() );
775 aPt
= OutputToScreenPixel( aItemRect
.BottomRight() );
776 aItemRect
.SetRight( aPt
.X() );
777 aItemRect
.SetBottom( aPt
.Y() );
779 if ( rHEvt
.GetMode() & HelpEventMode::BALLOON
)
781 OUString aStr
= GetHelpText( nItemId
);
782 Help::ShowBalloon( this, aItemRect
.Center(), aItemRect
, aStr
);
785 else if ( rHEvt
.GetMode() & HelpEventMode::QUICK
)
787 OUString
aStr(GetQuickHelpText(nItemId
));
788 // show quickhelp if available
791 Help::ShowQuickHelp( this, aItemRect
, aStr
);
794 aStr
= GetItemText( nItemId
);
795 // show a quick help if item text doesn't fit
796 if ( GetTextWidth( aStr
) > aItemRect
.GetWidth() )
798 Help::ShowQuickHelp( this, aItemRect
, aStr
);
804 Window::RequestHelp( rHEvt
);
807 void StatusBar::StateChanged( StateChangedType nType
)
809 Window::StateChanged( nType
);
811 if ( nType
== StateChangedType::InitShow
)
813 else if ( nType
== StateChangedType::UpdateMode
)
815 else if ( (nType
== StateChangedType::Zoom
) ||
816 (nType
== StateChangedType::ControlFont
) )
822 else if ( nType
== StateChangedType::ControlForeground
)
827 else if ( nType
== StateChangedType::ControlBackground
)
833 //invalidate layout cache
834 for (auto & pItem
: mvItemList
)
836 pItem
->mLayoutGlyphsCache
.reset();
841 void StatusBar::DataChanged( const DataChangedEvent
& rDCEvt
)
843 Window::DataChanged( rDCEvt
);
845 if ( !((rDCEvt
.GetType() == DataChangedEventType::DISPLAY
)
846 || (rDCEvt
.GetType() == DataChangedEventType::FONTS
)
847 || (rDCEvt
.GetType() == DataChangedEventType::FONTSUBSTITUTION
)
848 || ( (rDCEvt
.GetType() == DataChangedEventType::SETTINGS
)
849 && (rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
)
856 tools::Long nFudge
= GetTextHeight() / 4;
857 for (auto & pItem
: mvItemList
)
859 tools::Long nWidth
= GetTextWidth( pItem
->maText
) + nFudge
;
860 if( nWidth
> pItem
->mnWidth
+ STATUSBAR_OFFSET
)
861 pItem
->mnWidth
= nWidth
+ STATUSBAR_OFFSET
;
863 pItem
->mLayoutGlyphsCache
.reset();
865 Size aSize
= GetSizePixel();
866 // do not disturb current width, since
867 // CalcWindowSizePixel calculates a minimum width
868 aSize
.setHeight( CalcWindowSizePixel().Height() );
869 SetSizePixel( aSize
);
873 void StatusBar::Click()
875 maClickHdl
.Call( this );
878 void StatusBar::DoubleClick()
880 maDoubleClickHdl
.Call( this );
883 void StatusBar::UserDraw( const UserDrawEvent
& )
887 void StatusBar::InsertItem( sal_uInt16 nItemId
, sal_uLong nWidth
,
888 StatusBarItemBits nBits
,
889 tools::Long nOffset
, sal_uInt16 nPos
)
891 SAL_WARN_IF( !nItemId
, "vcl", "StatusBar::InsertItem(): ItemId == 0" );
892 SAL_WARN_IF( GetItemPos( nItemId
) != STATUSBAR_ITEM_NOTFOUND
, "vcl",
893 "StatusBar::InsertItem(): ItemId already exists" );
895 // default: IN and CENTER
896 if ( !(nBits
& (StatusBarItemBits::In
| StatusBarItemBits::Out
| StatusBarItemBits::Flat
)) )
897 nBits
|= StatusBarItemBits::In
;
898 if ( !(nBits
& (StatusBarItemBits::Left
| StatusBarItemBits::Right
| StatusBarItemBits::Center
)) )
899 nBits
|= StatusBarItemBits::Center
;
904 nWidth
*= GetDPIScaleFactor();
906 tools::Long nFudge
= GetTextHeight()/4;
907 std::unique_ptr
<ImplStatusItem
> pItem(new ImplStatusItem
);
908 pItem
->mnId
= nItemId
;
909 pItem
->mnBits
= nBits
;
910 pItem
->mnWidth
= static_cast<tools::Long
>(nWidth
)+nFudge
+STATUSBAR_OFFSET
;
911 pItem
->mnOffset
= nOffset
;
912 pItem
->mpUserData
= nullptr;
913 pItem
->mbVisible
= true;
916 if ( nPos
< mvItemList
.size() ) {
917 mvItemList
.insert( mvItemList
.begin() + nPos
, std::move(pItem
) );
919 mvItemList
.push_back( std::move(pItem
) );
923 if ( ImplIsItemUpdate() )
926 CallEventListeners( VclEventId::StatusbarItemAdded
, reinterpret_cast<void*>(nItemId
) );
929 void StatusBar::RemoveItem( sal_uInt16 nItemId
)
931 sal_uInt16 nPos
= GetItemPos( nItemId
);
932 if ( nPos
!= STATUSBAR_ITEM_NOTFOUND
)
934 mvItemList
.erase( mvItemList
.begin() + nPos
);
937 if ( ImplIsItemUpdate() )
940 CallEventListeners( VclEventId::StatusbarItemRemoved
, reinterpret_cast<void*>(nItemId
) );
944 void StatusBar::ShowItem( sal_uInt16 nItemId
)
946 sal_uInt16 nPos
= GetItemPos( nItemId
);
948 if ( nPos
== STATUSBAR_ITEM_NOTFOUND
)
951 ImplStatusItem
* pItem
= mvItemList
[ nPos
].get();
952 if ( !pItem
->mbVisible
)
954 pItem
->mbVisible
= true;
957 if ( ImplIsItemUpdate() )
960 CallEventListeners( VclEventId::StatusbarShowItem
, reinterpret_cast<void*>(nItemId
) );
964 void StatusBar::HideItem( sal_uInt16 nItemId
)
966 sal_uInt16 nPos
= GetItemPos( nItemId
);
968 if ( nPos
== STATUSBAR_ITEM_NOTFOUND
)
971 ImplStatusItem
* pItem
= mvItemList
[ nPos
].get();
972 if ( pItem
->mbVisible
)
974 pItem
->mbVisible
= false;
977 if ( ImplIsItemUpdate() )
980 CallEventListeners( VclEventId::StatusbarHideItem
, reinterpret_cast<void*>(nItemId
) );
984 bool StatusBar::IsItemVisible( sal_uInt16 nItemId
) const
986 sal_uInt16 nPos
= GetItemPos( nItemId
);
988 if ( nPos
!= STATUSBAR_ITEM_NOTFOUND
)
989 return mvItemList
[ nPos
]->mbVisible
;
994 void StatusBar::Clear()
1000 if ( ImplIsItemUpdate() )
1003 CallEventListeners( VclEventId::StatusbarAllItemsRemoved
);
1006 sal_uInt16
StatusBar::GetItemCount() const
1008 return static_cast<sal_uInt16
>(mvItemList
.size());
1011 sal_uInt16
StatusBar::GetItemId( sal_uInt16 nPos
) const
1013 if ( nPos
< mvItemList
.size() )
1014 return mvItemList
[ nPos
]->mnId
;
1018 sal_uInt16
StatusBar::GetItemPos( sal_uInt16 nItemId
) const
1020 for ( size_t i
= 0, n
= mvItemList
.size(); i
< n
; ++i
) {
1021 if ( mvItemList
[ i
]->mnId
== nItemId
) {
1022 return sal_uInt16( i
);
1026 return STATUSBAR_ITEM_NOTFOUND
;
1029 sal_uInt16
StatusBar::GetItemId( const Point
& rPos
) const
1033 sal_uInt16 nItemCount
= GetItemCount();
1035 for ( nPos
= 0; nPos
< nItemCount
; nPos
++ )
1038 tools::Rectangle aRect
= ImplGetItemRectPos( nPos
);
1039 if ( aRect
.Contains( rPos
) )
1040 return mvItemList
[ nPos
]->mnId
;
1047 tools::Rectangle
StatusBar::GetItemRect( sal_uInt16 nItemId
) const
1049 tools::Rectangle aRect
;
1053 sal_uInt16 nPos
= GetItemPos( nItemId
);
1054 if ( nPos
!= STATUSBAR_ITEM_NOTFOUND
)
1056 // get rectangle and subtract frame
1057 aRect
= ImplGetItemRectPos( nPos
);
1059 aRect
.AdjustTop(nW
-1 );
1060 aRect
.AdjustBottom( -(nW
-1) );
1061 aRect
.AdjustLeft(nW
);
1062 aRect
.AdjustRight( -nW
);
1070 Point
StatusBar::GetItemTextPos( sal_uInt16 nItemId
) const
1074 sal_uInt16 nPos
= GetItemPos( nItemId
);
1075 if ( nPos
!= STATUSBAR_ITEM_NOTFOUND
)
1078 ImplStatusItem
* pItem
= mvItemList
[ nPos
].get();
1079 tools::Rectangle aRect
= ImplGetItemRectPos( nPos
);
1081 tools::Rectangle
aTextRect( aRect
.Left()+nW
, aRect
.Top()+nW
,
1082 aRect
.Right()-nW
, aRect
.Bottom()-nW
);
1083 Point aPos
= ImplGetItemTextPos( aTextRect
.GetSize(),
1084 Size( GetTextWidth( pItem
->maText
), GetTextHeight() ),
1086 if ( !mbInUserDraw
)
1088 aPos
.AdjustX(aTextRect
.Left() );
1089 aPos
.AdjustY(aTextRect
.Top() );
1098 sal_uLong
StatusBar::GetItemWidth( sal_uInt16 nItemId
) const
1100 sal_uInt16 nPos
= GetItemPos( nItemId
);
1102 if ( nPos
!= STATUSBAR_ITEM_NOTFOUND
)
1103 return mvItemList
[ nPos
]->mnWidth
;
1108 StatusBarItemBits
StatusBar::GetItemBits( sal_uInt16 nItemId
) const
1110 sal_uInt16 nPos
= GetItemPos( nItemId
);
1112 if ( nPos
!= STATUSBAR_ITEM_NOTFOUND
)
1113 return mvItemList
[ nPos
]->mnBits
;
1115 return StatusBarItemBits::NONE
;
1118 tools::Long
StatusBar::GetItemOffset( sal_uInt16 nItemId
) const
1120 sal_uInt16 nPos
= GetItemPos( nItemId
);
1122 if ( nPos
!= STATUSBAR_ITEM_NOTFOUND
)
1123 return mvItemList
[ nPos
]->mnOffset
;
1128 void StatusBar::PaintSelfAndChildrenImmediately()
1130 WindowImpl
* pWindowImpl
= ImplGetWindowImpl();
1131 const bool bOrigOverlapWin
= pWindowImpl
->mbOverlapWin
;
1132 // Temporarily set mbOverlapWin so that any parent windows of StatusBar
1133 // that happen to have accumulated Invalidates are not taken as the root
1134 // paint candidate from which to paint the paint hierarchy. So we limit the
1135 // paint here to this statusbar and its children, disabling the
1136 // optimization to bundle pending paints together and suppressing any
1137 // unexpected side effects of entering parent window paint handlers if this
1138 // call is not from the primordial thread.
1139 pWindowImpl
->mbOverlapWin
= true;
1141 pWindowImpl
->mbOverlapWin
= bOrigOverlapWin
;
1144 void StatusBar::SetItemText( sal_uInt16 nItemId
, const OUString
& rText
, int nCharsWidth
)
1146 sal_uInt16 nPos
= GetItemPos( nItemId
);
1148 if ( nPos
== STATUSBAR_ITEM_NOTFOUND
)
1151 ImplStatusItem
* pItem
= mvItemList
[ nPos
].get();
1153 if ( pItem
->maText
== rText
)
1156 pItem
->maText
= rText
;
1158 // adjust item width - see also DataChanged()
1159 tools::Long nFudge
= GetTextHeight()/4;
1162 if (nCharsWidth
!= -1)
1164 nWidth
= GetTextWidth("0",0,-1,nullptr,
1165 SalLayoutGlyphsCache::self()->GetLayoutGlyphs(GetOutDev(),"0"));
1166 nWidth
= nWidth
* nCharsWidth
+ nFudge
;
1170 pItem
->mLayoutGlyphsCache
.reset();
1171 nWidth
= GetTextWidth( pItem
->maText
,0,-1,nullptr, pItem
->GetTextGlyphs(GetOutDev())) + nFudge
;
1174 if( (nWidth
> pItem
->mnWidth
+ STATUSBAR_OFFSET
) ||
1175 ((nWidth
< pItem
->mnWidth
) && (mnDX
- STATUSBAR_OFFSET
) < mnItemsWidth
))
1177 pItem
->mnWidth
= nWidth
+ STATUSBAR_OFFSET
;
1182 // re-draw item if StatusBar is visible and UpdateMode active
1183 if ( pItem
->mbVisible
&& !mbFormat
&& ImplIsItemUpdate() )
1185 tools::Rectangle aRect
= ImplGetItemRectPos(nPos
);
1187 PaintSelfAndChildrenImmediately();
1191 const OUString
& StatusBar::GetItemText( sal_uInt16 nItemId
) const
1193 sal_uInt16 nPos
= GetItemPos( nItemId
);
1195 assert( nPos
!= STATUSBAR_ITEM_NOTFOUND
);
1197 return mvItemList
[ nPos
]->maText
;
1200 void StatusBar::SetItemCommand( sal_uInt16 nItemId
, const OUString
& rCommand
)
1202 sal_uInt16 nPos
= GetItemPos( nItemId
);
1204 if ( nPos
!= STATUSBAR_ITEM_NOTFOUND
)
1206 ImplStatusItem
* pItem
= mvItemList
[ nPos
].get();
1208 if ( pItem
->maCommand
!= rCommand
)
1209 pItem
->maCommand
= rCommand
;
1213 OUString
StatusBar::GetItemCommand( sal_uInt16 nItemId
)
1215 sal_uInt16 nPos
= GetItemPos( nItemId
);
1217 if ( nPos
!= STATUSBAR_ITEM_NOTFOUND
)
1218 return mvItemList
[ nPos
]->maCommand
;
1223 void StatusBar::SetItemData( sal_uInt16 nItemId
, void* pNewData
)
1225 sal_uInt16 nPos
= GetItemPos( nItemId
);
1227 if ( nPos
== STATUSBAR_ITEM_NOTFOUND
)
1230 ImplStatusItem
* pItem
= mvItemList
[ nPos
].get();
1232 pItem
->mLayoutGlyphsCache
.reset();
1233 pItem
->mpUserData
= pNewData
;
1235 // call Draw-Item if it's a User-Item
1236 if ( (pItem
->mnBits
& StatusBarItemBits::UserDraw
) && pItem
->mbVisible
&&
1237 !mbFormat
&& ImplIsItemUpdate() )
1239 tools::Rectangle aRect
= ImplGetItemRectPos(nPos
);
1240 Invalidate(aRect
, InvalidateFlags::NoErase
);
1241 PaintSelfAndChildrenImmediately();
1245 void* StatusBar::GetItemData( sal_uInt16 nItemId
) const
1247 sal_uInt16 nPos
= GetItemPos( nItemId
);
1249 if ( nPos
!= STATUSBAR_ITEM_NOTFOUND
)
1250 return mvItemList
[ nPos
]->mpUserData
;
1255 void StatusBar::RedrawItem(sal_uInt16 nItemId
)
1260 sal_uInt16 nPos
= GetItemPos(nItemId
);
1261 if ( nPos
== STATUSBAR_ITEM_NOTFOUND
)
1264 ImplStatusItem
* pItem
= mvItemList
[ nPos
].get();
1265 if ((pItem
->mnBits
& StatusBarItemBits::UserDraw
) &&
1266 pItem
->mbVisible
&& ImplIsItemUpdate())
1268 tools::Rectangle aRect
= ImplGetItemRectPos(nPos
);
1270 PaintSelfAndChildrenImmediately();
1274 void StatusBar::SetHelpText( sal_uInt16 nItemId
, const OUString
& rText
)
1276 sal_uInt16 nPos
= GetItemPos( nItemId
);
1278 if ( nPos
!= STATUSBAR_ITEM_NOTFOUND
)
1279 mvItemList
[ nPos
]->maHelpText
= rText
;
1282 const OUString
& StatusBar::GetHelpText( sal_uInt16 nItemId
) const
1284 sal_uInt16 nPos
= GetItemPos( nItemId
);
1286 assert ( nPos
!= STATUSBAR_ITEM_NOTFOUND
);
1288 ImplStatusItem
* pItem
= mvItemList
[ nPos
].get();
1289 if ( pItem
->maHelpText
.isEmpty() && ( !pItem
->maHelpId
.isEmpty() || !pItem
->maCommand
.isEmpty() ))
1291 Help
* pHelp
= Application::GetHelp();
1294 if ( !pItem
->maCommand
.isEmpty() )
1295 pItem
->maHelpText
= pHelp
->GetHelpText( pItem
->maCommand
, this );
1296 if ( pItem
->maHelpText
.isEmpty() && !pItem
->maHelpId
.isEmpty() )
1297 pItem
->maHelpText
= pHelp
->GetHelpText( pItem
->maHelpId
, this );
1301 return pItem
->maHelpText
;
1304 void StatusBar::SetQuickHelpText( sal_uInt16 nItemId
, const OUString
& rText
)
1306 sal_uInt16 nPos
= GetItemPos( nItemId
);
1308 if ( nPos
!= STATUSBAR_ITEM_NOTFOUND
)
1309 mvItemList
[ nPos
]->maQuickHelpText
= rText
;
1312 const OUString
& StatusBar::GetQuickHelpText( sal_uInt16 nItemId
) const
1314 sal_uInt16 nPos
= GetItemPos( nItemId
);
1316 assert ( nPos
!= STATUSBAR_ITEM_NOTFOUND
);
1318 ImplStatusItem
* pItem
= mvItemList
[ nPos
].get();
1319 return pItem
->maQuickHelpText
;
1322 void StatusBar::SetHelpId( sal_uInt16 nItemId
, const OUString
& rHelpId
)
1324 sal_uInt16 nPos
= GetItemPos( nItemId
);
1326 if ( nPos
!= STATUSBAR_ITEM_NOTFOUND
)
1327 mvItemList
[ nPos
]->maHelpId
= rHelpId
;
1330 void StatusBar::StartProgressMode( const OUString
& rText
)
1332 SAL_WARN_IF( mbProgressMode
, "vcl", "StatusBar::StartProgressMode(): progress mode is active" );
1334 mbProgressMode
= true;
1339 ImplCalcProgressRect();
1341 // trigger Paint, which draws text and frame
1342 if ( IsReallyVisible() )
1345 PaintSelfAndChildrenImmediately();
1349 void StatusBar::SetProgressValue( sal_uInt16 nNewPercent
)
1351 SAL_WARN_IF( !mbProgressMode
, "vcl", "StatusBar::SetProgressValue(): no progress mode" );
1352 SAL_WARN_IF( nNewPercent
> 100, "vcl", "StatusBar::SetProgressValue(): nPercent > 100" );
1354 bool bInvalidate
= mbProgressMode
&& IsReallyVisible() && (!mnPercent
|| (mnPercent
!= nNewPercent
));
1356 mnPercent
= nNewPercent
;
1360 // Rate limit how often we paint, otherwise in some loading scenarios we can spend significant
1361 // time just painting progress bars.
1362 sal_uInt32 nTime_ms
= osl_getGlobalTimer();
1363 if ((nTime_ms
- mnLastProgressPaint_ms
) > 100)
1365 Invalidate(maPrgsFrameRect
);
1366 PaintSelfAndChildrenImmediately();
1367 mnLastProgressPaint_ms
= nTime_ms
;
1372 void StatusBar::EndProgressMode()
1374 SAL_WARN_IF( !mbProgressMode
, "vcl", "StatusBar::EndProgressMode(): no progress mode" );
1376 mbProgressMode
= false;
1379 if ( IsReallyVisible() )
1382 PaintSelfAndChildrenImmediately();
1386 void StatusBar::SetText(const OUString
& rText
)
1388 if ((GetStyle() & WB_RIGHT
) && !mbProgressMode
&& IsReallyVisible() && IsUpdateMode())
1393 Window::SetText(rText
);
1398 Window::SetText(rText
);
1399 PaintSelfAndChildrenImmediately();
1402 else if (mbProgressMode
)
1405 if (IsReallyVisible())
1408 PaintSelfAndChildrenImmediately();
1413 Window::SetText(rText
);
1417 Size
StatusBar::CalcWindowSizePixel() const
1420 size_t nCount
= mvItemList
.size();
1421 tools::Long nOffset
= 0;
1422 tools::Long nCalcWidth
= STATUSBAR_OFFSET_X
*2;
1423 tools::Long nCalcHeight
;
1425 while ( i
< nCount
)
1427 ImplStatusItem
* pItem
= mvItemList
[ i
].get();
1428 nCalcWidth
+= pItem
->mnWidth
+ nOffset
;
1429 nOffset
= pItem
->mnOffset
;
1433 tools::Long nMinHeight
= std::max( static_cast<int>(GetTextHeight()), STATUSBAR_MIN_HEIGHT
);
1434 const tools::Long nBarTextOffset
= STATUSBAR_OFFSET_TEXTY
*2;
1435 tools::Long nProgressHeight
= nMinHeight
+ nBarTextOffset
;
1437 if( IsNativeControlSupported( ControlType::Progress
, ControlPart::Entire
) )
1439 ImplControlValue aValue
;
1440 tools::Rectangle
aControlRegion( Point(), Size( nCalcWidth
, nMinHeight
) );
1441 tools::Rectangle aNativeControlRegion
, aNativeContentRegion
;
1442 if( GetNativeControlRegion( ControlType::Progress
, ControlPart::Entire
,
1443 aControlRegion
, ControlState::ENABLED
, aValue
,
1444 aNativeControlRegion
, aNativeContentRegion
) )
1446 nProgressHeight
= aNativeControlRegion
.GetHeight();
1450 nCalcHeight
= nMinHeight
+nBarTextOffset
;
1451 if( nCalcHeight
< nProgressHeight
+2 )
1452 nCalcHeight
= nProgressHeight
+2;
1454 return Size( nCalcWidth
, nCalcHeight
);
1457 void StatusBar::SetAccessibleName( sal_uInt16 nItemId
, const OUString
& rName
)
1459 sal_uInt16 nPos
= GetItemPos( nItemId
);
1461 if ( nPos
!= STATUSBAR_ITEM_NOTFOUND
)
1463 ImplStatusItem
* pItem
= mvItemList
[ nPos
].get();
1465 if ( pItem
->maAccessibleName
!= rName
)
1467 pItem
->maAccessibleName
= rName
;
1468 CallEventListeners( VclEventId::StatusbarNameChanged
, reinterpret_cast<void*>(pItem
->mnId
) );
1473 const OUString
& StatusBar::GetAccessibleName( sal_uInt16 nItemId
) const
1475 sal_uInt16 nPos
= GetItemPos( nItemId
);
1477 assert ( nPos
!= STATUSBAR_ITEM_NOTFOUND
);
1479 return mvItemList
[ nPos
]->maAccessibleName
;
1482 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */