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