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