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