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