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 2193 : StatusBar::ImplData::ImplData()
58 : {
59 2193 : mpVirDev = NULL;
60 2193 : mbDrawItemFrames = false;
61 2193 : mnItemBorderWidth = 0;
62 2193 : }
63 :
64 2186 : StatusBar::ImplData::~ImplData()
65 : {
66 2186 : }
67 :
68 13276 : 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 : OString maHelpId;
80 : void* mpUserData;
81 : sal_Bool mbVisible;
82 : XubString maAccessibleName;
83 : XubString maCommand;
84 : };
85 :
86 : // =======================================================================
87 :
88 60376 : inline long ImplCalcProgessWidth( sal_uInt16 nMax, long nSize )
89 : {
90 60376 : return ((nMax*(nSize+(nSize/2)))-(nSize/2)+(STATUSBAR_PRGS_OFFSET*2));
91 : }
92 :
93 : // -----------------------------------------------------------------------
94 :
95 15963 : static Point ImplGetItemTextPos( const Size& rRectSize, const Size& rTextSize,
96 : sal_uInt16 nStyle )
97 : {
98 : long nX;
99 : long nY;
100 15963 : long delta = (rTextSize.Height()/4) + 1;
101 15963 : if( delta + rTextSize.Width() > rRectSize.Width() )
102 22 : delta = 0;
103 :
104 15963 : if ( nStyle & SIB_LEFT )
105 6052 : nX = delta;
106 9911 : else if ( nStyle & SIB_RIGHT )
107 13 : nX = rRectSize.Width()-rTextSize.Width()-delta;
108 : else // SIB_CENTER
109 9898 : nX = (rRectSize.Width()-rTextSize.Width())/2;
110 15963 : nY = (rRectSize.Height()-rTextSize.Height())/2 + 1;
111 15963 : return Point( nX, nY );
112 : }
113 :
114 : // -----------------------------------------------------------------------
115 :
116 16265 : sal_Bool StatusBar::ImplIsItemUpdate()
117 : {
118 16265 : if ( !mbProgressMode && mbVisibleItems && IsReallyVisible() && IsUpdateMode() )
119 2548 : return sal_True;
120 : else
121 13717 : return sal_False;
122 : }
123 :
124 : // -----------------------------------------------------------------------
125 :
126 2193 : void StatusBar::ImplInit( Window* pParent, WinBits nStyle )
127 : {
128 2193 : mpImplData = new ImplData;
129 :
130 : // Default ist RightAlign
131 2193 : if ( !(nStyle & (WB_LEFT | WB_RIGHT)) )
132 0 : nStyle |= WB_RIGHT;
133 :
134 2193 : Window::ImplInit( pParent, nStyle & ~WB_BORDER, NULL );
135 :
136 : // WinBits merken
137 2193 : mpItemList = new ImplStatusItemList;
138 2193 : mpImplData->mpVirDev = new VirtualDevice( *this );
139 2193 : mnCurItemId = 0;
140 2193 : mbFormat = sal_True;
141 2193 : mbVisibleItems = sal_True;
142 2193 : mbProgressMode = sal_False;
143 2193 : mbInUserDraw = sal_False;
144 2193 : mnItemsWidth = STATUSBAR_OFFSET_X;
145 2193 : mnDX = 0;
146 2193 : mnDY = 0;
147 2193 : mnCalcHeight = 0;
148 2193 : mnItemY = STATUSBAR_OFFSET_Y;
149 2193 : mnTextY = STATUSBAR_OFFSET_TEXTY;
150 :
151 2193 : ImplInitSettings( sal_True, sal_True, sal_True );
152 2193 : SetLineColor();
153 :
154 2193 : SetOutputSizePixel( CalcWindowSizePixel() );
155 2193 : }
156 :
157 : // -----------------------------------------------------------------------
158 :
159 2193 : StatusBar::StatusBar( Window* pParent, WinBits nStyle ) :
160 2193 : Window( WINDOW_STATUSBAR )
161 : {
162 2193 : ImplInit( pParent, nStyle );
163 2193 : }
164 :
165 : // -----------------------------------------------------------------------
166 :
167 5473 : StatusBar::~StatusBar()
168 : {
169 : // Alle Items loeschen
170 8824 : for ( size_t i = 0, n = mpItemList->size(); i < n; ++i ) {
171 6638 : delete (*mpItemList)[ i ];
172 : }
173 2186 : delete mpItemList;
174 :
175 : // VirtualDevice loeschen
176 2186 : delete mpImplData->mpVirDev;
177 2186 : delete mpImplData;
178 3287 : }
179 :
180 : // -----------------------------------------------------------------------
181 :
182 2193 : void StatusBar::ImplInitSettings( sal_Bool bFont,
183 : sal_Bool bForeground, sal_Bool bBackground )
184 : {
185 2193 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
186 :
187 2193 : if ( bFont )
188 : {
189 2193 : Font aFont = rStyleSettings.GetToolFont();
190 2193 : if ( IsControlFont() )
191 0 : aFont.Merge( GetControlFont() );
192 2193 : SetZoomedPointFont( aFont );
193 : }
194 :
195 2193 : if ( bForeground || bFont )
196 : {
197 2193 : Color aColor;
198 2193 : if ( IsControlForeground() )
199 0 : aColor = GetControlForeground();
200 2193 : else if ( GetStyle() & WB_3DLOOK )
201 2193 : aColor = rStyleSettings.GetButtonTextColor();
202 : else
203 0 : aColor = rStyleSettings.GetWindowTextColor();
204 2193 : SetTextColor( aColor );
205 2193 : SetTextFillColor();
206 :
207 2193 : mpImplData->mpVirDev->SetFont( GetFont() );
208 2193 : mpImplData->mpVirDev->SetTextColor( GetTextColor() );
209 2193 : mpImplData->mpVirDev->SetTextAlign( GetTextAlign() );
210 2193 : mpImplData->mpVirDev->SetTextFillColor();
211 : }
212 :
213 2193 : if ( bBackground )
214 : {
215 2193 : Color aColor;
216 2193 : if ( IsControlBackground() )
217 0 : aColor = GetControlBackground();
218 2193 : else if ( GetStyle() & WB_3DLOOK )
219 2193 : aColor = rStyleSettings.GetFaceColor();
220 : else
221 0 : aColor = rStyleSettings.GetWindowColor();
222 2193 : SetBackground( aColor );
223 2193 : mpImplData->mpVirDev->SetBackground( GetBackground() );
224 :
225 : // NWF background
226 4386 : if( ! IsControlBackground() &&
227 2193 : IsNativeControlSupported( CTRL_WINDOW_BACKGROUND, PART_BACKGROUND_WINDOW ) )
228 : {
229 0 : ImplGetWindowImpl()->mnNativeBackground = PART_BACKGROUND_WINDOW;
230 0 : EnableChildTransparentMode( sal_True );
231 : }
232 : }
233 2193 : }
234 :
235 : // -----------------------------------------------------------------------
236 :
237 4406 : void StatusBar::ImplFormat()
238 : {
239 : ImplStatusItem* pItem;
240 : long nExtraWidth;
241 : long nExtraWidth2;
242 : long nX;
243 4406 : sal_uInt16 nAutoSizeItems = 0;
244 :
245 : // Breiten zusammenrechnen
246 4406 : mnItemsWidth = STATUSBAR_OFFSET_X;
247 4406 : long nOffset = 0;
248 43323 : for ( size_t i = 0, n = mpItemList->size(); i < n; ++i ) {
249 38917 : pItem = (*mpItemList)[ i ];
250 38917 : if ( pItem->mbVisible )
251 : {
252 38917 : if ( pItem->mnBits & SIB_AUTOSIZE ) {
253 15360 : nAutoSizeItems++;
254 : }
255 :
256 38917 : mnItemsWidth += pItem->mnWidth + nOffset;
257 38917 : nOffset = pItem->mnOffset;
258 : }
259 : }
260 :
261 4406 : 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 4406 : mnItemsWidth += STATUSBAR_OFFSET_X;
272 :
273 : // Bei linksbuendiger Ausrichtung muessen wir gegebenenfalls noch
274 : // AutoSize auswerten
275 4406 : if ( nAutoSizeItems && (mnDX > (mnItemsWidth - STATUSBAR_OFFSET)) )
276 : {
277 250 : nExtraWidth = (mnDX - mnItemsWidth - 1) / nAutoSizeItems;
278 250 : nExtraWidth2 = (mnDX - mnItemsWidth - 1) % nAutoSizeItems;
279 : }
280 : else
281 : {
282 4156 : nExtraWidth = 0;
283 4156 : nExtraWidth2 = 0;
284 : }
285 4406 : nX = STATUSBAR_OFFSET_X;
286 4406 : if( ImplHasMirroredGraphics() && IsRTLEnabled() )
287 0 : nX += ImplGetSVData()->maNWFData.mnStatusBarLowerRightOffset;
288 : }
289 :
290 43323 : for ( size_t i = 0, n = mpItemList->size(); i < n; ++i ) {
291 38917 : pItem = (*mpItemList)[ i ];
292 38917 : if ( pItem->mbVisible ) {
293 38917 : if ( pItem->mnBits & SIB_AUTOSIZE ) {
294 15360 : pItem->mnExtraWidth = nExtraWidth;
295 15360 : if ( nExtraWidth2 ) {
296 79 : pItem->mnExtraWidth++;
297 79 : nExtraWidth2--;
298 : }
299 : } else {
300 23557 : pItem->mnExtraWidth = 0;
301 : }
302 :
303 38917 : pItem->mnX = nX;
304 38917 : nX += pItem->mnWidth + pItem->mnExtraWidth + pItem->mnOffset;
305 : }
306 : }
307 :
308 4406 : mbFormat = sal_False;
309 4406 : }
310 :
311 : // -----------------------------------------------------------------------
312 :
313 25261 : Rectangle StatusBar::ImplGetItemRectPos( sal_uInt16 nPos ) const
314 : {
315 25261 : Rectangle aRect;
316 : ImplStatusItem* pItem;
317 25261 : pItem = ( nPos < mpItemList->size() ) ? (*mpItemList)[ nPos ] : NULL;
318 25261 : if ( pItem )
319 : {
320 25261 : if ( pItem->mbVisible )
321 : {
322 25261 : aRect.Left() = pItem->mnX;
323 25261 : aRect.Right() = aRect.Left() + pItem->mnWidth + pItem->mnExtraWidth;
324 25261 : aRect.Top() = mnItemY;
325 25261 : aRect.Bottom() = mnCalcHeight - STATUSBAR_OFFSET_Y;
326 : }
327 : }
328 :
329 25261 : return aRect;
330 : }
331 :
332 : // -----------------------------------------------------------------------
333 :
334 13474 : sal_uInt16 StatusBar::ImplGetFirstVisiblePos() const
335 : {
336 : ImplStatusItem* pItem;
337 :
338 13474 : for( size_t nPos = 0; nPos < mpItemList->size(); nPos++ )
339 : {
340 13474 : pItem = (*mpItemList)[ nPos ];
341 13474 : if ( pItem )
342 : {
343 13474 : if ( pItem->mbVisible )
344 13474 : 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( '\n' );
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 = std::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 16022 : void StatusBar::ImplDrawItem( sal_Bool bOffScreen, sal_uInt16 nPos, sal_Bool bDrawText, sal_Bool bDrawFrame )
391 : {
392 16022 : Rectangle aRect = ImplGetItemRectPos( nPos );
393 :
394 16022 : if ( aRect.IsEmpty() )
395 16022 : return;
396 :
397 : // Ausgabebereich berechnen
398 16022 : ImplStatusItem* pItem = (*mpItemList)[ nPos ];
399 16022 : long nW = mpImplData->mnItemBorderWidth + 1;
400 32044 : Rectangle aTextRect( aRect.Left()+nW, aRect.Top()+nW,
401 48066 : aRect.Right()-nW, aRect.Bottom()-nW );
402 16022 : Size aTextRectSize( aTextRect.GetSize() );
403 :
404 16022 : if ( bOffScreen )
405 2548 : mpImplData->mpVirDev->SetOutputSizePixel( aTextRectSize );
406 : else
407 : {
408 13474 : Region aRegion( aTextRect );
409 13474 : SetClipRegion( aRegion );
410 : }
411 :
412 : // Text ausgeben
413 16022 : if ( bDrawText )
414 : {
415 13880 : Size aTextSize( GetTextWidth( pItem->maText ), GetTextHeight() );
416 13880 : Point aTextPos = ImplGetItemTextPos( aTextRectSize, aTextSize, pItem->mnBits );
417 13880 : if ( bOffScreen )
418 406 : mpImplData->mpVirDev->DrawText( aTextPos, pItem->maText );
419 : else
420 : {
421 13474 : aTextPos.X() += aTextRect.Left();
422 13474 : aTextPos.Y() += aTextRect.Top();
423 13474 : DrawText( aTextPos, pItem->maText );
424 : }
425 : }
426 :
427 : // Gegebenenfalls auch DrawItem aufrufen
428 16022 : if ( pItem->mnBits & SIB_USERDRAW )
429 : {
430 9000 : if ( bOffScreen )
431 : {
432 2164 : mbInUserDraw = sal_True;
433 2164 : mpImplData->mpVirDev->EnableRTL( IsRTLEnabled() );
434 2164 : UserDrawEvent aODEvt( mpImplData->mpVirDev, Rectangle( Point(), aTextRectSize ), pItem->mnId );
435 2164 : UserDraw( aODEvt );
436 2164 : mpImplData->mpVirDev->EnableRTL( sal_False );
437 2164 : mbInUserDraw = sal_False;
438 : }
439 : else
440 : {
441 6836 : UserDrawEvent aODEvt( this, aTextRect, pItem->mnId );
442 6836 : UserDraw( aODEvt );
443 : }
444 : }
445 :
446 16022 : if ( bOffScreen )
447 2548 : DrawOutDev( aTextRect.TopLeft(), aTextRectSize, Point(), aTextRectSize, *mpImplData->mpVirDev );
448 : else
449 13474 : SetClipRegion();
450 :
451 : // Frame ausgeben
452 16022 : if ( bDrawFrame )
453 : {
454 13474 : 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 13474 : else if( nPos != ImplGetFirstVisiblePos() )
470 : {
471 : // draw separator
472 12260 : Point aFrom( aRect.TopLeft() );
473 12260 : aFrom.X()-=4;
474 12260 : aFrom.Y()++;
475 12260 : Point aTo( aRect.BottomLeft() );
476 12260 : aTo.X()-=4;
477 12260 : aTo.Y()--;
478 :
479 12260 : DecorationView aDecoView( this );
480 12260 : aDecoView.DrawSeparator( aFrom, aTo );
481 : }
482 : }
483 :
484 16022 : if ( !ImplIsRecordLayout() )
485 13178 : ImplCallEventListeners( VCLEVENT_STATUSBAR_DRAWITEM, (void*) sal_IntPtr(pItem->mnId) );
486 : }
487 :
488 : // -----------------------------------------------------------------------
489 :
490 12004 : 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 12004 : 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, OUString() );
532 0 : if( bNeedErase )
533 0 : pWindow->Pop();
534 0 : if( bNativeOK )
535 : {
536 0 : pWindow->Flush();
537 12004 : return;
538 0 : }
539 : }
540 :
541 : // Werte vorberechnen
542 12004 : sal_uInt16 nPerc1 = nPercent1 / nPercentCount;
543 12004 : sal_uInt16 nPerc2 = nPercent2 / nPercentCount;
544 :
545 12004 : if ( nPerc1 > nPerc2 )
546 : {
547 : // Support progress that can also decrease
548 :
549 : // Rechteck berechnen
550 181 : long nDX = nPrgsWidth + nOffset;
551 181 : long nLeft = rPos.X()+((nPerc1-1)*nDX);
552 181 : Rectangle aRect( nLeft, rPos.Y(), nLeft+nPrgsWidth, rPos.Y()+nPrgsHeight );
553 :
554 7260 : do
555 : {
556 7260 : pWindow->Erase( aRect );
557 7260 : aRect.Left() -= nDX;
558 7260 : aRect.Right() -= nDX;
559 7260 : nPerc1--;
560 : }
561 : while ( nPerc1 > nPerc2 );
562 :
563 181 : pWindow->Flush();
564 : }
565 11823 : else if ( nPerc1 < nPerc2 )
566 : {
567 : // Percent-Rechtecke malen
568 : // Wenn Percent2 ueber 100%, Werte anpassen
569 6082 : 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 6082 : long nDX = nPrgsWidth + nOffset;
578 6082 : long nLeft = rPos.X()+(nPerc1*nDX);
579 6082 : Rectangle aRect( nLeft, rPos.Y(), nLeft+nPrgsWidth, rPos.Y()+nPrgsHeight );
580 :
581 26041 : do
582 : {
583 26041 : pWindow->DrawRect( aRect );
584 26041 : aRect.Left() += nDX;
585 26041 : aRect.Right() += nDX;
586 26041 : nPerc1++;
587 : }
588 : while ( nPerc1 < nPerc2 );
589 :
590 : // Bei mehr als 100%, lassen wir das Rechteck blinken
591 6082 : 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 6082 : pWindow->Flush();
603 : }
604 : }
605 :
606 : // -----------------------------------------------------------------------
607 :
608 12004 : void StatusBar::ImplDrawProgress( sal_Bool bPaint,
609 : sal_uInt16 nPercent1, sal_uInt16 nPercent2 )
610 : {
611 12004 : bool bNative = IsNativeControlSupported( CTRL_PROGRESS, PART_ENTIRE_CONTROL );
612 : // bPaint: draw text also, else only update progress
613 12004 : if ( bPaint )
614 : {
615 636 : DrawText( maPrgsTxtPos, maPrgsTxt );
616 636 : if( ! bNative )
617 : {
618 636 : DecorationView aDecoView( this );
619 636 : aDecoView.DrawFrame( maPrgsFrameRect, FRAME_DRAW_IN );
620 : }
621 : }
622 :
623 12004 : Point aPos( maPrgsFrameRect.Left()+STATUSBAR_PRGS_OFFSET,
624 24008 : maPrgsFrameRect.Top()+STATUSBAR_PRGS_OFFSET );
625 12004 : long nPrgsHeight = mnPrgsSize;
626 12004 : if( bNative )
627 : {
628 0 : aPos = maPrgsFrameRect.TopLeft();
629 0 : nPrgsHeight = maPrgsFrameRect.GetHeight();
630 : }
631 : DrawProgress( this, aPos, mnPrgsSize/2, mnPrgsSize, nPrgsHeight,
632 12004 : nPercent1*100, nPercent2*100, mnPercentCount, maPrgsFrameRect );
633 12004 : }
634 :
635 : // -----------------------------------------------------------------------
636 :
637 837 : void StatusBar::ImplCalcProgressRect()
638 : {
639 : // calculate text size
640 837 : Size aPrgsTxtSize( GetTextWidth( maPrgsTxt ), GetTextHeight() );
641 837 : maPrgsTxtPos.X() = STATUSBAR_OFFSET_X+1;
642 :
643 : // calculate progress frame
644 837 : maPrgsFrameRect.Left() = maPrgsTxtPos.X()+aPrgsTxtSize.Width()+STATUSBAR_OFFSET;
645 837 : maPrgsFrameRect.Top() = mnItemY;
646 837 : maPrgsFrameRect.Bottom() = mnCalcHeight - STATUSBAR_OFFSET_Y;
647 :
648 : // calculate size of progress rects
649 837 : mnPrgsSize = maPrgsFrameRect.Bottom()-maPrgsFrameRect.Top()-(STATUSBAR_PRGS_OFFSET*2);
650 837 : sal_uInt16 nMaxPercent = STATUSBAR_PRGS_COUNT;
651 :
652 837 : long nMaxWidth = mnDX-STATUSBAR_OFFSET-1;
653 :
654 : // make smaller if there are too many rects
655 60376 : while ( maPrgsFrameRect.Left()+ImplCalcProgessWidth( nMaxPercent, mnPrgsSize ) > nMaxWidth )
656 : {
657 59009 : nMaxPercent--;
658 59009 : if ( nMaxPercent <= STATUSBAR_PRGS_MIN )
659 307 : break;
660 : }
661 837 : maPrgsFrameRect.Right() = maPrgsFrameRect.Left() + ImplCalcProgessWidth( nMaxPercent, mnPrgsSize );
662 :
663 : // save the divisor for later
664 837 : mnPercentCount = 10000 / nMaxPercent;
665 837 : sal_Bool bNativeOK = sal_False;
666 837 : 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, 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 837 : if( ! bNativeOK )
686 837 : maPrgsTxtPos.Y() = mnTextY;
687 837 : }
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 2853 : void StatusBar::Paint( const Rectangle& )
731 : {
732 2853 : if ( mbFormat )
733 1186 : ImplFormat();
734 :
735 2853 : sal_uInt16 nItemCount = sal_uInt16( mpItemList->size() );
736 :
737 2853 : if ( mbProgressMode )
738 636 : ImplDrawProgress( sal_True, 0, mnPercent );
739 : else
740 : {
741 : // Text zeichen
742 2217 : if ( !mbVisibleItems || (GetStyle() & WB_RIGHT) )
743 0 : ImplDrawText( sal_False, 0 );
744 :
745 : // Items zeichnen
746 2217 : if ( mbVisibleItems )
747 : {
748 : // Items zeichnen
749 15691 : for ( sal_uInt16 i = 0; i < nItemCount; i++ )
750 13474 : 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 2853 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
757 2853 : SetLineColor( rStyleSettings.GetShadowColor() );
758 2853 : DrawLine( Point( 0, 0 ), Point( mnDX-1, 0 ) );
759 2853 : }
760 :
761 : // -----------------------------------------------------------------------
762 :
763 2755 : void StatusBar::Move()
764 : {
765 2755 : Window::Move();
766 2755 : }
767 :
768 : // -----------------------------------------------------------------------
769 :
770 3066 : void StatusBar::Resize()
771 : {
772 : // Breite und Hoehe abfragen und merken
773 3066 : Size aSize = GetOutputSizePixel();
774 3066 : mnDX = aSize.Width() - ImplGetSVData()->maNWFData.mnStatusBarLowerRightOffset;
775 3066 : mnDY = aSize.Height();
776 3066 : mnCalcHeight = mnDY;
777 :
778 3066 : mnItemY = STATUSBAR_OFFSET_Y;
779 3066 : mnTextY = (mnCalcHeight-GetTextHeight())/2;
780 :
781 : // Formatierung neu ausloesen
782 3066 : mbFormat = sal_True;
783 :
784 3066 : if ( mbProgressMode )
785 285 : ImplCalcProgressRect();
786 :
787 3066 : Invalidate();
788 3066 : }
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 0 : 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 0 : return;
831 0 : }
832 : }
833 0 : else if ( rHEvt.GetMode() & HELPMODE_EXTENDED )
834 : {
835 0 : String aCommand = GetItemCommand( nItemId );
836 0 : 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( OStringToOUString( aHelpId, RTL_TEXTENCODING_UTF8 ), this );
848 : }
849 0 : return;
850 0 : }
851 : }
852 : }
853 :
854 0 : Window::RequestHelp( rHEvt );
855 : }
856 :
857 : // -----------------------------------------------------------------------
858 :
859 1185 : void StatusBar::StateChanged( StateChangedType nType )
860 : {
861 1185 : Window::StateChanged( nType );
862 :
863 1185 : if ( nType == STATE_CHANGE_INITSHOW )
864 321 : ImplFormat();
865 864 : else if ( nType == STATE_CHANGE_UPDATEMODE )
866 222 : Invalidate();
867 642 : 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 642 : else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
875 : {
876 0 : ImplInitSettings( sal_False, sal_True, sal_False );
877 0 : Invalidate();
878 : }
879 642 : else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
880 : {
881 0 : ImplInitSettings( sal_False, sal_False, sal_True );
882 0 : Invalidate();
883 : }
884 1185 : }
885 :
886 : // -----------------------------------------------------------------------
887 :
888 4 : void StatusBar::DataChanged( const DataChangedEvent& rDCEvt )
889 : {
890 4 : Window::DataChanged( rDCEvt );
891 :
892 8 : if ( (rDCEvt.GetType() == DATACHANGED_DISPLAY )
893 4 : || (rDCEvt.GetType() == DATACHANGED_FONTS )
894 4 : || (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION)
895 8 : || ( (rDCEvt.GetType() == DATACHANGED_SETTINGS)
896 4 : && (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 4 : }
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 6638 : 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 6638 : if ( !(nBits & (SIB_IN | SIB_OUT | SIB_FLAT)) )
953 0 : nBits |= SIB_IN;
954 6638 : if ( !(nBits & (SIB_LEFT | SIB_RIGHT | SIB_CENTER)) )
955 0 : nBits |= SIB_CENTER;
956 :
957 : // Item anlegen
958 6638 : long nFudge = GetTextHeight()/4;
959 6638 : ImplStatusItem* pItem = new ImplStatusItem;
960 6638 : pItem->mnId = nItemId;
961 6638 : pItem->mnBits = nBits;
962 6638 : pItem->mnWidth = (long)nWidth+nFudge+STATUSBAR_OFFSET;
963 6638 : pItem->mnOffset = nOffset;
964 6638 : pItem->mpUserData = 0;
965 6638 : pItem->mbVisible = sal_True;
966 :
967 : // Item in die Liste einfuegen
968 6638 : if ( nPos < mpItemList->size() ) {
969 0 : mpItemList->insert( mpItemList->begin() + nPos, pItem );
970 : } else {
971 6638 : mpItemList->push_back( pItem );
972 : }
973 :
974 6638 : mbFormat = sal_True;
975 6638 : if ( ImplIsItemUpdate() )
976 0 : Invalidate();
977 :
978 6638 : ImplCallEventListeners( VCLEVENT_STATUSBAR_ITEMADDED, (void*) sal_IntPtr(nItemId) );
979 6638 : }
980 :
981 : // -----------------------------------------------------------------------
982 :
983 0 : void StatusBar::RemoveItem( sal_uInt16 nItemId )
984 : {
985 0 : sal_uInt16 nPos = GetItemPos( nItemId );
986 0 : if ( nPos != STATUSBAR_ITEM_NOTFOUND )
987 : {
988 0 : delete (*mpItemList)[ nPos ];
989 0 : mpItemList->erase( mpItemList->begin() + nPos );
990 :
991 0 : mbFormat = sal_True;
992 0 : if ( ImplIsItemUpdate() )
993 0 : Invalidate();
994 :
995 0 : ImplCallEventListeners( VCLEVENT_STATUSBAR_ITEMREMOVED, (void*) sal_IntPtr(nItemId) );
996 : }
997 0 : }
998 :
999 : // -----------------------------------------------------------------------
1000 :
1001 0 : void StatusBar::ShowItem( sal_uInt16 nItemId )
1002 : {
1003 0 : sal_uInt16 nPos = GetItemPos( nItemId );
1004 :
1005 0 : if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1006 : {
1007 0 : ImplStatusItem* pItem = (*mpItemList)[ nPos ];
1008 0 : if ( !pItem->mbVisible )
1009 : {
1010 0 : pItem->mbVisible = sal_True;
1011 :
1012 0 : mbFormat = sal_True;
1013 0 : if ( ImplIsItemUpdate() )
1014 0 : Invalidate();
1015 :
1016 0 : ImplCallEventListeners( VCLEVENT_STATUSBAR_SHOWITEM, (void*) sal_IntPtr(nItemId) );
1017 : }
1018 : }
1019 0 : }
1020 :
1021 : // -----------------------------------------------------------------------
1022 :
1023 0 : void StatusBar::HideItem( sal_uInt16 nItemId )
1024 : {
1025 0 : sal_uInt16 nPos = GetItemPos( nItemId );
1026 :
1027 0 : if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1028 : {
1029 0 : ImplStatusItem* pItem = (*mpItemList)[ nPos ];
1030 0 : if ( pItem->mbVisible )
1031 : {
1032 0 : pItem->mbVisible = sal_False;
1033 :
1034 0 : mbFormat = sal_True;
1035 0 : if ( ImplIsItemUpdate() )
1036 0 : Invalidate();
1037 :
1038 0 : ImplCallEventListeners( VCLEVENT_STATUSBAR_HIDEITEM, (void*) sal_IntPtr(nItemId) );
1039 : }
1040 : }
1041 0 : }
1042 :
1043 : // -----------------------------------------------------------------------
1044 :
1045 2 : sal_Bool StatusBar::IsItemVisible( sal_uInt16 nItemId ) const
1046 : {
1047 2 : sal_uInt16 nPos = GetItemPos( nItemId );
1048 :
1049 2 : if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1050 2 : return (*mpItemList)[ nPos ]->mbVisible;
1051 : else
1052 0 : return sal_False;
1053 : }
1054 :
1055 : // -----------------------------------------------------------------------
1056 :
1057 0 : void StatusBar::ShowItems()
1058 : {
1059 0 : if ( !mbVisibleItems )
1060 : {
1061 0 : mbVisibleItems = sal_True;
1062 0 : if ( !mbProgressMode )
1063 0 : Invalidate();
1064 :
1065 0 : ImplCallEventListeners( VCLEVENT_STATUSBAR_SHOWALLITEMS );
1066 : }
1067 0 : }
1068 :
1069 : // -----------------------------------------------------------------------
1070 :
1071 0 : void StatusBar::HideItems()
1072 : {
1073 0 : if ( mbVisibleItems )
1074 : {
1075 0 : mbVisibleItems = sal_False;
1076 0 : if ( !mbProgressMode )
1077 0 : Invalidate();
1078 :
1079 0 : ImplCallEventListeners( VCLEVENT_STATUSBAR_HIDEALLITEMS );
1080 : }
1081 0 : }
1082 :
1083 : // -----------------------------------------------------------------------
1084 :
1085 0 : void StatusBar::CopyItems( const StatusBar& rStatusBar )
1086 : {
1087 : // Alle Items entfernen
1088 0 : for ( size_t i = 0, n = mpItemList->size(); i < n; ++i ) {
1089 0 : delete (*mpItemList)[ i ];
1090 : }
1091 0 : mpItemList->clear();
1092 :
1093 : // Items kopieren
1094 0 : for ( size_t i = 0, n = rStatusBar.mpItemList->size(); i < n; ++i ) {
1095 0 : mpItemList->push_back( new ImplStatusItem( *(*rStatusBar.mpItemList)[ i ] ) );
1096 : }
1097 :
1098 0 : mbFormat = sal_True;
1099 0 : if ( ImplIsItemUpdate() )
1100 0 : Invalidate();
1101 0 : }
1102 :
1103 : // -----------------------------------------------------------------------
1104 :
1105 640 : void StatusBar::Clear()
1106 : {
1107 : // Alle Item loeschen
1108 640 : for ( size_t i = 0, n = mpItemList->size(); i < n; ++i ) {
1109 0 : delete (*mpItemList)[ i ];
1110 : }
1111 640 : mpItemList->clear();
1112 :
1113 640 : mbFormat = sal_True;
1114 640 : if ( ImplIsItemUpdate() )
1115 0 : Invalidate();
1116 :
1117 640 : ImplCallEventListeners( VCLEVENT_STATUSBAR_ALLITEMSREMOVED );
1118 640 : }
1119 :
1120 : // -----------------------------------------------------------------------
1121 :
1122 15002 : sal_uInt16 StatusBar::GetItemCount() const
1123 : {
1124 15002 : return (sal_uInt16)mpItemList->size();
1125 : }
1126 :
1127 : // -----------------------------------------------------------------------
1128 :
1129 13278 : sal_uInt16 StatusBar::GetItemId( sal_uInt16 nPos ) const
1130 : {
1131 13278 : if ( nPos < mpItemList->size() )
1132 13278 : return (*mpItemList)[ nPos ]->mnId;
1133 0 : return 0;
1134 : }
1135 :
1136 : // -----------------------------------------------------------------------
1137 :
1138 81051 : sal_uInt16 StatusBar::GetItemPos( sal_uInt16 nItemId ) const
1139 : {
1140 559376 : for ( size_t i = 0, n = mpItemList->size(); i < n; ++i ) {
1141 553133 : if ( (*mpItemList)[ i ]->mnId == nItemId ) {
1142 74808 : return sal_uInt16( i );
1143 : }
1144 : }
1145 :
1146 6243 : return STATUSBAR_ITEM_NOTFOUND;
1147 : }
1148 :
1149 : // -----------------------------------------------------------------------
1150 :
1151 0 : sal_uInt16 StatusBar::GetItemId( const Point& rPos ) const
1152 : {
1153 0 : if ( AreItemsVisible() && !mbFormat )
1154 : {
1155 0 : sal_uInt16 nItemCount = GetItemCount();
1156 : sal_uInt16 nPos;
1157 0 : for ( nPos = 0; nPos < nItemCount; nPos++ )
1158 : {
1159 : // Rechteck holen
1160 0 : Rectangle aRect = ImplGetItemRectPos( nPos );
1161 0 : if ( aRect.IsInside( rPos ) )
1162 0 : return (*mpItemList)[ nPos ]->mnId;
1163 : }
1164 : }
1165 :
1166 0 : return 0;
1167 : }
1168 :
1169 : // -----------------------------------------------------------------------
1170 :
1171 7184 : Rectangle StatusBar::GetItemRect( sal_uInt16 nItemId ) const
1172 : {
1173 7184 : Rectangle aRect;
1174 :
1175 7184 : if ( AreItemsVisible() && !mbFormat )
1176 : {
1177 7156 : sal_uInt16 nPos = GetItemPos( nItemId );
1178 7156 : if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1179 : {
1180 : // Rechteck holen und Rahmen abziehen
1181 7156 : aRect = ImplGetItemRectPos( nPos );
1182 7156 : long nW = mpImplData->mnItemBorderWidth+1;
1183 7156 : aRect.Top() += nW-1;
1184 7156 : aRect.Bottom() -= nW-1;
1185 7156 : aRect.Left() += nW;
1186 7156 : aRect.Right() -= nW;
1187 7156 : return aRect;
1188 : }
1189 : }
1190 :
1191 28 : return aRect;
1192 : }
1193 :
1194 : // -----------------------------------------------------------------------
1195 :
1196 2083 : Point StatusBar::GetItemTextPos( sal_uInt16 nItemId ) const
1197 : {
1198 2083 : if ( !mbFormat )
1199 : {
1200 2083 : sal_uInt16 nPos = GetItemPos( nItemId );
1201 2083 : if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1202 : {
1203 : // Rechteck holen
1204 2083 : ImplStatusItem* pItem = (*mpItemList)[ nPos ];
1205 2083 : Rectangle aRect = ImplGetItemRectPos( nPos );
1206 2083 : long nW = mpImplData->mnItemBorderWidth + 1;
1207 4166 : Rectangle aTextRect( aRect.Left()+nW, aRect.Top()+nW,
1208 6249 : aRect.Right()-nW, aRect.Bottom()-nW );
1209 : Point aPos = ImplGetItemTextPos( aTextRect.GetSize(),
1210 : Size( GetTextWidth( pItem->maText ), GetTextHeight() ),
1211 2083 : pItem->mnBits );
1212 2083 : if ( !mbInUserDraw )
1213 : {
1214 1181 : aPos.X() += aTextRect.Left();
1215 1181 : aPos.Y() += aTextRect.Top();
1216 : }
1217 2083 : return aPos;
1218 : }
1219 : }
1220 :
1221 0 : return Point();
1222 : }
1223 :
1224 : // -----------------------------------------------------------------------
1225 :
1226 0 : sal_uLong StatusBar::GetItemWidth( sal_uInt16 nItemId ) const
1227 : {
1228 0 : sal_uInt16 nPos = GetItemPos( nItemId );
1229 :
1230 0 : if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1231 0 : return (*mpItemList)[ nPos ]->mnWidth;
1232 :
1233 0 : return 0;
1234 : }
1235 :
1236 : // -----------------------------------------------------------------------
1237 :
1238 6638 : StatusBarItemBits StatusBar::GetItemBits( sal_uInt16 nItemId ) const
1239 : {
1240 6638 : sal_uInt16 nPos = GetItemPos( nItemId );
1241 :
1242 6638 : if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1243 6638 : return (*mpItemList)[ nPos ]->mnBits;
1244 :
1245 0 : return 0;
1246 : }
1247 :
1248 : // -----------------------------------------------------------------------
1249 :
1250 0 : long StatusBar::GetItemOffset( sal_uInt16 nItemId ) const
1251 : {
1252 0 : sal_uInt16 nPos = GetItemPos( nItemId );
1253 :
1254 0 : if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1255 0 : return (*mpItemList)[ nPos ]->mnOffset;
1256 :
1257 0 : return 0;
1258 : }
1259 :
1260 : // -----------------------------------------------------------------------
1261 :
1262 11302 : void StatusBar::SetItemText( sal_uInt16 nItemId, const XubString& rText )
1263 : {
1264 11302 : sal_uInt16 nPos = GetItemPos( nItemId );
1265 :
1266 11302 : if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1267 : {
1268 11302 : ImplStatusItem* pItem = (*mpItemList)[ nPos ];
1269 :
1270 11302 : if ( pItem->maText != rText )
1271 : {
1272 3533 : pItem->maText = rText;
1273 :
1274 : // adjust item width - see also DataChanged()
1275 3533 : long nFudge = GetTextHeight()/4;
1276 3533 : long nWidth = GetTextWidth( pItem->maText ) + nFudge;
1277 6449 : if( (nWidth > pItem->mnWidth + STATUSBAR_OFFSET) ||
1278 5276 : ((nWidth < pItem->mnWidth) && (mnDX - STATUSBAR_OFFSET) < mnItemsWidth ))
1279 : {
1280 2899 : pItem->mnWidth = nWidth + STATUSBAR_OFFSET;
1281 2899 : ImplFormat();
1282 2899 : Invalidate();
1283 : }
1284 :
1285 : // Item neu Zeichen, wenn StatusBar sichtbar und
1286 : // UpdateMode gesetzt ist
1287 3533 : if ( pItem->mbVisible && !mbFormat && ImplIsItemUpdate() )
1288 : {
1289 406 : Update();
1290 406 : ImplDrawItem( sal_True, nPos, sal_True, sal_False );
1291 406 : Flush();
1292 : }
1293 : }
1294 : }
1295 11302 : }
1296 :
1297 : // -----------------------------------------------------------------------
1298 :
1299 0 : const XubString& StatusBar::GetItemText( sal_uInt16 nItemId ) const
1300 : {
1301 0 : sal_uInt16 nPos = GetItemPos( nItemId );
1302 :
1303 0 : if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1304 0 : return (*mpItemList)[ nPos ]->maText;
1305 :
1306 0 : return ImplGetSVEmptyStr();
1307 : }
1308 :
1309 : // -----------------------------------------------------------------------
1310 :
1311 6638 : void StatusBar::SetItemCommand( sal_uInt16 nItemId, const XubString& rCommand )
1312 : {
1313 6638 : sal_uInt16 nPos = GetItemPos( nItemId );
1314 :
1315 6638 : if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1316 : {
1317 6638 : ImplStatusItem* pItem = (*mpItemList)[ nPos ];
1318 :
1319 6638 : if ( pItem->maCommand != rCommand )
1320 6638 : pItem->maCommand = rCommand;
1321 : }
1322 6638 : }
1323 :
1324 : // -----------------------------------------------------------------------
1325 :
1326 6638 : const XubString& StatusBar::GetItemCommand( sal_uInt16 nItemId )
1327 : {
1328 6638 : sal_uInt16 nPos = GetItemPos( nItemId );
1329 :
1330 6638 : if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1331 6638 : return (*mpItemList)[ nPos ]->maCommand;
1332 :
1333 0 : return ImplGetSVEmptyStr();
1334 : }
1335 :
1336 : // -----------------------------------------------------------------------
1337 :
1338 6337 : void StatusBar::SetItemData( sal_uInt16 nItemId, void* pNewData )
1339 : {
1340 6337 : sal_uInt16 nPos = GetItemPos( nItemId );
1341 :
1342 6337 : if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1343 : {
1344 6337 : ImplStatusItem* pItem = (*mpItemList)[ nPos ];
1345 6337 : pItem->mpUserData = pNewData;
1346 :
1347 : // Wenn es ein User-Item ist, DrawItem-Aufrufen
1348 25348 : if ( (pItem->mnBits & SIB_USERDRAW) && pItem->mbVisible &&
1349 18666 : !mbFormat && ImplIsItemUpdate() )
1350 : {
1351 2142 : Update();
1352 2142 : ImplDrawItem( sal_True, nPos, sal_False, sal_False );
1353 2142 : Flush();
1354 : }
1355 : }
1356 6337 : }
1357 :
1358 13276 : void* StatusBar::GetItemData( sal_uInt16 nItemId ) const
1359 : {
1360 13276 : sal_uInt16 nPos = GetItemPos( nItemId );
1361 :
1362 13276 : if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1363 13276 : return (*mpItemList)[ nPos ]->mpUserData;
1364 :
1365 0 : return NULL;
1366 : }
1367 :
1368 0 : void StatusBar::RedrawItem( sal_uInt16 nItemId )
1369 : {
1370 0 : if ( mbFormat )
1371 0 : return;
1372 :
1373 0 : sal_uInt16 nPos = GetItemPos( nItemId );
1374 0 : if ( nPos == STATUSBAR_ITEM_NOTFOUND )
1375 0 : return;
1376 :
1377 0 : ImplStatusItem* pItem = (*mpItemList)[ nPos ];
1378 0 : if ( pItem && (pItem->mnBits & SIB_USERDRAW) &&
1379 0 : pItem->mbVisible && ImplIsItemUpdate() )
1380 : {
1381 0 : Update();
1382 0 : ImplDrawItem( sal_True, nPos, sal_False, sal_False );
1383 0 : Flush();
1384 : }
1385 : }
1386 :
1387 : // -----------------------------------------------------------------------
1388 :
1389 2827 : void StatusBar::SetHelpText( sal_uInt16 nItemId, const XubString& rText )
1390 : {
1391 2827 : sal_uInt16 nPos = GetItemPos( nItemId );
1392 :
1393 2827 : if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1394 2827 : (*mpItemList)[ nPos ]->maHelpText = rText;
1395 2827 : }
1396 :
1397 : // -----------------------------------------------------------------------
1398 :
1399 0 : const XubString& StatusBar::GetHelpText( sal_uInt16 nItemId ) const
1400 : {
1401 0 : sal_uInt16 nPos = GetItemPos( nItemId );
1402 :
1403 0 : if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1404 : {
1405 0 : ImplStatusItem* pItem = (*mpItemList)[ nPos ];
1406 0 : if ( !pItem->maHelpText.Len() && ( !pItem->maHelpId.isEmpty() || pItem->maCommand.Len() ))
1407 : {
1408 0 : Help* pHelp = Application::GetHelp();
1409 0 : if ( pHelp )
1410 : {
1411 0 : if ( pItem->maCommand.Len() )
1412 0 : pItem->maHelpText = pHelp->GetHelpText( pItem->maCommand, this );
1413 0 : if ( !pItem->maHelpText.Len() && !pItem->maHelpId.isEmpty() )
1414 0 : pItem->maHelpText = pHelp->GetHelpText( OStringToOUString( pItem->maHelpId, RTL_TEXTENCODING_UTF8 ), this );
1415 : }
1416 : }
1417 :
1418 0 : return pItem->maHelpText;
1419 : }
1420 : else
1421 0 : return ImplGetSVEmptyStr();
1422 : }
1423 :
1424 : // -----------------------------------------------------------------------
1425 :
1426 3356 : void StatusBar::SetQuickHelpText( sal_uInt16 nItemId, const XubString& rText )
1427 : {
1428 3356 : sal_uInt16 nPos = GetItemPos( nItemId );
1429 :
1430 3356 : if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1431 3356 : (*mpItemList)[ nPos ]->maQuickHelpText = rText;
1432 3356 : }
1433 :
1434 : // -----------------------------------------------------------------------
1435 :
1436 0 : const XubString& StatusBar::GetQuickHelpText( sal_uInt16 nItemId ) const
1437 : {
1438 0 : sal_uInt16 nPos = GetItemPos( nItemId );
1439 :
1440 0 : if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1441 : {
1442 0 : ImplStatusItem* pItem = (*mpItemList)[ nPos ];
1443 0 : return pItem->maQuickHelpText;
1444 : }
1445 :
1446 0 : return ImplGetSVEmptyStr();
1447 : }
1448 :
1449 : // -----------------------------------------------------------------------
1450 :
1451 8158 : void StatusBar::SetHelpId( sal_uInt16 nItemId, const OString& rHelpId )
1452 : {
1453 8158 : sal_uInt16 nPos = GetItemPos( nItemId );
1454 :
1455 8158 : if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1456 1915 : (*mpItemList)[ nPos ]->maHelpId = rHelpId;
1457 8158 : }
1458 :
1459 : // -----------------------------------------------------------------------
1460 :
1461 0 : OString StatusBar::GetHelpId( sal_uInt16 nItemId ) const
1462 : {
1463 0 : sal_uInt16 nPos = GetItemPos( nItemId );
1464 :
1465 0 : OString aRet;
1466 0 : if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1467 : {
1468 0 : ImplStatusItem* pItem = (*mpItemList)[ nPos ];
1469 0 : if ( !pItem->maHelpId.isEmpty() )
1470 0 : aRet = pItem->maHelpId;
1471 : else
1472 0 : aRet = OUStringToOString( pItem->maCommand, RTL_TEXTENCODING_UTF8 );
1473 : }
1474 :
1475 0 : return aRet;
1476 : }
1477 :
1478 552 : void StatusBar::StartProgressMode( const XubString& rText )
1479 : {
1480 : DBG_ASSERT( !mbProgressMode, "StatusBar::StartProgressMode(): progress mode is active" );
1481 :
1482 552 : mbProgressMode = sal_True;
1483 552 : mnPercent = 0;
1484 552 : maPrgsTxt = rText;
1485 :
1486 : // Groessen berechnen
1487 552 : ImplCalcProgressRect();
1488 :
1489 : // Paint ausloesen (dort wird der Text und der Frame gemalt)
1490 552 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1491 552 : Color aPrgsColor = rStyleSettings.GetHighlightColor();
1492 552 : if ( aPrgsColor == rStyleSettings.GetFaceColor() )
1493 0 : aPrgsColor = rStyleSettings.GetDarkShadowColor();
1494 552 : SetLineColor();
1495 552 : SetFillColor( aPrgsColor );
1496 552 : if ( IsReallyVisible() )
1497 : {
1498 552 : Invalidate();
1499 552 : Update();
1500 552 : Flush();
1501 : }
1502 552 : }
1503 :
1504 : // -----------------------------------------------------------------------
1505 :
1506 11368 : void StatusBar::SetProgressValue( sal_uInt16 nNewPercent )
1507 : {
1508 : DBG_ASSERT( mbProgressMode, "StatusBar::SetProgressValue(): no progrss mode" );
1509 : DBG_ASSERTWARNING( nNewPercent <= 100, "StatusBar::SetProgressValue(): nPercent > 100" );
1510 :
1511 11368 : if ( mbProgressMode
1512 11368 : && IsReallyVisible()
1513 22736 : && (!mnPercent || (mnPercent != nNewPercent)) )
1514 : {
1515 11368 : Update();
1516 11368 : SetLineColor();
1517 11368 : ImplDrawProgress( sal_False, mnPercent, nNewPercent );
1518 11368 : Flush();
1519 : }
1520 11368 : mnPercent = nNewPercent;
1521 11368 : }
1522 :
1523 : // -----------------------------------------------------------------------
1524 :
1525 552 : void StatusBar::EndProgressMode()
1526 : {
1527 : DBG_ASSERT( mbProgressMode, "StatusBar::EndProgressMode(): no progress mode" );
1528 :
1529 552 : mbProgressMode = sal_False;
1530 552 : maPrgsTxt.Erase();
1531 :
1532 : // Paint neu ausloesen um StatusBar wieder herzustellen
1533 552 : SetFillColor( GetSettings().GetStyleSettings().GetFaceColor() );
1534 552 : if ( IsReallyVisible() )
1535 : {
1536 552 : Invalidate();
1537 552 : Update();
1538 552 : Flush();
1539 : }
1540 552 : }
1541 :
1542 : // -----------------------------------------------------------------------
1543 :
1544 0 : void StatusBar::SetText( const OUString& rText )
1545 : {
1546 0 : if ( (!mbVisibleItems || (GetStyle() & WB_RIGHT)) && !mbProgressMode &&
1547 0 : IsReallyVisible() && IsUpdateMode() )
1548 : {
1549 0 : if ( mbFormat )
1550 : {
1551 0 : Invalidate();
1552 0 : Window::SetText( rText );
1553 : }
1554 : else
1555 : {
1556 0 : Update();
1557 0 : long nOldTextWidth = GetTextWidth( GetText() );
1558 0 : Window::SetText( rText );
1559 0 : ImplDrawText( sal_True, nOldTextWidth );
1560 0 : Flush();
1561 : }
1562 : }
1563 0 : else if ( mbProgressMode )
1564 : {
1565 0 : maPrgsTxt = rText;
1566 0 : if ( IsReallyVisible() )
1567 : {
1568 0 : Invalidate();
1569 0 : Update();
1570 0 : Flush();
1571 : }
1572 : }
1573 : else
1574 0 : Window::SetText( rText );
1575 0 : }
1576 :
1577 : // -----------------------------------------------------------------------
1578 :
1579 3280 : Size StatusBar::CalcWindowSizePixel() const
1580 : {
1581 3280 : size_t i = 0;
1582 3280 : size_t nCount = mpItemList->size();
1583 3280 : long nOffset = 0;
1584 3280 : long nCalcWidth = (STATUSBAR_OFFSET_X*2);
1585 : long nCalcHeight;
1586 :
1587 6560 : while ( i < nCount )
1588 : {
1589 0 : ImplStatusItem* pItem = (*mpItemList)[ i ];
1590 0 : nCalcWidth += pItem->mnWidth + nOffset;
1591 0 : nOffset = pItem->mnOffset;
1592 0 : i++;
1593 : }
1594 :
1595 3280 : long nMinHeight = GetTextHeight();
1596 3280 : const long nBarTextOffset = STATUSBAR_OFFSET_TEXTY*2;
1597 3280 : long nProgressHeight = nMinHeight + nBarTextOffset;
1598 :
1599 3280 : if( IsNativeControlSupported( CTRL_PROGRESS, PART_ENTIRE_CONTROL ) )
1600 : {
1601 0 : ImplControlValue aValue;
1602 0 : Rectangle aControlRegion( (const Point&)Point(), Size( nCalcWidth, nMinHeight ) );
1603 0 : Rectangle aNativeControlRegion, aNativeContentRegion;
1604 0 : if( GetNativeControlRegion( CTRL_PROGRESS, PART_ENTIRE_CONTROL,
1605 : aControlRegion, CTRL_STATE_ENABLED, aValue, OUString(),
1606 0 : aNativeControlRegion, aNativeContentRegion ) )
1607 : {
1608 0 : nProgressHeight = aNativeControlRegion.GetHeight();
1609 0 : }
1610 : }
1611 :
1612 3280 : if( mpImplData->mbDrawItemFrames &&
1613 0 : IsNativeControlSupported( CTRL_FRAME, PART_BORDER ) )
1614 : {
1615 0 : ImplControlValue aControlValue( FRAME_DRAW_NODRAW );
1616 0 : Rectangle aBound, aContent;
1617 0 : Rectangle aNatRgn( Point( 0, 0 ), Size( 150, 50 ) );
1618 0 : if( GetNativeControlRegion(CTRL_FRAME, PART_BORDER,
1619 0 : aNatRgn, 0, aControlValue, OUString(), aBound, aContent) )
1620 : {
1621 : mpImplData->mnItemBorderWidth =
1622 0 : ( aBound.GetHeight() - aContent.GetHeight() ) / 2;
1623 0 : }
1624 : }
1625 :
1626 3280 : nCalcHeight = nMinHeight+nBarTextOffset + 2*mpImplData->mnItemBorderWidth;
1627 3280 : if( nCalcHeight < nProgressHeight+2 )
1628 3280 : nCalcHeight = nProgressHeight+2;
1629 :
1630 3280 : return Size( nCalcWidth, nCalcHeight );
1631 : }
1632 :
1633 :
1634 : // -----------------------------------------------------------------------
1635 :
1636 6638 : void StatusBar::SetAccessibleName( sal_uInt16 nItemId, const XubString& rName )
1637 : {
1638 6638 : sal_uInt16 nPos = GetItemPos( nItemId );
1639 :
1640 6638 : if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1641 : {
1642 6638 : ImplStatusItem* pItem = (*mpItemList)[ nPos ];
1643 :
1644 6638 : if ( pItem->maAccessibleName != rName )
1645 : {
1646 5263 : pItem->maAccessibleName = rName;
1647 5263 : ImplCallEventListeners( VCLEVENT_STATUSBAR_NAMECHANGED, (void*) sal_IntPtr(pItem->mnId) );
1648 : }
1649 : }
1650 6638 : }
1651 :
1652 : // -----------------------------------------------------------------------
1653 :
1654 2 : const XubString& StatusBar::GetAccessibleName( sal_uInt16 nItemId ) const
1655 : {
1656 2 : sal_uInt16 nPos = GetItemPos( nItemId );
1657 :
1658 2 : if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1659 2 : return (*mpItemList)[ nPos ]->maAccessibleName;
1660 :
1661 0 : return ImplGetSVEmptyStr();
1662 465 : }
1663 :
1664 : // -----------------------------------------------------------------------
1665 :
1666 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|