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