LibreOffice Module vcl (master)  1
status.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 
21 #include <sal/log.hxx>
22 #include <comphelper/string.hxx>
23 #include <vcl/event.hxx>
24 #include <vcl/decoview.hxx>
25 #include <vcl/svapp.hxx>
26 #include <vcl/help.hxx>
27 #include <vcl/vcllayout.hxx>
28 #include <vcl/status.hxx>
29 #include <vcl/virdev.hxx>
30 #include <vcl/settings.hxx>
31 #include <config_features.h>
32 #if HAVE_FEATURE_OPENGL
34 #endif
35 #include <svdata.hxx>
36 #include <window.h>
37 
38 #define STATUSBAR_OFFSET_X STATUSBAR_OFFSET
39 #define STATUSBAR_OFFSET_Y 2
40 #define STATUSBAR_OFFSET_TEXTY 3
41 
42 #define STATUSBAR_PRGS_OFFSET 3
43 #define STATUSBAR_PRGS_COUNT 100
44 #define STATUSBAR_PRGS_MIN 5
45 
47 {
48 public:
49  ImplData();
50 
52 };
53 
55 {
56  mpVirDev = nullptr;
57 }
58 
60 {
61  sal_uInt16 mnId;
63  long mnWidth;
64  long mnOffset;
66  long mnX;
67  OUString maText;
68  OUString maHelpText;
69  OUString maQuickHelpText;
70  OString maHelpId;
71  void* mpUserData;
72  bool mbVisible;
73  OUString maAccessibleName;
74  OUString maCommand;
75  std::unique_ptr<SalLayout> mxLayoutCache;
76 };
77 
78 static long ImplCalcProgressWidth( sal_uInt16 nMax, long nSize )
79 {
80  return ((nMax*(nSize+(nSize/2)))-(nSize/2)+(STATUSBAR_PRGS_OFFSET*2));
81 }
82 
83 static Point ImplGetItemTextPos( const Size& rRectSize, const Size& rTextSize,
84  StatusBarItemBits nStyle )
85 {
86  long nX;
87  long nY;
88  long delta = (rTextSize.Height()/4) + 1;
89  if( delta + rTextSize.Width() > rRectSize.Width() )
90  delta = 0;
91 
92  if ( nStyle & StatusBarItemBits::Left )
93  nX = delta;
94  else if ( nStyle & StatusBarItemBits::Right )
95  nX = rRectSize.Width()-rTextSize.Width()-delta;
96  else // StatusBarItemBits::Center
97  nX = (rRectSize.Width()-rTextSize.Width())/2;
98  nY = (rRectSize.Height()-rTextSize.Height())/2 + 1;
99  return Point( nX, nY );
100 }
101 
103 {
104  return !mbProgressMode && IsReallyVisible() && IsUpdateMode();
105 }
106 
107 void StatusBar::ImplInit( vcl::Window* pParent, WinBits nStyle )
108 {
109  mpImplData.reset(new ImplData);
110 
111  // default: RightAlign
112  if ( !(nStyle & (WB_LEFT | WB_RIGHT)) )
113  nStyle |= WB_RIGHT;
114 
115  Window::ImplInit( pParent, nStyle & ~WB_BORDER, nullptr );
116 
117  // remember WinBits
118  mpImplData->mpVirDev = VclPtr<VirtualDevice>::Create( *this );
119  mnCurItemId = 0;
120  mbFormat = true;
121  mbProgressMode = false;
122  mbInUserDraw = false;
123  mbAdjustHiDPI = false;
125  mnDX = 0;
126  mnDY = 0;
127  mnCalcHeight = 0;
129 
131 
133 }
134 
137  mnLastProgressPaint_ms(osl_getGlobalTimer())
138 {
139  ImplInit( pParent, nStyle );
140 }
141 
143 {
144  disposeOnce();
145 }
146 
148 {
149  // delete all items
150  mvItemList.clear();
151 
152  // delete VirtualDevice
153  mpImplData->mpVirDev.disposeAndClear();
154  mpImplData.reset();
155  Window::dispose();
156 }
157 
159 {
160  mbAdjustHiDPI = true;
161 }
162 
164 {
165  rRenderContext.SetLineColor();
166 
167  const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
168  ApplyControlFont(rRenderContext, rStyleSettings.GetToolFont());
169 
170  Color aColor;
171  if (IsControlForeground())
172  aColor = GetControlForeground();
173  else if (GetStyle() & WB_3DLOOK)
174  aColor = rStyleSettings.GetButtonTextColor();
175  else
176  aColor = rStyleSettings.GetWindowTextColor();
177  rRenderContext.SetTextColor(aColor);
178 
179  rRenderContext.SetTextFillColor();
180 
181  if (IsControlBackground())
182  aColor = GetControlBackground();
183  else if (GetStyle() & WB_3DLOOK)
184  aColor = rStyleSettings.GetFaceColor();
185  else
186  aColor = rStyleSettings.GetWindowColor();
187  rRenderContext.SetBackground(aColor);
188 
189  // NWF background
190  if (!IsControlBackground() &&
192  {
195  }
196 }
197 
199 {
200  ApplySettings(*this);
201 
202  mpImplData->mpVirDev->SetFont(GetFont());
203  mpImplData->mpVirDev->SetTextColor(GetTextColor());
204  mpImplData->mpVirDev->SetTextAlign(GetTextAlign());
205  mpImplData->mpVirDev->SetTextFillColor();
206  mpImplData->mpVirDev->SetBackground(GetBackground());
207 }
208 
210 {
211  long nExtraWidth;
212  long nExtraWidth2;
213  long nX;
214  sal_uInt16 nAutoSizeItems;
215  bool bChanged;
216 
217  do {
218  // sum up widths
219  nAutoSizeItems = 0;
221  bChanged = false;
222  long nOffset = 0;
223  for ( const auto & pItem : mvItemList ) {
224  if ( pItem->mbVisible )
225  {
226  if ( pItem->mnBits & StatusBarItemBits::AutoSize ) {
227  nAutoSizeItems++;
228  }
229 
230  mnItemsWidth += pItem->mnWidth + nOffset;
231  nOffset = pItem->mnOffset;
232  }
233  }
234 
235  if ( mnDX > 0 && mnDX < mnItemsWidth )
236  {
237  // Total width of items is more than available width
238  // Try to hide secondary elements, if any
239  for ( auto & pItem : mvItemList )
240  {
241  if ( pItem->mbVisible && !(pItem->mnBits & StatusBarItemBits::Mandatory) )
242  {
243  pItem->mbVisible = false;
244  bChanged = true;
245  break;
246  }
247  }
248  }
249  else if ( mnDX > mnItemsWidth )
250  {
251  // Width of statusbar is sufficient.
252  // Try to restore hidden items, if any
253  for ( auto & pItem : mvItemList )
254  {
255  if ( !pItem->mbVisible &&
256  !(pItem->mnBits & StatusBarItemBits::Mandatory) &&
257  pItem->mnWidth + nOffset + mnItemsWidth < mnDX )
258  {
259  pItem->mbVisible = true;
260  bChanged = true;
261  break;
262  }
263  }
264  }
265  } while ( bChanged );
266 
267  if ( GetStyle() & WB_RIGHT )
268  {
269  // AutoSize isn't computed for right-alignment,
270  // because we show the text that is declared by SetText on the left side
271  nX = mnDX - mnItemsWidth;
272  nExtraWidth = 0;
273  nExtraWidth2 = 0;
274  }
275  else
276  {
278 
279  // calling AutoSize is potentially necessary for left-aligned text,
280  if ( nAutoSizeItems && (mnDX > (mnItemsWidth - STATUSBAR_OFFSET)) )
281  {
282  nExtraWidth = (mnDX - mnItemsWidth - 1) / nAutoSizeItems;
283  nExtraWidth2 = (mnDX - mnItemsWidth - 1) % nAutoSizeItems;
284  }
285  else
286  {
287  nExtraWidth = 0;
288  nExtraWidth2 = 0;
289  }
290  nX = STATUSBAR_OFFSET_X;
291 
292  if( HasMirroredGraphics() && IsRTLEnabled() )
294  }
295 
296  for (auto & pItem : mvItemList) {
297  if ( pItem->mbVisible ) {
298  if ( pItem->mnBits & StatusBarItemBits::AutoSize ) {
299  pItem->mnExtraWidth = nExtraWidth;
300  if ( nExtraWidth2 ) {
301  pItem->mnExtraWidth++;
302  nExtraWidth2--;
303  }
304  } else {
305  pItem->mnExtraWidth = 0;
306  }
307 
308  pItem->mnX = nX;
309  nX += pItem->mnWidth + pItem->mnExtraWidth + pItem->mnOffset;
310  }
311  }
312 
313  mbFormat = false;
314 }
315 
317 {
318  tools::Rectangle aRect;
319  ImplStatusItem* pItem = ( nPos < mvItemList.size() ) ? mvItemList[ nPos ].get() : nullptr;
320  if ( pItem && pItem->mbVisible )
321  {
322  aRect.SetLeft( pItem->mnX );
323  aRect.SetRight( aRect.Left() + pItem->mnWidth + pItem->mnExtraWidth );
324  aRect.SetTop( STATUSBAR_OFFSET_Y );
326  }
327 
328  return aRect;
329 }
330 
332 {
333  for( size_t nPos = 0; nPos < mvItemList.size(); nPos++ )
334  {
335  ImplStatusItem* pItem = mvItemList[ nPos ].get();
336  if ( pItem->mbVisible )
337  return sal_uInt16(nPos);
338  }
339 
340  return SAL_MAX_UINT16;
341 }
342 
344 {
345  // prevent item box from being overwritten
346  tools::Rectangle aTextRect;
347  aTextRect.SetLeft( STATUSBAR_OFFSET_X + 1 );
348  aTextRect.SetTop( mnTextY );
349  if (GetStyle() & WB_RIGHT)
350  aTextRect.SetRight( mnDX - mnItemsWidth - 1 );
351  else
352  aTextRect.SetRight( mnDX - 1 );
353  if (aTextRect.Right() > aTextRect.Left())
354  {
355  // compute position
356  OUString aStr = GetText();
357  sal_Int32 nPos = aStr.indexOf('\n');
358  if (nPos != -1)
359  aStr = aStr.copy(0, nPos);
360 
361  aTextRect.SetBottom( aTextRect.Top()+GetTextHeight()+1 );
362 
364  }
365 }
366 
367 void StatusBar::ImplDrawItem(vcl::RenderContext& rRenderContext, bool bOffScreen, sal_uInt16 nPos)
368 {
369  tools::Rectangle aRect = ImplGetItemRectPos(nPos);
370 
371  if (aRect.IsEmpty())
372  return;
373 
374  // compute output region
375  ImplStatusItem* pItem = mvItemList[nPos].get();
376  long nW = 1;
377  tools::Rectangle aTextRect(aRect.Left() + nW, aRect.Top() + nW,
378  aRect.Right() - nW, aRect.Bottom() - nW);
379 
380  Size aTextRectSize(aTextRect.GetSize());
381 
382  if (bOffScreen)
383  {
384  mpImplData->mpVirDev->SetOutputSizePixel(aTextRectSize);
385  }
386  else
387  {
388  vcl::Region aRegion(aTextRect);
389  rRenderContext.SetClipRegion(aRegion);
390  }
391 
392  // if the framework code is drawing status, let it do all the work
393  if (!(pItem->mnBits & StatusBarItemBits::UserDraw))
394  {
395  SalLayout* pLayoutCache = pItem->mxLayoutCache.get();
396 
397  if(!pLayoutCache)
398  {
399  // update cache
400  pItem->mxLayoutCache = rRenderContext.ImplLayout(pItem->maText, 0, -1);
401  pLayoutCache = pItem->mxLayoutCache.get();
402  }
403 
404  const SalLayoutGlyphs* pGlyphs = pLayoutCache ? pLayoutCache->GetGlyphs() : nullptr;
405  Size aTextSize(rRenderContext.GetTextWidth(pItem->maText,0,-1,nullptr,pGlyphs), rRenderContext.GetTextHeight());
406  Point aTextPos = ImplGetItemTextPos(aTextRectSize, aTextSize, pItem->mnBits);
407 
408  if (bOffScreen)
409  {
410  mpImplData->mpVirDev->DrawText(
411  aTextPos,
412  pItem->maText,
413  0, -1, nullptr, nullptr,
414  pGlyphs );
415  }
416  else
417  {
418  aTextPos.AdjustX(aTextRect.Left() );
419  aTextPos.AdjustY(aTextRect.Top() );
420  rRenderContext.DrawText(
421  aTextPos,
422  pItem->maText,
423  0, -1, nullptr, nullptr,
424  pGlyphs );
425  }
426  }
427 
428  // call DrawItem if necessary
429  if (pItem->mnBits & StatusBarItemBits::UserDraw)
430  {
431  if (bOffScreen)
432  {
433  mbInUserDraw = true;
434  mpImplData->mpVirDev->EnableRTL( IsRTLEnabled() );
435  UserDrawEvent aODEvt(this, mpImplData->mpVirDev, tools::Rectangle(Point(), aTextRectSize), pItem->mnId);
436  UserDraw(aODEvt);
437  mpImplData->mpVirDev->EnableRTL(false);
438  mbInUserDraw = false;
439  }
440  else
441  {
442  UserDrawEvent aODEvt(this, &rRenderContext, aTextRect, pItem->mnId);
443  UserDraw(aODEvt);
444  }
445  }
446 
447  if (bOffScreen)
448  rRenderContext.DrawOutDev(aTextRect.TopLeft(), aTextRectSize, Point(), aTextRectSize, *mpImplData->mpVirDev);
449  else
450  rRenderContext.SetClipRegion();
451 
452  if (nPos != ImplGetFirstVisiblePos())
453  {
454  // draw separator
455  Point aFrom(aRect.TopLeft());
456  aFrom.AdjustX( -4 );
457  aFrom.AdjustY( 1 );
458  Point aTo(aRect.BottomLeft());
459  aTo.AdjustX( -4 );
460  aTo.AdjustY( -1 );
461 
462  DecorationView aDecoView(&rRenderContext);
463  aDecoView.DrawSeparator(aFrom, aTo);
464  }
465 
466  if (!rRenderContext.ImplIsRecordLayout())
467  CallEventListeners(VclEventId::StatusbarDrawItem, reinterpret_cast<void*>(pItem->mnId));
468 }
469 
470 void DrawProgress(vcl::Window* pWindow, vcl::RenderContext& rRenderContext, const Point& rPos,
471  long nOffset, long nPrgsWidth, long nPrgsHeight,
472  sal_uInt16 nPercent1, sal_uInt16 nPercent2, sal_uInt16 nPercentCount,
473  const tools::Rectangle& rFramePosSize)
474 {
476  {
477  bool bNeedErase = ImplGetSVData()->maNWFData.mbProgressNeedsErase;
478 
479  long nFullWidth = (nPrgsWidth + nOffset) * (10000 / nPercentCount);
480  long nPerc = std::min<sal_uInt16>(nPercent2, 10000);
481  ImplControlValue aValue(nFullWidth * nPerc / 10000);
482  tools::Rectangle aDrawRect(rPos, Size(nFullWidth, nPrgsHeight));
483  tools::Rectangle aControlRegion(aDrawRect);
484 
485  if(bNeedErase)
486  {
487  vcl::Window* pEraseWindow = pWindow;
488  while (pEraseWindow->IsPaintTransparent() && !pEraseWindow->ImplGetWindowImpl()->mbFrame)
489  {
490  pEraseWindow = pEraseWindow->ImplGetWindowImpl()->mpParent;
491  }
492 
493  if (pEraseWindow == pWindow)
494  {
495  // restore background of pWindow
496  rRenderContext.Erase(rFramePosSize);
497  }
498  else
499  {
500  // restore transparent background
501  Point aTL(pWindow->OutputToAbsoluteScreenPixel(rFramePosSize.TopLeft()));
502  aTL = pEraseWindow->AbsoluteScreenToOutputPixel(aTL);
503  tools::Rectangle aRect(aTL, rFramePosSize.GetSize());
504  pEraseWindow->Invalidate(aRect, InvalidateFlags::NoChildren |
507  }
508  rRenderContext.Push(PushFlags::CLIPREGION);
509  rRenderContext.IntersectClipRegion(rFramePosSize);
510  }
511 
512  bool bNativeOK = rRenderContext.DrawNativeControl(ControlType::Progress, ControlPart::Entire, aControlRegion,
513  ControlState::ENABLED, aValue, OUString());
514  if (bNeedErase)
515  rRenderContext.Pop();
516  if (bNativeOK)
517  return;
518  }
519 
520  // precompute values
521  sal_uInt16 nPerc1 = nPercent1 / nPercentCount;
522  sal_uInt16 nPerc2 = nPercent2 / nPercentCount;
523 
524  if (nPerc1 > nPerc2)
525  {
526  // support progress that can also decrease
527 
528  // compute rectangle
529  long nDX = nPrgsWidth + nOffset;
530  long nLeft = rPos.X() + ((nPerc1 - 1) * nDX);
531  tools::Rectangle aRect(nLeft, rPos.Y(), nLeft + nPrgsWidth, rPos.Y() + nPrgsHeight);
532 
533  do
534  {
535  rRenderContext.Erase(aRect);
536  aRect.AdjustLeft( -nDX );
537  aRect.AdjustRight( -nDX );
538  nPerc1--;
539  }
540  while (nPerc1 > nPerc2);
541  }
542  else if (nPerc1 < nPerc2)
543  {
544  // draw Percent rectangle
545  // if Percent2 greater than 100%, adapt values
546  if (nPercent2 > 10000)
547  {
548  nPerc2 = 10000 / nPercentCount;
549  if (nPerc1 >= nPerc2)
550  nPerc1 = nPerc2 - 1;
551  }
552 
553  // compute rectangle
554  long nDX = nPrgsWidth + nOffset;
555  long nLeft = rPos.X() + (nPerc1 * nDX);
556  tools::Rectangle aRect(nLeft, rPos.Y(), nLeft + nPrgsWidth, rPos.Y() + nPrgsHeight);
557 
558  do
559  {
560  rRenderContext.DrawRect(aRect);
561  aRect.AdjustLeft(nDX );
562  aRect.AdjustRight(nDX );
563  nPerc1++;
564  }
565  while (nPerc1 < nPerc2);
566 
567  // if greater than 100%, set rectangle to blink
568  if (nPercent2 > 10000)
569  {
570  // define on/off status
571  if (((nPercent2 / nPercentCount) & 0x01) == (nPercentCount & 0x01))
572  {
573  aRect.AdjustLeft( -nDX );
574  aRect.AdjustRight( -nDX );
575  rRenderContext.Erase(aRect);
576  }
577  }
578  }
579 }
580 
581 void StatusBar::ImplDrawProgress(vcl::RenderContext& rRenderContext, sal_uInt16 nPercent2)
582 {
584  // bPaint: draw text also, else only update progress
585  rRenderContext.DrawText(maPrgsTxtPos, maPrgsTxt);
586  if (!bNative)
587  {
588  DecorationView aDecoView(&rRenderContext);
590  }
591 
594  long nPrgsHeight = mnPrgsSize;
595  if (bNative)
596  {
597  aPos = maPrgsFrameRect.TopLeft();
598  nPrgsHeight = maPrgsFrameRect.GetHeight();
599  }
600  DrawProgress(this, rRenderContext, aPos, mnPrgsSize / 2, mnPrgsSize, nPrgsHeight,
601  0, nPercent2 * 100, mnPercentCount, maPrgsFrameRect);
602 }
603 
605 {
606  // calculate text size
607  Size aPrgsTxtSize( GetTextWidth( maPrgsTxt ), GetTextHeight() );
609 
610  // calculate progress frame
614 
615  // calculate size of progress rects
617  sal_uInt16 nMaxPercent = STATUSBAR_PRGS_COUNT;
618 
619  long nMaxWidth = mnDX-STATUSBAR_OFFSET-1;
620 
621  // make smaller if there are too many rects
622  while ( maPrgsFrameRect.Left()+ImplCalcProgressWidth( nMaxPercent, mnPrgsSize ) > nMaxWidth )
623  {
624  nMaxPercent--;
625  if ( nMaxPercent <= STATUSBAR_PRGS_MIN )
626  break;
627  }
629 
630  // save the divisor for later
631  mnPercentCount = 10000 / nMaxPercent;
632  bool bNativeOK = false;
634  {
635  ImplControlValue aValue;
637  tools::Rectangle aNativeControlRegion, aNativeContentRegion;
638  if( (bNativeOK = GetNativeControlRegion( ControlType::Progress, ControlPart::Entire, aControlRegion,
639  ControlState::ENABLED, aValue,
640  aNativeControlRegion, aNativeContentRegion ) ) )
641  {
642  long nProgressHeight = aNativeControlRegion.GetHeight();
643  if( nProgressHeight > maPrgsFrameRect.GetHeight() )
644  {
645  long nDelta = nProgressHeight - maPrgsFrameRect.GetHeight();
646  maPrgsFrameRect.AdjustTop( -(nDelta - nDelta/2) );
647  maPrgsFrameRect.AdjustBottom(nDelta/2 );
648  }
649  maPrgsTxtPos.setY( maPrgsFrameRect.Top() + (nProgressHeight - GetTextHeight())/2 );
650  }
651  }
652  if( ! bNativeOK )
653  maPrgsTxtPos.setY( mnTextY );
654 }
655 
657 {
658  // trigger toolbox only for left mouse button
659  if ( rMEvt.IsLeft() )
660  {
661  Point aMousePos = rMEvt.GetPosPixel();
662 
663  // search for clicked item
664  for ( size_t i = 0; i < mvItemList.size(); ++i )
665  {
666  ImplStatusItem* pItem = mvItemList[ i ].get();
667  // check item for being clicked
668  if ( ImplGetItemRectPos( sal_uInt16(i) ).IsInside( aMousePos ) )
669  {
670  mnCurItemId = pItem->mnId;
671  if ( rMEvt.GetClicks() == 2 )
672  DoubleClick();
673  else
674  Click();
675  mnCurItemId = 0;
676 
677  // Item found
678  return;
679  }
680  }
681 
682  // if there's no item, trigger Click or DoubleClick
683  if ( rMEvt.GetClicks() == 2 )
684  DoubleClick();
685  else
686  Click();
687  }
688 }
689 
690 void StatusBar::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
691 {
692  if (mbFormat)
693  ImplFormat();
694 
695  sal_uInt16 nItemCount = sal_uInt16( mvItemList.size() );
696 
697  if (mbProgressMode)
698  {
700 
701  const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
702  Color aProgressColor = rStyleSettings.GetHighlightColor();
703  if (aProgressColor == rStyleSettings.GetFaceColor())
704  aProgressColor = rStyleSettings.GetDarkShadowColor();
705  rRenderContext.SetLineColor();
706  rRenderContext.SetFillColor(aProgressColor);
707 
708  ImplDrawProgress(rRenderContext, mnPercent);
709 
710  rRenderContext.Pop();
711  }
712  else
713  {
714  // draw text
715  if (GetStyle() & WB_RIGHT)
716  ImplDrawText(rRenderContext);
717 
718  // draw items
719 
720  // Do offscreen only when we are not recording layout...
721  bool bOffscreen = !rRenderContext.ImplIsRecordLayout();
722 
723  // tdf#94213 - un-necessary virtual-device in GL mode
724  // causes context switch & hence flicker during sizing.
725 #if HAVE_FEATURE_OPENGL
727  bOffscreen = false;
728 #endif
729 
730  if (!bOffscreen)
731  rRenderContext.Erase(rRect);
732 
733  for (sal_uInt16 i = 0; i < nItemCount; i++)
734  ImplDrawItem(rRenderContext, bOffscreen, i);
735  }
736 
737  // draw line at the top of the status bar (to visually distinguish it from
738  // shell / docking area)
739  const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
740  rRenderContext.SetLineColor(rStyleSettings.GetShadowColor());
741  rRenderContext.DrawLine(Point(0, 0), Point(mnDX-1, 0));
742 }
743 
745 {
746  // save width and height
747  Size aSize = GetOutputSizePixel();
749  mnDY = aSize.Height();
750  mnCalcHeight = mnDY;
751 
753 
754  // provoke re-formatting
755  mbFormat = true;
756 
757  if ( mbProgressMode )
759 
760  Invalidate();
761 }
762 
763 void StatusBar::RequestHelp( const HelpEvent& rHEvt )
764 {
765  // no keyboard help in status bar
766  if( rHEvt.KeyboardActivated() )
767  return;
768 
769  sal_uInt16 nItemId = GetItemId( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ) );
770 
771  if ( nItemId )
772  {
773  tools::Rectangle aItemRect = GetItemRect( nItemId );
774  Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
775  aItemRect.SetLeft( aPt.X() );
776  aItemRect.SetTop( aPt.Y() );
777  aPt = OutputToScreenPixel( aItemRect.BottomRight() );
778  aItemRect.SetRight( aPt.X() );
779  aItemRect.SetBottom( aPt.Y() );
780 
781  if ( rHEvt.GetMode() & HelpEventMode::BALLOON )
782  {
783  OUString aStr = GetHelpText( nItemId );
784  Help::ShowBalloon( this, aItemRect.Center(), aItemRect, aStr );
785  return;
786  }
787  else if ( rHEvt.GetMode() & HelpEventMode::QUICK )
788  {
789  OUString aStr(GetQuickHelpText(nItemId));
790  // show quickhelp if available
791  if (!aStr.isEmpty())
792  {
793  Help::ShowQuickHelp( this, aItemRect, aStr );
794  return;
795  }
796  aStr = GetItemText( nItemId );
797  // show a quick help if item text doesn't fit
798  if ( GetTextWidth( aStr ) > aItemRect.GetWidth() )
799  {
800  Help::ShowQuickHelp( this, aItemRect, aStr );
801  return;
802  }
803  }
804  }
805 
806  Window::RequestHelp( rHEvt );
807 }
808 
810 {
811  Window::StateChanged( nType );
812 
813  if ( nType == StateChangedType::InitShow )
814  ImplFormat();
815  else if ( nType == StateChangedType::UpdateMode )
816  Invalidate();
817  else if ( (nType == StateChangedType::Zoom) ||
818  (nType == StateChangedType::ControlFont) )
819  {
820  mbFormat = true;
822  Invalidate();
823  }
824  else if ( nType == StateChangedType::ControlForeground )
825  {
827  Invalidate();
828  }
829  else if ( nType == StateChangedType::ControlBackground )
830  {
832  Invalidate();
833  }
834 
835  //invalidate layout cache
836  for (auto & pItem : mvItemList)
837  {
838  pItem->mxLayoutCache.reset();
839  }
840 
841 }
842 
844 {
845  Window::DataChanged( rDCEvt );
846 
847  if ( (rDCEvt.GetType() == DataChangedEventType::DISPLAY )
848  || (rDCEvt.GetType() == DataChangedEventType::FONTS )
850  || ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS)
851  && (rDCEvt.GetFlags() & AllSettingsFlags::STYLE )
852  )
853  )
854  {
855  mbFormat = true;
857  long nFudge = GetTextHeight() / 4;
858  for (auto & pItem : mvItemList)
859  {
860  long nWidth = GetTextWidth( pItem->maText ) + nFudge;
861  if( nWidth > pItem->mnWidth + STATUSBAR_OFFSET )
862  pItem->mnWidth = nWidth + STATUSBAR_OFFSET;
863 
864  pItem->mxLayoutCache.reset();
865  }
866  Size aSize = GetSizePixel();
867  // do not disturb current width, since
868  // CalcWindowSizePixel calculates a minimum width
869  aSize.setHeight( CalcWindowSizePixel().Height() );
870  SetSizePixel( aSize );
871  Invalidate();
872  }
873 }
874 
876 {
877  maClickHdl.Call( this );
878 }
879 
881 {
882  maDoubleClickHdl.Call( this );
883 }
884 
886 {
887 }
888 
889 void StatusBar::InsertItem( sal_uInt16 nItemId, sal_uLong nWidth,
890  StatusBarItemBits nBits,
891  long nOffset, sal_uInt16 nPos )
892 {
893  SAL_WARN_IF( !nItemId, "vcl", "StatusBar::InsertItem(): ItemId == 0" );
894  SAL_WARN_IF( GetItemPos( nItemId ) != STATUSBAR_ITEM_NOTFOUND, "vcl",
895  "StatusBar::InsertItem(): ItemId already exists" );
896 
897  // default: IN and CENTER
899  nBits |= StatusBarItemBits::In;
901  nBits |= StatusBarItemBits::Center;
902 
903  // create item
904  if (mbAdjustHiDPI)
905  {
906  nWidth *= GetDPIScaleFactor();
907  }
908  long nFudge = GetTextHeight()/4;
909  std::unique_ptr<ImplStatusItem> pItem(new ImplStatusItem);
910  pItem->mnId = nItemId;
911  pItem->mnBits = nBits;
912  pItem->mnWidth = static_cast<long>(nWidth)+nFudge+STATUSBAR_OFFSET;
913  pItem->mnOffset = nOffset;
914  pItem->mpUserData = nullptr;
915  pItem->mbVisible = true;
916 
917  // add item to list
918  if ( nPos < mvItemList.size() ) {
919  mvItemList.insert( mvItemList.begin() + nPos, std::move(pItem) );
920  } else {
921  mvItemList.push_back( std::move(pItem) );
922  }
923 
924  mbFormat = true;
925  if ( ImplIsItemUpdate() )
926  Invalidate();
927 
928  CallEventListeners( VclEventId::StatusbarItemAdded, reinterpret_cast<void*>(nItemId) );
929 }
930 
931 void StatusBar::RemoveItem( sal_uInt16 nItemId )
932 {
933  sal_uInt16 nPos = GetItemPos( nItemId );
934  if ( nPos != STATUSBAR_ITEM_NOTFOUND )
935  {
936  mvItemList.erase( mvItemList.begin() + nPos );
937 
938  mbFormat = true;
939  if ( ImplIsItemUpdate() )
940  Invalidate();
941 
942  CallEventListeners( VclEventId::StatusbarItemRemoved, reinterpret_cast<void*>(nItemId) );
943  }
944 }
945 
946 void StatusBar::ShowItem( sal_uInt16 nItemId )
947 {
948  sal_uInt16 nPos = GetItemPos( nItemId );
949 
950  if ( nPos != STATUSBAR_ITEM_NOTFOUND )
951  {
952  ImplStatusItem* pItem = mvItemList[ nPos ].get();
953  if ( !pItem->mbVisible )
954  {
955  pItem->mbVisible = true;
956 
957  mbFormat = true;
958  if ( ImplIsItemUpdate() )
959  Invalidate();
960 
961  CallEventListeners( VclEventId::StatusbarShowItem, reinterpret_cast<void*>(nItemId) );
962  }
963  }
964 }
965 
966 void StatusBar::HideItem( sal_uInt16 nItemId )
967 {
968  sal_uInt16 nPos = GetItemPos( nItemId );
969 
970  if ( nPos != STATUSBAR_ITEM_NOTFOUND )
971  {
972  ImplStatusItem* pItem = mvItemList[ nPos ].get();
973  if ( pItem->mbVisible )
974  {
975  pItem->mbVisible = false;
976 
977  mbFormat = true;
978  if ( ImplIsItemUpdate() )
979  Invalidate();
980 
981  CallEventListeners( VclEventId::StatusbarHideItem, reinterpret_cast<void*>(nItemId) );
982  }
983  }
984 }
985 
986 bool StatusBar::IsItemVisible( sal_uInt16 nItemId ) const
987 {
988  sal_uInt16 nPos = GetItemPos( nItemId );
989 
990  if ( nPos != STATUSBAR_ITEM_NOTFOUND )
991  return mvItemList[ nPos ]->mbVisible;
992  else
993  return false;
994 }
995 
997 {
998  // delete all items
999  mvItemList.clear();
1000 
1001  mbFormat = true;
1002  if ( ImplIsItemUpdate() )
1003  Invalidate();
1004 
1006 }
1007 
1008 sal_uInt16 StatusBar::GetItemCount() const
1009 {
1010  return static_cast<sal_uInt16>(mvItemList.size());
1011 }
1012 
1013 sal_uInt16 StatusBar::GetItemId( sal_uInt16 nPos ) const
1014 {
1015  if ( nPos < mvItemList.size() )
1016  return mvItemList[ nPos ]->mnId;
1017  return 0;
1018 }
1019 
1020 sal_uInt16 StatusBar::GetItemPos( sal_uInt16 nItemId ) const
1021 {
1022  for ( size_t i = 0, n = mvItemList.size(); i < n; ++i ) {
1023  if ( mvItemList[ i ]->mnId == nItemId ) {
1024  return sal_uInt16( i );
1025  }
1026  }
1027 
1028  return STATUSBAR_ITEM_NOTFOUND;
1029 }
1030 
1031 sal_uInt16 StatusBar::GetItemId( const Point& rPos ) const
1032 {
1033  if ( !mbFormat )
1034  {
1035  sal_uInt16 nItemCount = GetItemCount();
1036  sal_uInt16 nPos;
1037  for ( nPos = 0; nPos < nItemCount; nPos++ )
1038  {
1039  // get rectangle
1040  tools::Rectangle aRect = ImplGetItemRectPos( nPos );
1041  if ( aRect.IsInside( rPos ) )
1042  return mvItemList[ nPos ]->mnId;
1043  }
1044  }
1045 
1046  return 0;
1047 }
1048 
1049 tools::Rectangle StatusBar::GetItemRect( sal_uInt16 nItemId ) const
1050 {
1051  tools::Rectangle aRect;
1052 
1053  if ( !mbFormat )
1054  {
1055  sal_uInt16 nPos = GetItemPos( nItemId );
1056  if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1057  {
1058  // get rectangle and subtract frame
1059  aRect = ImplGetItemRectPos( nPos );
1060  long nW = 1;
1061  aRect.AdjustTop(nW-1 );
1062  aRect.AdjustBottom( -(nW-1) );
1063  aRect.AdjustLeft(nW );
1064  aRect.AdjustRight( -nW );
1065  return aRect;
1066  }
1067  }
1068 
1069  return aRect;
1070 }
1071 
1072 Point StatusBar::GetItemTextPos( sal_uInt16 nItemId ) const
1073 {
1074  if ( !mbFormat )
1075  {
1076  sal_uInt16 nPos = GetItemPos( nItemId );
1077  if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1078  {
1079  // get rectangle
1080  ImplStatusItem* pItem = mvItemList[ nPos ].get();
1081  tools::Rectangle aRect = ImplGetItemRectPos( nPos );
1082  long nW = 1;
1083  tools::Rectangle aTextRect( aRect.Left()+nW, aRect.Top()+nW,
1084  aRect.Right()-nW, aRect.Bottom()-nW );
1085  Point aPos = ImplGetItemTextPos( aTextRect.GetSize(),
1086  Size( GetTextWidth( pItem->maText ), GetTextHeight() ),
1087  pItem->mnBits );
1088  if ( !mbInUserDraw )
1089  {
1090  aPos.AdjustX(aTextRect.Left() );
1091  aPos.AdjustY(aTextRect.Top() );
1092  }
1093  return aPos;
1094  }
1095  }
1096 
1097  return Point();
1098 }
1099 
1100 sal_uLong StatusBar::GetItemWidth( sal_uInt16 nItemId ) const
1101 {
1102  sal_uInt16 nPos = GetItemPos( nItemId );
1103 
1104  if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1105  return mvItemList[ nPos ]->mnWidth;
1106 
1107  return 0;
1108 }
1109 
1110 StatusBarItemBits StatusBar::GetItemBits( sal_uInt16 nItemId ) const
1111 {
1112  sal_uInt16 nPos = GetItemPos( nItemId );
1113 
1114  if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1115  return mvItemList[ nPos ]->mnBits;
1116 
1117  return StatusBarItemBits::NONE;
1118 }
1119 
1120 long StatusBar::GetItemOffset( sal_uInt16 nItemId ) const
1121 {
1122  sal_uInt16 nPos = GetItemPos( nItemId );
1123 
1124  if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1125  return mvItemList[ nPos ]->mnOffset;
1126 
1127  return 0;
1128 }
1129 
1130 void StatusBar::SetItemText( sal_uInt16 nItemId, const OUString& rText, int nCharsWidth )
1131 {
1132  sal_uInt16 nPos = GetItemPos( nItemId );
1133 
1134  if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1135  {
1136  ImplStatusItem* pItem = mvItemList[ nPos ].get();
1137 
1138  if ( pItem->maText != rText )
1139  {
1140  pItem->maText = rText;
1141 
1142  // adjust item width - see also DataChanged()
1143  long nFudge = GetTextHeight()/4;
1144 
1145  long nWidth;
1146  if (nCharsWidth != -1)
1147  {
1148  std::unique_ptr<SalLayout> pSalLayout = ImplLayout("0",0,-1);
1149  const SalLayoutGlyphs* pGlyphs = pSalLayout ? pSalLayout->GetGlyphs() : nullptr;
1150  nWidth = GetTextWidth("0",0,-1,nullptr,pGlyphs );
1151  nWidth = nWidth * nCharsWidth + nFudge;
1152  }
1153  else
1154  {
1155  std::unique_ptr<SalLayout> pSalLayout = ImplLayout(pItem->maText,0,-1);
1156  const SalLayoutGlyphs* pGlyphs = pSalLayout ? pSalLayout->GetGlyphs() : nullptr;
1157  nWidth = GetTextWidth( pItem->maText,0,-1,nullptr,pGlyphs ) + nFudge;
1158  // Store the calculated layout.
1159  pItem->mxLayoutCache = std::move(pSalLayout);
1160  }
1161 
1162  if( (nWidth > pItem->mnWidth + STATUSBAR_OFFSET) ||
1163  ((nWidth < pItem->mnWidth) && (mnDX - STATUSBAR_OFFSET) < mnItemsWidth ))
1164  {
1165  pItem->mnWidth = nWidth + STATUSBAR_OFFSET;
1166  ImplFormat();
1167  Invalidate();
1168  }
1169 
1170  // re-draw item if StatusBar is visible and UpdateMode active
1171  if ( pItem->mbVisible && !mbFormat && ImplIsItemUpdate() )
1172  {
1173  tools::Rectangle aRect = ImplGetItemRectPos(nPos);
1174  Invalidate(aRect);
1175  }
1176  }
1177  }
1178 }
1179 
1180 const OUString& StatusBar::GetItemText( sal_uInt16 nItemId ) const
1181 {
1182  sal_uInt16 nPos = GetItemPos( nItemId );
1183 
1184  assert( nPos != STATUSBAR_ITEM_NOTFOUND );
1185 
1186  return mvItemList[ nPos ]->maText;
1187 }
1188 
1189 void StatusBar::SetItemCommand( sal_uInt16 nItemId, const OUString& rCommand )
1190 {
1191  sal_uInt16 nPos = GetItemPos( nItemId );
1192 
1193  if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1194  {
1195  ImplStatusItem* pItem = mvItemList[ nPos ].get();
1196 
1197  if ( pItem->maCommand != rCommand )
1198  pItem->maCommand = rCommand;
1199  }
1200 }
1201 
1202 OUString StatusBar::GetItemCommand( sal_uInt16 nItemId )
1203 {
1204  sal_uInt16 nPos = GetItemPos( nItemId );
1205 
1206  if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1207  return mvItemList[ nPos ]->maCommand;
1208 
1209  return OUString();
1210 }
1211 
1212 void StatusBar::SetItemData( sal_uInt16 nItemId, void* pNewData )
1213 {
1214  sal_uInt16 nPos = GetItemPos( nItemId );
1215 
1216  if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1217  {
1218  ImplStatusItem* pItem = mvItemList[ nPos ].get();
1219  // invalidate cache
1220  pItem->mxLayoutCache.reset();
1221  pItem->mpUserData = pNewData;
1222 
1223  // call Draw-Item if it's a User-Item
1224  if ( (pItem->mnBits & StatusBarItemBits::UserDraw) && pItem->mbVisible &&
1225  !mbFormat && ImplIsItemUpdate() )
1226  {
1227  tools::Rectangle aRect = ImplGetItemRectPos(nPos);
1229  }
1230  }
1231 }
1232 
1233 void* StatusBar::GetItemData( sal_uInt16 nItemId ) const
1234 {
1235  sal_uInt16 nPos = GetItemPos( nItemId );
1236 
1237  if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1238  return mvItemList[ nPos ]->mpUserData;
1239 
1240  return nullptr;
1241 }
1242 
1243 void StatusBar::RedrawItem(sal_uInt16 nItemId)
1244 {
1245  if ( mbFormat )
1246  return;
1247 
1248  sal_uInt16 nPos = GetItemPos(nItemId);
1249  if ( nPos == STATUSBAR_ITEM_NOTFOUND )
1250  return;
1251 
1252  ImplStatusItem* pItem = mvItemList[ nPos ].get();
1253  if ((pItem->mnBits & StatusBarItemBits::UserDraw) &&
1254  pItem->mbVisible && ImplIsItemUpdate())
1255  {
1256  tools::Rectangle aRect = ImplGetItemRectPos(nPos);
1257  Invalidate(aRect);
1258  }
1259 }
1260 
1261 void StatusBar::SetHelpText( sal_uInt16 nItemId, const OUString& rText )
1262 {
1263  sal_uInt16 nPos = GetItemPos( nItemId );
1264 
1265  if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1266  mvItemList[ nPos ]->maHelpText = rText;
1267 }
1268 
1269 const OUString& StatusBar::GetHelpText( sal_uInt16 nItemId ) const
1270 {
1271  sal_uInt16 nPos = GetItemPos( nItemId );
1272 
1273  assert ( nPos != STATUSBAR_ITEM_NOTFOUND );
1274 
1275  ImplStatusItem* pItem = mvItemList[ nPos ].get();
1276  if ( pItem->maHelpText.isEmpty() && ( !pItem->maHelpId.isEmpty() || !pItem->maCommand.isEmpty() ))
1277  {
1278  Help* pHelp = Application::GetHelp();
1279  if ( pHelp )
1280  {
1281  if ( !pItem->maCommand.isEmpty() )
1282  pItem->maHelpText = pHelp->GetHelpText( pItem->maCommand, this );
1283  if ( pItem->maHelpText.isEmpty() && !pItem->maHelpId.isEmpty() )
1284  pItem->maHelpText = pHelp->GetHelpText( OStringToOUString( pItem->maHelpId, RTL_TEXTENCODING_UTF8 ), this );
1285  }
1286  }
1287 
1288  return pItem->maHelpText;
1289 }
1290 
1291 void StatusBar::SetQuickHelpText( sal_uInt16 nItemId, const OUString& rText )
1292 {
1293  sal_uInt16 nPos = GetItemPos( nItemId );
1294 
1295  if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1296  mvItemList[ nPos ]->maQuickHelpText = rText;
1297 }
1298 
1299 const OUString& StatusBar::GetQuickHelpText( sal_uInt16 nItemId ) const
1300 {
1301  sal_uInt16 nPos = GetItemPos( nItemId );
1302 
1303  assert ( nPos != STATUSBAR_ITEM_NOTFOUND );
1304 
1305  ImplStatusItem* pItem = mvItemList[ nPos ].get();
1306  return pItem->maQuickHelpText;
1307 }
1308 
1309 void StatusBar::SetHelpId( sal_uInt16 nItemId, const OString& rHelpId )
1310 {
1311  sal_uInt16 nPos = GetItemPos( nItemId );
1312 
1313  if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1314  mvItemList[ nPos ]->maHelpId = rHelpId;
1315 }
1316 
1317 void StatusBar::StartProgressMode( const OUString& rText )
1318 {
1319  SAL_WARN_IF( mbProgressMode, "vcl", "StatusBar::StartProgressMode(): progress mode is active" );
1320 
1321  mbProgressMode = true;
1322  mnPercent = 0;
1323  maPrgsTxt = rText;
1324 
1325  // compute size
1327 
1328  // trigger Paint, which draws text and frame
1329  if ( IsReallyVisible() )
1330  {
1331  Invalidate();
1332  }
1333 }
1334 
1335 void StatusBar::SetProgressValue( sal_uInt16 nNewPercent )
1336 {
1337  SAL_WARN_IF( !mbProgressMode, "vcl", "StatusBar::SetProgressValue(): no progress mode" );
1338  SAL_WARN_IF( nNewPercent > 100, "vcl", "StatusBar::SetProgressValue(): nPercent > 100" );
1339 
1340  bool bInvalidate = mbProgressMode && IsReallyVisible() && (!mnPercent || (mnPercent != nNewPercent));
1341 
1342  mnPercent = nNewPercent;
1343 
1344  if (bInvalidate)
1345  {
1346  // Rate limit how often we paint, otherwise in some loading scenarios we can spend significant
1347  // time just painting progress bars.
1348  sal_uInt32 nTime_ms = osl_getGlobalTimer();
1349  if ((nTime_ms - mnLastProgressPaint_ms) > 100)
1350  {
1352  mnLastProgressPaint_ms = nTime_ms;
1353  }
1354  }
1355 }
1356 
1358 {
1359  SAL_WARN_IF( !mbProgressMode, "vcl", "StatusBar::EndProgressMode(): no progress mode" );
1360 
1361  mbProgressMode = false;
1362  maPrgsTxt.clear();
1363 
1364  if ( IsReallyVisible() )
1365  {
1366  Invalidate();
1367  }
1368 }
1369 
1370 void StatusBar::SetText(const OUString& rText)
1371 {
1373  {
1374  Window::SetText(rText);
1375  Invalidate();
1376  }
1377  else if (mbProgressMode)
1378  {
1379  maPrgsTxt = rText;
1380  if (IsReallyVisible())
1381  {
1382  Invalidate();
1383  }
1384  }
1385  else
1386  {
1387  Window::SetText(rText);
1388  }
1389 }
1390 
1392 {
1393  size_t i = 0;
1394  size_t nCount = mvItemList.size();
1395  long nOffset = 0;
1396  long nCalcWidth = STATUSBAR_OFFSET_X*2;
1397  long nCalcHeight;
1398 
1399  while ( i < nCount )
1400  {
1401  ImplStatusItem* pItem = mvItemList[ i ].get();
1402  nCalcWidth += pItem->mnWidth + nOffset;
1403  nOffset = pItem->mnOffset;
1404  i++;
1405  }
1406 
1407  long nMinHeight = GetTextHeight();
1408  const long nBarTextOffset = STATUSBAR_OFFSET_TEXTY*2;
1409  long nProgressHeight = nMinHeight + nBarTextOffset;
1410 
1412  {
1413  ImplControlValue aValue;
1414  tools::Rectangle aControlRegion( Point(), Size( nCalcWidth, nMinHeight ) );
1415  tools::Rectangle aNativeControlRegion, aNativeContentRegion;
1417  aControlRegion, ControlState::ENABLED, aValue,
1418  aNativeControlRegion, aNativeContentRegion ) )
1419  {
1420  nProgressHeight = aNativeControlRegion.GetHeight();
1421  }
1422  }
1423 
1424  nCalcHeight = nMinHeight+nBarTextOffset;
1425  if( nCalcHeight < nProgressHeight+2 )
1426  nCalcHeight = nProgressHeight+2;
1427 
1428  return Size( nCalcWidth, nCalcHeight );
1429 }
1430 
1431 void StatusBar::SetAccessibleName( sal_uInt16 nItemId, const OUString& rName )
1432 {
1433  sal_uInt16 nPos = GetItemPos( nItemId );
1434 
1435  if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1436  {
1437  ImplStatusItem* pItem = mvItemList[ nPos ].get();
1438 
1439  if ( pItem->maAccessibleName != rName )
1440  {
1441  pItem->maAccessibleName = rName;
1442  CallEventListeners( VclEventId::StatusbarNameChanged, reinterpret_cast<void*>(pItem->mnId) );
1443  }
1444  }
1445 }
1446 
1447 const OUString& StatusBar::GetAccessibleName( sal_uInt16 nItemId ) const
1448 {
1449  sal_uInt16 nPos = GetItemPos( nItemId );
1450 
1451  assert ( nPos != STATUSBAR_ITEM_NOTFOUND );
1452 
1453  return mvItemList[ nPos ]->maAccessibleName;
1454 }
1455 
1456 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Point TopLeft() const
long Width() const
const Color & GetTextColor() const
Definition: outdev.hxx:1117
void DrawText(const Point &rStartPt, const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1, MetricVector *pVector=nullptr, OUString *pDisplayText=nullptr, const SalLayoutGlyphs *pLayoutCache=nullptr)
Definition: text.cxx:782
const Color & GetShadowColor() const
SAL_DLLPRIVATE void ImplDrawText(vcl::RenderContext &rRenderContext)
Definition: status.cxx:343
bool IsControlBackground() const
Definition: window2.cxx:1087
long mnTextY
Definition: status.hxx:78
long mnItemsWidth
Definition: status.hxx:74
long GetWidth() const
const Wallpaper & GetBackground() const
Definition: outdev.hxx:637
void * GetItemData(sal_uInt16 nItemId) const
Definition: status.cxx:1233
OUString maHelpText
Definition: status.cxx:68
void RedrawItem(sal_uInt16 nItemId)
Definition: status.cxx:1243
tools::Rectangle maPrgsFrameRect
Definition: status.hxx:72
long GetHeight() const
SAL_DLLPRIVATE bool ImplIsRecordLayout() const
Definition: outdev.cxx:650
bool DrawNativeControl(ControlType nType, ControlPart nPart, const tools::Rectangle &rControlRegion, ControlState nState, const ImplControlValue &aValue, const OUString &aCaption)
Request rendering of a particular control and/or part.
SAL_DLLPRIVATE sal_uInt16 ImplGetFirstVisiblePos() const
Definition: status.cxx:331
bool GetNativeControlRegion(ControlType nType, ControlPart nPart, const tools::Rectangle &rControlRegion, ControlState nState, const ImplControlValue &aValue, tools::Rectangle &rNativeBoundingRegion, tools::Rectangle &rNativeContentRegion) const
Query the native control's actual drawing region (including adornment)
void StartProgressMode(const OUString &rText)
Definition: status.cxx:1317
sal_uInt16 mnId
Definition: status.cxx:61
long Height() const
Definition: help.hxx:60
static Help * GetHelp()
Gets the application's help.
Definition: svapp.cxx:1353
Point BottomLeft() const
#define STATUSBAR_PRGS_OFFSET
Definition: status.cxx:42
long AdjustLeft(long nHorzMoveDelta)
int mnStatusBarLowerRightOffset
Definition: svdata.hxx:311
long mnExtraWidth
Definition: status.cxx:65
static long ImplCalcProgressWidth(sal_uInt16 nMax, long nSize)
Definition: status.cxx:78
Point AbsoluteScreenToOutputPixel(const Point &rPos) const
Definition: window.cxx:2931
sal_uIntPtr sal_uLong
void InsertItem(sal_uInt16 nItemId, sal_uLong nWidth, StatusBarItemBits nBits=StatusBarItemBits::Center|StatusBarItemBits::In, long nOffset=STATUSBAR_OFFSET, sal_uInt16 nPos=STATUSBAR_APPEND)
Definition: status.cxx:889
const StyleSettings & GetStyleSettings() const
TextAlign GetTextAlign() const
Definition: outdev.hxx:1135
const Color & GetFaceColor() const
const OUString & GetItemText(sal_uInt16 nItemId) const
Definition: status.cxx:1180
const OUString & GetHelpText() const
Definition: window.cxx:3148
void DrawFrame(const tools::Rectangle &rRect, const Color &rLeftTopColor, const Color &rRightBottomColor)
Definition: decoview.cxx:848
ImplSVNWFData maNWFData
Definition: svdata.hxx:399
sal_Int64 n
const OUString & GetQuickHelpText() const
Definition: window2.cxx:1232
OUString GetItemCommand(sal_uInt16 nItemId)
Definition: status.cxx:1202
virtual Size GetSizePixel() const
Definition: window.cxx:2418
virtual void SetSizePixel(const Size &rNewSize)
Definition: window2.cxx:1262
WinBits const WB_RIGHT
void SetItemText(sal_uInt16 nItemId, const OUString &rText, int nCharsWidth=-1)
Definition: status.cxx:1130
SAL_DLLPRIVATE WindowImpl * ImplGetWindowImpl() const
Definition: window.hxx:555
void SetTextFillColor()
Definition: text.cxx:700
DataChangedEventType GetType() const
Definition: event.hxx:357
void IntersectClipRegion(const tools::Rectangle &rRect)
long mnWidth
Definition: status.cxx:63
Size CalcWindowSizePixel() const
Definition: status.cxx:1391
const Color & GetControlBackground() const
Definition: window2.cxx:1082
bool IsItemVisible(sal_uInt16 nItemId) const
Definition: status.cxx:986
virtual ~StatusBar() override
Definition: status.cxx:142
sal_uInt16 mnId
Link< StatusBar *, void > maDoubleClickHdl
Definition: status.hxx:88
bool IsNativeControlSupported(ControlType nType, ControlPart nPart) const
Query the platform layer for control support.
HelpEventMode GetMode() const
Definition: event.hxx:205
#define STATUSBAR_OFFSET_Y
Definition: status.cxx:39
void AdjustItemWidthsForHiDPI()
Definition: status.cxx:158
const Color & GetHighlightColor() const
long AdjustBottom(long nVertMoveDelta)
virtual void MouseButtonDown(const MouseEvent &rMEvt) override
Definition: status.cxx:656
bool IsEmpty() const
OUString maCommand
Definition: status.cxx:74
void SetHelpText(sal_uInt16 nItemId, const OUString &rText)
Definition: status.cxx:1261
StateChangedType
Definition: window.hxx:311
virtual void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect) override
Definition: status.cxx:690
OUString GetAccessibleName() const
long mnDY
Definition: status.hxx:76
sal_uInt16 GetClicks() const
Definition: event.hxx:123
sal_Int64 WinBits
void SetBackground()
long Right() const
SAL_DLLPRIVATE void ImplDrawProgress(vcl::RenderContext &rRenderContext, sal_uInt16 nNewPerc)
Definition: status.cxx:581
#define STATUSBAR_PRGS_MIN
Definition: status.cxx:44
SAL_DLLPRIVATE void ImplDrawItem(vcl::RenderContext &rRenderContext, bool bOffScreen, sal_uInt16 nPos)
Definition: status.cxx:367
#define SAL_MAX_UINT16
#define STATUSBAR_PRGS_COUNT
Definition: status.cxx:43
const vcl::Font & GetFont() const
Definition: outdev.hxx:643
tools::Rectangle GetItemRect(sal_uInt16 nItemId) const
Definition: status.cxx:1049
bool IsControlForeground() const
Definition: window2.cxx:1077
void SetItemData(sal_uInt16 nItemId, void *pNewData)
Definition: status.cxx:1212
Environment aTo
int nCount
AllSettingsFlags GetFlags() const
Definition: event.hxx:358
bool mbVisible
Definition: status.cxx:72
virtual void DataChanged(const DataChangedEvent &rDCEvt) override
Definition: status.cxx:843
void Click()
Definition: status.cxx:875
void DrawProgress(vcl::Window *pWindow, vcl::RenderContext &rRenderContext, const Point &rPos, long nOffset, long nPrgsWidth, long nPrgsHeight, sal_uInt16 nPercent1, sal_uInt16 nPercent2, sal_uInt16 nPercentCount, const tools::Rectangle &rFramePosSize)
Definition: status.cxx:470
sal_uInt16 mnPercentCount
Definition: status.hxx:81
virtual void SetOutputSizePixel(const Size &rNewSize)
Definition: window2.cxx:1274
virtual OUString GetText() const
Definition: window.cxx:3113
long Top() const
virtual void UserDraw(const UserDrawEvent &rUDEvt)
Definition: status.cxx:885
static bool isVCLOpenGLEnabled()
Returns true if VCL has OpenGL rendering enabled.
void DrawLine(const Point &rStartPt, const Point &rEndPt)
Definition: line.cxx:88
void DrawRect(const tools::Rectangle &rRect)
Definition: rect.cxx:32
long mnOffset
Definition: status.cxx:64
SAL_DLLPRIVATE bool ImplIsItemUpdate()
Definition: status.cxx:102
const Color & GetControlForeground() const
Definition: window2.cxx:1072
const Point & GetMousePosPixel() const
Definition: event.hxx:204
sal_uInt16 GetItemCount() const
Definition: status.cxx:1008
Point GetItemTextPos(sal_uInt16 nItemId) const
Definition: status.cxx:1072
#define STATUSBAR_ITEM_NOTFOUND
Definition: status.hxx:60
Point BottomRight() const
const Color & GetDarkShadowColor() const
bool mbFrame
Definition: window.h:317
ImplSVData * ImplGetSVData()
Definition: svdata.cxx:75
void EndProgressMode()
Definition: status.cxx:1357
void SetLineColor()
virtual OUString GetHelpText(const OUString &aHelpURL, const vcl::Window *pWindow)
Definition: help.cxx:67
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects...
Definition: status.cxx:147
bool IsRTLEnabled() const
Definition: outdev.hxx:1361
void SetTop(long v)
Window(WindowType nType)
Definition: window.cxx:88
void DoubleClick()
Definition: status.cxx:880
SAL_DLLPRIVATE tools::Rectangle ImplGetItemRectPos(sal_uInt16 nPos) const
Definition: status.cxx:316
int i
const vcl::Font & GetToolFont() const
OUString maText
Definition: status.cxx:67
OUString maQuickHelpText
Definition: status.cxx:69
OUString maAccessibleName
Definition: status.cxx:73
bool mbInUserDraw
Definition: status.hxx:85
SAL_DLLPRIVATE void ImplInitSettings()
Definition: status.cxx:198
virtual void Invalidate(InvalidateFlags nFlags=InvalidateFlags::NONE)
Definition: paint.cxx:1160
void SetRight(long v)
bool IsUpdateMode() const
Definition: window2.cxx:1173
void SetFillColor()
Some things multiple-inherit from VclAbstractDialog and OutputDevice, so we need to use virtual inher...
Definition: outdev.hxx:304
bool mbFormat
Definition: status.hxx:83
sal_uInt32 mnLastProgressPaint_ms
Definition: status.hxx:82
void SetTextColor(const Color &rColor)
Definition: text.cxx:665
long Bottom() const
StatusBar(vcl::Window *pParent, WinBits nWinStyle=WB_BORDER|WB_RIGHT)
Definition: status.cxx:135
bool IsInside(const Point &rPOINT) const
const AllSettings & GetSettings() const
Definition: outdev.hxx:420
Size GetOutputSizePixel() const
Definition: outdev.hxx:441
bool mbAdjustHiDPI
Definition: status.hxx:86
virtual void Resize() override
Definition: status.cxx:744
void HideItem(sal_uInt16 nItemId)
Definition: status.cxx:966
void RemoveItem(sal_uInt16 nItemId)
Definition: status.cxx:931
void SetAccessibleName(sal_uInt16 nItemId, const OUString &rName)
Definition: status.cxx:1431
std::vector< std::unique_ptr< ImplStatusItem > > mvItemList
Definition: status.hxx:68
OUString maPrgsTxt
Definition: status.hxx:70
virtual void StateChanged(StateChangedType nType) override
Definition: status.cxx:809
std::unique_ptr< SalLayout > ImplLayout(const OUString &, sal_Int32 nIndex, sal_Int32 nLen, const Point &rLogicPos=Point(0, 0), long nLogicWidth=0, const long *pLogicDXArray=nullptr, SalLayoutFlags flags=SalLayoutFlags::NONE, vcl::TextLayoutCache const *=nullptr, const SalLayoutGlyphs *pGlyphs=nullptr) const
Definition: text.cxx:1241
Point ScreenToOutputPixel(const Point &rPos) const
Definition: window.cxx:2878
bool KeyboardActivated() const
Definition: event.hxx:206
ControlPart mnNativeBackground
Definition: window.h:296
long mnDX
Definition: status.hxx:75
long GetTextHeight() const
Height where any character of the current font fits; in logic coordinates.
Definition: text.cxx:891
static void ShowQuickHelp(vcl::Window *pParent, const tools::Rectangle &rScreenRect, const OUString &rHelpText, QuickHelpFlags nStyle=QuickHelpFlags::NONE)
Definition: help.cxx:180
WinBits const WB_LEFT
Point OutputToAbsoluteScreenPixel(const Point &rPos) const
Definition: window.cxx:2921
void DrawSeparator(const Point &rStart, const Point &rStop, bool bVertical=true)
Definition: decoview.cxx:1021
void SetItemCommand(sal_uInt16 nItemId, const OUString &rCommand)
Definition: status.cxx:1189
Size GetSize() const
float GetDPIScaleFactor() const
Definition: outdev.hxx:512
void * mpUserData
Definition: status.cxx:71
StatusBarItemBits GetItemBits(sal_uInt16 nItemId) const
Definition: status.cxx:1110
void SetProgressValue(sal_uInt16 nPercent)
Definition: status.cxx:1335
StatusBarItemBits
Definition: status.hxx:42
#define STATUSBAR_OFFSET_TEXTY
Definition: status.cxx:40
WinBits const WB_3DLOOK
virtual void ApplySettings(vcl::RenderContext &rRenderContext) override
Definition: status.cxx:163
sal_uLong GetItemWidth(sal_uInt16 nItemId) const
Definition: status.cxx:1100
Point maPrgsTxtPos
Definition: status.hxx:71
SAL_DLLPRIVATE void ImplCalcProgressRect()
Definition: status.cxx:604
VclPtr< VirtualDevice > mpVirDev
Definition: status.cxx:51
void SetQuickHelpText(sal_uInt16 nItemId, const OUString &rText)
Definition: status.cxx:1291
void Erase()
Definition: wallpaper.cxx:103
void SetText(const OUString &rText) override
Definition: status.cxx:1370
long AdjustRight(long nHorzMoveDelta)
sal_uInt16 GetItemPos(sal_uInt16 nItemId) const
Definition: status.cxx:1020
WindowType
const Color & GetButtonTextColor() const
#define SAL_WARN_IF(condition, area, stream)
WinBits const WB_BORDER
bool mbProgressNeedsErase
Definition: svdata.hxx:326
#define STATUSBAR_OFFSET_X
Definition: status.cxx:38
void ShowItem(sal_uInt16 nItemId)
Definition: status.cxx:946
OString maHelpId
Definition: status.cxx:70
long mnPrgsSize
Definition: status.hxx:73
void EnableChildTransparentMode(bool bEnable=true)
Definition: window2.cxx:1022
bool IsLeft() const
Definition: event.hxx:146
virtual void RequestHelp(const HelpEvent &rHEvt) override
Definition: status.cxx:763
double mnWidth
static VclPtr< reference_type > Create(Arg &&...arg)
A construction helper for VclPtr.
Definition: vclptr.hxx:127
StatusBarItemBits mnBits
Definition: status.cxx:62
VclPtr< vcl::Window > mpParent
Definition: window.h:231
void SetBottom(long v)
long AdjustTop(long nVertMoveDelta)
const Color & GetWindowColor() const
void SetHelpId(sal_uInt16 nItemId, const OString &rHelpId)
Definition: status.cxx:1309
const Point & GetPosPixel() const
Definition: event.hxx:120
virtual void DrawOutDev(const Point &rDestPt, const Size &rDestSize, const Point &rSrcPt, const Size &rSrcSize)
Definition: outdev.cxx:348
std::unique_ptr< ImplData > mpImplData
Definition: status.hxx:69
long Left() const
long GetTextWidth(const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1, vcl::TextLayoutCache const *=nullptr, SalLayoutGlyphs const *const pLayoutCache=nullptr) const
Width of the text.
Definition: text.cxx:880
Link< StatusBar *, void > maClickHdl
Definition: status.hxx:87
long GetItemOffset(sal_uInt16 nItemId) const
Definition: status.cxx:1120
sal_uInt16 GetItemId(sal_uInt16 nPos) const
Definition: status.cxx:1013
Event to pass information for UserDraw() handling eg. in comboboxes.
Definition: event.hxx:218
bool IsPaintTransparent() const
Definition: window2.cxx:1037
void SetLeft(long v)
Environment aFrom
WinBits GetStyle() const
Definition: window2.cxx:953
void ApplyControlFont(vcl::RenderContext &rRenderContext, const vcl::Font &rDefaultFont)
Definition: window2.cxx:449
Point OutputToScreenPixel(const Point &rPos) const
Definition: window.cxx:2872
long mnCalcHeight
Definition: status.hxx:77
void CallEventListeners(VclEventId nEvent, void *pData=nullptr)
Definition: event.cxx:213
bool IsReallyVisible() const
Definition: window2.cxx:1107
SAL_DLLPRIVATE void ImplInit(vcl::Window *pParent, WinBits nStyle)
Definition: status.cxx:107
virtual const SalLayoutGlyphs * GetGlyphs() const
Definition: sallayout.cxx:1579
void Push(PushFlags nFlags=PushFlags::ALL)
Definition: outdevstate.cxx:60
void Clear()
Definition: status.cxx:996
sal_uInt16 mnPercent
Definition: status.hxx:80
aStr
bool mbProgressMode
Definition: status.hxx:84
const Color & GetWindowTextColor() const
static Point ImplGetItemTextPos(const Size &rRectSize, const Size &rTextSize, StatusBarItemBits nStyle)
Definition: status.cxx:83
#define STATUSBAR_OFFSET
Definition: status.hxx:61
Point Center() const
std::unique_ptr< SalLayout > mxLayoutCache
Definition: status.cxx:75
sal_uInt16 nPos
bool HasMirroredGraphics() const override
sal_uInt16 mnCurItemId
Definition: status.hxx:79
static void ShowBalloon(vcl::Window *pParent, const Point &rScreenPos, const tools::Rectangle &, const OUString &rHelpText)
Definition: help.cxx:157
SAL_DLLPRIVATE void ImplFormat()
Definition: status.cxx:209
void setHeight(long nHeight)