xref: /trunk/main/svtools/source/control/headbar.cxx (revision ca62e2c2083b5d0995f1245bad6c2edfb455fbec)
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_svtools.hxx"
26 
27 #define _SV_HEADBAR_CXX
28 #include <svtools/headbar.hxx>
29 #include <tools/debug.hxx>
30 #ifndef _TOOLS_LIST_HXX
31 #include <tools/list.hxx>
32 #endif
33 
34 #ifndef _VCL_APP_HXX
35 #include <vcl/svapp.hxx>
36 #endif
37 #ifndef _VCL_HELP_HXX
38 #include <vcl/help.hxx>
39 #endif
40 #ifndef _VCL_IMAGE_HXX
41 #include <vcl/image.hxx>
42 #endif
43 #include <com/sun/star/accessibility/XAccessible.hpp>
44 
45 //IAccessibility2 Implementation 2009-----
46 #include <com/sun/star/accessibility/AccessibleRole.hpp>
47 #include <vclxaccessibleheaderbar.hxx>
48 //-----IAccessibility2 Implementation 2009
49 // =======================================================================
50 
51 struct ImplHeadItem
52 {
53     sal_uInt16              mnId;
54     HeaderBarItemBits   mnBits;
55     long                mnSize;
56     rtl::OString        maHelpId;
57     Image               maImage;
58     XubString           maOutText;
59     XubString           maText;
60     XubString           maHelpText;
61     void*               mpUserData;
62 };
63 
64 DECLARE_LIST( ImplHeadItemList, ImplHeadItem* )
65 
66 // =======================================================================
67 
68 #define HEAD_ARROWSIZE1             4
69 #define HEAD_ARROWSIZE2             7
70 
71 #define HEADERBAR_TEXTOFF           2
72 #define HEADERBAR_ARROWOFF          5
73 #define HEADERBAR_SPLITOFF          3
74 
75 #define HEADERBAR_DRAGOFF           4
76 #define HEADERBAR_DRAGOUTOFF        15
77 
78 #define HEAD_HITTEST_ITEM           ((sal_uInt16)0x0001)
79 #define HEAD_HITTEST_DIVIDER        ((sal_uInt16)0x0002)
80 
81 // =======================================================================
82 
83 void HeaderBar::ImplInit( WinBits nWinStyle )
84 {
85     mpItemList      = new ImplHeadItemList;
86     mnBorderOff1    = 0;
87     mnBorderOff2    = 0;
88     mnOffset        = 0;
89     mnDX            = 0;
90     mnDY            = 0;
91     mnDragSize      = 0;
92     mnStartPos      = 0;
93     mnDragPos       = 0;
94     mnMouseOff      = 0;
95     mnCurItemId     = 0;
96     mnItemDragPos   = HEADERBAR_ITEM_NOTFOUND;
97     mbDrag          = sal_False;
98     mbItemDrag      = sal_False;
99     mbOutDrag       = sal_False;
100     mbItemMode      = sal_False;
101 
102     //IAccessibility2 Implementation 2009-----
103     m_pVCLXHeaderBar = NULL;
104     //-----IAccessibility2 Implementation 2009
105     // StyleBits auswerten
106     if ( nWinStyle & WB_DRAG )
107         mbDragable = sal_True;
108     else
109         mbDragable = sal_False;
110     if ( nWinStyle & WB_BUTTONSTYLE )
111         mbButtonStyle = sal_True;
112     else
113         mbButtonStyle = sal_False;
114     if ( nWinStyle & WB_BORDER )
115     {
116         mnBorderOff1 = 1;
117         mnBorderOff2 = 1;
118     }
119     else
120     {
121         if ( nWinStyle & WB_BOTTOMBORDER )
122             mnBorderOff2 = 1;
123     }
124 
125     ImplInitSettings( sal_True, sal_True, sal_True );
126     //IAccessibility2 Implementation 2009-----
127     //SetAccessibleRole(com::sun::star::accessibility::AccessibleRole::COLUMN_HEADER);
128     //-----IAccessibility2 Implementation 2009
129 }
130 
131 // -----------------------------------------------------------------------
132 
133 HeaderBar::HeaderBar( Window* pParent, WinBits nWinStyle ) :
134     Window( pParent, nWinStyle & WB_3DLOOK )
135 {
136     ImplInit( nWinStyle );
137     SetSizePixel( CalcWindowSizePixel() );
138 }
139 
140 // -----------------------------------------------------------------------
141 
142 HeaderBar::HeaderBar( Window* pParent, const ResId& rResId ) :
143     Window( pParent, rResId )
144 {
145     ImplInit( rResId.GetWinBits() );
146 }
147 
148 // -----------------------------------------------------------------------
149 
150 HeaderBar::~HeaderBar()
151 {
152     // Alle Items loeschen
153     ImplHeadItem* pItem = mpItemList->First();
154     while ( pItem )
155     {
156         delete pItem;
157         pItem = mpItemList->Next();
158     }
159 
160     delete mpItemList;
161 }
162 
163 // -----------------------------------------------------------------------
164 
165 void HeaderBar::ImplInitSettings( sal_Bool bFont,
166                                   sal_Bool bForeground, sal_Bool bBackground )
167 {
168     const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
169 
170     if ( bFont )
171     {
172         Font aFont;
173         aFont = rStyleSettings.GetToolFont();
174         if ( IsControlFont() )
175             aFont.Merge( GetControlFont() );
176         SetZoomedPointFont( aFont );
177     }
178 
179     if ( bForeground || bFont )
180     {
181         Color aColor;
182         if ( IsControlForeground() )
183             aColor = GetControlForeground();
184         else
185             aColor = rStyleSettings.GetButtonTextColor();
186         SetTextColor( aColor );
187         SetTextFillColor();
188     }
189 
190     if ( bBackground )
191     {
192         Color aColor;
193         if ( IsControlBackground() )
194             aColor = GetControlBackground();
195         else
196             aColor = rStyleSettings.GetFaceColor();
197         SetBackground( aColor );
198     }
199 }
200 
201 // -----------------------------------------------------------------------
202 
203 long HeaderBar::ImplGetItemPos( sal_uInt16 nPos ) const
204 {
205     long nX = -mnOffset;
206     for ( sal_uInt16 i = 0; i < nPos; i++ )
207         nX += mpItemList->GetObject( i )->mnSize;
208     return nX;
209 }
210 
211 // -----------------------------------------------------------------------
212 
213 Rectangle HeaderBar::ImplGetItemRect( sal_uInt16 nPos ) const
214 {
215     Rectangle aRect( ImplGetItemPos( nPos ), 0, 0, mnDY-1 );
216     aRect.Right() = aRect.Left() + mpItemList->GetObject( nPos )->mnSize - 1;
217     // Gegen Ueberlauf auf einigen Systemen testen
218     if ( aRect.Right() > 16000 )
219         aRect.Right() = 16000;
220     return aRect;
221 }
222 
223 // -----------------------------------------------------------------------
224 
225 sal_uInt16 HeaderBar::ImplHitTest( const Point& rPos,
226                                long& nMouseOff, sal_uInt16& nPos ) const
227 {
228     ImplHeadItem*   pItem;
229     sal_uInt16          nCount = (sal_uInt16)mpItemList->Count();
230     sal_Bool            bLastFixed = sal_True;
231     long            nX = -mnOffset;
232 
233     for ( sal_uInt16 i = 0; i < nCount; i++ )
234     {
235         pItem = mpItemList->GetObject( i );
236 
237         if ( rPos.X() < (nX+pItem->mnSize) )
238         {
239             sal_uInt16 nMode;
240 
241             if ( !bLastFixed && (rPos.X() < (nX+HEADERBAR_SPLITOFF)) )
242             {
243                 nMode = HEAD_HITTEST_DIVIDER;
244                 nPos = i-1;
245                 nMouseOff = rPos.X()-nX+1;
246             }
247             else
248             {
249                 nPos = i;
250 
251                 if ( !(pItem->mnBits & HIB_FIXED) && (rPos.X() >= (nX+pItem->mnSize-HEADERBAR_SPLITOFF)) )
252                 {
253                     nMode = HEAD_HITTEST_DIVIDER;
254                     nMouseOff = rPos.X()-(nX+pItem->mnSize);
255                 }
256                 else
257                 {
258                     nMode = HEAD_HITTEST_ITEM;
259                     nMouseOff = rPos.X()-nX;
260                 }
261             }
262 
263             return nMode;
264         }
265 
266         if ( pItem->mnBits & HIB_FIXED )
267             bLastFixed = sal_True;
268         else
269             bLastFixed = sal_False;
270 
271         nX += pItem->mnSize;
272     }
273 
274     if ( !bLastFixed )
275     {
276         pItem = mpItemList->GetObject( nCount-1 );
277         if ( (pItem->mnSize < 4)  && (rPos.X() < (nX+HEADERBAR_SPLITOFF)) )
278         {
279             nPos = nCount-1;
280             nMouseOff = rPos.X()-nX+1;
281             return HEAD_HITTEST_DIVIDER;
282         }
283     }
284 
285     return 0;
286 }
287 
288 // -----------------------------------------------------------------------
289 
290 void HeaderBar::ImplInvertDrag( sal_uInt16 nStartPos, sal_uInt16 nEndPos )
291 {
292     Rectangle aRect1 = ImplGetItemRect( nStartPos );
293     Rectangle aRect2 = ImplGetItemRect( nEndPos );
294     Point     aStartPos = aRect1.Center();
295     Point     aEndPos = aStartPos;
296     Rectangle aStartRect( aStartPos.X()-2, aStartPos.Y()-2,
297                           aStartPos.X()+2, aStartPos.Y()+2 );
298 
299     if ( nEndPos > nStartPos )
300     {
301         aStartPos.X() += 3;
302         aEndPos.X() = aRect2.Right()-6;
303     }
304     else
305     {
306         aStartPos.X() -= 3;
307         aEndPos.X() = aRect2.Left()+6;
308     }
309 
310     SetRasterOp( ROP_INVERT );
311     DrawRect( aStartRect );
312     DrawLine( aStartPos, aEndPos );
313     if ( nEndPos > nStartPos )
314     {
315         DrawLine( Point( aEndPos.X()+1, aEndPos.Y()-3 ),
316                   Point( aEndPos.X()+1, aEndPos.Y()+3 ) );
317         DrawLine( Point( aEndPos.X()+2, aEndPos.Y()-2 ),
318                   Point( aEndPos.X()+2, aEndPos.Y()+2 ) );
319         DrawLine( Point( aEndPos.X()+3, aEndPos.Y()-1 ),
320                   Point( aEndPos.X()+3, aEndPos.Y()+1 ) );
321         DrawPixel( Point( aEndPos.X()+4, aEndPos.Y() ) );
322     }
323     else
324     {
325         DrawLine( Point( aEndPos.X()-1, aEndPos.Y()-3 ),
326                   Point( aEndPos.X()-1, aEndPos.Y()+3 ) );
327         DrawLine( Point( aEndPos.X()-2, aEndPos.Y()-2 ),
328                   Point( aEndPos.X()-2, aEndPos.Y()+2 ) );
329         DrawLine( Point( aEndPos.X()-3, aEndPos.Y()-1 ),
330                   Point( aEndPos.X()-3, aEndPos.Y()+1 ) );
331         DrawPixel( Point( aEndPos.X()-4, aEndPos.Y() ) );
332     }
333     SetRasterOp( ROP_OVERPAINT );
334 }
335 
336 // -----------------------------------------------------------------------
337 
338 void HeaderBar::ImplDrawItem( OutputDevice* pDev,
339                               sal_uInt16 nPos, sal_Bool bHigh, sal_Bool bDrag,
340                               const Rectangle& rItemRect,
341                               const Rectangle* pRect,
342                               sal_uLong )
343 {
344     Rectangle aRect = rItemRect;
345 
346     // Wenn kein Platz, dann brauchen wir auch nichts ausgeben
347     if ( aRect.GetWidth() <= 1 )
348         return;
349 
350     // Feststellen, ob Rectangle ueberhaupt sichtbar
351     if ( pRect )
352     {
353         if ( aRect.Right() < pRect->Left() )
354             return;
355         else if ( aRect.Left() > pRect->Right() )
356             return;
357     }
358     else
359     {
360         if ( aRect.Right() < 0 )
361             return;
362         else if ( aRect.Left() > mnDX )
363             return;
364     }
365 
366     ImplHeadItem*           pItem  = mpItemList->GetObject( nPos );
367     HeaderBarItemBits       nBits = pItem->mnBits;
368     const StyleSettings&    rStyleSettings = GetSettings().GetStyleSettings();
369 
370     // Border muss nicht gemalt werden
371     aRect.Top()     += mnBorderOff1;
372     aRect.Bottom()  -= mnBorderOff2;
373 
374     // Hintergrund loeschen
375     if ( !pRect || bDrag )
376     {
377         if ( bDrag )
378         {
379             pDev->SetLineColor();
380             pDev->SetFillColor( rStyleSettings.GetCheckedColor() );
381             pDev->DrawRect( aRect );
382         }
383         else
384             pDev->DrawWallpaper( aRect, GetBackground() );
385     }
386 
387     // Trennlinie malen
388     pDev->SetLineColor( rStyleSettings.GetDarkShadowColor() );
389     pDev->DrawLine( Point( aRect.Right(), aRect.Top() ),
390                     Point( aRect.Right(), aRect.Bottom() ) );
391 
392     // ButtonStyle malen
393     // avoid 3D borders
394     Color aSelectionTextColor( COL_TRANSPARENT );
395     if( bHigh )
396         DrawSelectionBackground( aRect, 1, sal_True, sal_False, sal_False, &aSelectionTextColor );
397     else if ( !mbButtonStyle || (nBits & HIB_FLAT) )
398         DrawSelectionBackground( aRect, 0, sal_True, sal_False, sal_False, &aSelectionTextColor );
399 
400     // Wenn kein Platz, dann brauchen wir auch nichts ausgeben
401     if ( aRect.GetWidth() < 1 )
402         return;
403 
404     // Positionen und Groessen berechnen und Inhalt ausgeben
405     pItem->maOutText = pItem->maText;
406     Size aImageSize = pItem->maImage.GetSizePixel();
407     Size aTxtSize( pDev->GetTextWidth( pItem->maOutText ), 0  );
408     if ( pItem->maOutText.Len() )
409         aTxtSize.Height() = pDev->GetTextHeight();
410     long nArrowWidth = 0;
411     if ( nBits & (HIB_UPARROW | HIB_DOWNARROW) )
412         nArrowWidth = HEAD_ARROWSIZE2+HEADERBAR_ARROWOFF;
413 
414     // Wenn kein Platz fuer Image, dann nicht ausgeben
415     long nTestHeight = aImageSize.Height();
416     if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) )
417         nTestHeight += aTxtSize.Height();
418     if ( (aImageSize.Width() > aRect.GetWidth()) || (nTestHeight > aRect.GetHeight()) )
419     {
420         aImageSize.Width() = 0;
421         aImageSize.Height() = 0;
422     }
423 
424     // Text auf entsprechende Laenge kuerzen
425     sal_Bool bLeftText = sal_False;
426     long nMaxTxtWidth = aRect.GetWidth()-(HEADERBAR_TEXTOFF*2)-nArrowWidth;
427     if ( nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE) )
428         nMaxTxtWidth -= aImageSize.Width();
429     long nTxtWidth = aTxtSize.Width();
430     if ( nTxtWidth > nMaxTxtWidth )
431     {
432         bLeftText = sal_True;
433         // 3 == Len of "..."
434         pItem->maOutText.AppendAscii( "..." );
435         do
436         {
437             pItem->maOutText.Erase( pItem->maOutText.Len()-3-1, 1 );
438             nTxtWidth = pDev->GetTextWidth( pItem->maOutText );
439         }
440         while ( (nTxtWidth > nMaxTxtWidth) && (pItem->maOutText.Len() > 3) );
441         if ( pItem->maOutText.Len() == 3 )
442         {
443             nTxtWidth = 0;
444             pItem->maOutText.Erase();
445         }
446     }
447 
448     // Text/Imageposition berechnen
449     long nTxtPos;
450     if ( !bLeftText && (nBits & HIB_RIGHT) )
451     {
452         nTxtPos = aRect.Right()-nTxtWidth-HEADERBAR_TEXTOFF;
453         if ( nBits & HIB_RIGHTIMAGE )
454             nTxtPos -= aImageSize.Width();
455     }
456     else if ( !bLeftText && (nBits & HIB_CENTER) )
457     {
458         long nTempWidth = nTxtWidth;
459         if ( nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE) )
460             nTempWidth += aImageSize.Width();
461         nTxtPos = aRect.Left()+(aRect.GetWidth()-nTempWidth)/2;
462         if ( nBits & HIB_LEFTIMAGE )
463             nTxtPos += aImageSize.Width();
464         if ( nArrowWidth )
465         {
466             if ( nTxtPos+nTxtWidth+nArrowWidth >= aRect.Right() )
467             {
468                 nTxtPos = aRect.Left()+HEADERBAR_TEXTOFF;
469                 if ( nBits & HIB_LEFTIMAGE )
470                     nTxtPos += aImageSize.Width();
471             }
472         }
473     }
474     else
475     {
476         nTxtPos = aRect.Left()+HEADERBAR_TEXTOFF;
477         if ( nBits & HIB_LEFTIMAGE )
478             nTxtPos += aImageSize.Width();
479         if ( nBits & HIB_RIGHT )
480             nTxtPos += nArrowWidth;
481     }
482 
483     // TextPosition berechnen
484     long nTxtPosY = 0;
485     if ( pItem->maOutText.Len() || (nArrowWidth && aTxtSize.Height()) )
486     {
487         if ( nBits & HIB_TOP )
488         {
489             nTxtPosY = aRect.Top();
490             if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) )
491                 nTxtPosY += aImageSize.Height();
492         }
493         else if ( nBits & HIB_BOTTOM )
494             nTxtPosY = aRect.Bottom()-aTxtSize.Height();
495         else
496         {
497             long nTempHeight = aTxtSize.Height();
498             if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) )
499                 nTempHeight += aImageSize.Height();
500             nTxtPosY = aRect.Top()+((aRect.GetHeight()-nTempHeight)/2);
501             if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) )
502                 nTxtPosY += aImageSize.Height();
503         }
504     }
505 
506     // Text ausgebeben
507     if ( pItem->maOutText.Len() )
508     {
509         if( aSelectionTextColor != Color( COL_TRANSPARENT ) )
510         {
511             pDev->Push( PUSH_TEXTCOLOR );
512             pDev->SetTextColor( aSelectionTextColor );
513         }
514         if ( IsEnabled() )
515             pDev->DrawText( Point( nTxtPos, nTxtPosY ), pItem->maOutText );
516         else
517             pDev->DrawCtrlText( Point( nTxtPos, nTxtPosY ), pItem->maOutText, 0, STRING_LEN, TEXT_DRAW_DISABLE );
518         if( aSelectionTextColor != Color( COL_TRANSPARENT ) )
519             pDev->Pop();
520     }
521 
522     // Wenn Image vorhanden, Position berechnen und ausgeben
523     long nImagePosY = 0;
524     if ( aImageSize.Width() && aImageSize.Height() )
525     {
526         long nImagePos = nTxtPos;
527         if ( nBits & HIB_LEFTIMAGE )
528         {
529             nImagePos -= aImageSize.Width();
530             if ( nBits & HIB_RIGHT )
531                 nImagePos -= nArrowWidth;
532         }
533         else if ( nBits & HIB_RIGHTIMAGE )
534         {
535             nImagePos += nTxtWidth;
536             if ( !(nBits & HIB_RIGHT) )
537                 nImagePos += nArrowWidth;
538         }
539         else
540         {
541             if ( nBits & HIB_RIGHT )
542                 nImagePos = aRect.Right()-aImageSize.Width();
543             else if ( nBits & HIB_CENTER )
544                 nImagePos = aRect.Left()+(aRect.GetWidth()-aImageSize.Width())/2;
545             else
546                 nImagePos = aRect.Left()+HEADERBAR_TEXTOFF;
547         }
548 
549         if ( nBits & HIB_TOP )
550             nImagePosY = aRect.Top();
551         else if ( nBits & HIB_BOTTOM )
552         {
553             nImagePosY = aRect.Bottom()-aImageSize.Height();
554             if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) )
555                 nImagePosY -= aTxtSize.Height();
556         }
557         else
558         {
559             long nTempHeight = aImageSize.Height();
560             if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) )
561                 nTempHeight += aTxtSize.Height();
562             nImagePosY = aRect.Top()+((aRect.GetHeight()-nTempHeight)/2);
563         }
564         if ( nImagePos+aImageSize.Width() <= aRect.Right() )
565         {
566             sal_uInt16 nStyle = 0;
567             if ( !IsEnabled() )
568                 nStyle |= IMAGE_DRAW_DISABLE;
569             pDev->DrawImage( Point( nImagePos, nImagePosY ), pItem->maImage, nStyle );
570         }
571     }
572 
573     if ( nBits & (HIB_UPARROW | HIB_DOWNARROW) )
574     {
575         long nArrowX = nTxtPos;
576         if ( nBits & HIB_RIGHT )
577             nArrowX -= nArrowWidth;
578         else
579             nArrowX += nTxtWidth+HEADERBAR_ARROWOFF;
580         if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) && !pItem->maText.Len() )
581         {
582             if ( nBits & HIB_RIGHT )
583                 nArrowX -= aImageSize.Width();
584             else
585                 nArrowX += aImageSize.Width();
586         }
587 
588         // Feststellen, ob Platz genug ist, das Item zu malen
589         sal_Bool bDraw = sal_True;
590         if ( nArrowX < aRect.Left()+HEADERBAR_TEXTOFF )
591             bDraw = sal_False;
592         else if ( nArrowX+HEAD_ARROWSIZE2 > aRect.Right() )
593             bDraw = sal_False;
594 
595         if ( bDraw )
596         {
597             long nArrowY;
598             if ( aTxtSize.Height() )
599                 nArrowY = nTxtPosY+(aTxtSize.Height()/2);
600             else if ( aImageSize.Width() && aImageSize.Height() )
601                 nArrowY = nImagePosY+(aImageSize.Height()/2);
602             else
603             {
604                 if ( nBits & HIB_TOP )
605                     nArrowY = aRect.Top()+1;
606                 else if ( nBits & HIB_BOTTOM )
607                     nArrowY = aRect.Bottom()-HEAD_ARROWSIZE2-1;
608                 else
609                     nArrowY = aRect.Top()+((aRect.GetHeight()-HEAD_ARROWSIZE2)/2);;
610             }
611             nArrowY -= HEAD_ARROWSIZE1-1;
612             if ( nBits & HIB_DOWNARROW )
613             {
614                 pDev->SetLineColor( rStyleSettings.GetLightColor() );
615                 pDev->DrawLine( Point( nArrowX, nArrowY ),
616                                 Point( nArrowX+HEAD_ARROWSIZE2, nArrowY ) );
617                 pDev->DrawLine( Point( nArrowX, nArrowY ),
618                                 Point( nArrowX+HEAD_ARROWSIZE1, nArrowY+HEAD_ARROWSIZE2 ) );
619                 pDev->SetLineColor( rStyleSettings.GetShadowColor() );
620                 pDev->DrawLine( Point( nArrowX+HEAD_ARROWSIZE1, nArrowY+HEAD_ARROWSIZE2 ),
621                                 Point( nArrowX+HEAD_ARROWSIZE2, nArrowY ) );
622             }
623             else
624             {
625                 pDev->SetLineColor( rStyleSettings.GetLightColor() );
626                 pDev->DrawLine( Point( nArrowX, nArrowY+HEAD_ARROWSIZE2 ),
627                                 Point( nArrowX+HEAD_ARROWSIZE1, nArrowY ) );
628                 pDev->SetLineColor( rStyleSettings.GetShadowColor() );
629                 pDev->DrawLine( Point( nArrowX, nArrowY+HEAD_ARROWSIZE2 ),
630                                 Point( nArrowX+HEAD_ARROWSIZE2, nArrowY+HEAD_ARROWSIZE2 ) );
631                 pDev->DrawLine( Point( nArrowX+HEAD_ARROWSIZE2, nArrowY+HEAD_ARROWSIZE2 ),
632                                 Point( nArrowX+HEAD_ARROWSIZE1, nArrowY ) );
633             }
634         }
635     }
636 
637     // Gegebenenfalls auch UserDraw aufrufen
638     if ( nBits & HIB_USERDRAW )
639     {
640         Region aRegion( aRect );
641         if ( pRect )
642             aRegion.Intersect( *pRect );
643         pDev->SetClipRegion( aRegion );
644         UserDrawEvent aODEvt( pDev, aRect, pItem->mnId );
645         UserDraw( aODEvt );
646         pDev->SetClipRegion();
647     }
648 }
649 
650 // -----------------------------------------------------------------------
651 
652 void HeaderBar::ImplDrawItem( sal_uInt16 nPos, sal_Bool bHigh, sal_Bool bDrag,
653                               const Rectangle* pRect )
654 {
655     Rectangle aRect = ImplGetItemRect( nPos );
656     ImplDrawItem( this, nPos, bHigh, bDrag, aRect, pRect, 0 );
657 }
658 
659 // -----------------------------------------------------------------------
660 
661 void HeaderBar::ImplUpdate( sal_uInt16 nPos, sal_Bool bEnd, sal_Bool bDirect )
662 {
663     if ( IsVisible() && IsUpdateMode() )
664     {
665         if ( !bDirect )
666         {
667             Rectangle   aRect;
668             sal_uInt16      nItemCount = (sal_uInt16)(mpItemList->Count());
669             if ( nPos < nItemCount )
670                 aRect = ImplGetItemRect( nPos );
671             else
672             {
673                 aRect.Bottom() = mnDY-1;
674                 if ( nItemCount )
675                     aRect.Left() = ImplGetItemRect( nItemCount-1 ).Right();
676             }
677             if ( bEnd )
678                 aRect.Right() = mnDX-1;
679             aRect.Top()     += mnBorderOff1;
680             aRect.Bottom()  -= mnBorderOff2;
681             Invalidate( aRect );
682         }
683         else
684         {
685             for ( sal_uInt16 i = nPos; i < mpItemList->Count(); i++ )
686                 ImplDrawItem( i );
687             if ( bEnd )
688             {
689                 Rectangle aRect = ImplGetItemRect( (sal_uInt16)mpItemList->Count() );
690                 aRect.Left()  = aRect.Right();
691                 aRect.Right() = mnDX-1;
692                 if ( aRect.Left() < aRect.Right() )
693                 {
694                     aRect.Top()     += mnBorderOff1;
695                     aRect.Bottom()  -= mnBorderOff2;
696                     Erase( aRect );
697                 }
698             }
699         }
700     }
701 }
702 
703 // -----------------------------------------------------------------------
704 
705 void HeaderBar::ImplStartDrag( const Point& rMousePos, sal_Bool bCommand )
706 {
707     sal_uInt16  nPos;
708     sal_uInt16  nHitTest = ImplHitTest( rMousePos, mnMouseOff, nPos );
709     if ( nHitTest )
710     {
711         mbDrag = sal_False;
712         ImplHeadItem* pItem = mpItemList->GetObject( nPos );
713         if ( nHitTest & HEAD_HITTEST_DIVIDER )
714             mbDrag = sal_True;
715         else
716         {
717             if ( ((pItem->mnBits & HIB_CLICKABLE) && !(pItem->mnBits & HIB_FLAT)) ||
718                  (mbDragable && !(pItem->mnBits & HIB_FIXEDPOS)) )
719             {
720                 mbItemMode = sal_True;
721                 mbDrag = sal_True;
722                 if ( bCommand )
723                 {
724                     if ( mbDragable )
725                         mbItemDrag = sal_True;
726                     else
727                     {
728                         mbItemMode = sal_False;
729                         mbDrag = sal_False;
730                     }
731                 }
732             }
733             else
734             {
735                 if ( !bCommand )
736                 {
737                     mnCurItemId = pItem->mnId;
738                     Select();
739                     mnCurItemId = 0;
740                 }
741             }
742         }
743 
744         if ( mbDrag )
745         {
746             mbOutDrag = sal_False;
747             mnCurItemId = pItem->mnId;
748             mnItemDragPos = nPos;
749             StartTracking();
750             mnStartPos = rMousePos.X()-mnMouseOff;
751             mnDragPos = mnStartPos;
752             StartDrag();
753             if ( mbItemMode )
754                 ImplDrawItem( nPos, sal_True, mbItemDrag );
755             else
756             {
757                 Rectangle aSizeRect( mnDragPos, 0, mnDragPos, mnDragSize+mnDY );
758                 ShowTracking( aSizeRect, SHOWTRACK_SPLIT );
759             }
760         }
761         else
762             mnMouseOff = 0;
763     }
764 }
765 
766 // -----------------------------------------------------------------------
767 
768 void HeaderBar::ImplDrag( const Point& rMousePos )
769 {
770     sal_Bool    bNewOutDrag;
771     sal_uInt16  nPos = GetItemPos( mnCurItemId );
772 
773     mnDragPos = rMousePos.X()-mnMouseOff;
774     if ( mbItemMode )
775     {
776         Rectangle aItemRect = ImplGetItemRect( nPos );
777         if ( aItemRect.IsInside( rMousePos ) )
778             bNewOutDrag = sal_False;
779         else
780             bNewOutDrag = sal_True;
781 
782         // Evt. ItemDrag anschalten
783         if ( bNewOutDrag && mbDragable && !mbItemDrag &&
784              !(mpItemList->GetObject(nPos)->mnBits & HIB_FIXEDPOS) )
785         {
786             if ( (rMousePos.Y() >= aItemRect.Top()) && (rMousePos.Y() <= aItemRect.Bottom()) )
787             {
788                 mbItemDrag = sal_True;
789                 ImplDrawItem( nPos, sal_True, mbItemDrag );
790             }
791         }
792 
793         sal_uInt16 nOldItemDragPos = mnItemDragPos;
794         if ( mbItemDrag )
795         {
796             if ( (rMousePos.Y() < -HEADERBAR_DRAGOUTOFF) || (rMousePos.Y() > mnDY+HEADERBAR_DRAGOUTOFF) )
797                 bNewOutDrag = sal_True;
798             else
799                 bNewOutDrag = sal_False;
800 
801             if ( bNewOutDrag )
802                 mnItemDragPos = HEADERBAR_ITEM_NOTFOUND;
803             else
804             {
805                 sal_uInt16 nTempId = GetItemId( Point( rMousePos.X(), 2 ) );
806                 if ( nTempId )
807                     mnItemDragPos = GetItemPos( nTempId );
808                 else
809                 {
810                     if ( rMousePos.X() <= 0 )
811                         mnItemDragPos = 0;
812                     else
813                         mnItemDragPos = GetItemCount()-1;
814                 }
815 
816                 // Nicht verschiebbare Items aussparen
817                 if ( mnItemDragPos < nPos )
818                 {
819                     while ( (mpItemList->GetObject(mnItemDragPos)->mnBits & HIB_FIXEDPOS) &&
820                             (mnItemDragPos < nPos) )
821                         mnItemDragPos++;
822                 }
823                 else if ( mnItemDragPos > nPos )
824                 {
825                     while ( (mpItemList->GetObject(mnItemDragPos)->mnBits & HIB_FIXEDPOS) &&
826                             (mnItemDragPos > nPos) )
827                         mnItemDragPos--;
828                 }
829             }
830 
831             if ( (mnItemDragPos != nOldItemDragPos) &&
832                  (nOldItemDragPos != nPos) &&
833                  (nOldItemDragPos != HEADERBAR_ITEM_NOTFOUND) )
834             {
835                 ImplInvertDrag( nPos, nOldItemDragPos );
836                 ImplDrawItem( nOldItemDragPos );
837             }
838         }
839 
840         if ( bNewOutDrag != mbOutDrag )
841             ImplDrawItem( nPos, !bNewOutDrag, mbItemDrag );
842 
843         if ( mbItemDrag  )
844         {
845             if ( (mnItemDragPos != nOldItemDragPos) &&
846                  (mnItemDragPos != nPos) &&
847                  (mnItemDragPos != HEADERBAR_ITEM_NOTFOUND) )
848             {
849                 ImplDrawItem( mnItemDragPos, sal_False, sal_True );
850                 ImplInvertDrag( nPos, mnItemDragPos );
851             }
852         }
853 
854         mbOutDrag = bNewOutDrag;
855     }
856     else
857     {
858         Rectangle aItemRect = ImplGetItemRect( nPos );
859         if ( mnDragPos < aItemRect.Left() )
860             mnDragPos = aItemRect.Left();
861         if ( (mnDragPos < 0) || (mnDragPos > mnDX-1) )
862             HideTracking();
863         else
864         {
865             Rectangle aSizeRect( mnDragPos, 0, mnDragPos, mnDragSize+mnDY );
866             ShowTracking( aSizeRect, SHOWTRACK_SPLIT );
867         }
868     }
869 
870     Drag();
871 }
872 
873 // -----------------------------------------------------------------------
874 
875 void HeaderBar::ImplEndDrag( sal_Bool bCancel )
876 {
877     HideTracking();
878 
879     if ( bCancel || mbOutDrag )
880     {
881         if ( mbItemMode && (!mbOutDrag || mbItemDrag) )
882         {
883             sal_uInt16 nPos = GetItemPos( mnCurItemId );
884             ImplDrawItem( nPos );
885         }
886 
887         mnCurItemId = 0;
888     }
889     else
890     {
891         sal_uInt16 nPos = GetItemPos( mnCurItemId );
892         if ( mbItemMode )
893         {
894             if ( mbItemDrag )
895             {
896                 Pointer aPointer( POINTER_ARROW );
897                 SetPointer( aPointer );
898                 if ( (mnItemDragPos != nPos) &&
899                      (mnItemDragPos != HEADERBAR_ITEM_NOTFOUND) )
900                 {
901                     ImplInvertDrag( nPos, mnItemDragPos );
902                     MoveItem( mnCurItemId, mnItemDragPos );
903                 }
904                 else
905                     ImplDrawItem( nPos );
906             }
907             else
908             {
909                 Select();
910                 ImplUpdate( nPos );
911             }
912         }
913         else
914         {
915             long nDelta = mnDragPos - mnStartPos;
916             if ( nDelta )
917             {
918                 ImplHeadItem* pItem = mpItemList->GetObject( nPos );
919                 pItem->mnSize += nDelta;
920                 ImplUpdate( nPos, sal_True );
921             }
922         }
923     }
924 
925     mbDrag          = sal_False;
926     EndDrag();
927     mnCurItemId     = 0;
928     mnItemDragPos   = HEADERBAR_ITEM_NOTFOUND;
929     mbOutDrag       = sal_False;
930     mbItemMode      = sal_False;
931     mbItemDrag      = sal_False;
932 }
933 
934 // -----------------------------------------------------------------------
935 
936 void HeaderBar::MouseButtonDown( const MouseEvent& rMEvt )
937 {
938     if ( rMEvt.IsLeft() )
939     {
940         if ( rMEvt.GetClicks() == 2 )
941         {
942             long    nTemp;
943             sal_uInt16  nPos;
944             sal_uInt16  nHitTest = ImplHitTest( rMEvt.GetPosPixel(), nTemp, nPos );
945             if ( nHitTest )
946             {
947                 ImplHeadItem* pItem = mpItemList->GetObject( nPos );
948                 if ( nHitTest & HEAD_HITTEST_DIVIDER )
949                     mbItemMode = sal_False;
950                 else
951                     mbItemMode = sal_True;
952                 mnCurItemId = pItem->mnId;
953                 DoubleClick();
954                 mbItemMode = sal_False;
955                 mnCurItemId = 0;
956             }
957         }
958         else
959             ImplStartDrag( rMEvt.GetPosPixel(), sal_False );
960     }
961 }
962 
963 // -----------------------------------------------------------------------
964 
965 void HeaderBar::MouseMove( const MouseEvent& rMEvt )
966 {
967     long            nTemp1;
968     sal_uInt16          nTemp2;
969     PointerStyle    eStyle = POINTER_ARROW;
970     sal_uInt16          nHitTest = ImplHitTest( rMEvt.GetPosPixel(), nTemp1, nTemp2 );
971 
972     if ( nHitTest & HEAD_HITTEST_DIVIDER )
973         eStyle = POINTER_HSIZEBAR;
974     Pointer aPtr( eStyle );
975     SetPointer( aPtr );
976 }
977 
978 // -----------------------------------------------------------------------
979 
980 void HeaderBar::Tracking( const TrackingEvent& rTEvt )
981 {
982     Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel();
983 
984     if ( rTEvt.IsTrackingEnded() )
985         ImplEndDrag( rTEvt.IsTrackingCanceled() );
986     else
987         ImplDrag( aMousePos );
988 }
989 
990 // -----------------------------------------------------------------------
991 
992 void HeaderBar::Paint( const Rectangle& rRect )
993 {
994     if ( mnBorderOff1 || mnBorderOff2 )
995     {
996         SetLineColor( GetSettings().GetStyleSettings().GetDarkShadowColor() );
997         if ( mnBorderOff1 )
998             DrawLine( Point( 0, 0 ), Point( mnDX-1, 0 ) );
999         if ( mnBorderOff2 )
1000             DrawLine( Point( 0, mnDY-1 ), Point( mnDX-1, mnDY-1 ) );
1001         // #i40393# draw left and right border, if WB_BORDER was set in ImplInit()
1002         if ( mnBorderOff1 && mnBorderOff2 )
1003         {
1004             DrawLine( Point( 0, 0 ), Point( 0, mnDY-1 ) );
1005             DrawLine( Point( mnDX-1, 0 ), Point( mnDX-1, mnDY-1 ) );
1006         }
1007     }
1008 
1009     sal_uInt16 nCurItemPos;
1010     if ( mbDrag )
1011         nCurItemPos = GetItemPos( mnCurItemId );
1012     else
1013         nCurItemPos = HEADERBAR_ITEM_NOTFOUND;
1014     sal_uInt16 nItemCount = (sal_uInt16)mpItemList->Count();
1015     for ( sal_uInt16 i = 0; i < nItemCount; i++ )
1016         ImplDrawItem( i, (i == nCurItemPos) ? sal_True : sal_False, sal_False, &rRect );
1017 }
1018 
1019 // -----------------------------------------------------------------------
1020 
1021 void HeaderBar::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize,
1022                       sal_uLong nFlags )
1023 {
1024     Point       aPos  = pDev->LogicToPixel( rPos );
1025     Size        aSize = pDev->LogicToPixel( rSize );
1026     Rectangle   aRect( aPos, aSize );
1027     Font        aFont = GetDrawPixelFont( pDev );
1028 
1029     pDev->Push();
1030     pDev->SetMapMode();
1031     pDev->SetFont( aFont );
1032     if ( nFlags & WINDOW_DRAW_MONO )
1033         pDev->SetTextColor( Color( COL_BLACK ) );
1034     else
1035         pDev->SetTextColor( GetTextColor() );
1036     pDev->SetTextFillColor();
1037 
1038     if ( !(nFlags & WINDOW_DRAW_NOBACKGROUND) )
1039     {
1040         pDev->DrawWallpaper( aRect, GetBackground() );
1041         if ( mnBorderOff1 || mnBorderOff2 )
1042         {
1043             pDev->SetLineColor( GetSettings().GetStyleSettings().GetDarkShadowColor() );
1044             if ( mnBorderOff1 )
1045                 pDev->DrawLine( aRect.TopLeft(), Point( aRect.Right(), aRect.Top() ) );
1046             if ( mnBorderOff2 )
1047                 pDev->DrawLine( Point( aRect.Left(), aRect.Bottom() ), Point( aRect.Right(), aRect.Bottom() ) );
1048             // #i40393# draw left and right border, if WB_BORDER was set in ImplInit()
1049             if ( mnBorderOff1 && mnBorderOff2 )
1050             {
1051                 pDev->DrawLine( aRect.TopLeft(), Point( aRect.Left(), aRect.Bottom() ) );
1052                 pDev->DrawLine( Point( aRect.Right(), aRect.Top() ), Point( aRect.Right(), aRect.Bottom() ) );
1053             }
1054         }
1055     }
1056 
1057     Rectangle aItemRect( aRect );
1058 //    aItemRect.Bottom()--;
1059     sal_uInt16 nItemCount = (sal_uInt16)mpItemList->Count();
1060     for ( sal_uInt16 i = 0; i < nItemCount; i++ )
1061     {
1062         aItemRect.Left() = aRect.Left()+ImplGetItemPos( i );
1063         aItemRect.Right() = aItemRect.Left() + mpItemList->GetObject( i )->mnSize - 1;
1064         // Gegen Ueberlauf auf einigen Systemen testen
1065         if ( aItemRect.Right() > 16000 )
1066             aItemRect.Right() = 16000;
1067         Region aRegion( aRect );
1068         pDev->SetClipRegion( aRegion );
1069         ImplDrawItem( pDev, i, sal_False, sal_False, aItemRect, &aRect, nFlags );
1070         pDev->SetClipRegion();
1071     }
1072 
1073     pDev->Pop();
1074 }
1075 
1076 // -----------------------------------------------------------------------
1077 
1078 void HeaderBar::Resize()
1079 {
1080     Size aSize = GetOutputSizePixel();
1081     if ( IsVisible() && (mnDY != aSize.Height()) )
1082         Invalidate();
1083     mnDX = aSize.Width();
1084     mnDY = aSize.Height();
1085 }
1086 
1087 // -----------------------------------------------------------------------
1088 
1089 void HeaderBar::Command( const CommandEvent& rCEvt )
1090 {
1091     if ( rCEvt.IsMouseEvent() && (rCEvt.GetCommand() == COMMAND_STARTDRAG) && !mbDrag )
1092     {
1093         ImplStartDrag( rCEvt.GetMousePosPixel(), sal_True );
1094         return;
1095     }
1096 
1097     Window::Command( rCEvt );
1098 }
1099 
1100 // -----------------------------------------------------------------------
1101 
1102 void HeaderBar::RequestHelp( const HelpEvent& rHEvt )
1103 {
1104     sal_uInt16 nItemId = GetItemId( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ) );
1105     if ( nItemId )
1106     {
1107         if ( rHEvt.GetMode() & (HELPMODE_QUICK | HELPMODE_BALLOON) )
1108         {
1109             Rectangle aItemRect = GetItemRect( nItemId );
1110             Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
1111             aItemRect.Left()   = aPt.X();
1112             aItemRect.Top()    = aPt.Y();
1113             aPt = OutputToScreenPixel( aItemRect.BottomRight() );
1114             aItemRect.Right()  = aPt.X();
1115             aItemRect.Bottom() = aPt.Y();
1116 
1117             XubString aStr = GetHelpText( nItemId );
1118             if ( !aStr.Len() || !(rHEvt.GetMode() & HELPMODE_BALLOON) )
1119             {
1120                 ImplHeadItem* pItem = mpItemList->GetObject( GetItemPos( nItemId ) );
1121                 // Wir zeigen die Quick-Hilfe nur an, wenn Text nicht
1122                 // vollstaendig sichtbar, ansonsten zeigen wir den Hilfetext
1123                 // an, wenn das Item keinen Text besitzt
1124                 if ( pItem->maOutText != pItem->maText )
1125                     aStr = pItem->maText;
1126                 else if ( pItem->maText.Len() )
1127                     aStr.Erase();
1128             }
1129 
1130             if ( aStr.Len() )
1131             {
1132                 if ( rHEvt.GetMode() & HELPMODE_BALLOON )
1133                     Help::ShowBalloon( this, aItemRect.Center(), aItemRect, aStr );
1134                 else
1135                     Help::ShowQuickHelp( this, aItemRect, aStr );
1136                 return;
1137             }
1138         }
1139         else if ( rHEvt.GetMode() & HELPMODE_EXTENDED )
1140         {
1141             rtl::OUString aHelpId( rtl::OStringToOUString( GetHelpId( nItemId ), RTL_TEXTENCODING_UTF8 ) );
1142             if ( aHelpId.getLength() )
1143             {
1144                 // Wenn eine Hilfe existiert, dann ausloesen
1145                 Help* pHelp = Application::GetHelp();
1146                 if ( pHelp )
1147                     pHelp->Start( aHelpId, this );
1148                 return;
1149             }
1150         }
1151     }
1152 
1153     Window::RequestHelp( rHEvt );
1154 }
1155 
1156 // -----------------------------------------------------------------------
1157 
1158 void HeaderBar::StateChanged( StateChangedType nType )
1159 {
1160     Window::StateChanged( nType );
1161 
1162     if ( nType == STATE_CHANGE_ENABLE )
1163         Invalidate();
1164     else if ( (nType == STATE_CHANGE_ZOOM) ||
1165               (nType == STATE_CHANGE_CONTROLFONT) )
1166     {
1167         ImplInitSettings( sal_True, sal_False, sal_False );
1168         Invalidate();
1169     }
1170     else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
1171     {
1172         ImplInitSettings( sal_False, sal_True, sal_False );
1173         Invalidate();
1174     }
1175     else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
1176     {
1177         ImplInitSettings( sal_False, sal_False, sal_True );
1178         Invalidate();
1179     }
1180 }
1181 
1182 // -----------------------------------------------------------------------
1183 
1184 void HeaderBar::DataChanged( const DataChangedEvent& rDCEvt )
1185 {
1186     Window::DataChanged( rDCEvt );
1187 
1188     if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
1189          (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
1190          ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
1191           (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
1192     {
1193         ImplInitSettings( sal_True, sal_True, sal_True );
1194         Invalidate();
1195     }
1196 }
1197 
1198 // -----------------------------------------------------------------------
1199 
1200 void HeaderBar::UserDraw( const UserDrawEvent& )
1201 {
1202 }
1203 
1204 // -----------------------------------------------------------------------
1205 
1206 void HeaderBar::StartDrag()
1207 {
1208     maStartDragHdl.Call( this );
1209 }
1210 
1211 // -----------------------------------------------------------------------
1212 
1213 void HeaderBar::Drag()
1214 {
1215     maDragHdl.Call( this );
1216 }
1217 
1218 // -----------------------------------------------------------------------
1219 
1220 void HeaderBar::EndDrag()
1221 {
1222     maEndDragHdl.Call( this );
1223 }
1224 
1225 // -----------------------------------------------------------------------
1226 
1227 void HeaderBar::Select()
1228 {
1229     maSelectHdl.Call( this );
1230 }
1231 
1232 // -----------------------------------------------------------------------
1233 
1234 void HeaderBar::DoubleClick()
1235 {
1236     maDoubleClickHdl.Call( this );
1237 }
1238 
1239 // -----------------------------------------------------------------------
1240 
1241 void HeaderBar::InsertItem( sal_uInt16 nItemId, const Image& rImage,
1242                             long nSize, HeaderBarItemBits nBits, sal_uInt16 nPos )
1243 {
1244     DBG_ASSERT( nItemId, "HeaderBar::InsertItem(): ItemId == 0" );
1245     DBG_ASSERT( GetItemPos( nItemId ) == HEADERBAR_ITEM_NOTFOUND,
1246                 "HeaderBar::InsertItem(): ItemId already exists" );
1247 
1248     // Item anlegen und in die Liste einfuegen
1249     ImplHeadItem* pItem = new ImplHeadItem;
1250     pItem->mnId         = nItemId;
1251     pItem->mnBits       = nBits;
1252     pItem->mnSize       = nSize;
1253     pItem->maImage      = rImage;
1254     pItem->mpUserData   = 0;
1255     mpItemList->Insert( pItem, nPos );
1256 
1257     // Ausgabe updaten
1258     ImplUpdate( nPos, sal_True );
1259 }
1260 
1261 // -----------------------------------------------------------------------
1262 
1263 void HeaderBar::InsertItem( sal_uInt16 nItemId, const XubString& rText,
1264                             long nSize, HeaderBarItemBits nBits, sal_uInt16 nPos )
1265 {
1266     DBG_ASSERT( nItemId, "HeaderBar::InsertItem(): ItemId == 0" );
1267     DBG_ASSERT( GetItemPos( nItemId ) == HEADERBAR_ITEM_NOTFOUND,
1268                 "HeaderBar::InsertItem(): ItemId already exists" );
1269 
1270     // Item anlegen und in die Liste einfuegen
1271     ImplHeadItem* pItem = new ImplHeadItem;
1272     pItem->mnId         = nItemId;
1273     pItem->mnBits       = nBits;
1274     pItem->mnSize       = nSize;
1275     pItem->maText       = rText;
1276     pItem->mpUserData   = 0;
1277     mpItemList->Insert( pItem, nPos );
1278 
1279     // Ausgabe updaten
1280     ImplUpdate( nPos, sal_True );
1281 }
1282 
1283 // -----------------------------------------------------------------------
1284 
1285 void HeaderBar::InsertItem( sal_uInt16 nItemId,
1286                             const Image& rImage, const XubString& rText,
1287                             long nSize, HeaderBarItemBits nBits,
1288                             sal_uInt16 nPos )
1289 {
1290     DBG_ASSERT( nItemId, "HeaderBar::InsertItem(): ItemId == 0" );
1291     DBG_ASSERT( GetItemPos( nItemId ) == HEADERBAR_ITEM_NOTFOUND,
1292                 "HeaderBar::InsertItem(): ItemId already exists" );
1293 
1294     // Item anlegen und in die Liste einfuegen
1295     ImplHeadItem* pItem = new ImplHeadItem;
1296     pItem->mnId         = nItemId;
1297     pItem->mnBits       = nBits;
1298     pItem->mnSize       = nSize;
1299     pItem->maImage      = rImage;
1300     pItem->maText       = rText;
1301     pItem->mpUserData   = 0;
1302     mpItemList->Insert( pItem, nPos );
1303 
1304     // Ausgabe updaten
1305     ImplUpdate( nPos, sal_True );
1306 }
1307 
1308 // -----------------------------------------------------------------------
1309 
1310 void HeaderBar::RemoveItem( sal_uInt16 nItemId )
1311 {
1312     sal_uInt16 nPos = GetItemPos( nItemId );
1313     if ( nPos != HEADERBAR_ITEM_NOTFOUND )
1314     {
1315         ImplHeadItem* pItem = mpItemList->Remove( nPos );
1316         delete pItem;
1317         ImplUpdate( nPos, sal_True );
1318     }
1319 }
1320 
1321 // -----------------------------------------------------------------------
1322 
1323 void HeaderBar::MoveItem( sal_uInt16 nItemId, sal_uInt16 nNewPos )
1324 {
1325     sal_uInt16 nPos = GetItemPos( nItemId );
1326     if ( nPos != HEADERBAR_ITEM_NOTFOUND )
1327     {
1328         if ( nPos != nNewPos )
1329         {
1330             ImplHeadItem* pItem = mpItemList->Remove( nPos );
1331             if ( nNewPos < nPos )
1332                 nPos = nNewPos;
1333             mpItemList->Insert( pItem, nNewPos );
1334             ImplUpdate( nPos, sal_True );
1335         }
1336     }
1337 }
1338 
1339 // -----------------------------------------------------------------------
1340 
1341 void HeaderBar::Clear()
1342 {
1343     // Alle Items loeschen
1344     ImplHeadItem* pItem = mpItemList->First();
1345     while ( pItem )
1346     {
1347         delete pItem;
1348         pItem = mpItemList->Next();
1349     }
1350     mpItemList->Clear();
1351 
1352     ImplUpdate( 0, sal_True );
1353 }
1354 
1355 // -----------------------------------------------------------------------
1356 
1357 void HeaderBar::SetOffset( long nNewOffset )
1358 {
1359     // Hier erstmal neu zeichnen, damit mit alten Offset noch das
1360     // richtige gemalt wird
1361     //Update();
1362 
1363     // Bereich verschieben
1364     Rectangle aRect( 0, mnBorderOff1, mnDX-1, mnDY-mnBorderOff1-mnBorderOff2-1 );
1365     long nDelta = mnOffset-nNewOffset;
1366     mnOffset = nNewOffset;
1367     Scroll( nDelta, 0, aRect );
1368 }
1369 
1370 // -----------------------------------------------------------------------
1371 
1372 sal_uInt16 HeaderBar::GetItemCount() const
1373 {
1374     return (sal_uInt16)mpItemList->Count();
1375 }
1376 
1377 // -----------------------------------------------------------------------
1378 
1379 sal_uInt16 HeaderBar::GetItemPos( sal_uInt16 nItemId ) const
1380 {
1381     ImplHeadItem* pItem = mpItemList->First();
1382     while ( pItem )
1383     {
1384         if ( pItem->mnId == nItemId )
1385             return (sal_uInt16)mpItemList->GetCurPos();
1386         pItem = mpItemList->Next();
1387     }
1388 
1389     return HEADERBAR_ITEM_NOTFOUND;
1390 }
1391 
1392 // -----------------------------------------------------------------------
1393 
1394 sal_uInt16 HeaderBar::GetItemId( sal_uInt16 nPos ) const
1395 {
1396     ImplHeadItem* pItem = mpItemList->GetObject( nPos );
1397     if ( pItem )
1398         return pItem->mnId;
1399     else
1400         return 0;
1401 }
1402 
1403 // -----------------------------------------------------------------------
1404 
1405 sal_uInt16 HeaderBar::GetItemId( const Point& rPos ) const
1406 {
1407     sal_uInt16 nPos = 0;
1408     while ( nPos < mpItemList->Count() )
1409     {
1410         if ( ImplGetItemRect( nPos ).IsInside( rPos ) )
1411             return GetItemId( nPos );
1412 
1413         nPos++;
1414     }
1415 
1416     return 0;
1417 }
1418 
1419 // -----------------------------------------------------------------------
1420 
1421 Rectangle HeaderBar::GetItemRect( sal_uInt16 nItemId ) const
1422 {
1423     Rectangle aRect;
1424     sal_uInt16 nPos = GetItemPos( nItemId );
1425     if ( nPos != HEADERBAR_ITEM_NOTFOUND )
1426         aRect = ImplGetItemRect( nPos );
1427     return aRect;
1428 }
1429 
1430 // -----------------------------------------------------------------------
1431 
1432 void HeaderBar::SetItemSize( sal_uInt16 nItemId, long nNewSize )
1433 {
1434     sal_uInt16 nPos = GetItemPos( nItemId );
1435     if ( nPos != HEADERBAR_ITEM_NOTFOUND )
1436     {
1437         ImplHeadItem* pItem = mpItemList->GetObject( nPos );
1438         if ( pItem->mnSize != nNewSize )
1439         {
1440             pItem->mnSize = nNewSize;
1441             ImplUpdate( nPos, sal_True );
1442         }
1443     }
1444 }
1445 
1446 // -----------------------------------------------------------------------
1447 
1448 long HeaderBar::GetItemSize( sal_uInt16 nItemId ) const
1449 {
1450     sal_uInt16 nPos = GetItemPos( nItemId );
1451     if ( nPos != HEADERBAR_ITEM_NOTFOUND )
1452         return mpItemList->GetObject( nPos )->mnSize;
1453     else
1454         return 0;
1455 }
1456 
1457 // -----------------------------------------------------------------------
1458 
1459 void HeaderBar::SetItemBits( sal_uInt16 nItemId, HeaderBarItemBits nNewBits )
1460 {
1461     sal_uInt16 nPos = GetItemPos( nItemId );
1462     if ( nPos != HEADERBAR_ITEM_NOTFOUND )
1463     {
1464         ImplHeadItem* pItem = mpItemList->GetObject( nPos );
1465         if ( pItem->mnBits != nNewBits )
1466         {
1467             pItem->mnBits = nNewBits;
1468             ImplUpdate( nPos );
1469         }
1470     }
1471 }
1472 
1473 // -----------------------------------------------------------------------
1474 
1475 HeaderBarItemBits HeaderBar::GetItemBits( sal_uInt16 nItemId ) const
1476 {
1477     sal_uInt16 nPos = GetItemPos( nItemId );
1478     if ( nPos != HEADERBAR_ITEM_NOTFOUND )
1479         return mpItemList->GetObject( nPos )->mnBits;
1480     else
1481         return 0;
1482 }
1483 
1484 // -----------------------------------------------------------------------
1485 
1486 void HeaderBar::SetItemData( sal_uInt16 nItemId, void* pNewData )
1487 {
1488     sal_uInt16 nPos = GetItemPos( nItemId );
1489     if ( nPos != HEADERBAR_ITEM_NOTFOUND )
1490     {
1491         mpItemList->GetObject( nPos )->mpUserData = pNewData;
1492         ImplUpdate( nPos );
1493     }
1494 }
1495 
1496 // -----------------------------------------------------------------------
1497 
1498 void* HeaderBar::GetItemData( sal_uInt16 nItemId ) const
1499 {
1500     sal_uInt16 nPos = GetItemPos( nItemId );
1501     if ( nPos != HEADERBAR_ITEM_NOTFOUND )
1502         return mpItemList->GetObject( nPos )->mpUserData;
1503     else
1504         return NULL;
1505 }
1506 
1507 // -----------------------------------------------------------------------
1508 
1509 void HeaderBar::SetItemImage( sal_uInt16 nItemId, const Image& rImage )
1510 {
1511     sal_uInt16 nPos = GetItemPos( nItemId );
1512     if ( nPos != HEADERBAR_ITEM_NOTFOUND )
1513     {
1514         mpItemList->GetObject( nPos )->maImage = rImage;
1515         ImplUpdate( nPos );
1516     }
1517 }
1518 
1519 // -----------------------------------------------------------------------
1520 
1521 Image HeaderBar::GetItemImage( sal_uInt16 nItemId ) const
1522 {
1523     sal_uInt16 nPos = GetItemPos( nItemId );
1524     if ( nPos != HEADERBAR_ITEM_NOTFOUND )
1525         return mpItemList->GetObject( nPos )->maImage;
1526     else
1527         return Image();
1528 }
1529 
1530 // -----------------------------------------------------------------------
1531 
1532 void HeaderBar::SetItemText( sal_uInt16 nItemId, const XubString& rText )
1533 {
1534     sal_uInt16 nPos = GetItemPos( nItemId );
1535     if ( nPos != HEADERBAR_ITEM_NOTFOUND )
1536     {
1537         mpItemList->GetObject( nPos )->maText = rText;
1538         ImplUpdate( nPos );
1539     }
1540 }
1541 
1542 // -----------------------------------------------------------------------
1543 
1544 XubString HeaderBar::GetItemText( sal_uInt16 nItemId ) const
1545 {
1546     sal_uInt16 nPos = GetItemPos( nItemId );
1547     if ( nPos != HEADERBAR_ITEM_NOTFOUND )
1548         return mpItemList->GetObject( nPos )->maText;
1549     else
1550         return String();
1551 }
1552 
1553 // -----------------------------------------------------------------------
1554 
1555 void HeaderBar::SetHelpText( sal_uInt16 nItemId, const XubString& rText )
1556 {
1557     sal_uInt16 nPos = GetItemPos( nItemId );
1558     if ( nPos != HEADERBAR_ITEM_NOTFOUND )
1559         mpItemList->GetObject( nPos )->maHelpText = rText;
1560 }
1561 
1562 // -----------------------------------------------------------------------
1563 
1564 XubString HeaderBar::GetHelpText( sal_uInt16 nItemId ) const
1565 {
1566     sal_uInt16 nPos = GetItemPos( nItemId );
1567     if ( nPos != HEADERBAR_ITEM_NOTFOUND )
1568     {
1569         ImplHeadItem* pItem = mpItemList->GetObject( nPos );
1570         if ( !pItem->maHelpText.Len() && pItem->maHelpId.getLength() )
1571         {
1572             Help* pHelp = Application::GetHelp();
1573             if ( pHelp )
1574                 pItem->maHelpText = pHelp->GetHelpText( rtl::OStringToOUString( pItem->maHelpId, RTL_TEXTENCODING_UTF8 ), this );
1575         }
1576 
1577         return pItem->maHelpText;
1578     }
1579     else
1580         return XubString();
1581 }
1582 
1583 // -----------------------------------------------------------------------
1584 
1585 void HeaderBar::SetHelpId( sal_uInt16 nItemId, const rtl::OString& rHelpId )
1586 {
1587     sal_uInt16 nPos = GetItemPos( nItemId );
1588     if ( nPos != HEADERBAR_ITEM_NOTFOUND )
1589         mpItemList->GetObject( nPos )->maHelpId = rHelpId;
1590 }
1591 
1592 // -----------------------------------------------------------------------
1593 
1594 rtl::OString HeaderBar::GetHelpId( sal_uInt16 nItemId ) const
1595 {
1596     sal_uInt16 nPos = GetItemPos( nItemId );
1597     rtl::OString aRet;
1598     if ( nPos != HEADERBAR_ITEM_NOTFOUND )
1599         aRet = mpItemList->GetObject( nPos )->maHelpId;
1600     return aRet;
1601 }
1602 
1603 // -----------------------------------------------------------------------
1604 
1605 Size HeaderBar::CalcWindowSizePixel() const
1606 {
1607     long nMaxImageSize = 0;
1608     Size aSize( 0, GetTextHeight() );
1609 
1610     ImplHeadItem* pItem = mpItemList->First();
1611     while ( pItem )
1612     {
1613         // Image-Groessen beruecksichtigen
1614         long nImageHeight = pItem->maImage.GetSizePixel().Height();
1615         if ( !(pItem->mnBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) && pItem->maText.Len() )
1616             nImageHeight += aSize.Height();
1617         if ( nImageHeight > nMaxImageSize )
1618             nMaxImageSize = nImageHeight;
1619 
1620         // Breite aufaddieren
1621         aSize.Width() += pItem->mnSize;
1622 
1623         pItem = mpItemList->Next();
1624     }
1625 
1626     if ( nMaxImageSize > aSize.Height() )
1627         aSize.Height() = nMaxImageSize;
1628 
1629     // Border aufaddieren
1630     if ( mbButtonStyle )
1631         aSize.Height() += 4;
1632     else
1633         aSize.Height() += 2;
1634     aSize.Height() += mnBorderOff1+mnBorderOff2;
1635 
1636     return aSize;
1637 }
1638 
1639 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > HeaderBar::CreateAccessible()
1640 {
1641     if ( !mxAccessible.is() )
1642     {
1643         if ( maCreateAccessibleHdl.IsSet() )
1644             maCreateAccessibleHdl.Call( this );
1645 
1646         if ( !mxAccessible.is() )
1647             mxAccessible = Window::CreateAccessible();
1648     }
1649 
1650     return mxAccessible;
1651 }
1652 
1653 void HeaderBar::SetAccessible( ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > _xAccessible )
1654 {
1655     mxAccessible = _xAccessible;
1656 }
1657 
1658 //IAccessibility2 Implementation 2009-----
1659 ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > HeaderBar::GetComponentInterface( sal_Bool bCreate )
1660 {
1661     ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > xPeer
1662         (Window::GetComponentInterface(false));
1663     if ( !xPeer.is() && bCreate )
1664     {
1665         ::com::sun::star::awt::XWindowPeer* mxPeer = new VCLXHeaderBar(this);
1666         m_pVCLXHeaderBar = (VCLXHeaderBar*)(mxPeer);
1667         SetComponentInterface(mxPeer);
1668         return mxPeer;
1669     }
1670     else
1671         return xPeer;
1672 }
1673 //-----IAccessibility2 Implementation 2009
1674 
1675