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 {
138  ImplInit( pParent, nStyle );
139 }
140 
142 {
143  disposeOnce();
144 }
145 
147 {
148  // delete all items
149  mvItemList.clear();
150 
151  // delete VirtualDevice
152  mpImplData->mpVirDev.disposeAndClear();
153  mpImplData.reset();
154  Window::dispose();
155 }
156 
158 {
159  mbAdjustHiDPI = true;
160 }
161 
163 {
164  rRenderContext.SetLineColor();
165 
166  const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
167  ApplyControlFont(rRenderContext, rStyleSettings.GetToolFont());
168 
169  Color aColor;
170  if (IsControlForeground())
171  aColor = GetControlForeground();
172  else if (GetStyle() & WB_3DLOOK)
173  aColor = rStyleSettings.GetButtonTextColor();
174  else
175  aColor = rStyleSettings.GetWindowTextColor();
176  rRenderContext.SetTextColor(aColor);
177 
178  rRenderContext.SetTextFillColor();
179 
180  if (IsControlBackground())
181  aColor = GetControlBackground();
182  else if (GetStyle() & WB_3DLOOK)
183  aColor = rStyleSettings.GetFaceColor();
184  else
185  aColor = rStyleSettings.GetWindowColor();
186  rRenderContext.SetBackground(aColor);
187 
188  // NWF background
189  if (!IsControlBackground() &&
191  {
194  }
195 }
196 
198 {
199  ApplySettings(*this);
200 
201  mpImplData->mpVirDev->SetFont(GetFont());
202  mpImplData->mpVirDev->SetTextColor(GetTextColor());
203  mpImplData->mpVirDev->SetTextAlign(GetTextAlign());
204  mpImplData->mpVirDev->SetTextFillColor();
205  mpImplData->mpVirDev->SetBackground(GetBackground());
206 }
207 
209 {
210  long nExtraWidth;
211  long nExtraWidth2;
212  long nX;
213  sal_uInt16 nAutoSizeItems;
214  bool bChanged;
215 
216  do {
217  // sum up widths
218  nAutoSizeItems = 0;
220  bChanged = false;
221  long nOffset = 0;
222  for ( const auto & pItem : mvItemList ) {
223  if ( pItem->mbVisible )
224  {
225  if ( pItem->mnBits & StatusBarItemBits::AutoSize ) {
226  nAutoSizeItems++;
227  }
228 
229  mnItemsWidth += pItem->mnWidth + nOffset;
230  nOffset = pItem->mnOffset;
231  }
232  }
233 
234  if ( mnDX > 0 && mnDX < mnItemsWidth )
235  {
236  // Total width of items is more than available width
237  // Try to hide secondary elements, if any
238  for ( auto & pItem : mvItemList )
239  {
240  if ( pItem->mbVisible && !(pItem->mnBits & StatusBarItemBits::Mandatory) )
241  {
242  pItem->mbVisible = false;
243  bChanged = true;
244  break;
245  }
246  }
247  }
248  else if ( mnDX > mnItemsWidth )
249  {
250  // Width of statusbar is sufficient.
251  // Try to restore hidden items, if any
252  for ( auto & pItem : mvItemList )
253  {
254  if ( !pItem->mbVisible &&
255  !(pItem->mnBits & StatusBarItemBits::Mandatory) &&
256  pItem->mnWidth + nOffset + mnItemsWidth < mnDX )
257  {
258  pItem->mbVisible = true;
259  bChanged = true;
260  break;
261  }
262  }
263  }
264  } while ( bChanged );
265 
266  if ( GetStyle() & WB_RIGHT )
267  {
268  // AutoSize isn't computed for right-alignment,
269  // because we show the text that is declared by SetText on the left side
270  nX = mnDX - mnItemsWidth;
271  nExtraWidth = 0;
272  nExtraWidth2 = 0;
273  }
274  else
275  {
277 
278  // calling AutoSize is potentially necessary for left-aligned text,
279  if ( nAutoSizeItems && (mnDX > (mnItemsWidth - STATUSBAR_OFFSET)) )
280  {
281  nExtraWidth = (mnDX - mnItemsWidth - 1) / nAutoSizeItems;
282  nExtraWidth2 = (mnDX - mnItemsWidth - 1) % nAutoSizeItems;
283  }
284  else
285  {
286  nExtraWidth = 0;
287  nExtraWidth2 = 0;
288  }
289  nX = STATUSBAR_OFFSET_X;
290 
291  if( HasMirroredGraphics() && IsRTLEnabled() )
293  }
294 
295  for (auto & pItem : mvItemList) {
296  if ( pItem->mbVisible ) {
297  if ( pItem->mnBits & StatusBarItemBits::AutoSize ) {
298  pItem->mnExtraWidth = nExtraWidth;
299  if ( nExtraWidth2 ) {
300  pItem->mnExtraWidth++;
301  nExtraWidth2--;
302  }
303  } else {
304  pItem->mnExtraWidth = 0;
305  }
306 
307  pItem->mnX = nX;
308  nX += pItem->mnWidth + pItem->mnExtraWidth + pItem->mnOffset;
309  }
310  }
311 
312  mbFormat = false;
313 }
314 
316 {
317  tools::Rectangle aRect;
318  ImplStatusItem* pItem = ( nPos < mvItemList.size() ) ? mvItemList[ nPos ].get() : nullptr;
319  if ( pItem && pItem->mbVisible )
320  {
321  aRect.SetLeft( pItem->mnX );
322  aRect.SetRight( aRect.Left() + pItem->mnWidth + pItem->mnExtraWidth );
323  aRect.SetTop( STATUSBAR_OFFSET_Y );
325  }
326 
327  return aRect;
328 }
329 
331 {
332  for( size_t nPos = 0; nPos < mvItemList.size(); nPos++ )
333  {
334  ImplStatusItem* pItem = mvItemList[ nPos ].get();
335  if ( pItem->mbVisible )
336  return sal_uInt16(nPos);
337  }
338 
339  return SAL_MAX_UINT16;
340 }
341 
343 {
344  // prevent item box from being overwritten
345  tools::Rectangle aTextRect;
346  aTextRect.SetLeft( STATUSBAR_OFFSET_X + 1 );
347  aTextRect.SetTop( mnTextY );
348  if (GetStyle() & WB_RIGHT)
349  aTextRect.SetRight( mnDX - mnItemsWidth - 1 );
350  else
351  aTextRect.SetRight( mnDX - 1 );
352  if (aTextRect.Right() > aTextRect.Left())
353  {
354  // compute position
355  OUString aStr = GetText();
356  sal_Int32 nPos = aStr.indexOf('\n');
357  if (nPos != -1)
358  aStr = aStr.copy(0, nPos);
359 
360  aTextRect.SetBottom( aTextRect.Top()+GetTextHeight()+1 );
361 
363  }
364 }
365 
366 void StatusBar::ImplDrawItem(vcl::RenderContext& rRenderContext, bool bOffScreen, sal_uInt16 nPos)
367 {
368  tools::Rectangle aRect = ImplGetItemRectPos(nPos);
369 
370  if (aRect.IsEmpty())
371  return;
372 
373  // compute output region
374  ImplStatusItem* pItem = mvItemList[nPos].get();
375  long nW = 1;
376  tools::Rectangle aTextRect(aRect.Left() + nW, aRect.Top() + nW,
377  aRect.Right() - nW, aRect.Bottom() - nW);
378 
379  Size aTextRectSize(aTextRect.GetSize());
380 
381  if (bOffScreen)
382  {
383  mpImplData->mpVirDev->SetOutputSizePixel(aTextRectSize);
384  }
385  else
386  {
387  vcl::Region aRegion(aTextRect);
388  rRenderContext.SetClipRegion(aRegion);
389  }
390 
391  // if the framework code is drawing status, let it do all the work
392  if (!(pItem->mnBits & StatusBarItemBits::UserDraw))
393  {
394  SalLayout* pLayoutCache = pItem->mxLayoutCache.get();
395 
396  if(!pLayoutCache)
397  {
398  // update cache
399  pItem->mxLayoutCache = rRenderContext.ImplLayout(pItem->maText, 0, -1);
400  pLayoutCache = pItem->mxLayoutCache.get();
401  }
402 
403  const SalLayoutGlyphs* pGlyphs = pLayoutCache ? pLayoutCache->GetGlyphs() : nullptr;
404  Size aTextSize(rRenderContext.GetTextWidth(pItem->maText,0,-1,nullptr,pGlyphs), rRenderContext.GetTextHeight());
405  Point aTextPos = ImplGetItemTextPos(aTextRectSize, aTextSize, pItem->mnBits);
406 
407  if (bOffScreen)
408  {
409  mpImplData->mpVirDev->DrawText(
410  aTextPos,
411  pItem->maText,
412  0, -1, nullptr, nullptr,
413  pGlyphs );
414  }
415  else
416  {
417  aTextPos.AdjustX(aTextRect.Left() );
418  aTextPos.AdjustY(aTextRect.Top() );
419  rRenderContext.DrawText(
420  aTextPos,
421  pItem->maText,
422  0, -1, nullptr, nullptr,
423  pGlyphs );
424  }
425  }
426 
427  // call DrawItem if necessary
428  if (pItem->mnBits & StatusBarItemBits::UserDraw)
429  {
430  if (bOffScreen)
431  {
432  mbInUserDraw = true;
433  mpImplData->mpVirDev->EnableRTL( IsRTLEnabled() );
434  UserDrawEvent aODEvt(this, mpImplData->mpVirDev, tools::Rectangle(Point(), aTextRectSize), pItem->mnId);
435  UserDraw(aODEvt);
436  mpImplData->mpVirDev->EnableRTL(false);
437  mbInUserDraw = false;
438  }
439  else
440  {
441  UserDrawEvent aODEvt(this, &rRenderContext, aTextRect, pItem->mnId);
442  UserDraw(aODEvt);
443  }
444  }
445 
446  if (bOffScreen)
447  rRenderContext.DrawOutDev(aTextRect.TopLeft(), aTextRectSize, Point(), aTextRectSize, *mpImplData->mpVirDev);
448  else
449  rRenderContext.SetClipRegion();
450 
451  if (nPos != ImplGetFirstVisiblePos())
452  {
453  // draw separator
454  Point aFrom(aRect.TopLeft());
455  aFrom.AdjustX( -4 );
456  aFrom.AdjustY( 1 );
457  Point aTo(aRect.BottomLeft());
458  aTo.AdjustX( -4 );
459  aTo.AdjustY( -1 );
460 
461  DecorationView aDecoView(&rRenderContext);
462  aDecoView.DrawSeparator(aFrom, aTo);
463  }
464 
465  if (!rRenderContext.ImplIsRecordLayout())
466  CallEventListeners(VclEventId::StatusbarDrawItem, reinterpret_cast<void*>(pItem->mnId));
467 }
468 
469 void DrawProgress(vcl::Window* pWindow, vcl::RenderContext& rRenderContext, const Point& rPos,
470  long nOffset, long nPrgsWidth, long nPrgsHeight,
471  sal_uInt16 nPercent1, sal_uInt16 nPercent2, sal_uInt16 nPercentCount,
472  const tools::Rectangle& rFramePosSize)
473 {
475  {
476  bool bNeedErase = ImplGetSVData()->maNWFData.mbProgressNeedsErase;
477 
478  long nFullWidth = (nPrgsWidth + nOffset) * (10000 / nPercentCount);
479  long nPerc = std::min<sal_uInt16>(nPercent2, 10000);
480  ImplControlValue aValue(nFullWidth * nPerc / 10000);
481  tools::Rectangle aDrawRect(rPos, Size(nFullWidth, nPrgsHeight));
482  tools::Rectangle aControlRegion(aDrawRect);
483 
484  if(bNeedErase)
485  {
486  vcl::Window* pEraseWindow = pWindow;
487  while (pEraseWindow->IsPaintTransparent() && !pEraseWindow->ImplGetWindowImpl()->mbFrame)
488  {
489  pEraseWindow = pEraseWindow->ImplGetWindowImpl()->mpParent;
490  }
491 
492  if (pEraseWindow == pWindow)
493  {
494  // restore background of pWindow
495  rRenderContext.Erase(rFramePosSize);
496  }
497  else
498  {
499  // restore transparent background
500  Point aTL(pWindow->OutputToAbsoluteScreenPixel(rFramePosSize.TopLeft()));
501  aTL = pEraseWindow->AbsoluteScreenToOutputPixel(aTL);
502  tools::Rectangle aRect(aTL, rFramePosSize.GetSize());
503  pEraseWindow->Invalidate(aRect, InvalidateFlags::NoChildren |
506  pEraseWindow->Update();
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 )
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  Update();
1176  }
1177  }
1178  }
1179 }
1180 
1181 const OUString& StatusBar::GetItemText( sal_uInt16 nItemId ) const
1182 {
1183  sal_uInt16 nPos = GetItemPos( nItemId );
1184 
1185  assert( nPos != STATUSBAR_ITEM_NOTFOUND );
1186 
1187  return mvItemList[ nPos ]->maText;
1188 }
1189 
1190 void StatusBar::SetItemCommand( sal_uInt16 nItemId, const OUString& rCommand )
1191 {
1192  sal_uInt16 nPos = GetItemPos( nItemId );
1193 
1194  if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1195  {
1196  ImplStatusItem* pItem = mvItemList[ nPos ].get();
1197 
1198  if ( pItem->maCommand != rCommand )
1199  pItem->maCommand = rCommand;
1200  }
1201 }
1202 
1203 OUString StatusBar::GetItemCommand( sal_uInt16 nItemId )
1204 {
1205  sal_uInt16 nPos = GetItemPos( nItemId );
1206 
1207  if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1208  return mvItemList[ nPos ]->maCommand;
1209 
1210  return OUString();
1211 }
1212 
1213 void StatusBar::SetItemData( sal_uInt16 nItemId, void* pNewData )
1214 {
1215  sal_uInt16 nPos = GetItemPos( nItemId );
1216 
1217  if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1218  {
1219  ImplStatusItem* pItem = mvItemList[ nPos ].get();
1220  // invalidate cache
1221  pItem->mxLayoutCache.reset();
1222  pItem->mpUserData = pNewData;
1223 
1224  // call Draw-Item if it's a User-Item
1225  if ( (pItem->mnBits & StatusBarItemBits::UserDraw) && pItem->mbVisible &&
1226  !mbFormat && ImplIsItemUpdate() )
1227  {
1228  tools::Rectangle aRect = ImplGetItemRectPos(nPos);
1230  Update();
1231  }
1232  }
1233 }
1234 
1235 void* StatusBar::GetItemData( sal_uInt16 nItemId ) const
1236 {
1237  sal_uInt16 nPos = GetItemPos( nItemId );
1238 
1239  if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1240  return mvItemList[ nPos ]->mpUserData;
1241 
1242  return nullptr;
1243 }
1244 
1245 void StatusBar::RedrawItem(sal_uInt16 nItemId)
1246 {
1247  if ( mbFormat )
1248  return;
1249 
1250  sal_uInt16 nPos = GetItemPos(nItemId);
1251  if ( nPos == STATUSBAR_ITEM_NOTFOUND )
1252  return;
1253 
1254  ImplStatusItem* pItem = mvItemList[ nPos ].get();
1255  if ((pItem->mnBits & StatusBarItemBits::UserDraw) &&
1256  pItem->mbVisible && ImplIsItemUpdate())
1257  {
1258  tools::Rectangle aRect = ImplGetItemRectPos(nPos);
1259  Invalidate(aRect);
1260  Update();
1261  }
1262 }
1263 
1264 void StatusBar::SetHelpText( sal_uInt16 nItemId, const OUString& rText )
1265 {
1266  sal_uInt16 nPos = GetItemPos( nItemId );
1267 
1268  if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1269  mvItemList[ nPos ]->maHelpText = rText;
1270 }
1271 
1272 const OUString& StatusBar::GetHelpText( sal_uInt16 nItemId ) const
1273 {
1274  sal_uInt16 nPos = GetItemPos( nItemId );
1275 
1276  assert ( nPos != STATUSBAR_ITEM_NOTFOUND );
1277 
1278  ImplStatusItem* pItem = mvItemList[ nPos ].get();
1279  if ( pItem->maHelpText.isEmpty() && ( !pItem->maHelpId.isEmpty() || !pItem->maCommand.isEmpty() ))
1280  {
1281  Help* pHelp = Application::GetHelp();
1282  if ( pHelp )
1283  {
1284  if ( !pItem->maCommand.isEmpty() )
1285  pItem->maHelpText = pHelp->GetHelpText( pItem->maCommand, this );
1286  if ( pItem->maHelpText.isEmpty() && !pItem->maHelpId.isEmpty() )
1287  pItem->maHelpText = pHelp->GetHelpText( OStringToOUString( pItem->maHelpId, RTL_TEXTENCODING_UTF8 ), this );
1288  }
1289  }
1290 
1291  return pItem->maHelpText;
1292 }
1293 
1294 void StatusBar::SetQuickHelpText( sal_uInt16 nItemId, const OUString& rText )
1295 {
1296  sal_uInt16 nPos = GetItemPos( nItemId );
1297 
1298  if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1299  mvItemList[ nPos ]->maQuickHelpText = rText;
1300 }
1301 
1302 const OUString& StatusBar::GetQuickHelpText( sal_uInt16 nItemId ) const
1303 {
1304  sal_uInt16 nPos = GetItemPos( nItemId );
1305 
1306  assert ( nPos != STATUSBAR_ITEM_NOTFOUND );
1307 
1308  ImplStatusItem* pItem = mvItemList[ nPos ].get();
1309  return pItem->maQuickHelpText;
1310 }
1311 
1312 void StatusBar::SetHelpId( sal_uInt16 nItemId, const OString& rHelpId )
1313 {
1314  sal_uInt16 nPos = GetItemPos( nItemId );
1315 
1316  if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1317  mvItemList[ nPos ]->maHelpId = rHelpId;
1318 }
1319 
1320 void StatusBar::StartProgressMode( const OUString& rText )
1321 {
1322  SAL_WARN_IF( mbProgressMode, "vcl", "StatusBar::StartProgressMode(): progress mode is active" );
1323 
1324  mbProgressMode = true;
1325  mnPercent = 0;
1326  maPrgsTxt = rText;
1327 
1328  // compute size
1330 
1331  // trigger Paint, which draws text and frame
1332  if ( IsReallyVisible() )
1333  {
1334  Invalidate();
1335  Update();
1336  }
1337 }
1338 
1339 void StatusBar::SetProgressValue( sal_uInt16 nNewPercent )
1340 {
1341  SAL_WARN_IF( !mbProgressMode, "vcl", "StatusBar::SetProgressValue(): no progress mode" );
1342  SAL_WARN_IF( nNewPercent > 100, "vcl", "StatusBar::SetProgressValue(): nPercent > 100" );
1343 
1344  bool bInvalidate = mbProgressMode && IsReallyVisible() && (!mnPercent || (mnPercent != nNewPercent));
1345 
1346  mnPercent = nNewPercent;
1347 
1348  if (bInvalidate)
1349  {
1351  Update();
1352  }
1353 }
1354 
1356 {
1357  SAL_WARN_IF( !mbProgressMode, "vcl", "StatusBar::EndProgressMode(): no progress mode" );
1358 
1359  mbProgressMode = false;
1360  maPrgsTxt.clear();
1361 
1362  if ( IsReallyVisible() )
1363  {
1364  Invalidate();
1365  Update();
1366  }
1367 }
1368 
1369 void StatusBar::SetText(const OUString& rText)
1370 {
1372  {
1373  if (mbFormat)
1374  {
1375  Invalidate();
1376  Window::SetText(rText);
1377  }
1378  else
1379  {
1380  Invalidate();
1381  Window::SetText(rText);
1382  Update();
1383  }
1384  }
1385  else if (mbProgressMode)
1386  {
1387  maPrgsTxt = rText;
1388  if (IsReallyVisible())
1389  {
1390  Invalidate();
1391  Update();
1392  }
1393  }
1394  else
1395  {
1396  Window::SetText(rText);
1397  }
1398 }
1399 
1401 {
1402  size_t i = 0;
1403  size_t nCount = mvItemList.size();
1404  long nOffset = 0;
1405  long nCalcWidth = STATUSBAR_OFFSET_X*2;
1406  long nCalcHeight;
1407 
1408  while ( i < nCount )
1409  {
1410  ImplStatusItem* pItem = mvItemList[ i ].get();
1411  nCalcWidth += pItem->mnWidth + nOffset;
1412  nOffset = pItem->mnOffset;
1413  i++;
1414  }
1415 
1416  long nMinHeight = GetTextHeight();
1417  const long nBarTextOffset = STATUSBAR_OFFSET_TEXTY*2;
1418  long nProgressHeight = nMinHeight + nBarTextOffset;
1419 
1421  {
1422  ImplControlValue aValue;
1423  tools::Rectangle aControlRegion( Point(), Size( nCalcWidth, nMinHeight ) );
1424  tools::Rectangle aNativeControlRegion, aNativeContentRegion;
1426  aControlRegion, ControlState::ENABLED, aValue,
1427  aNativeControlRegion, aNativeContentRegion ) )
1428  {
1429  nProgressHeight = aNativeControlRegion.GetHeight();
1430  }
1431  }
1432 
1433  nCalcHeight = nMinHeight+nBarTextOffset;
1434  if( nCalcHeight < nProgressHeight+2 )
1435  nCalcHeight = nProgressHeight+2;
1436 
1437  return Size( nCalcWidth, nCalcHeight );
1438 }
1439 
1440 void StatusBar::SetAccessibleName( sal_uInt16 nItemId, const OUString& rName )
1441 {
1442  sal_uInt16 nPos = GetItemPos( nItemId );
1443 
1444  if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1445  {
1446  ImplStatusItem* pItem = mvItemList[ nPos ].get();
1447 
1448  if ( pItem->maAccessibleName != rName )
1449  {
1450  pItem->maAccessibleName = rName;
1451  CallEventListeners( VclEventId::StatusbarNameChanged, reinterpret_cast<void*>(pItem->mnId) );
1452  }
1453  }
1454 }
1455 
1456 const OUString& StatusBar::GetAccessibleName( sal_uInt16 nItemId ) const
1457 {
1458  sal_uInt16 nPos = GetItemPos( nItemId );
1459 
1460  assert ( nPos != STATUSBAR_ITEM_NOTFOUND );
1461 
1462  return mvItemList[ nPos ]->maAccessibleName;
1463 }
1464 
1465 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Point TopLeft() const
long Width() const
const Color & GetTextColor() const
Definition: outdev.hxx:1110
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:780
const Color & GetShadowColor() const
SAL_DLLPRIVATE void ImplDrawText(vcl::RenderContext &rRenderContext)
Definition: status.cxx:342
bool IsControlBackground() const
Definition: window2.cxx:1076
long mnTextY
Definition: status.hxx:78
long mnItemsWidth
Definition: status.hxx:74
long GetWidth() const
const Wallpaper & GetBackground() const
Definition: outdev.hxx:631
void * GetItemData(sal_uInt16 nItemId) const
Definition: status.cxx:1235
OUString maHelpText
Definition: status.cxx:68
void RedrawItem(sal_uInt16 nItemId)
Definition: status.cxx:1245
tools::Rectangle maPrgsFrameRect
Definition: status.hxx:72
long GetHeight() const
SAL_DLLPRIVATE bool ImplIsRecordLayout() const
Definition: outdev.cxx:657
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:330
long AdjustX(long nHorzMove)
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:1320
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:1317
Point BottomLeft() const
#define STATUSBAR_PRGS_OFFSET
Definition: status.cxx:42
long AdjustLeft(long nHorzMoveDelta)
int mnStatusBarLowerRightOffset
Definition: svdata.hxx:266
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:2877
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:1128
const Color & GetFaceColor() const
const OUString & GetItemText(sal_uInt16 nItemId) const
Definition: status.cxx:1181
const OUString & GetHelpText() const
Definition: window.cxx:3094
void DrawFrame(const tools::Rectangle &rRect, const Color &rLeftTopColor, const Color &rRightBottomColor)
Definition: decoview.cxx:848
ImplSVNWFData maNWFData
Definition: svdata.hxx:352
const OUString & GetQuickHelpText() const
Definition: window2.cxx:1221
OUString GetItemCommand(sal_uInt16 nItemId)
Definition: status.cxx:1203
virtual Size GetSizePixel() const
Definition: window.cxx:2364
virtual void SetSizePixel(const Size &rNewSize)
Definition: window2.cxx:1251
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:554
void SetTextFillColor()
Definition: text.cxx:698
DataChangedEventType GetType() const
Definition: event.hxx:348
void IntersectClipRegion(const tools::Rectangle &rRect)
long mnWidth
Definition: status.cxx:63
Size CalcWindowSizePixel() const
Definition: status.cxx:1400
const Color & GetControlBackground() const
Definition: window2.cxx:1071
bool IsItemVisible(sal_uInt16 nItemId) const
Definition: status.cxx:986
virtual ~StatusBar() override
Definition: status.cxx:141
Link< StatusBar *, void > maDoubleClickHdl
Definition: status.hxx:87
bool IsNativeControlSupported(ControlType nType, ControlPart nPart) const
Query the platform layer for control support.
HelpEventMode GetMode() const
Definition: event.hxx:192
#define STATUSBAR_OFFSET_Y
Definition: status.cxx:39
void AdjustItemWidthsForHiDPI()
Definition: status.cxx:157
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:1264
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:120
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:366
void setX(long nX)
#define SAL_MAX_UINT16
#define STATUSBAR_PRGS_COUNT
Definition: status.cxx:43
const vcl::Font & GetFont() const
Definition: outdev.hxx:637
tools::Rectangle GetItemRect(sal_uInt16 nItemId) const
Definition: status.cxx:1049
bool IsControlForeground() const
Definition: window2.cxx:1066
void SetItemData(sal_uInt16 nItemId, void *pNewData)
Definition: status.cxx:1213
AllSettingsFlags GetFlags() const
Definition: event.hxx:349
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:469
sal_uInt16 mnPercentCount
Definition: status.hxx:81
virtual void SetOutputSizePixel(const Size &rNewSize)
Definition: window2.cxx:1263
virtual OUString GetText() const
Definition: window.cxx:3059
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 setY(long nY)
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:1061
void Update()
Definition: paint.cxx:1276
const Point & GetMousePosPixel() const
Definition: event.hxx:191
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:316
ImplSVData * ImplGetSVData()
Definition: svdata.cxx:67
void EndProgressMode()
Definition: status.cxx:1355
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:146
bool IsRTLEnabled() const
Definition: outdev.hxx:1354
void SetTop(long v)
Window(WindowType nType)
Definition: window.cxx:85
void DoubleClick()
Definition: status.cxx:880
SAL_DLLPRIVATE tools::Rectangle ImplGetItemRectPos(sal_uInt16 nPos) const
Definition: status.cxx:315
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:84
SAL_DLLPRIVATE void ImplInitSettings()
Definition: status.cxx:197
int i
virtual void Invalidate(InvalidateFlags nFlags=InvalidateFlags::NONE)
Definition: paint.cxx:1156
void SetRight(long v)
bool IsUpdateMode() const
Definition: window2.cxx:1162
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:82
void SetTextColor(const Color &rColor)
Definition: text.cxx:663
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:85
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:1440
std::vector< std::unique_ptr< ImplStatusItem > > mvItemList
Definition: status.hxx:66
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:1234
Point ScreenToOutputPixel(const Point &rPos) const
Definition: window.cxx:2824
bool KeyboardActivated() const
Definition: event.hxx:193
ControlPart mnNativeBackground
Definition: window.h:295
long mnDX
Definition: status.hxx:75
long GetTextHeight() const
Height where any character of the current font fits; in logic coordinates.
Definition: text.cxx:889
static void ShowQuickHelp(vcl::Window *pParent, const tools::Rectangle &rScreenRect, const OUString &rHelpText, QuickHelpFlags nStyle=QuickHelpFlags::NONE)
Definition: help.cxx:178
WinBits const WB_LEFT
long X() const
Point OutputToAbsoluteScreenPixel(const Point &rPos) const
Definition: window.cxx:2867
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:1190
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:1339
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:162
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:1294
void Erase()
Definition: wallpaper.cxx:103
void SetText(const OUString &rText) override
Definition: status.cxx:1369
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:281
sal_uInt16 const mnId
#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:1011
bool IsLeft() const
Definition: event.hxx:133
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:1312
const Point & GetPosPixel() const
Definition: event.hxx:117
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:878
Link< StatusBar *, void > maClickHdl
Definition: status.hxx:86
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:205
bool IsPaintTransparent() const
Definition: window2.cxx:1026
void SetLeft(long v)
WinBits GetStyle() const
Definition: window2.cxx:942
void ApplyControlFont(vcl::RenderContext &rRenderContext, const vcl::Font &rDefaultFont)
Definition: window2.cxx:449
Point OutputToScreenPixel(const Point &rPos) const
Definition: window.cxx:2818
long mnCalcHeight
Definition: status.hxx:77
void CallEventListeners(VclEventId nEvent, void *pData=nullptr)
Definition: event.cxx:213
bool IsReallyVisible() const
Definition: window2.cxx:1096
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
sal_Int32 nPos
void Clear()
Definition: status.cxx:996
sal_uInt16 mnPercent
Definition: status.hxx:80
aStr
bool mbProgressMode
Definition: status.hxx:83
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
long Y() const
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:155
SAL_DLLPRIVATE void ImplFormat()
Definition: status.cxx:208
void setHeight(long nHeight)