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