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