1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_vcl.hxx"
26
27 #include <tools/list.hxx>
28 #include <tools/debug.hxx>
29 #include <tools/rc.h>
30
31 #include <vcl/event.hxx>
32 #include <vcl/decoview.hxx>
33 #include <vcl/svapp.hxx>
34 #include <vcl/help.hxx>
35 #include <vcl/status.hxx>
36 #include <vcl/virdev.hxx>
37
38 #include <svdata.hxx>
39 #include <window.h>
40
41 // =======================================================================
42
43 #define STATUSBAR_OFFSET_X STATUSBAR_OFFSET
44 #define STATUSBAR_OFFSET_Y 2
45 #define STATUSBAR_OFFSET_TEXTY 3
46
47 #define STATUSBAR_PRGS_OFFSET 3
48 #define STATUSBAR_PRGS_COUNT 100
49 #define STATUSBAR_PRGS_MIN 5
50
51 // -----------------------------------------------------------------------
52
53 class StatusBar::ImplData
54 {
55 public:
56 ImplData();
57 ~ImplData();
58
59 VirtualDevice* mpVirDev;
60 long mnItemBorderWidth;
61 bool mbTopBorder:1;
62 bool mbDrawItemFrames:1;
63 };
64
ImplData()65 StatusBar::ImplData::ImplData()
66 {
67 mpVirDev = NULL;
68 mbTopBorder = false;
69 mbDrawItemFrames = false;
70 mnItemBorderWidth = 0;
71 }
72
~ImplData()73 StatusBar::ImplData::~ImplData()
74 {
75 }
76
77 struct ImplStatusItem
78 {
79 sal_uInt16 mnId;
80 StatusBarItemBits mnBits;
81 long mnWidth;
82 long mnOffset;
83 long mnExtraWidth;
84 long mnX;
85 XubString maText;
86 XubString maHelpText;
87 XubString maQuickHelpText;
88 rtl::OString maHelpId;
89 void* mpUserData;
90 sal_Bool mbVisible;
91 XubString maAccessibleName;
92 XubString maCommand;
93 };
94
DECLARE_LIST(ImplStatusItemList,ImplStatusItem *)95 DECLARE_LIST( ImplStatusItemList, ImplStatusItem* )
96
97 // =======================================================================
98
99 inline long ImplCalcProgessWidth( sal_uInt16 nMax, long nSize )
100 {
101 return ((nMax*(nSize+(nSize/2)))-(nSize/2)+(STATUSBAR_PRGS_OFFSET*2));
102 }
103
104 // -----------------------------------------------------------------------
105
ImplGetItemTextPos(const Size & rRectSize,const Size & rTextSize,sal_uInt16 nStyle)106 static Point ImplGetItemTextPos( const Size& rRectSize, const Size& rTextSize,
107 sal_uInt16 nStyle )
108 {
109 long nX;
110 long nY;
111 long delta = (rTextSize.Height()/4) + 1;
112 if( delta + rTextSize.Width() > rRectSize.Width() )
113 delta = 0;
114
115 if ( nStyle & SIB_LEFT )
116 nX = delta;
117 else if ( nStyle & SIB_RIGHT )
118 nX = rRectSize.Width()-rTextSize.Width()-delta;
119 else // SIB_CENTER
120 nX = (rRectSize.Width()-rTextSize.Width())/2;
121 nY = (rRectSize.Height()-rTextSize.Height())/2 + 1;
122 return Point( nX, nY );
123 }
124
125 // -----------------------------------------------------------------------
126
ImplIsItemUpdate()127 sal_Bool StatusBar::ImplIsItemUpdate()
128 {
129 if ( !mbProgressMode && mbVisibleItems && IsReallyVisible() && IsUpdateMode() )
130 return sal_True;
131 else
132 return sal_False;
133 }
134
135 // -----------------------------------------------------------------------
136
ImplInit(Window * pParent,WinBits nStyle)137 void StatusBar::ImplInit( Window* pParent, WinBits nStyle )
138 {
139 mpImplData = new ImplData;
140
141 // Default ist RightAlign
142 if ( !(nStyle & (WB_LEFT | WB_RIGHT)) )
143 nStyle |= WB_RIGHT;
144
145 Window::ImplInit( pParent, nStyle & ~WB_BORDER, NULL );
146
147 // WinBits merken
148 mpItemList = new ImplStatusItemList;
149 mpImplData->mpVirDev = new VirtualDevice( *this );
150 mnCurItemId = 0;
151 mbFormat = sal_True;
152 mbVisibleItems = sal_True;
153 mbProgressMode = sal_False;
154 mbInUserDraw = sal_False;
155 mbBottomBorder = sal_False;
156 mnItemsWidth = STATUSBAR_OFFSET_X;
157 mnDX = 0;
158 mnDY = 0;
159 mnCalcHeight = 0;
160 mnItemY = STATUSBAR_OFFSET_Y;
161 mnTextY = STATUSBAR_OFFSET_TEXTY;
162
163 ImplInitSettings( sal_True, sal_True, sal_True );
164 SetLineColor();
165
166 SetOutputSizePixel( CalcWindowSizePixel() );
167 }
168
169 // -----------------------------------------------------------------------
170
StatusBar(Window * pParent,WinBits nStyle)171 StatusBar::StatusBar( Window* pParent, WinBits nStyle ) :
172 Window( WINDOW_STATUSBAR )
173 {
174 ImplInit( pParent, nStyle );
175 }
176
177 // -----------------------------------------------------------------------
178
StatusBar(Window * pParent,const ResId & rResId)179 StatusBar::StatusBar( Window* pParent, const ResId& rResId ) :
180 Window( WINDOW_STATUSBAR )
181 {
182 rResId.SetRT( RSC_STATUSBAR );
183 WinBits nStyle = ImplInitRes( rResId );
184 ImplInit( pParent, nStyle );
185 ImplLoadRes( rResId );
186
187 if ( !(nStyle & WB_HIDE) )
188 Show();
189 }
190
191 // -----------------------------------------------------------------------
192
~StatusBar()193 StatusBar::~StatusBar()
194 {
195 // Alle Items loeschen
196 ImplStatusItem* pItem = mpItemList->First();
197 while ( pItem )
198 {
199 delete pItem;
200 pItem = mpItemList->Next();
201 }
202
203 delete mpItemList;
204
205 // VirtualDevice loeschen
206 delete mpImplData->mpVirDev;
207
208 delete mpImplData;
209 }
210
211 // -----------------------------------------------------------------------
212
ImplInitSettings(sal_Bool bFont,sal_Bool bForeground,sal_Bool bBackground)213 void StatusBar::ImplInitSettings( sal_Bool bFont,
214 sal_Bool bForeground, sal_Bool bBackground )
215 {
216 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
217
218 if ( bFont )
219 {
220 Font aFont = rStyleSettings.GetToolFont();
221 if ( IsControlFont() )
222 aFont.Merge( GetControlFont() );
223 SetZoomedPointFont( aFont );
224 }
225
226 if ( bForeground || bFont )
227 {
228 Color aColor;
229 if ( IsControlForeground() )
230 aColor = GetControlForeground();
231 else if ( GetStyle() & WB_3DLOOK )
232 aColor = rStyleSettings.GetButtonTextColor();
233 else
234 aColor = rStyleSettings.GetWindowTextColor();
235 SetTextColor( aColor );
236 SetTextFillColor();
237
238 mpImplData->mpVirDev->SetFont( GetFont() );
239 mpImplData->mpVirDev->SetTextColor( GetTextColor() );
240 mpImplData->mpVirDev->SetTextAlign( GetTextAlign() );
241 mpImplData->mpVirDev->SetTextFillColor();
242 }
243
244 if ( bBackground )
245 {
246 Color aColor;
247 if ( IsControlBackground() )
248 aColor = GetControlBackground();
249 else if ( GetStyle() & WB_3DLOOK )
250 aColor = rStyleSettings.GetFaceColor();
251 else
252 aColor = rStyleSettings.GetWindowColor();
253 SetBackground( aColor );
254 mpImplData->mpVirDev->SetBackground( GetBackground() );
255
256 // NWF background
257 if( ! IsControlBackground() &&
258 IsNativeControlSupported( CTRL_WINDOW_BACKGROUND, PART_BACKGROUND_WINDOW ) )
259 {
260 ImplGetWindowImpl()->mnNativeBackground = PART_BACKGROUND_WINDOW;
261 EnableChildTransparentMode( sal_True );
262 }
263 }
264 }
265
266 // -----------------------------------------------------------------------
267
ImplFormat()268 void StatusBar::ImplFormat()
269 {
270 ImplStatusItem* pItem;
271 long nExtraWidth;
272 long nExtraWidth2;
273 long nX;
274 sal_uInt16 nAutoSizeItems = 0;
275
276 // Breiten zusammenrechnen
277 mnItemsWidth = STATUSBAR_OFFSET_X;
278 long nOffset = 0;
279 pItem = mpItemList->First();
280 while ( pItem )
281 {
282 if ( pItem->mbVisible )
283 {
284 if ( pItem->mnBits & SIB_AUTOSIZE )
285 nAutoSizeItems++;
286
287 mnItemsWidth += pItem->mnWidth + nOffset;
288 nOffset = pItem->mnOffset;
289 }
290
291 pItem = mpItemList->Next();
292 }
293
294 if ( GetStyle() & WB_RIGHT )
295 {
296 // Bei rechtsbuendiger Ausrichtung wird kein AutoSize ausgewertet,
297 // da wir links den Text anzeigen, der mit SetText gesetzt wird
298 nX = mnDX - mnItemsWidth;
299 nExtraWidth = 0;
300 nExtraWidth2 = 0;
301 }
302 else
303 {
304 mnItemsWidth += STATUSBAR_OFFSET_X;
305
306 // Bei linksbuendiger Ausrichtung muessen wir gegebenenfalls noch
307 // AutoSize auswerten
308 if ( nAutoSizeItems && (mnDX > (mnItemsWidth - STATUSBAR_OFFSET)) )
309 {
310 nExtraWidth = (mnDX - mnItemsWidth - 1) / nAutoSizeItems;
311 nExtraWidth2 = (mnDX - mnItemsWidth - 1) % nAutoSizeItems;
312 }
313 else
314 {
315 nExtraWidth = 0;
316 nExtraWidth2 = 0;
317 }
318 nX = STATUSBAR_OFFSET_X;
319 if( ImplHasMirroredGraphics() && IsRTLEnabled() )
320 nX += ImplGetSVData()->maNWFData.mnStatusBarLowerRightOffset;
321 }
322
323 pItem = mpItemList->First();
324 while ( pItem )
325 {
326 if ( pItem->mbVisible )
327 {
328 if ( pItem->mnBits & SIB_AUTOSIZE )
329 {
330 pItem->mnExtraWidth = nExtraWidth;
331 if ( nExtraWidth2 )
332 {
333 pItem->mnExtraWidth++;
334 nExtraWidth2--;
335 }
336 }
337 else
338 pItem->mnExtraWidth = 0;
339
340 pItem->mnX = nX;
341 nX += pItem->mnWidth + pItem->mnExtraWidth + pItem->mnOffset;
342 }
343
344 pItem = mpItemList->Next();
345 }
346
347 mbFormat = sal_False;
348 }
349
350 // -----------------------------------------------------------------------
351
ImplGetItemRectPos(sal_uInt16 nPos) const352 Rectangle StatusBar::ImplGetItemRectPos( sal_uInt16 nPos ) const
353 {
354 Rectangle aRect;
355 ImplStatusItem* pItem;
356 pItem = mpItemList->GetObject( nPos );
357 if ( pItem )
358 {
359 if ( pItem->mbVisible )
360 {
361 aRect.Left() = pItem->mnX;
362 aRect.Right() = aRect.Left() + pItem->mnWidth + pItem->mnExtraWidth;
363 aRect.Top() = mnItemY;
364 aRect.Bottom() = mnCalcHeight - STATUSBAR_OFFSET_Y;
365 if( IsTopBorder() )
366 aRect.Bottom()+=2;
367 }
368 }
369
370 return aRect;
371 }
372
373 // -----------------------------------------------------------------------
374
ImplGetFirstVisiblePos() const375 sal_uInt16 StatusBar::ImplGetFirstVisiblePos() const
376 {
377 ImplStatusItem* pItem;
378
379 for( sal_uInt16 nPos = 0; nPos < mpItemList->Count(); nPos++ )
380 {
381 pItem = mpItemList->GetObject( nPos );
382 if ( pItem )
383 {
384 if ( pItem->mbVisible )
385 return nPos;
386 }
387 }
388
389 return ~0;
390 }
391
392 // -----------------------------------------------------------------------
393
ImplDrawText(sal_Bool bOffScreen,long nOldTextWidth)394 void StatusBar::ImplDrawText( sal_Bool bOffScreen, long nOldTextWidth )
395 {
396 // Das ueberschreiben der Item-Box verhindern
397 Rectangle aTextRect;
398 aTextRect.Left() = STATUSBAR_OFFSET_X+1;
399 aTextRect.Top() = mnTextY;
400 if ( mbVisibleItems && (GetStyle() & WB_RIGHT) )
401 aTextRect.Right() = mnDX - mnItemsWidth - 1;
402 else
403 aTextRect.Right() = mnDX - 1;
404 if ( aTextRect.Right() > aTextRect.Left() )
405 {
406 // Position ermitteln
407 XubString aStr = GetText();
408 sal_uInt16 nPos = aStr.Search( _LF );
409 if ( nPos != STRING_NOTFOUND )
410 aStr.Erase( nPos );
411
412 aTextRect.Bottom() = aTextRect.Top()+GetTextHeight()+1;
413
414 if ( bOffScreen )
415 {
416 long nMaxWidth = Max( nOldTextWidth, GetTextWidth( aStr ) );
417 Size aVirDevSize( nMaxWidth, aTextRect.GetHeight() );
418 mpImplData->mpVirDev->SetOutputSizePixel( aVirDevSize );
419 Rectangle aTempRect = aTextRect;
420 aTempRect.SetPos( Point( 0, 0 ) );
421 mpImplData->mpVirDev->DrawText( aTempRect, aStr, TEXT_DRAW_LEFT | TEXT_DRAW_TOP | TEXT_DRAW_CLIP | TEXT_DRAW_ENDELLIPSIS );
422 DrawOutDev( aTextRect.TopLeft(), aVirDevSize, Point(), aVirDevSize, *mpImplData->mpVirDev );
423 }
424 else
425 DrawText( aTextRect, aStr, TEXT_DRAW_LEFT | TEXT_DRAW_TOP | TEXT_DRAW_CLIP | TEXT_DRAW_ENDELLIPSIS );
426 }
427 }
428
429 // -----------------------------------------------------------------------
430
ImplDrawItem(sal_Bool bOffScreen,sal_uInt16 nPos,sal_Bool bDrawText,sal_Bool bDrawFrame)431 void StatusBar::ImplDrawItem( sal_Bool bOffScreen, sal_uInt16 nPos, sal_Bool bDrawText, sal_Bool bDrawFrame )
432 {
433 Rectangle aRect = ImplGetItemRectPos( nPos );
434
435 if ( aRect.IsEmpty() )
436 return;
437
438 // Ausgabebereich berechnen
439 ImplStatusItem* pItem = mpItemList->GetObject( nPos );
440 long nW = mpImplData->mnItemBorderWidth + 1;
441 Rectangle aTextRect( aRect.Left()+nW, aRect.Top()+nW,
442 aRect.Right()-nW, aRect.Bottom()-nW );
443 Size aTextRectSize( aTextRect.GetSize() );
444
445 if ( bOffScreen )
446 mpImplData->mpVirDev->SetOutputSizePixel( aTextRectSize );
447 else
448 {
449 Region aRegion( aTextRect );
450 SetClipRegion( aRegion );
451 }
452
453 // Text ausgeben
454 if ( bDrawText )
455 {
456 Size aTextSize( GetTextWidth( pItem->maText ), GetTextHeight() );
457 Point aTextPos = ImplGetItemTextPos( aTextRectSize, aTextSize, pItem->mnBits );
458 if ( bOffScreen )
459 mpImplData->mpVirDev->DrawText( aTextPos, pItem->maText );
460 else
461 {
462 aTextPos.X() += aTextRect.Left();
463 aTextPos.Y() += aTextRect.Top();
464 DrawText( aTextPos, pItem->maText );
465 }
466 }
467
468 // Gegebenenfalls auch DrawItem aufrufen
469 if ( pItem->mnBits & SIB_USERDRAW )
470 {
471 if ( bOffScreen )
472 {
473 mbInUserDraw = sal_True;
474 mpImplData->mpVirDev->EnableRTL( IsRTLEnabled() );
475 UserDrawEvent aODEvt( mpImplData->mpVirDev, Rectangle( Point(), aTextRectSize ), pItem->mnId );
476 UserDraw( aODEvt );
477 mpImplData->mpVirDev->EnableRTL( sal_False );
478 mbInUserDraw = sal_False;
479 }
480 else
481 {
482 UserDrawEvent aODEvt( this, aTextRect, pItem->mnId );
483 UserDraw( aODEvt );
484 }
485 }
486
487 if ( bOffScreen )
488 DrawOutDev( aTextRect.TopLeft(), aTextRectSize, Point(), aTextRectSize, *mpImplData->mpVirDev );
489 else
490 SetClipRegion();
491
492 // Frame ausgeben
493 if ( bDrawFrame )
494 {
495 if( mpImplData->mbDrawItemFrames )
496 {
497 if( !(pItem->mnBits & SIB_FLAT) )
498 {
499 sal_uInt16 nStyle;
500
501 if ( pItem->mnBits & SIB_IN )
502 nStyle = FRAME_DRAW_IN;
503 else
504 nStyle = FRAME_DRAW_OUT;
505
506 DecorationView aDecoView( this );
507 aDecoView.DrawFrame( aRect, nStyle );
508 }
509 }
510 else if( nPos != ImplGetFirstVisiblePos() )
511 {
512 // draw separator
513 Point aFrom( aRect.TopLeft() );
514 aFrom.X()--;
515 aFrom.Y()++;
516 Point aTo( aRect.BottomLeft() );
517 aTo.X()--;
518 aTo.Y()--;
519
520 DecorationView aDecoView( this );
521 aDecoView.DrawSeparator( aFrom, aTo );
522 }
523 }
524
525 if ( !ImplIsRecordLayout() )
526 ImplCallEventListeners( VCLEVENT_STATUSBAR_DRAWITEM, (void*) sal_IntPtr(pItem->mnId) );
527 }
528
529 // -----------------------------------------------------------------------
530
DrawProgress(Window * pWindow,const Point & rPos,long nOffset,long nPrgsWidth,long nPrgsHeight,sal_uInt16 nPercent1,sal_uInt16 nPercent2,sal_uInt16 nPercentCount,const Rectangle & rFramePosSize)531 void DrawProgress( Window* pWindow, const Point& rPos,
532 long nOffset, long nPrgsWidth, long nPrgsHeight,
533 sal_uInt16 nPercent1, sal_uInt16 nPercent2, sal_uInt16 nPercentCount,
534 const Rectangle& rFramePosSize
535 )
536 {
537 if( pWindow->IsNativeControlSupported( CTRL_PROGRESS, PART_ENTIRE_CONTROL ) )
538 {
539 bool bNeedErase = ImplGetSVData()->maNWFData.mbProgressNeedsErase;
540
541 long nFullWidth = (nPrgsWidth + nOffset) * (10000 / nPercentCount);
542 long nPerc = (nPercent2 > 10000) ? 10000 : nPercent2;
543 ImplControlValue aValue( nFullWidth * (long)nPerc / 10000 );
544 Rectangle aDrawRect( rPos, Size( nFullWidth, nPrgsHeight ) );
545 Rectangle aControlRegion( aDrawRect );
546 if( bNeedErase )
547 {
548 Window* pEraseWindow = pWindow;
549 while( pEraseWindow->IsPaintTransparent() &&
550 ! pEraseWindow->ImplGetWindowImpl()->mbFrame )
551 {
552 pEraseWindow = pEraseWindow->ImplGetWindowImpl()->mpParent;
553 }
554 if( pEraseWindow == pWindow )
555 // restore background of pWindow
556 pEraseWindow->Erase( rFramePosSize );
557 else
558 {
559 // restore transparent background
560 Point aTL( pWindow->OutputToAbsoluteScreenPixel( rFramePosSize.TopLeft() ) );
561 aTL = pEraseWindow->AbsoluteScreenToOutputPixel( aTL );
562 Rectangle aRect( aTL, rFramePosSize.GetSize() );
563 pEraseWindow->Invalidate( aRect, INVALIDATE_NOCHILDREN |
564 INVALIDATE_NOCLIPCHILDREN |
565 INVALIDATE_TRANSPARENT );
566 pEraseWindow->Update();
567 }
568 pWindow->Push( PUSH_CLIPREGION );
569 pWindow->IntersectClipRegion( rFramePosSize );
570 }
571 sal_Bool bNativeOK = pWindow->DrawNativeControl( CTRL_PROGRESS, PART_ENTIRE_CONTROL, aControlRegion,
572 CTRL_STATE_ENABLED, aValue, rtl::OUString() );
573 if( bNeedErase )
574 pWindow->Pop();
575 if( bNativeOK )
576 {
577 pWindow->Flush();
578 return;
579 }
580 }
581
582 // Werte vorberechnen
583 sal_uInt16 nPerc1 = nPercent1 / nPercentCount;
584 sal_uInt16 nPerc2 = nPercent2 / nPercentCount;
585
586 if ( nPerc1 > nPerc2 )
587 {
588 // Support progress that can also decrease
589
590 // Rechteck berechnen
591 long nDX = nPrgsWidth + nOffset;
592 long nLeft = rPos.X()+((nPerc1-1)*nDX);
593 Rectangle aRect( nLeft, rPos.Y(), nLeft+nPrgsWidth, rPos.Y()+nPrgsHeight );
594
595 do
596 {
597 pWindow->Erase( aRect );
598 aRect.Left() -= nDX;
599 aRect.Right() -= nDX;
600 nPerc1--;
601 }
602 while ( nPerc1 > nPerc2 );
603
604 pWindow->Flush();
605 }
606 else if ( nPerc1 < nPerc2 )
607 {
608 // Percent-Rechtecke malen
609 // Wenn Percent2 ueber 100%, Werte anpassen
610 if ( nPercent2 > 10000 )
611 {
612 nPerc2 = 10000 / nPercentCount;
613 if ( nPerc1 >= nPerc2 )
614 nPerc1 = nPerc2-1;
615 }
616
617 // Rechteck berechnen
618 long nDX = nPrgsWidth + nOffset;
619 long nLeft = rPos.X()+(nPerc1*nDX);
620 Rectangle aRect( nLeft, rPos.Y(), nLeft+nPrgsWidth, rPos.Y()+nPrgsHeight );
621
622 do
623 {
624 pWindow->DrawRect( aRect );
625 aRect.Left() += nDX;
626 aRect.Right() += nDX;
627 nPerc1++;
628 }
629 while ( nPerc1 < nPerc2 );
630
631 // Bei mehr als 100%, lassen wir das Rechteck blinken
632 if ( nPercent2 > 10000 )
633 {
634 // an/aus-Status festlegen
635 if ( ((nPercent2 / nPercentCount) & 0x01) == (nPercentCount & 0x01) )
636 {
637 aRect.Left() -= nDX;
638 aRect.Right() -= nDX;
639 pWindow->Erase( aRect );
640 }
641 }
642
643 pWindow->Flush();
644 }
645 }
646
647 // -----------------------------------------------------------------------
648
ImplDrawProgress(sal_Bool bPaint,sal_uInt16 nPercent1,sal_uInt16 nPercent2)649 void StatusBar::ImplDrawProgress( sal_Bool bPaint,
650 sal_uInt16 nPercent1, sal_uInt16 nPercent2 )
651 {
652 bool bNative = IsNativeControlSupported( CTRL_PROGRESS, PART_ENTIRE_CONTROL );
653 // bPaint: draw text also, else only update progress
654 if ( bPaint )
655 {
656 DrawText( maPrgsTxtPos, maPrgsTxt );
657 if( ! bNative )
658 {
659 DecorationView aDecoView( this );
660 aDecoView.DrawFrame( maPrgsFrameRect, FRAME_DRAW_IN );
661 }
662 }
663
664 Point aPos( maPrgsFrameRect.Left()+STATUSBAR_PRGS_OFFSET,
665 maPrgsFrameRect.Top()+STATUSBAR_PRGS_OFFSET );
666 long nPrgsHeight = mnPrgsSize;
667 if( bNative )
668 {
669 aPos = maPrgsFrameRect.TopLeft();
670 nPrgsHeight = maPrgsFrameRect.GetHeight();
671 }
672 DrawProgress( this, aPos, mnPrgsSize/2, mnPrgsSize, nPrgsHeight,
673 nPercent1*100, nPercent2*100, mnPercentCount, maPrgsFrameRect );
674 }
675
676 // -----------------------------------------------------------------------
677
ImplCalcProgressRect()678 void StatusBar::ImplCalcProgressRect()
679 {
680 // calculate text size
681 Size aPrgsTxtSize( GetTextWidth( maPrgsTxt ), GetTextHeight() );
682 maPrgsTxtPos.X() = STATUSBAR_OFFSET_X+1;
683
684 // calculate progress frame
685 maPrgsFrameRect.Left() = maPrgsTxtPos.X()+aPrgsTxtSize.Width()+STATUSBAR_OFFSET;
686 maPrgsFrameRect.Top() = mnItemY;
687 maPrgsFrameRect.Bottom() = mnCalcHeight - STATUSBAR_OFFSET_Y;
688 if( IsTopBorder() )
689 maPrgsFrameRect.Bottom()+=2;
690
691 // calculate size of progress rects
692 mnPrgsSize = maPrgsFrameRect.Bottom()-maPrgsFrameRect.Top()-(STATUSBAR_PRGS_OFFSET*2);
693 sal_uInt16 nMaxPercent = STATUSBAR_PRGS_COUNT;
694
695 long nMaxWidth = mnDX-STATUSBAR_OFFSET-1;
696
697 // make smaller if there are too many rects
698 while ( maPrgsFrameRect.Left()+ImplCalcProgessWidth( nMaxPercent, mnPrgsSize ) > nMaxWidth )
699 {
700 nMaxPercent--;
701 if ( nMaxPercent <= STATUSBAR_PRGS_MIN )
702 break;
703 }
704 maPrgsFrameRect.Right() = maPrgsFrameRect.Left() + ImplCalcProgessWidth( nMaxPercent, mnPrgsSize );
705
706 // save the divisor for later
707 mnPercentCount = 10000 / nMaxPercent;
708 sal_Bool bNativeOK = sal_False;
709 if( IsNativeControlSupported( CTRL_PROGRESS, PART_ENTIRE_CONTROL ) )
710 {
711 ImplControlValue aValue;
712 Rectangle aControlRegion( Rectangle( (const Point&)Point(), maPrgsFrameRect.GetSize() ) );
713 Rectangle aNativeControlRegion, aNativeContentRegion;
714 if( (bNativeOK = GetNativeControlRegion( CTRL_PROGRESS, PART_ENTIRE_CONTROL, aControlRegion,
715 CTRL_STATE_ENABLED, aValue, rtl::OUString(),
716 aNativeControlRegion, aNativeContentRegion ) ) != sal_False )
717 {
718 long nProgressHeight = aNativeControlRegion.GetHeight();
719 if( nProgressHeight > maPrgsFrameRect.GetHeight() )
720 {
721 long nDelta = nProgressHeight - maPrgsFrameRect.GetHeight();
722 maPrgsFrameRect.Top() -= (nDelta - nDelta/2);
723 maPrgsFrameRect.Bottom() += nDelta/2;
724 }
725 maPrgsTxtPos.Y() = maPrgsFrameRect.Top() + (nProgressHeight - GetTextHeight())/2;
726 }
727 }
728 if( ! bNativeOK )
729 maPrgsTxtPos.Y() = mnTextY;
730 }
731
732 // -----------------------------------------------------------------------
733
MouseButtonDown(const MouseEvent & rMEvt)734 void StatusBar::MouseButtonDown( const MouseEvent& rMEvt )
735 {
736 // Nur bei linker Maustaste ToolBox ausloesen
737 if ( rMEvt.IsLeft() )
738 {
739 if ( mbVisibleItems )
740 {
741 Point aMousePos = rMEvt.GetPosPixel();
742 sal_uInt16 i = 0;
743
744 // Item suchen, das geklickt wurde
745 ImplStatusItem* pItem = mpItemList->First();
746 while ( pItem )
747 {
748 // Ist es dieses Item
749 if ( ImplGetItemRectPos( i ).IsInside( aMousePos ) )
750 {
751 mnCurItemId = pItem->mnId;
752 if ( rMEvt.GetClicks() == 2 )
753 DoubleClick();
754 else
755 Click();
756 mnCurItemId = 0;
757
758 // Item wurde gefunden
759 return;
760 }
761
762 i++;
763 pItem = mpItemList->Next();
764 }
765 }
766
767 // Kein Item, dann nur Click oder DoubleClick
768 if ( rMEvt.GetClicks() == 2 )
769 DoubleClick();
770 else
771 Click();
772 }
773 }
774
775 // -----------------------------------------------------------------------
776
Paint(const Rectangle &)777 void StatusBar::Paint( const Rectangle& )
778 {
779 if ( mbFormat )
780 ImplFormat();
781
782 sal_uInt16 nItemCount = (sal_uInt16)mpItemList->Count();
783
784 if ( mbProgressMode )
785 ImplDrawProgress( sal_True, 0, mnPercent );
786 else
787 {
788 // Text zeichen
789 if ( !mbVisibleItems || (GetStyle() & WB_RIGHT) )
790 ImplDrawText( sal_False, 0 );
791
792 // Items zeichnen
793 if ( mbVisibleItems )
794 {
795 // Items zeichnen
796 for ( sal_uInt16 i = 0; i < nItemCount; i++ )
797 ImplDrawItem( sal_False, i, sal_True, sal_True );
798 }
799 }
800
801 // draw borders
802 if( IsTopBorder() )
803 {
804 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
805 SetLineColor( rStyleSettings.GetShadowColor() );
806 DrawLine( Point( 0, 0 ), Point( mnDX-1, 0 ) );
807 SetLineColor( rStyleSettings.GetLightColor() );
808 DrawLine( Point( 0, 1 ), Point( mnDX-1, 1 ) );
809 }
810
811 if ( IsBottomBorder() )
812 {
813 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
814 SetLineColor( rStyleSettings.GetShadowColor() );
815 DrawLine( Point( 0, mnDY-2 ), Point( mnDX-1, mnDY-2 ) );
816 SetLineColor( rStyleSettings.GetLightColor() );
817 DrawLine( Point( 0, mnDY-1 ), Point( mnDX-1, mnDY-1 ) );
818 }
819 }
820
821 // -----------------------------------------------------------------------
822
Move()823 void StatusBar::Move()
824 {
825 Window::Move();
826 }
827
828 // -----------------------------------------------------------------------
829
Resize()830 void StatusBar::Resize()
831 {
832 // Breite und Hoehe abfragen und merken
833 Size aSize = GetOutputSizePixel();
834 mnDX = aSize.Width() - ImplGetSVData()->maNWFData.mnStatusBarLowerRightOffset;
835 mnDY = aSize.Height();
836 mnCalcHeight = mnDY;
837 // subtract border
838 if( IsTopBorder() )
839 mnCalcHeight -= 2;
840 if ( IsBottomBorder() )
841 mnCalcHeight -= 2;
842
843 mnItemY = STATUSBAR_OFFSET_Y;
844 if( IsTopBorder() )
845 mnItemY += 2;
846 mnTextY = (mnCalcHeight-GetTextHeight())/2;
847 if( IsTopBorder() )
848 mnTextY += 2;
849
850 // Formatierung neu ausloesen
851 mbFormat = sal_True;
852
853 if ( mbProgressMode )
854 ImplCalcProgressRect();
855
856 Invalidate();
857 }
858
859 // -----------------------------------------------------------------------
860
RequestHelp(const HelpEvent & rHEvt)861 void StatusBar::RequestHelp( const HelpEvent& rHEvt )
862 {
863 // no keyboard help in status bar
864 if( rHEvt.KeyboardActivated() )
865 return;
866
867 sal_uInt16 nItemId = GetItemId( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ) );
868
869 if ( nItemId )
870 {
871 Rectangle aItemRect = GetItemRect( nItemId );
872 Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
873 aItemRect.Left() = aPt.X();
874 aItemRect.Top() = aPt.Y();
875 aPt = OutputToScreenPixel( aItemRect.BottomRight() );
876 aItemRect.Right() = aPt.X();
877 aItemRect.Bottom() = aPt.Y();
878
879 if ( rHEvt.GetMode() & HELPMODE_BALLOON )
880 {
881 XubString aStr = GetHelpText( nItemId );
882 Help::ShowBalloon( this, aItemRect.Center(), aItemRect, aStr );
883 return;
884 }
885 else if ( rHEvt.GetMode() & HELPMODE_QUICK )
886 {
887 XubString aStr = GetQuickHelpText( nItemId );
888 // Show quickhelp if available
889 if( aStr.Len() )
890 {
891 Help::ShowQuickHelp( this, aItemRect, aStr );
892 return;
893 }
894 aStr = GetItemText( nItemId );
895 // show a quick help if item text doesn't fit
896 if ( GetTextWidth( aStr ) > aItemRect.GetWidth() )
897 {
898 Help::ShowQuickHelp( this, aItemRect, aStr );
899 return;
900 }
901 }
902 else if ( rHEvt.GetMode() & HELPMODE_EXTENDED )
903 {
904 String aCommand = GetItemCommand( nItemId );
905 rtl::OString aHelpId( GetHelpId( nItemId ) );
906
907 if ( aCommand.Len() || aHelpId.getLength() )
908 {
909 // Wenn eine Hilfe existiert, dann ausloesen
910 Help* pHelp = Application::GetHelp();
911 if ( pHelp )
912 {
913 if ( aCommand.Len() )
914 pHelp->Start( aCommand, this );
915 else if ( aHelpId.getLength() )
916 pHelp->Start( rtl::OStringToOUString( aHelpId, RTL_TEXTENCODING_UTF8 ), this );
917 }
918 return;
919 }
920 }
921 }
922
923 Window::RequestHelp( rHEvt );
924 }
925
926 // -----------------------------------------------------------------------
927
StateChanged(StateChangedType nType)928 void StatusBar::StateChanged( StateChangedType nType )
929 {
930 Window::StateChanged( nType );
931
932 if ( nType == STATE_CHANGE_INITSHOW )
933 ImplFormat();
934 else if ( nType == STATE_CHANGE_UPDATEMODE )
935 Invalidate();
936 else if ( (nType == STATE_CHANGE_ZOOM) ||
937 (nType == STATE_CHANGE_CONTROLFONT) )
938 {
939 mbFormat = sal_True;
940 ImplInitSettings( sal_True, sal_False, sal_False );
941 Invalidate();
942 }
943 else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
944 {
945 ImplInitSettings( sal_False, sal_True, sal_False );
946 Invalidate();
947 }
948 else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
949 {
950 ImplInitSettings( sal_False, sal_False, sal_True );
951 Invalidate();
952 }
953 }
954
955 // -----------------------------------------------------------------------
956
DataChanged(const DataChangedEvent & rDCEvt)957 void StatusBar::DataChanged( const DataChangedEvent& rDCEvt )
958 {
959 Window::DataChanged( rDCEvt );
960
961 if ( (rDCEvt.GetType() == DATACHANGED_DISPLAY) ||
962 (rDCEvt.GetType() == DATACHANGED_FONTS) ||
963 (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
964 ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
965 (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
966 {
967 mbFormat = sal_True;
968 ImplInitSettings( sal_True, sal_True, sal_True );
969 ImplStatusItem* pItem = mpItemList->First();
970 long nFudge = GetTextHeight() / 4;
971 while ( pItem )
972 {
973 long nWidth = GetTextWidth( pItem->maText ) + nFudge;
974 if( nWidth > pItem->mnWidth + STATUSBAR_OFFSET )
975 pItem->mnWidth = nWidth + STATUSBAR_OFFSET;
976 pItem = mpItemList->Next();
977 }
978 Size aSize = GetSizePixel();
979 // do not disturb current width, since
980 // CalcWindowSizePixel calculates a minimum width
981 aSize.Height() = CalcWindowSizePixel().Height();
982 SetSizePixel( aSize );
983 Invalidate();
984 }
985 }
986
987 // -----------------------------------------------------------------------
988
Click()989 void StatusBar::Click()
990 {
991 ImplCallEventListeners( VCLEVENT_STATUSBAR_CLICK );
992 maClickHdl.Call( this );
993 }
994
995 // -----------------------------------------------------------------------
996
DoubleClick()997 void StatusBar::DoubleClick()
998 {
999 ImplCallEventListeners( VCLEVENT_STATUSBAR_DOUBLECLICK );
1000 maDoubleClickHdl.Call( this );
1001 }
1002
1003 // -----------------------------------------------------------------------
1004
UserDraw(const UserDrawEvent &)1005 void StatusBar::UserDraw( const UserDrawEvent& )
1006 {
1007 }
1008
1009 // -----------------------------------------------------------------------
1010
InsertItem(sal_uInt16 nItemId,sal_uLong nWidth,StatusBarItemBits nBits,long nOffset,sal_uInt16 nPos)1011 void StatusBar::InsertItem( sal_uInt16 nItemId, sal_uLong nWidth,
1012 StatusBarItemBits nBits,
1013 long nOffset, sal_uInt16 nPos )
1014 {
1015 DBG_ASSERT( nItemId, "StatusBar::InsertItem(): ItemId == 0" );
1016 DBG_ASSERT( GetItemPos( nItemId ) == STATUSBAR_ITEM_NOTFOUND,
1017 "StatusBar::InsertItem(): ItemId already exists" );
1018
1019 // IN und CENTER sind Default
1020 if ( !(nBits & (SIB_IN | SIB_OUT | SIB_FLAT)) )
1021 nBits |= SIB_IN;
1022 if ( !(nBits & (SIB_LEFT | SIB_RIGHT | SIB_CENTER)) )
1023 nBits |= SIB_CENTER;
1024
1025 // Item anlegen
1026 long nFudge = GetTextHeight()/4;
1027 ImplStatusItem* pItem = new ImplStatusItem;
1028 pItem->mnId = nItemId;
1029 pItem->mnBits = nBits;
1030 pItem->mnWidth = (long)nWidth+nFudge+STATUSBAR_OFFSET;
1031 pItem->mnOffset = nOffset;
1032 pItem->mpUserData = 0;
1033 pItem->mbVisible = sal_True;
1034
1035 // Item in die Liste einfuegen
1036 mpItemList->Insert( pItem, nPos );
1037
1038 mbFormat = sal_True;
1039 if ( ImplIsItemUpdate() )
1040 Invalidate();
1041
1042 ImplCallEventListeners( VCLEVENT_STATUSBAR_ITEMADDED, (void*) sal_IntPtr(nItemId) );
1043 }
1044
1045 // -----------------------------------------------------------------------
1046
RemoveItem(sal_uInt16 nItemId)1047 void StatusBar::RemoveItem( sal_uInt16 nItemId )
1048 {
1049 sal_uInt16 nPos = GetItemPos( nItemId );
1050 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1051 {
1052 ImplStatusItem* pItem = mpItemList->Remove( nPos );
1053 delete pItem;
1054
1055 mbFormat = sal_True;
1056 if ( ImplIsItemUpdate() )
1057 Invalidate();
1058
1059 ImplCallEventListeners( VCLEVENT_STATUSBAR_ITEMREMOVED, (void*) sal_IntPtr(nItemId) );
1060 }
1061 }
1062
1063 // -----------------------------------------------------------------------
1064
ShowItem(sal_uInt16 nItemId)1065 void StatusBar::ShowItem( sal_uInt16 nItemId )
1066 {
1067 sal_uInt16 nPos = GetItemPos( nItemId );
1068
1069 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1070 {
1071 ImplStatusItem* pItem = mpItemList->GetObject( nPos );
1072 if ( !pItem->mbVisible )
1073 {
1074 pItem->mbVisible = sal_True;
1075
1076 mbFormat = sal_True;
1077 if ( ImplIsItemUpdate() )
1078 Invalidate();
1079
1080 ImplCallEventListeners( VCLEVENT_STATUSBAR_SHOWITEM, (void*) sal_IntPtr(nItemId) );
1081 }
1082 }
1083 }
1084
1085 // -----------------------------------------------------------------------
1086
HideItem(sal_uInt16 nItemId)1087 void StatusBar::HideItem( sal_uInt16 nItemId )
1088 {
1089 sal_uInt16 nPos = GetItemPos( nItemId );
1090
1091 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1092 {
1093 ImplStatusItem* pItem = mpItemList->GetObject( nPos );
1094 if ( pItem->mbVisible )
1095 {
1096 pItem->mbVisible = sal_False;
1097
1098 mbFormat = sal_True;
1099 if ( ImplIsItemUpdate() )
1100 Invalidate();
1101
1102 ImplCallEventListeners( VCLEVENT_STATUSBAR_HIDEITEM, (void*) sal_IntPtr(nItemId) );
1103 }
1104 }
1105 }
1106
1107 // -----------------------------------------------------------------------
1108
IsItemVisible(sal_uInt16 nItemId) const1109 sal_Bool StatusBar::IsItemVisible( sal_uInt16 nItemId ) const
1110 {
1111 sal_uInt16 nPos = GetItemPos( nItemId );
1112
1113 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1114 return mpItemList->GetObject( nPos )->mbVisible;
1115 else
1116 return sal_False;
1117 }
1118
1119 // -----------------------------------------------------------------------
1120
ShowItems()1121 void StatusBar::ShowItems()
1122 {
1123 if ( !mbVisibleItems )
1124 {
1125 mbVisibleItems = sal_True;
1126 if ( !mbProgressMode )
1127 Invalidate();
1128
1129 ImplCallEventListeners( VCLEVENT_STATUSBAR_SHOWALLITEMS );
1130 }
1131 }
1132
1133 // -----------------------------------------------------------------------
1134
HideItems()1135 void StatusBar::HideItems()
1136 {
1137 if ( mbVisibleItems )
1138 {
1139 mbVisibleItems = sal_False;
1140 if ( !mbProgressMode )
1141 Invalidate();
1142
1143 ImplCallEventListeners( VCLEVENT_STATUSBAR_HIDEALLITEMS );
1144 }
1145 }
1146
1147 // -----------------------------------------------------------------------
1148
CopyItems(const StatusBar & rStatusBar)1149 void StatusBar::CopyItems( const StatusBar& rStatusBar )
1150 {
1151 // Alle Items entfernen
1152 ImplStatusItem* pItem = mpItemList->First();
1153 while ( pItem )
1154 {
1155 delete pItem;
1156 pItem = mpItemList->Next();
1157 }
1158
1159 // Items aus der Liste loeschen
1160 mpItemList->Clear();
1161
1162 // Items kopieren
1163 sal_uLong i = 0;
1164 pItem = rStatusBar.mpItemList->GetObject( i );
1165 while ( pItem )
1166 {
1167 mpItemList->Insert( new ImplStatusItem( *pItem ), LIST_APPEND );
1168 i++;
1169 pItem = rStatusBar.mpItemList->GetObject( i );
1170 }
1171
1172 mbFormat = sal_True;
1173 if ( ImplIsItemUpdate() )
1174 Invalidate();
1175 }
1176
1177 // -----------------------------------------------------------------------
1178
Clear()1179 void StatusBar::Clear()
1180 {
1181 // Alle Item loeschen
1182 ImplStatusItem* pItem = mpItemList->First();
1183 while ( pItem )
1184 {
1185 delete pItem;
1186 pItem = mpItemList->Next();
1187 }
1188
1189 // Items aus der Liste loeschen
1190 mpItemList->Clear();
1191
1192 mbFormat = sal_True;
1193 if ( ImplIsItemUpdate() )
1194 Invalidate();
1195
1196 ImplCallEventListeners( VCLEVENT_STATUSBAR_ALLITEMSREMOVED );
1197 }
1198
1199 // -----------------------------------------------------------------------
1200
GetItemCount() const1201 sal_uInt16 StatusBar::GetItemCount() const
1202 {
1203 return (sal_uInt16)mpItemList->Count();
1204 }
1205
1206 // -----------------------------------------------------------------------
1207
GetItemId(sal_uInt16 nPos) const1208 sal_uInt16 StatusBar::GetItemId( sal_uInt16 nPos ) const
1209 {
1210 ImplStatusItem* pItem = mpItemList->GetObject( nPos );
1211 if ( pItem )
1212 return pItem->mnId;
1213 else
1214 return 0;
1215 }
1216
1217 // -----------------------------------------------------------------------
1218
GetItemPos(sal_uInt16 nItemId) const1219 sal_uInt16 StatusBar::GetItemPos( sal_uInt16 nItemId ) const
1220 {
1221 ImplStatusItem* pItem = mpItemList->First();
1222 while ( pItem )
1223 {
1224 if ( pItem->mnId == nItemId )
1225 return (sal_uInt16)mpItemList->GetCurPos();
1226
1227 pItem = mpItemList->Next();
1228 }
1229
1230 return STATUSBAR_ITEM_NOTFOUND;
1231 }
1232
1233 // -----------------------------------------------------------------------
1234
GetItemId(const Point & rPos) const1235 sal_uInt16 StatusBar::GetItemId( const Point& rPos ) const
1236 {
1237 if ( AreItemsVisible() && !mbFormat )
1238 {
1239 sal_uInt16 nItemCount = GetItemCount();
1240 sal_uInt16 nPos;
1241 for ( nPos = 0; nPos < nItemCount; nPos++ )
1242 {
1243 // Rechteck holen
1244 Rectangle aRect = ImplGetItemRectPos( nPos );
1245 if ( aRect.IsInside( rPos ) )
1246 return mpItemList->GetObject( nPos )->mnId;
1247 }
1248 }
1249
1250 return 0;
1251 }
1252
1253 // -----------------------------------------------------------------------
1254
GetItemRect(sal_uInt16 nItemId) const1255 Rectangle StatusBar::GetItemRect( sal_uInt16 nItemId ) const
1256 {
1257 Rectangle aRect;
1258
1259 if ( AreItemsVisible() && !mbFormat )
1260 {
1261 sal_uInt16 nPos = GetItemPos( nItemId );
1262 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1263 {
1264 // Rechteck holen und Rahmen abziehen
1265 aRect = ImplGetItemRectPos( nPos );
1266 long nW = mpImplData->mnItemBorderWidth+1;
1267 aRect.Top() += nW-1;
1268 aRect.Bottom() -= nW-1;
1269 aRect.Left() += nW;
1270 aRect.Right() -= nW;
1271 return aRect;
1272 }
1273 }
1274
1275 return aRect;
1276 }
1277
1278 // -----------------------------------------------------------------------
1279
GetItemTextPos(sal_uInt16 nItemId) const1280 Point StatusBar::GetItemTextPos( sal_uInt16 nItemId ) const
1281 {
1282 if ( !mbFormat )
1283 {
1284 sal_uInt16 nPos = GetItemPos( nItemId );
1285 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1286 {
1287 // Rechteck holen
1288 ImplStatusItem* pItem = mpItemList->GetObject( nPos );
1289 Rectangle aRect = ImplGetItemRectPos( nPos );
1290 long nW = mpImplData->mnItemBorderWidth + 1;
1291 Rectangle aTextRect( aRect.Left()+nW, aRect.Top()+nW,
1292 aRect.Right()-nW, aRect.Bottom()-nW );
1293 Point aPos = ImplGetItemTextPos( aTextRect.GetSize(),
1294 Size( GetTextWidth( pItem->maText ), GetTextHeight() ),
1295 pItem->mnBits );
1296 if ( !mbInUserDraw )
1297 {
1298 aPos.X() += aTextRect.Left();
1299 aPos.Y() += aTextRect.Top();
1300 }
1301 return aPos;
1302 }
1303 }
1304
1305 return Point();
1306 }
1307
1308 // -----------------------------------------------------------------------
1309
GetItemWidth(sal_uInt16 nItemId) const1310 sal_uLong StatusBar::GetItemWidth( sal_uInt16 nItemId ) const
1311 {
1312 sal_uInt16 nPos = GetItemPos( nItemId );
1313
1314 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1315 return mpItemList->GetObject( nPos )->mnWidth;
1316 else
1317 return 0;
1318 }
1319
1320 // -----------------------------------------------------------------------
1321
GetItemBits(sal_uInt16 nItemId) const1322 StatusBarItemBits StatusBar::GetItemBits( sal_uInt16 nItemId ) const
1323 {
1324 sal_uInt16 nPos = GetItemPos( nItemId );
1325
1326 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1327 return mpItemList->GetObject( nPos )->mnBits;
1328 else
1329 return 0;
1330 }
1331
1332 // -----------------------------------------------------------------------
1333
GetItemOffset(sal_uInt16 nItemId) const1334 long StatusBar::GetItemOffset( sal_uInt16 nItemId ) const
1335 {
1336 sal_uInt16 nPos = GetItemPos( nItemId );
1337
1338 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1339 return mpItemList->GetObject( nPos )->mnOffset;
1340 else
1341 return 0;
1342 }
1343
1344 // -----------------------------------------------------------------------
1345
SetItemText(sal_uInt16 nItemId,const XubString & rText)1346 void StatusBar::SetItemText( sal_uInt16 nItemId, const XubString& rText )
1347 {
1348 sal_uInt16 nPos = GetItemPos( nItemId );
1349
1350 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1351 {
1352 ImplStatusItem* pItem = mpItemList->GetObject( nPos );
1353
1354 if ( pItem->maText != rText )
1355 {
1356 pItem->maText = rText;
1357
1358 // adjust item width - see also DataChanged()
1359 long nFudge = GetTextHeight()/4;
1360 long nWidth = GetTextWidth( pItem->maText ) + nFudge;
1361 if( (nWidth > pItem->mnWidth + STATUSBAR_OFFSET) ||
1362 ((nWidth < pItem->mnWidth) && (mnDX - STATUSBAR_OFFSET) < mnItemsWidth ))
1363 {
1364 pItem->mnWidth = nWidth + STATUSBAR_OFFSET;
1365 ImplFormat();
1366 Invalidate();
1367 }
1368
1369 // Item neu Zeichen, wenn StatusBar sichtbar und
1370 // UpdateMode gesetzt ist
1371 if ( pItem->mbVisible && !mbFormat && ImplIsItemUpdate() )
1372 {
1373 Update();
1374 ImplDrawItem( sal_True, nPos, sal_True, sal_False );
1375 Flush();
1376 }
1377 }
1378 }
1379 }
1380
1381 // -----------------------------------------------------------------------
1382
GetItemText(sal_uInt16 nItemId) const1383 const XubString& StatusBar::GetItemText( sal_uInt16 nItemId ) const
1384 {
1385 sal_uInt16 nPos = GetItemPos( nItemId );
1386
1387 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1388 return mpItemList->GetObject( nPos )->maText;
1389 else
1390 return ImplGetSVEmptyStr();
1391 }
1392
1393 // -----------------------------------------------------------------------
1394
SetItemCommand(sal_uInt16 nItemId,const XubString & rCommand)1395 void StatusBar::SetItemCommand( sal_uInt16 nItemId, const XubString& rCommand )
1396 {
1397 sal_uInt16 nPos = GetItemPos( nItemId );
1398
1399 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1400 {
1401 ImplStatusItem* pItem = mpItemList->GetObject( nPos );
1402
1403 if ( pItem->maCommand != rCommand )
1404 pItem->maCommand = rCommand;
1405 }
1406 }
1407
1408 // -----------------------------------------------------------------------
1409
GetItemCommand(sal_uInt16 nItemId)1410 const XubString& StatusBar::GetItemCommand( sal_uInt16 nItemId )
1411 {
1412 sal_uInt16 nPos = GetItemPos( nItemId );
1413
1414 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1415 return mpItemList->GetObject( nPos )->maCommand;
1416 else
1417 return ImplGetSVEmptyStr();
1418 }
1419
1420 // -----------------------------------------------------------------------
1421
SetItemData(sal_uInt16 nItemId,void * pNewData)1422 void StatusBar::SetItemData( sal_uInt16 nItemId, void* pNewData )
1423 {
1424 sal_uInt16 nPos = GetItemPos( nItemId );
1425
1426 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1427 {
1428 ImplStatusItem* pItem = mpItemList->GetObject( nPos );
1429 pItem->mpUserData = pNewData;
1430
1431 // Wenn es ein User-Item ist, DrawItem-Aufrufen
1432 if ( (pItem->mnBits & SIB_USERDRAW) && pItem->mbVisible &&
1433 !mbFormat && ImplIsItemUpdate() )
1434 {
1435 Update();
1436 ImplDrawItem( sal_True, nPos, sal_False, sal_False );
1437 Flush();
1438 }
1439 }
1440 }
1441
RedrawItem(sal_uInt16 nItemId)1442 void StatusBar::RedrawItem( sal_uInt16 nItemId )
1443 {
1444 if ( mbFormat )
1445 return;
1446
1447 sal_uInt16 nPos = GetItemPos( nItemId );
1448 if ( nPos == STATUSBAR_ITEM_NOTFOUND )
1449 return;
1450
1451 ImplStatusItem* pItem = mpItemList->GetObject( nPos );
1452 if ( pItem && (pItem->mnBits & SIB_USERDRAW) &&
1453 pItem->mbVisible && ImplIsItemUpdate() )
1454 {
1455 Update();
1456 ImplDrawItem( sal_True, nPos, sal_False, sal_False );
1457 Flush();
1458 }
1459 }
1460
1461 // -----------------------------------------------------------------------
1462
GetItemData(sal_uInt16 nItemId) const1463 void* StatusBar::GetItemData( sal_uInt16 nItemId ) const
1464 {
1465 sal_uInt16 nPos = GetItemPos( nItemId );
1466
1467 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1468 return mpItemList->GetObject( nPos )->mpUserData;
1469 else
1470 return NULL;
1471 }
1472
1473 // -----------------------------------------------------------------------
1474
SetHelpText(sal_uInt16 nItemId,const XubString & rText)1475 void StatusBar::SetHelpText( sal_uInt16 nItemId, const XubString& rText )
1476 {
1477 sal_uInt16 nPos = GetItemPos( nItemId );
1478
1479 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1480 mpItemList->GetObject( nPos )->maHelpText = rText;
1481 }
1482
1483 // -----------------------------------------------------------------------
1484
GetHelpText(sal_uInt16 nItemId) const1485 const XubString& StatusBar::GetHelpText( sal_uInt16 nItemId ) const
1486 {
1487 sal_uInt16 nPos = GetItemPos( nItemId );
1488
1489 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1490 {
1491 ImplStatusItem* pItem = mpItemList->GetObject( nPos );
1492 if ( !pItem->maHelpText.Len() && ( pItem->maHelpId.getLength() || pItem->maCommand.Len() ))
1493 {
1494 Help* pHelp = Application::GetHelp();
1495 if ( pHelp )
1496 {
1497 if ( pItem->maCommand.Len() )
1498 pItem->maHelpText = pHelp->GetHelpText( pItem->maCommand, this );
1499 if ( !pItem->maHelpText.Len() && pItem->maHelpId.getLength() )
1500 pItem->maHelpText = pHelp->GetHelpText( rtl::OStringToOUString( pItem->maHelpId, RTL_TEXTENCODING_UTF8 ), this );
1501 }
1502 }
1503
1504 return pItem->maHelpText;
1505 }
1506 else
1507 return ImplGetSVEmptyStr();
1508 }
1509
1510 // -----------------------------------------------------------------------
1511
SetQuickHelpText(sal_uInt16 nItemId,const XubString & rText)1512 void StatusBar::SetQuickHelpText( sal_uInt16 nItemId, const XubString& rText )
1513 {
1514 sal_uInt16 nPos = GetItemPos( nItemId );
1515
1516 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1517 mpItemList->GetObject( nPos )->maQuickHelpText = rText;
1518 }
1519
1520 // -----------------------------------------------------------------------
1521
GetQuickHelpText(sal_uInt16 nItemId) const1522 const XubString& StatusBar::GetQuickHelpText( sal_uInt16 nItemId ) const
1523 {
1524 sal_uInt16 nPos = GetItemPos( nItemId );
1525
1526 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1527 {
1528 ImplStatusItem* pItem = mpItemList->GetObject( nPos );
1529 return pItem->maQuickHelpText;
1530 }
1531 else
1532 return ImplGetSVEmptyStr();
1533 }
1534
1535 // -----------------------------------------------------------------------
1536
SetHelpId(sal_uInt16 nItemId,const rtl::OString & rHelpId)1537 void StatusBar::SetHelpId( sal_uInt16 nItemId, const rtl::OString& rHelpId )
1538 {
1539 sal_uInt16 nPos = GetItemPos( nItemId );
1540
1541 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1542 mpItemList->GetObject( nPos )->maHelpId = rHelpId;
1543 }
1544
1545 // -----------------------------------------------------------------------
1546
GetHelpId(sal_uInt16 nItemId) const1547 rtl::OString StatusBar::GetHelpId( sal_uInt16 nItemId ) const
1548 {
1549 sal_uInt16 nPos = GetItemPos( nItemId );
1550
1551 rtl::OString aRet;
1552 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1553 {
1554 ImplStatusItem* pItem = mpItemList->GetObject( nPos );
1555 if ( pItem->maHelpId.getLength() )
1556 aRet = pItem->maHelpId;
1557 else
1558 aRet = ::rtl::OUStringToOString( pItem->maCommand, RTL_TEXTENCODING_UTF8 );
1559 }
1560
1561 return aRet;
1562 }
1563
1564 // -----------------------------------------------------------------------
1565
ImplCalcBorder()1566 void StatusBar::ImplCalcBorder( )
1567 {
1568 mnCalcHeight = mnDY;
1569 // subtract border
1570 if( IsTopBorder() )
1571 {
1572 mnCalcHeight -= 2;
1573 mnTextY += 2;
1574 mnItemY += 2;
1575 }
1576 if ( IsBottomBorder() )
1577 mnCalcHeight -= 2;
1578 mbFormat = sal_True;
1579 Invalidate();
1580 }
1581
SetBottomBorder(sal_Bool bBottomBorder)1582 void StatusBar::SetBottomBorder( sal_Bool bBottomBorder )
1583 {
1584 if ( mbBottomBorder != bBottomBorder )
1585 {
1586 mbBottomBorder = bBottomBorder;
1587 ImplCalcBorder();
1588 }
1589 }
1590
SetTopBorder(sal_Bool bTopBorder)1591 void StatusBar::SetTopBorder( sal_Bool bTopBorder )
1592 {
1593 if ( mpImplData->mbTopBorder != static_cast<bool>(bTopBorder) )
1594 {
1595 mpImplData->mbTopBorder = static_cast<bool>(bTopBorder);
1596 ImplCalcBorder();
1597 }
1598 }
1599
IsTopBorder() const1600 sal_Bool StatusBar::IsTopBorder() const
1601 {
1602 return mpImplData->mbTopBorder;
1603 }
1604
1605 // -----------------------------------------------------------------------
1606
StartProgressMode(const XubString & rText)1607 void StatusBar::StartProgressMode( const XubString& rText )
1608 {
1609 DBG_ASSERT( !mbProgressMode, "StatusBar::StartProgressMode(): progress mode is active" );
1610
1611 mbProgressMode = sal_True;
1612 mnPercent = 0;
1613 maPrgsTxt = rText;
1614
1615 // Groessen berechnen
1616 ImplCalcProgressRect();
1617
1618 // Paint ausloesen (dort wird der Text und der Frame gemalt)
1619 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1620 Color aPrgsColor = rStyleSettings.GetHighlightColor();
1621 if ( aPrgsColor == rStyleSettings.GetFaceColor() )
1622 aPrgsColor = rStyleSettings.GetDarkShadowColor();
1623 SetLineColor();
1624 SetFillColor( aPrgsColor );
1625 if ( IsReallyVisible() )
1626 {
1627 Invalidate();
1628 Update();
1629 Flush();
1630 }
1631 }
1632
1633 // -----------------------------------------------------------------------
1634
SetProgressValue(sal_uInt16 nNewPercent)1635 void StatusBar::SetProgressValue( sal_uInt16 nNewPercent )
1636 {
1637 DBG_ASSERT( mbProgressMode, "StatusBar::SetProgressValue(): no progrss mode" );
1638 DBG_ASSERTWARNING( nNewPercent <= 100, "StatusBar::SetProgressValue(): nPercent > 100" );
1639
1640 if ( mbProgressMode
1641 && IsReallyVisible()
1642 && (!mnPercent || (mnPercent != nNewPercent)) )
1643 {
1644 Update();
1645 SetLineColor();
1646 ImplDrawProgress( sal_False, mnPercent, nNewPercent );
1647 Flush();
1648 }
1649 mnPercent = nNewPercent;
1650 }
1651
1652 // -----------------------------------------------------------------------
1653
EndProgressMode()1654 void StatusBar::EndProgressMode()
1655 {
1656 DBG_ASSERT( mbProgressMode, "StatusBar::EndProgressMode(): no progress mode" );
1657
1658 mbProgressMode = sal_False;
1659 maPrgsTxt.Erase();
1660
1661 // Paint neu ausloesen um StatusBar wieder herzustellen
1662 SetFillColor( GetSettings().GetStyleSettings().GetFaceColor() );
1663 if ( IsReallyVisible() )
1664 {
1665 Invalidate();
1666 Update();
1667 Flush();
1668 }
1669 }
1670
1671 // -----------------------------------------------------------------------
1672
ResetProgressMode()1673 void StatusBar::ResetProgressMode()
1674 {
1675 if ( mbProgressMode )
1676 {
1677 mnPercent = 0;
1678 maPrgsTxt.Erase();
1679 if ( IsReallyVisible() )
1680 {
1681 Invalidate();
1682 Update();
1683 Flush();
1684 }
1685 }
1686 }
1687
1688 // -----------------------------------------------------------------------
1689
SetText(const XubString & rText)1690 void StatusBar::SetText( const XubString& rText )
1691 {
1692 if ( (!mbVisibleItems || (GetStyle() & WB_RIGHT)) && !mbProgressMode &&
1693 IsReallyVisible() && IsUpdateMode() )
1694 {
1695 if ( mbFormat )
1696 {
1697 Invalidate();
1698 Window::SetText( rText );
1699 }
1700 else
1701 {
1702 Update();
1703 long nOldTextWidth = GetTextWidth( GetText() );
1704 Window::SetText( rText );
1705 ImplDrawText( sal_True, nOldTextWidth );
1706 Flush();
1707 }
1708 }
1709 else if ( mbProgressMode )
1710 {
1711 maPrgsTxt = rText;
1712 if ( IsReallyVisible() )
1713 {
1714 Invalidate();
1715 Update();
1716 Flush();
1717 }
1718 }
1719 else
1720 Window::SetText( rText );
1721 }
1722
1723 // -----------------------------------------------------------------------
1724
CalcWindowSizePixel() const1725 Size StatusBar::CalcWindowSizePixel() const
1726 {
1727 sal_uLong i = 0;
1728 sal_uLong nCount = mpItemList->Count();
1729 long nOffset = 0;
1730 long nCalcWidth = (STATUSBAR_OFFSET_X*2);
1731 long nCalcHeight;
1732
1733 while ( i < nCount )
1734 {
1735 ImplStatusItem* pItem = mpItemList->GetObject( i );
1736 nCalcWidth += pItem->mnWidth + nOffset;
1737 nOffset = pItem->mnOffset;
1738 i++;
1739 }
1740
1741 long nMinHeight = GetTextHeight();
1742 const long nBarTextOffset = STATUSBAR_OFFSET_TEXTY*2;
1743 long nProgressHeight = nMinHeight + nBarTextOffset;
1744 // FIXME: IsNativeControlSupported and GetNativeControlRegion should be const ?
1745 StatusBar* pThis = const_cast<StatusBar*>( this );
1746 if( pThis->IsNativeControlSupported( CTRL_PROGRESS, PART_ENTIRE_CONTROL ) )
1747 {
1748 ImplControlValue aValue;
1749 Rectangle aControlRegion( (const Point&)Point(), Size( nCalcWidth, nMinHeight ) );
1750 Rectangle aNativeControlRegion, aNativeContentRegion;
1751 if( pThis->GetNativeControlRegion( CTRL_PROGRESS, PART_ENTIRE_CONTROL, aControlRegion,
1752 CTRL_STATE_ENABLED, aValue, rtl::OUString(),
1753 aNativeControlRegion, aNativeContentRegion ) )
1754 {
1755 nProgressHeight = aNativeControlRegion.GetHeight();
1756 }
1757 }
1758
1759 if( mpImplData->mbDrawItemFrames &&
1760 pThis->IsNativeControlSupported( CTRL_FRAME, PART_BORDER ) )
1761 {
1762 ImplControlValue aControlValue( FRAME_DRAW_NODRAW );
1763 Rectangle aBound, aContent;
1764 Rectangle aNatRgn( Point( 0, 0 ), Size( 150, 50 ) );
1765 if( pThis->GetNativeControlRegion(CTRL_FRAME, PART_BORDER,
1766 aNatRgn, 0, aControlValue, rtl::OUString(), aBound, aContent) )
1767 {
1768 mpImplData->mnItemBorderWidth =
1769 ( aBound.GetHeight() - aContent.GetHeight() ) / 2;
1770 }
1771 }
1772
1773 nCalcHeight = nMinHeight+nBarTextOffset + 2*mpImplData->mnItemBorderWidth;
1774 if( nCalcHeight < nProgressHeight+2 )
1775 nCalcHeight = nProgressHeight+2;
1776
1777 // add border
1778 if( IsTopBorder() )
1779 nCalcHeight += 2;
1780 if ( IsBottomBorder() )
1781 nCalcHeight += 2;
1782
1783 return Size( nCalcWidth, nCalcHeight );
1784 }
1785
1786
1787 // -----------------------------------------------------------------------
1788
SetAccessibleName(sal_uInt16 nItemId,const XubString & rName)1789 void StatusBar::SetAccessibleName( sal_uInt16 nItemId, const XubString& rName )
1790 {
1791 sal_uInt16 nPos = GetItemPos( nItemId );
1792
1793 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1794 {
1795 ImplStatusItem* pItem = mpItemList->GetObject( nPos );
1796
1797 if ( pItem->maAccessibleName != rName )
1798 {
1799 pItem->maAccessibleName = rName;
1800 ImplCallEventListeners( VCLEVENT_STATUSBAR_NAMECHANGED, (void*) sal_IntPtr(pItem->mnId) );
1801 }
1802 }
1803 }
1804
1805 // -----------------------------------------------------------------------
1806
GetAccessibleName(sal_uInt16 nItemId) const1807 const XubString& StatusBar::GetAccessibleName( sal_uInt16 nItemId ) const
1808 {
1809 sal_uInt16 nPos = GetItemPos( nItemId );
1810
1811 if ( nPos != STATUSBAR_ITEM_NOTFOUND )
1812 return mpItemList->GetObject( nPos )->maAccessibleName;
1813 else
1814 return ImplGetSVEmptyStr();
1815 }
1816
1817 // -----------------------------------------------------------------------
1818