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