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