xref: /AOO41X/main/vcl/source/window/toolbox2.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_vcl.hxx"
30 
31 #include <tools/list.hxx>
32 #include <tools/debug.hxx>
33 #include <tools/rc.h>
34 
35 #include <vcl/svapp.hxx>
36 #include <vcl/help.hxx>
37 #include <vcl/bitmap.hxx>
38 #include <vcl/toolbox.hxx>
39 #include <vcl/mnemonic.hxx>
40 #include <vcl/menu.hxx>
41 #include <vcl/unohelp.hxx>
42 #include <vcl/ImageListProvider.hxx>
43 
44 #include <svdata.hxx>
45 #include <brdwin.hxx>
46 #include <toolbox.h>
47 
48 #include <unotools/confignode.hxx>
49 
50 #include <com/sun/star/lang/IllegalArgumentException.hpp>
51 
52 using namespace vcl;
53 using namespace rtl;
54 
55 // =======================================================================
56 
57 #define TB_SEP_SIZE 			8
58 
59 // -----------------------------------------------------------------------
60 
61 ImplToolBoxPrivateData::ImplToolBoxPrivateData() :
62         m_pLayoutData( NULL ),
63         mpImageListProvider( NULL ),
64         meImageListType( vcl::IMAGELISTTYPE_UNKNOWN )
65 {
66     meButtonSize = TOOLBOX_BUTTONSIZE_DONTCARE;
67     mpMenu = new PopupMenu();
68     mnEventId = 0;
69 
70     maMenuType = TOOLBOX_MENUTYPE_NONE;
71     maMenubuttonItem.maItemSize = Size( TB_MENUBUTTON_SIZE+TB_MENUBUTTON_OFFSET, TB_MENUBUTTON_SIZE+TB_MENUBUTTON_OFFSET );
72     maMenubuttonItem.meState = STATE_NOCHECK;
73     mnMenuButtonWidth = TB_MENUBUTTON_SIZE;
74 
75 
76     mbIsLocked = sal_False;
77     mbNativeButtons = sal_False;
78     mbIsPaintLocked = sal_False;
79     mbAssumeDocked = sal_False;
80     mbAssumePopupMode = sal_False;
81     mbAssumeFloating = sal_False;
82     mbKeyInputDisabled = sal_False;
83     mbMenubuttonSelected = sal_False;
84     mbPageScroll = sal_False;
85     mbWillUsePopupMode = sal_False;
86     mbDropDownByKeyboard = sal_False;
87 }
88 
89 ImplToolBoxPrivateData::~ImplToolBoxPrivateData()
90 {
91     if( m_pLayoutData )
92         delete m_pLayoutData;
93     delete mpMenu;
94 }
95 
96 // -----------------------------------------------------------------------
97 ImplToolItem::ImplToolItem()
98 {
99 	mnId			= 0;
100 	mpWindow		= NULL;
101 	mpUserData		= NULL;
102 	meType			= TOOLBOXITEM_BUTTON;
103 	mnBits			= 0;
104 	meState 		= STATE_NOCHECK;
105 	mbEnabled		= sal_True;
106 	mbVisible		= sal_True;
107 	mbEmptyBtn		= sal_True;
108 	mbShowWindow	= sal_False;
109 	mbBreak 		= sal_False;
110 	mnSepSize		= TB_SEP_SIZE;
111     mnDropDownArrowWidth = TB_DROPDOWNARROWWIDTH;
112     mnImageAngle	= 0;
113     mbMirrorMode	= sal_False;
114     mbVisibleText   = sal_False;
115 }
116 
117 // -----------------------------------------------------------------------
118 
119 ImplToolItem::ImplToolItem( sal_uInt16 nItemId, const Image& rImage,
120 							ToolBoxItemBits nItemBits ) :
121 	maImage( rImage )
122 {
123 	mnId			= nItemId;
124 	mpWindow		= NULL;
125 	mpUserData		= NULL;
126 	meType			= TOOLBOXITEM_BUTTON;
127 	mnBits			= nItemBits;
128 	meState 		= STATE_NOCHECK;
129 	mbEnabled		= sal_True;
130 	mbVisible		= sal_True;
131 	mbEmptyBtn		= sal_False;
132 	mbShowWindow	= sal_False;
133 	mbBreak 		= sal_False;
134 	mnSepSize		= TB_SEP_SIZE;
135     mnDropDownArrowWidth = TB_DROPDOWNARROWWIDTH;
136     mnImageAngle	= 0;
137     mbMirrorMode	= false;
138     mbVisibleText   = false;
139 }
140 
141 // -----------------------------------------------------------------------
142 
143 ImplToolItem::ImplToolItem( sal_uInt16 nItemId, const XubString& rText,
144 							ToolBoxItemBits nItemBits ) :
145 	maText( rText )
146 {
147 	mnId			= nItemId;
148 	mpWindow		= NULL;
149 	mpUserData		= NULL;
150 	meType			= TOOLBOXITEM_BUTTON;
151 	mnBits			= nItemBits;
152 	meState 		= STATE_NOCHECK;
153 	mbEnabled		= sal_True;
154 	mbVisible		= sal_True;
155 	mbEmptyBtn		= sal_False;
156 	mbShowWindow	= sal_False;
157 	mbBreak 		= sal_False;
158 	mnSepSize		= TB_SEP_SIZE;
159     mnDropDownArrowWidth = TB_DROPDOWNARROWWIDTH;
160     mnImageAngle	= 0;
161     mbMirrorMode	= false;
162     mbVisibleText   = false;
163 }
164 
165 // -----------------------------------------------------------------------
166 
167 ImplToolItem::ImplToolItem( sal_uInt16 nItemId, const Image& rImage,
168 							const XubString& rText, ToolBoxItemBits nItemBits ) :
169 	maImage( rImage ),
170 	maText( rText )
171 {
172 	mnId			= nItemId;
173 	mpWindow		= NULL;
174 	mpUserData		= NULL;
175 	meType			= TOOLBOXITEM_BUTTON;
176 	mnBits			= nItemBits;
177 	meState 		= STATE_NOCHECK;
178 	mbEnabled		= sal_True;
179 	mbVisible		= sal_True;
180 	mbEmptyBtn		= sal_False;
181 	mbShowWindow	= sal_False;
182 	mbBreak 		= sal_False;
183 	mnSepSize		= TB_SEP_SIZE;
184     mnDropDownArrowWidth = TB_DROPDOWNARROWWIDTH;
185     mnImageAngle	= 0;
186     mbMirrorMode	= false;
187     mbVisibleText   = false;
188 }
189 
190 // -----------------------------------------------------------------------
191 
192 ImplToolItem::ImplToolItem( const ImplToolItem& rItem ) :
193         mpWindow				( rItem.mpWindow ),
194         mpUserData				( rItem.mpUserData ),
195         maImage					( rItem.maImage ),
196         maHighImage				( rItem.maHighImage ),
197         mnImageAngle			( rItem.mnImageAngle ),
198         mbMirrorMode			( rItem.mbMirrorMode ),
199         maText					( rItem.maText ),
200         maQuickHelpText			( rItem.maQuickHelpText ),
201         maHelpText				( rItem.maHelpText ),
202         maCommandStr			( rItem.maCommandStr ),
203         maHelpId				( rItem.maHelpId ),
204         maRect					( rItem.maRect ),
205         maCalcRect				( rItem.maCalcRect ),
206         maItemSize				( rItem.maItemSize ),
207         mnSepSize				( rItem.mnSepSize ),
208         mnDropDownArrowWidth    ( rItem.mnDropDownArrowWidth ),
209         meType					( rItem.meType ),
210         mnBits					( rItem.mnBits ),
211         meState					( rItem.meState ),
212         mnId					( rItem.mnId ),
213         mbEnabled				( rItem.mbEnabled ),
214         mbVisible				( rItem.mbVisible ),
215         mbEmptyBtn				( rItem.mbEmptyBtn ),
216         mbShowWindow			( rItem.mbShowWindow ),
217         mbBreak					( rItem.mbBreak ),
218         mbVisibleText			( rItem.mbVisibleText )
219 {
220 }
221 
222 // -----------------------------------------------------------------------
223 
224 ImplToolItem::~ImplToolItem()
225 {
226 }
227 
228 // -----------------------------------------------------------------------
229 
230 ImplToolItem& ImplToolItem::operator=( const ImplToolItem& rItem )
231 {
232     mpWindow				= rItem.mpWindow;
233     mpUserData				= rItem.mpUserData;
234     maImage					= rItem.maImage;
235     maHighImage				= rItem.maHighImage;
236     mnImageAngle			= rItem.mnImageAngle;
237     mbMirrorMode			= rItem.mbMirrorMode;
238     maText					= rItem.maText;
239     maQuickHelpText			= rItem.maQuickHelpText;
240     maHelpText				= rItem.maHelpText;
241     maCommandStr			= rItem.maCommandStr;
242     maHelpId				= rItem.maHelpId;
243     maRect					= rItem.maRect;
244     maCalcRect				= rItem.maCalcRect;
245     mnSepSize				= rItem.mnSepSize;
246     mnDropDownArrowWidth    = rItem.mnDropDownArrowWidth;
247     maItemSize				= rItem.maItemSize;
248     mbVisibleText			= rItem.mbVisibleText;
249     meType					= rItem.meType;
250     mnBits					= rItem.mnBits;
251     meState					= rItem.meState;
252     mnId					= rItem.mnId;
253     mbEnabled				= rItem.mbEnabled;
254     mbVisible				= rItem.mbVisible;
255     mbEmptyBtn				= rItem.mbEmptyBtn;
256     mbShowWindow			= rItem.mbShowWindow;
257     mbBreak					= rItem.mbBreak;
258     return *this;
259 }
260 
261 // -----------------------------------------------------------------------
262 
263 Size ImplToolItem::GetSize( sal_Bool bHorz, sal_Bool bCheckMaxWidth, long maxWidth, const Size& rDefaultSize )
264 {
265     Size aSize( rDefaultSize ); // the size of 'standard' toolbox items
266                                 // non-standard items are eg windows or buttons with text
267 
268     if ( (meType == TOOLBOXITEM_BUTTON) || (meType == TOOLBOXITEM_SPACE) )
269     {
270         aSize = maItemSize;
271 
272         if ( mpWindow && bHorz )
273         {
274             // get size of item window and check if it fits
275             // no windows in vertical toolbars (the default is mbShowWindow=sal_False)
276             Size aWinSize = mpWindow->GetSizePixel();
277             if ( !bCheckMaxWidth || (aWinSize.Width() <= maxWidth) )
278             {
279                 aSize.Width()   = aWinSize.Width();
280                 aSize.Height()  = aWinSize.Height();
281                 mbShowWindow = sal_True;
282             }
283             else
284             {
285                 if ( mbEmptyBtn )
286                 {
287                     aSize.Width()   = 0;
288                     aSize.Height()  = 0;
289                 }
290             }
291         }
292     }
293     else if ( meType == TOOLBOXITEM_SEPARATOR )
294     {
295         if ( bHorz )
296         {
297             aSize.Width()   = mnSepSize;
298             aSize.Height()  = rDefaultSize.Height();
299         }
300         else
301         {
302             aSize.Width()   = rDefaultSize.Width();
303             aSize.Height()  = mnSepSize;
304         }
305     }
306     else if ( meType == TOOLBOXITEM_BREAK )
307     {
308         aSize.Width()   = 0;
309         aSize.Height()  = 0;
310     }
311 
312     return aSize;
313 }
314 
315 // -----------------------------------------------------------------------
316 
317 void ImplToolItem::DetermineButtonDrawStyle( ButtonType eButtonType, sal_Bool& rbImage, sal_Bool& rbText ) const
318 {
319     if ( meType != TOOLBOXITEM_BUTTON )
320     {
321         // no button -> draw nothing
322         rbImage = rbText = sal_False;
323         return;
324     }
325 
326     sal_Bool bHasImage;
327     sal_Bool bHasText;
328 
329     // check for image and/or text
330     if ( !(maImage) )
331         bHasImage = sal_False;
332     else
333         bHasImage = sal_True;
334     if ( !maText.Len() )
335         bHasText = sal_False;
336     else
337         bHasText = sal_True;
338 
339     // prefer images if symbolonly buttons are drawn
340     // prefer texts if textonly buttons are dreawn
341 
342     if ( eButtonType == BUTTON_SYMBOL )         // drawing icons only
343     {
344         if( bHasImage || !bHasText )
345         {
346             rbImage = sal_True;
347             rbText  = sal_False;
348         }
349         else
350         {
351             rbImage = sal_False;
352             rbText  = sal_True;
353         }
354     }
355     else if ( eButtonType == BUTTON_TEXT )      // drawing text only
356     {
357         if( bHasText || !bHasImage )
358         {
359             rbImage = sal_False;
360             rbText  = sal_True;
361         }
362         else
363         {
364             rbImage = sal_True;
365             rbText  = sal_False;
366         }
367     }
368     else                                        // drawing icons and text both
369     {
370         rbImage = sal_True;
371         rbText  = sal_True;
372     }
373 }
374 
375 // -----------------------------------------------------------------------
376 
377 Rectangle ImplToolItem::GetDropDownRect( sal_Bool bHorz ) const
378 {
379     Rectangle aRect;
380     if( (mnBits & TIB_DROPDOWN) && !maRect.IsEmpty() )
381     {
382         aRect = maRect;
383         if( mbVisibleText && !bHorz )
384             // item will be rotated -> place dropdown to the bottom
385             aRect.Top() = aRect.Bottom() - mnDropDownArrowWidth;
386         else
387             // place dropdown to the right
388             aRect.Left() = aRect.Right() - mnDropDownArrowWidth;
389     }
390     return aRect;
391 }
392 
393 // -----------------------------------------------------------------------
394 
395 sal_Bool ImplToolItem::IsClipped() const
396 {
397     return ( meType == TOOLBOXITEM_BUTTON && mbVisible && maRect.IsEmpty() );
398 }
399 
400 // -----------------------------------------------------------------------
401 // -----------------------------------------------------------------------
402 
403 const XubString& ToolBox::ImplConvertMenuString( const XubString& rStr )
404 {
405     maCvtStr = rStr;
406 	if ( mbMenuStrings )
407 		maCvtStr.EraseTrailingChars( '.' );
408 	maCvtStr = MnemonicGenerator::EraseAllMnemonicChars( maCvtStr );
409 	return maCvtStr;
410 }
411 
412 // -----------------------------------------------------------------------
413 
414 void ToolBox::ImplInvalidate( sal_Bool bNewCalc, sal_Bool bFullPaint )
415 {
416 	ImplUpdateInputEnable();
417 
418 	if ( bNewCalc )
419 		mbCalc = sal_True;
420 
421 	if ( bFullPaint )
422 	{
423 		mbFormat = sal_True;
424 
425 		// Muss ueberhaupt eine neue Ausgabe erfolgen
426 		if ( IsReallyVisible() && IsUpdateMode() )
427 		{
428 			Invalidate( Rectangle( mnLeftBorder, mnTopBorder,
429 								   mnDX-mnRightBorder-1, mnDY-mnBottomBorder-1 ) );
430 			maTimer.Stop();
431 		}
432 	}
433 	else
434 	{
435 		if ( !mbFormat )
436 		{
437 			mbFormat = sal_True;
438 
439 			// Muss ueberhaupt eine neue Ausgabe erfolgen
440 			if ( IsReallyVisible() && IsUpdateMode() )
441 				maTimer.Start();
442 		}
443 	}
444 
445     // request new layout by layoutmanager
446     ImplCallEventListeners( VCLEVENT_TOOLBOX_FORMATCHANGED );
447 }
448 
449 // -----------------------------------------------------------------------
450 
451 void ToolBox::ImplUpdateItem( sal_uInt16 nIndex )
452 {
453 	// Muss ueberhaupt eine neue Ausgabe erfolgen
454 	if ( IsReallyVisible() && IsUpdateMode() )
455 	{
456 		if ( nIndex == 0xFFFF )
457 		{
458             // #i52217# no immediate draw as this might lead to paint problems
459 			Invalidate( Rectangle( mnLeftBorder, mnTopBorder,
460 									mnDX-mnRightBorder-1, mnDY-mnBottomBorder-1 ) );
461 		}
462 		else
463 		{
464 			if ( !mbFormat )
465             {
466                 // #i52217# no immediate draw as this might lead to paint problems
467                 Invalidate( mpData->m_aItems[nIndex].maRect );
468             }
469 			else
470 				maPaintRect.Union( mpData->m_aItems[nIndex].maRect );
471 		}
472 	}
473 }
474 
475 // -----------------------------------------------------------------------
476 
477 void ToolBox::Click()
478 {
479     ImplCallEventListeners( VCLEVENT_TOOLBOX_CLICK );
480 	maClickHdl.Call( this );
481 }
482 
483 // -----------------------------------------------------------------------
484 
485 void ToolBox::DoubleClick()
486 {
487     ImplCallEventListeners( VCLEVENT_TOOLBOX_DOUBLECLICK );
488 	maDoubleClickHdl.Call( this );
489 }
490 
491 // -----------------------------------------------------------------------
492 
493 void ToolBox::Activate()
494 {
495     mnActivateCount++;
496     ImplCallEventListeners( VCLEVENT_TOOLBOX_ACTIVATE );
497 	maActivateHdl.Call( this );
498 }
499 
500 // -----------------------------------------------------------------------
501 
502 void ToolBox::Deactivate()
503 {
504     mnActivateCount--;
505     ImplCallEventListeners( VCLEVENT_TOOLBOX_DEACTIVATE );
506 	maDeactivateHdl.Call( this );
507 
508 	if ( mbHideStatusText )
509 	{
510 		GetpApp()->HideHelpStatusText();
511 		mbHideStatusText = sal_False;
512 	}
513 }
514 
515 // -----------------------------------------------------------------------
516 
517 void ToolBox::Highlight()
518 {
519     ImplCallEventListeners( VCLEVENT_TOOLBOX_HIGHLIGHT );
520 	maHighlightHdl.Call( this );
521 
522 	XubString aStr = GetHelpText( mnCurItemId );
523 	if ( aStr.Len() || mbHideStatusText )
524 	{
525 		GetpApp()->ShowHelpStatusText( aStr );
526 		mbHideStatusText = sal_True;
527 	}
528 }
529 
530 // -----------------------------------------------------------------------
531 
532 void ToolBox::Select()
533 {
534     ImplDelData aDelData;
535     ImplAddDel( &aDelData );
536 
537     ImplCallEventListeners( VCLEVENT_TOOLBOX_SELECT );
538 	maSelectHdl.Call( this );
539 
540     if ( aDelData.IsDelete() )
541         return;
542     ImplRemoveDel( &aDelData );
543 
544     // TODO: GetFloatingWindow in DockingWindow is currently inline, change it to check dockingwrapper
545     ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
546     if( pWrapper && pWrapper->GetFloatingWindow() && pWrapper->GetFloatingWindow()->IsInPopupMode() )
547         pWrapper->GetFloatingWindow()->EndPopupMode();
548 }
549 
550 // -----------------------------------------------------------------------
551 
552 void ToolBox::NextToolBox()
553 {
554 	maNextToolBoxHdl.Call( this );
555 }
556 
557 // -----------------------------------------------------------------------
558 
559 void ToolBox::Customize( const ToolBoxCustomizeEvent& )
560 {
561 }
562 
563 // -----------------------------------------------------------------------
564 
565 void ToolBox::UserDraw( const UserDrawEvent& )
566 {
567 }
568 
569 // -----------------------------------------------------------------------
570 
571 void ToolBox::InsertItem( const ResId& rResId, sal_uInt16 nPos )
572 {
573 	sal_uLong					nObjMask;
574 	sal_Bool					bImage = sal_False; 	// Wurde Image gesetzt
575 
576 	// Item anlegen
577 	ImplToolItem aItem;
578 
579 	GetRes( rResId.SetRT( RSC_TOOLBOXITEM ) );
580 	nObjMask			= ReadLongRes();
581 
582 	if ( nObjMask & RSC_TOOLBOXITEM_ID )
583 		aItem.mnId = sal::static_int_cast<sal_uInt16>(ReadLongRes());
584 	else
585 		aItem.mnId = 1;
586 
587 	if ( nObjMask & RSC_TOOLBOXITEM_TYPE )
588 		aItem.meType = (ToolBoxItemType)ReadLongRes();
589 
590 	if ( nObjMask & RSC_TOOLBOXITEM_STATUS )
591 		aItem.mnBits = (ToolBoxItemBits)ReadLongRes();
592 
593 	if( nObjMask & RSC_TOOLBOXITEM_HELPID )
594 		aItem.maHelpId = ReadByteStringRes();
595 
596 	if ( nObjMask & RSC_TOOLBOXITEM_TEXT )
597 	{
598 		aItem.maText = ReadStringRes();
599 		aItem.maText = ImplConvertMenuString( aItem.maText );
600 	}
601 	if ( nObjMask & RSC_TOOLBOXITEM_HELPTEXT )
602 		aItem.maHelpText = ReadStringRes();
603 
604 	if ( nObjMask & RSC_TOOLBOXITEM_BITMAP )
605 	{
606 		Bitmap aBmp = Bitmap( ResId( (RSHEADER_TYPE*)GetClassRes(), *rResId.GetResMgr() ) );
607 		IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) );
608 		aItem.maImage = Image( aBmp, IMAGE_STDBTN_COLOR );
609 		bImage = sal_True;
610 	}
611 	if ( nObjMask & RSC_TOOLBOXITEM_IMAGE )
612 	{
613 		aItem.maImage = Image( ResId( (RSHEADER_TYPE*)GetClassRes(), *rResId.GetResMgr() ) );
614 		IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) );
615 		bImage = sal_True;
616 	}
617 	if ( nObjMask & RSC_TOOLBOXITEM_DISABLE )
618 		aItem.mbEnabled = !(sal_Bool)ReadShortRes();
619 
620 	if ( nObjMask & RSC_TOOLBOXITEM_STATE )
621 		aItem.meState	= (TriState)ReadLongRes();
622 
623 	if ( nObjMask & RSC_TOOLBOXITEM_HIDE )
624 		aItem.mbVisible = !((sal_Bool)ReadShortRes());
625 
626 	if ( nObjMask & RSC_TOOLBOXITEM_COMMAND )
627 		aItem.maCommandStr = ReadStringRes();
628 
629 	// Wenn kein Image geladen wurde, versuchen wir das Image aus der
630 	// Image-Liste zu holen
631 	if ( !bImage && aItem.mnId )
632 		aItem.maImage = maImageList.GetImage( aItem.mnId );
633 
634 	// Wenn es sich um ein ButtonItem handelt, die ID ueberpruefen
635 	sal_Bool bNewCalc;
636 	if ( aItem.meType != TOOLBOXITEM_BUTTON )
637 	{
638 		bNewCalc = sal_False;
639 		aItem.mnId = 0;
640 	}
641 	else
642 	{
643 		bNewCalc = sal_True;
644 
645 		DBG_ASSERT( aItem.mnId, "ToolBox::InsertItem(): ItemId == 0" );
646 		DBG_ASSERT( GetItemPos( aItem.mnId ) == TOOLBOX_ITEM_NOTFOUND,
647 					"ToolBox::InsertItem(): ItemId already exists" );
648 	}
649 
650 	// Item anlegen und in die Liste einfuegen
651     mpData->m_aItems.insert( (nPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nPos : mpData->m_aItems.end(), aItem );
652     mpData->ImplClearLayoutData();
653 
654 	// ToolBox neu brechnen und neu ausgeben
655 	ImplInvalidate( bNewCalc );
656 
657     // Notify
658 	sal_uInt16 nNewPos = sal::static_int_cast<sal_uInt16>(( nPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nPos);
659     ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >( nNewPos ) );
660 }
661 
662 // -----------------------------------------------------------------------
663 
664 void ToolBox::InsertItem( sal_uInt16 nItemId, const Image& rImage,
665 						  ToolBoxItemBits nBits, sal_uInt16 nPos )
666 {
667 	DBG_ASSERT( nItemId, "ToolBox::InsertItem(): ItemId == 0" );
668 	DBG_ASSERT( GetItemPos( nItemId ) == TOOLBOX_ITEM_NOTFOUND,
669 				"ToolBox::InsertItem(): ItemId already exists" );
670 
671 	// Item anlegen und in die Liste einfuegen
672     mpData->m_aItems.insert( (nPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nPos : mpData->m_aItems.end(), ImplToolItem( nItemId, rImage, nBits ) );
673     mpData->ImplClearLayoutData();
674 
675 	ImplInvalidate( sal_True );
676 
677     // Notify
678     sal_uInt16 nNewPos = sal::static_int_cast<sal_uInt16>(( nPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nPos);
679     ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >(nNewPos ) );
680 }
681 
682 // -----------------------------------------------------------------------
683 
684 void ToolBox::InsertItem( sal_uInt16 nItemId, const Image& rImage,
685 						  const XubString& rText,
686 						  ToolBoxItemBits nBits, sal_uInt16 nPos )
687 {
688 	DBG_ASSERT( nItemId, "ToolBox::InsertItem(): ItemId == 0" );
689 	DBG_ASSERT( GetItemPos( nItemId ) == TOOLBOX_ITEM_NOTFOUND,
690 				"ToolBox::InsertItem(): ItemId already exists" );
691 
692 	// Item anlegen und in die Liste einfuegen
693     mpData->m_aItems.insert( (nPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nPos : mpData->m_aItems.end(), ImplToolItem( nItemId, rImage, ImplConvertMenuString( rText ), nBits ) );
694     mpData->ImplClearLayoutData();
695 
696 	ImplInvalidate( sal_True );
697 
698     // Notify
699     sal_uInt16 nNewPos = sal::static_int_cast<sal_uInt16>(( nPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nPos);
700     ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >( nNewPos ) );
701 }
702 
703 // -----------------------------------------------------------------------
704 
705 void ToolBox::InsertItem( sal_uInt16 nItemId, const XubString& rText,
706 						  ToolBoxItemBits nBits, sal_uInt16 nPos )
707 {
708 	DBG_ASSERT( nItemId, "ToolBox::InsertItem(): ItemId == 0" );
709 	DBG_ASSERT( GetItemPos( nItemId ) == TOOLBOX_ITEM_NOTFOUND,
710 				"ToolBox::InsertItem(): ItemId already exists" );
711 
712 	// Item anlegen und in die Liste einfuegen
713     mpData->m_aItems.insert( (nPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nPos : mpData->m_aItems.end(), ImplToolItem( nItemId, ImplConvertMenuString( rText ), nBits ) );
714     mpData->ImplClearLayoutData();
715 
716 	ImplInvalidate( sal_True );
717 
718     // Notify
719     sal_uInt16 nNewPos = sal::static_int_cast<sal_uInt16>(( nPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nPos);
720     ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >( nNewPos ) );
721 }
722 
723 // -----------------------------------------------------------------------
724 
725 void ToolBox::InsertWindow( sal_uInt16 nItemId, Window* pWindow,
726 							ToolBoxItemBits nBits, sal_uInt16 nPos )
727 {
728 	DBG_ASSERT( nItemId, "ToolBox::InsertWindow(): ItemId == 0" );
729 	DBG_ASSERT( GetItemPos( nItemId ) == TOOLBOX_ITEM_NOTFOUND,
730 				"ToolBox::InsertWindow(): ItemId already exists" );
731 
732 	// Item anlegen und in die Liste einfuegen
733 	ImplToolItem aItem;
734 	aItem.mnId 		 = nItemId;
735 	aItem.meType	 = TOOLBOXITEM_BUTTON;
736 	aItem.mnBits	 = nBits;
737 	aItem.mpWindow 	 = pWindow;
738     mpData->m_aItems.insert( (nPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nPos : mpData->m_aItems.end(), aItem );
739     mpData->ImplClearLayoutData();
740 
741 	if ( pWindow )
742 		pWindow->Hide();
743 
744 	ImplInvalidate( sal_True );
745 
746     // Notify
747     sal_uInt16 nNewPos = sal::static_int_cast<sal_uInt16>(( nPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nPos);
748     ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >( nNewPos ) );
749 }
750 
751 // -----------------------------------------------------------------------
752 
753 void ToolBox::InsertSpace( sal_uInt16 nPos )
754 {
755 	// Item anlegen und in die Liste einfuegen
756 	ImplToolItem aItem;
757 	aItem.meType	 = TOOLBOXITEM_SPACE;
758 	aItem.mbEnabled	 = sal_False;
759     mpData->m_aItems.insert( (nPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nPos : mpData->m_aItems.end(), aItem );
760     mpData->ImplClearLayoutData();
761 
762 	ImplInvalidate( sal_False );
763 
764     // Notify
765     sal_uInt16 nNewPos = sal::static_int_cast<sal_uInt16>(( nPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nPos);
766     ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >( nNewPos ) );
767 }
768 
769 // -----------------------------------------------------------------------
770 
771 void ToolBox::InsertSeparator( sal_uInt16 nPos, sal_uInt16 nPixSize )
772 {
773 	// Item anlegen und in die Liste einfuegen
774 	ImplToolItem aItem;
775 	aItem.meType	 = TOOLBOXITEM_SEPARATOR;
776 	aItem.mbEnabled	 = sal_False;
777 	if ( nPixSize )
778 		aItem.mnSepSize = nPixSize;
779     mpData->m_aItems.insert( (nPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nPos : mpData->m_aItems.end(), aItem );
780     mpData->ImplClearLayoutData();
781 
782 	ImplInvalidate( sal_False );
783 
784     // Notify
785     sal_uInt16 nNewPos = sal::static_int_cast<sal_uInt16>(( nPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nPos);
786     ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >( nNewPos ) );
787 }
788 
789 // -----------------------------------------------------------------------
790 
791 void ToolBox::InsertBreak( sal_uInt16 nPos )
792 {
793 	// Item anlegen und in die Liste einfuegen
794 	ImplToolItem aItem;
795 	aItem.meType	 = TOOLBOXITEM_BREAK;
796 	aItem.mbEnabled	 = sal_False;
797     mpData->m_aItems.insert( (nPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nPos : mpData->m_aItems.end(), aItem );
798     mpData->ImplClearLayoutData();
799 
800 	ImplInvalidate( sal_False );
801 
802     // Notify
803     sal_uInt16 nNewPos = sal::static_int_cast<sal_uInt16>(( nPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nPos);
804     ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >( nNewPos ) );
805 }
806 
807 // -----------------------------------------------------------------------
808 
809 void ToolBox::RemoveItem( sal_uInt16 nPos )
810 {
811     if( nPos < mpData->m_aItems.size() )
812 	{
813 		sal_Bool bMustCalc;
814 		if ( mpData->m_aItems[nPos].meType == TOOLBOXITEM_BUTTON )
815 			bMustCalc = sal_True;
816 		else
817 			bMustCalc = sal_False;
818 
819 		if ( mpData->m_aItems[nPos].mpWindow )
820 			mpData->m_aItems[nPos].mpWindow->Hide();
821 
822 		// PaintRect um das removete Item erweitern
823 		maPaintRect.Union( mpData->m_aItems[nPos].maRect );
824 
825 		// Absichern gegen das Loeschen im Select-Handler
826 		if ( mpData->m_aItems[nPos].mnId == mnCurItemId )
827 			mnCurItemId = 0;
828 		if ( mpData->m_aItems[nPos].mnId == mnHighItemId )
829 			mnHighItemId = 0;
830 
831 		ImplInvalidate( bMustCalc );
832 
833         mpData->m_aItems.erase( mpData->m_aItems.begin()+nPos );
834         mpData->ImplClearLayoutData();
835 
836         // Notify
837         ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMREMOVED, reinterpret_cast< void* >( nPos ) );
838 	}
839 }
840 
841 // -----------------------------------------------------------------------
842 
843 void ToolBox::MoveItem( sal_uInt16 nItemId, sal_uInt16 nNewPos )
844 {
845 	sal_uInt16 nPos = GetItemPos( nItemId );
846 
847 	if ( nPos == nNewPos )
848 		return;
849 
850 	if ( nPos < nNewPos )
851 		nNewPos--;
852 
853 	// Existiert Item
854 	if ( nPos != TOOLBOX_ITEM_NOTFOUND )
855 	{
856 		// ToolBox-Item in der Liste verschieben
857         ImplToolItem aItem = mpData->m_aItems[nPos];
858         mpData->m_aItems.erase( mpData->m_aItems.begin()+nPos );
859         mpData->m_aItems.insert( (nNewPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nNewPos : mpData->m_aItems.end(), aItem );
860         mpData->ImplClearLayoutData();
861 
862 		// ToolBox neu ausgeben
863 		ImplInvalidate( sal_False );
864 
865         // Notify
866         if( nPos < nNewPos )    // only send one event, all indices above this item are invalid anyway
867             ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMREMOVED, reinterpret_cast< void* >( nPos ) );
868         else
869 		{
870 			sal_uInt16 nNewPos2 = sal::static_int_cast<sal_uInt16>(( nNewPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nNewPos);
871 			ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >( nNewPos2 ) );
872 		}
873 	}
874 }
875 
876 // -----------------------------------------------------------------------
877 
878 void ToolBox::CopyItem( const ToolBox& rToolBox, sal_uInt16 nItemId,
879 						sal_uInt16 nNewPos )
880 {
881 	DBG_ASSERT( GetItemPos( nItemId ) == TOOLBOX_ITEM_NOTFOUND,
882 				"ToolBox::CopyItem(): ItemId already exists" );
883 
884 	sal_uInt16 nPos = rToolBox.GetItemPos( nItemId );
885 
886 	// Existiert Item
887 	if ( nPos != TOOLBOX_ITEM_NOTFOUND )
888 	{
889 		// ToolBox-Item in der Liste verschieben
890         ImplToolItem aNewItem = rToolBox.mpData->m_aItems[nPos];
891 		// Bestimme Daten zuruecksetzen
892 		aNewItem.mpWindow	   = NULL;
893 		aNewItem.mbShowWindow = sal_False;
894 
895         mpData->m_aItems.insert( (nNewPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nNewPos : mpData->m_aItems.end(), aNewItem );
896         mpData->ImplClearLayoutData();
897 		// ToolBox neu ausgeben
898 		ImplInvalidate( sal_False );
899 
900         // Notify
901 		sal_uInt16 nNewPos2 = sal::static_int_cast<sal_uInt16>(( nNewPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nNewPos);
902 		ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >( nNewPos2 ) );
903 	}
904 }
905 
906 // -----------------------------------------------------------------------
907 
908 void ToolBox::CopyItems( const ToolBox& rToolBox )
909 {
910     mpData->ImplClearLayoutData();
911     mpData->m_aItems = rToolBox.mpData->m_aItems;
912 	// Absichern gegen das Loeschen im Select-Handler
913 	mnCurItemId = 0;
914 	mnHighItemId = 0;
915 
916     for( std::vector< ImplToolItem >::iterator it = mpData->m_aItems.begin();
917          it != mpData->m_aItems.end(); ++it )
918     {
919         it->mpWindow		= NULL;
920         it->mbShowWindow	= sal_False;
921     }
922 
923 	ImplInvalidate( sal_True, sal_True );
924 
925     // Notify
926     ImplCallEventListeners( VCLEVENT_TOOLBOX_ALLITEMSCHANGED );
927 }
928 
929 // -----------------------------------------------------------------------
930 
931 void ToolBox::Clear()
932 {
933     mpData->m_aItems.clear();
934     mpData->ImplClearLayoutData();
935 
936 	// Absichern gegen das Loeschen im Select-Handler
937 	mnCurItemId = 0;
938 	mnHighItemId = 0;
939 
940 	ImplInvalidate( sal_True, sal_True );
941 
942     // Notify
943     ImplCallEventListeners( VCLEVENT_TOOLBOX_ALLITEMSCHANGED );
944 }
945 
946 // -----------------------------------------------------------------------
947 
948 void ToolBox::SetButtonType( ButtonType eNewType )
949 {
950 	if ( meButtonType != eNewType )
951 	{
952 		meButtonType = eNewType;
953 
954 		// Hier besser alles neu ausgeben, da es ansonsten zu Problemen
955 		// mit den per CopyBits kopierten Bereichen geben kann
956 		ImplInvalidate( sal_True );
957 	}
958 }
959 
960 // -----------------------------------------------------------------------
961 
962 void ToolBox::SetToolboxButtonSize( ToolBoxButtonSize eSize )
963 {
964     if( mpData->meButtonSize != eSize )
965     {
966         mpData->meButtonSize = eSize;
967 		mbCalc = sal_True;
968 		mbFormat = sal_True;
969     }
970 }
971 
972 ToolBoxButtonSize ToolBox::GetToolboxButtonSize() const
973 {
974     return mpData->meButtonSize;
975 }
976 
977 // -----------------------------------------------------------------------
978 
979 const Size& ToolBox::GetDefaultImageSize() const
980 {
981     static Size aSmallButtonSize( TB_SMALLIMAGESIZE, TB_SMALLIMAGESIZE );
982 
983     static sal_uLong s_nSymbolsStyle = STYLE_SYMBOLS_DEFAULT;
984     static Size aLargeButtonSize( TB_LARGEIMAGESIZE, TB_LARGEIMAGESIZE );
985 
986     sal_uLong nSymbolsStyle = Application::GetSettings().GetStyleSettings().GetCurrentSymbolsStyle();
987     if ( s_nSymbolsStyle != nSymbolsStyle )
988     {
989         s_nSymbolsStyle = nSymbolsStyle;
990         switch ( nSymbolsStyle )
991         {
992             case STYLE_SYMBOLS_INDUSTRIAL:
993                 aLargeButtonSize = Size( TB_LARGEIMAGESIZE_INDUSTRIAL, TB_LARGEIMAGESIZE_INDUSTRIAL );
994                 break;
995             case STYLE_SYMBOLS_CRYSTAL:
996                 aLargeButtonSize = Size( TB_LARGEIMAGESIZE_CRYSTAL, TB_LARGEIMAGESIZE_CRYSTAL );
997                 break;
998             case STYLE_SYMBOLS_OXYGEN:
999                 aLargeButtonSize = Size( TB_LARGEIMAGESIZE_OXYGEN, TB_LARGEIMAGESIZE_OXYGEN );
1000                 break;
1001             default:
1002                 aLargeButtonSize = Size( TB_LARGEIMAGESIZE, TB_LARGEIMAGESIZE );
1003         }
1004     }
1005 
1006     return GetToolboxButtonSize() == TOOLBOX_BUTTONSIZE_LARGE ? aLargeButtonSize : aSmallButtonSize;
1007 }
1008 
1009 // -----------------------------------------------------------------------
1010 
1011 void ToolBox::SetAlign( WindowAlign eNewAlign )
1012 {
1013 	if ( meAlign != eNewAlign )
1014 	{
1015 		meAlign = eNewAlign;
1016 
1017         if ( !ImplIsFloatingMode() )
1018 		{
1019 			// Setzen, ob Items horizontal oder vertikal angeordnet werden sollen
1020 			if ( (eNewAlign == WINDOWALIGN_LEFT) || (eNewAlign == WINDOWALIGN_RIGHT) )
1021 				mbHorz = sal_False;
1022 			else
1023 				mbHorz = sal_True;
1024 
1025 			// Hier alles neu ausgeben, da sich Border auch aendert
1026 			mbCalc = sal_True;
1027 			mbFormat = sal_True;
1028 			if ( IsReallyVisible() && IsUpdateMode() )
1029 				Invalidate();
1030 		}
1031 	}
1032 }
1033 
1034 // -----------------------------------------------------------------------
1035 
1036 void ToolBox::SetLineCount( sal_uInt16 nNewLines )
1037 {
1038 	if ( !nNewLines )
1039 		nNewLines = 1;
1040 
1041 	if ( mnLines != nNewLines )
1042 	{
1043 		mnLines = nNewLines;
1044 
1045 		// Hier besser alles neu ausgeben, da es ansonsten zu Problemen
1046 		// mit den per CopyBits kopierten Bereichen geben kann
1047 		ImplInvalidate( sal_False );
1048 	}
1049 }
1050 
1051 // -----------------------------------------------------------------------
1052 
1053 void ToolBox::SetPageScroll( sal_Bool b )
1054 {
1055 	mpData->mbPageScroll = b;
1056 }
1057 
1058 sal_Bool ToolBox::GetPageScroll()
1059 {
1060 	return mpData->mbPageScroll;
1061 }
1062 
1063 // -----------------------------------------------------------------------
1064 
1065 void ToolBox::SetNextToolBox( const XubString& rStr )
1066 {
1067 	sal_Bool bCalcNew = (!maNextToolBoxStr.Len() != !rStr.Len());
1068 	maNextToolBoxStr = rStr;
1069 	if ( bCalcNew )
1070 		ImplInvalidate( sal_True, sal_False );
1071 }
1072 
1073 // -----------------------------------------------------------------------
1074 
1075 sal_uInt16 ToolBox::GetItemCount() const
1076 {
1077 	return (sal_uInt16)mpData->m_aItems.size();
1078 }
1079 
1080 // -----------------------------------------------------------------------
1081 
1082 ToolBoxItemType ToolBox::GetItemType( sal_uInt16 nPos ) const
1083 {
1084     return (nPos < mpData->m_aItems.size()) ? mpData->m_aItems[nPos].meType : TOOLBOXITEM_DONTKNOW;
1085 }
1086 
1087 // -----------------------------------------------------------------------
1088 
1089 sal_uInt16 ToolBox::GetItemPos( sal_uInt16 nItemId ) const
1090 {
1091     int nCount = mpData->m_aItems.size();
1092     for( int nPos = 0; nPos < nCount; nPos++ )
1093         if( mpData->m_aItems[nPos].mnId == nItemId )
1094             return (sal_uInt16)nPos;
1095 
1096 	return TOOLBOX_ITEM_NOTFOUND;
1097 }
1098 
1099 // -----------------------------------------------------------------------
1100 
1101 sal_uInt16 ToolBox::GetItemPos( const Point& rPos ) const
1102 {
1103 	// search the item position on the given point
1104 	sal_uInt16 nRet = TOOLBOX_ITEM_NOTFOUND;
1105 	sal_uInt16 nPos = 0;
1106 	std::vector< ImplToolItem >::const_iterator it = mpData->m_aItems.begin();
1107 	while( it != mpData->m_aItems.end() )
1108 	{
1109 		if ( it->maRect.IsInside( rPos ) )
1110 		{
1111 			// item found -> save position and break
1112 			nRet = nPos;
1113 			break;
1114 		}
1115 
1116 		++it;
1117 		++nPos;
1118 	}
1119 
1120 	return nRet;
1121 }
1122 
1123 // -----------------------------------------------------------------------
1124 
1125 sal_uInt16 ToolBox::GetItemId( sal_uInt16 nPos ) const
1126 {
1127     return (nPos < mpData->m_aItems.size()) ? mpData->m_aItems[nPos].mnId : 0;
1128 }
1129 
1130 // -----------------------------------------------------------------------
1131 
1132 sal_uInt16 ToolBox::GetItemId( const Point& rPos ) const
1133 {
1134 	// Item suchen, das geklickt wurde
1135     std::vector< ImplToolItem >::const_iterator it = mpData->m_aItems.begin();
1136     while( it != mpData->m_aItems.end() )
1137 	{
1138 		// Ist es dieses Item
1139 		if ( it->maRect.IsInside( rPos ) )
1140 		{
1141 			if ( it->meType == TOOLBOXITEM_BUTTON )
1142 				return it->mnId;
1143 			else
1144 				return 0;
1145 		}
1146 
1147         ++it;
1148 	}
1149 
1150 	return 0;
1151 }
1152 
1153 // -----------------------------------------------------------------------
1154 
1155 Point ToolBox::ImplGetPopupPosition( const Rectangle& rRect, const Size& rSize ) const
1156 {
1157     Point aPos;
1158     if( !rRect.IsEmpty() )
1159     {
1160         Rectangle aScreen = GetDesktopRectPixel();
1161 
1162         // the popup should be positioned so that it will not cover
1163         // the item rect and that it fits the desktop
1164         // the preferred direction is always towards the center of
1165         // the application window
1166 
1167         Point devPos;           // the position in device coordinates for screen comparison
1168         switch( meAlign )
1169         {
1170             case WINDOWALIGN_TOP:
1171                 aPos = rRect.BottomLeft();
1172                 aPos.Y()++;
1173                 devPos = OutputToAbsoluteScreenPixel( aPos );
1174                 if( devPos.Y() + rSize.Height() >= aScreen.Bottom() )
1175                     aPos.Y() = rRect.Top() - rSize.Height();
1176                 break;
1177             case WINDOWALIGN_BOTTOM:
1178                 aPos = rRect.TopLeft();
1179                 aPos.Y()--;
1180                 devPos = OutputToAbsoluteScreenPixel( aPos );
1181                 if( devPos.Y() - rSize.Height() > aScreen.Top() )
1182                     aPos.Y() -= rSize.Height();
1183                 else
1184                     aPos.Y() = rRect.Bottom();
1185                 break;
1186             case WINDOWALIGN_LEFT:
1187                 aPos = rRect.TopRight();
1188                 aPos.X()++;
1189                 devPos = OutputToAbsoluteScreenPixel( aPos );
1190                 if( devPos.X() + rSize.Width() >= aScreen.Right() )
1191                     aPos.X() = rRect.Left() - rSize.Width();
1192                 break;
1193             case WINDOWALIGN_RIGHT:
1194                 aPos = rRect.TopLeft();
1195                 aPos.X()--;
1196                 devPos = OutputToAbsoluteScreenPixel( aPos );
1197                 if( devPos.X() - rSize.Width() > aScreen.Left() )
1198                     aPos.X() -= rSize.Width();
1199                 else
1200                     aPos.X() = rRect.Right();
1201                 break;
1202             default:
1203                 break;
1204         };
1205     }
1206     return aPos;
1207 }
1208 
1209 
1210 Point ToolBox::GetItemPopupPosition( sal_uInt16 nItemId, const Size& rSize ) const
1211 {
1212     return ImplGetPopupPosition( GetItemRect( nItemId ), rSize );
1213 }
1214 
1215 // -----------------------------------------------------------------------
1216 
1217 Rectangle ToolBox::GetItemRect( sal_uInt16 nItemId ) const
1218 {
1219 	if ( mbCalc || mbFormat )
1220 		((ToolBox*)this)->ImplFormat();
1221 
1222 	sal_uInt16 nPos = GetItemPos( nItemId );
1223     return GetItemPosRect( nPos );
1224 }
1225 
1226 // -----------------------------------------------------------------------
1227 
1228 Rectangle ToolBox::GetItemPosRect( sal_uInt16 nPos ) const
1229 {
1230 	if ( mbCalc || mbFormat )
1231 		((ToolBox*)this)->ImplFormat();
1232 
1233 	if ( nPos < mpData->m_aItems.size() )
1234 		return mpData->m_aItems[nPos].maRect;
1235 	else
1236 		return Rectangle();
1237 }
1238 
1239 // -----------------------------------------------------------------------
1240 Rectangle ToolBox::GetItemDropDownRect( sal_uInt16 nItemId ) const
1241 {
1242 	if ( mbCalc || mbFormat )
1243 		((ToolBox*)this)->ImplFormat();
1244 
1245 	sal_uInt16 nPos = GetItemPos( nItemId );
1246     return GetItemPosDropDownRect( nPos );
1247 }
1248 
1249 // -----------------------------------------------------------------------
1250 
1251 Rectangle ToolBox::GetItemPosDropDownRect( sal_uInt16 nPos ) const
1252 {
1253 	if ( mbCalc || mbFormat )
1254 		((ToolBox*)this)->ImplFormat();
1255 
1256 	if ( nPos < mpData->m_aItems.size() )
1257 		return mpData->m_aItems[nPos].GetDropDownRect( mbHorz );
1258 	else
1259 		return Rectangle();
1260 }
1261 
1262 // -----------------------------------------------------------------------
1263 
1264 Rectangle ToolBox::GetMenubuttonRect() const
1265 {
1266     return mpData->maMenubuttonItem.maRect;
1267 }
1268 
1269 sal_Bool ToolBox::ImplHasExternalMenubutton()
1270 {
1271     // check if the borderwindow (i.e. the decoration) provides the menu button
1272     sal_Bool bRet = sal_False;
1273     if( ImplIsFloatingMode() )
1274     {
1275         // custom menu is placed in the decoration
1276         ImplBorderWindow *pBorderWin = dynamic_cast<ImplBorderWindow*>( GetWindow( WINDOW_BORDER ) );
1277         if( pBorderWin && !pBorderWin->GetMenuRect().IsEmpty() )
1278             bRet = sal_True;
1279     }
1280     return bRet;
1281 }
1282 // -----------------------------------------------------------------------
1283 
1284 void ToolBox::SetItemBits( sal_uInt16 nItemId, ToolBoxItemBits nBits )
1285 {
1286 	sal_uInt16 nPos = GetItemPos( nItemId );
1287 
1288 	if ( nPos < mpData->m_aItems.size() )
1289 	{
1290 		ToolBoxItemBits nOldBits = mpData->m_aItems[nPos].mnBits;
1291 		mpData->m_aItems[nPos].mnBits = nBits;
1292 		nBits &= TIB_LEFT | TIB_AUTOSIZE | TIB_DROPDOWN;
1293 		nOldBits &= TIB_LEFT | TIB_AUTOSIZE | TIB_DROPDOWN;
1294         // trigger reformat when the item width has changed (dropdown arrow)
1295         sal_Bool bFormat = (nBits & TIB_DROPDOWN) != (nOldBits & TIB_DROPDOWN);
1296 		if ( nBits != nOldBits )
1297 			ImplInvalidate( sal_True, bFormat );
1298 	}
1299 }
1300 
1301 // -----------------------------------------------------------------------
1302 
1303 ToolBoxItemBits ToolBox::GetItemBits( sal_uInt16 nItemId ) const
1304 {
1305 	ImplToolItem* pItem = ImplGetItem( nItemId );
1306 
1307 	if ( pItem )
1308 		return pItem->mnBits;
1309 	else
1310 		return 0;
1311 }
1312 
1313 // -----------------------------------------------------------------------
1314 
1315 void ToolBox::SetItemData( sal_uInt16 nItemId, void* pNewData )
1316 {
1317 	sal_uInt16 nPos = GetItemPos( nItemId );
1318 
1319 	if ( nPos < mpData->m_aItems.size() )
1320 	{
1321 		mpData->m_aItems[nPos].mpUserData = pNewData;
1322 		ImplUpdateItem( nPos );
1323 	}
1324 }
1325 
1326 // -----------------------------------------------------------------------
1327 
1328 void* ToolBox::GetItemData( sal_uInt16 nItemId ) const
1329 {
1330 	ImplToolItem* pItem = ImplGetItem( nItemId );
1331 
1332 	if ( pItem )
1333 		return pItem->mpUserData;
1334 	else
1335 		return NULL;
1336 }
1337 
1338 // -----------------------------------------------------------------------
1339 
1340 void ToolBox::SetItemImage( sal_uInt16 nItemId, const Image& rImage )
1341 {
1342 	sal_uInt16 nPos = GetItemPos( nItemId );
1343 
1344 	if ( nPos != TOOLBOX_ITEM_NOTFOUND )
1345 	{
1346 		ImplToolItem* pItem = &mpData->m_aItems[nPos];
1347 		// Nur wenn alles berechnet ist, mehr Aufwand treiben
1348 		if ( !mbCalc )
1349 		{
1350 			Size aOldSize = pItem->maImage.GetSizePixel();
1351 			pItem->maImage = rImage;
1352 			if ( aOldSize != pItem->maImage.GetSizePixel() )
1353 				ImplInvalidate( sal_True );
1354 			else
1355 				ImplUpdateItem( nPos );
1356 		}
1357 		else
1358 			pItem->maImage = rImage;
1359 	}
1360 }
1361 
1362 // -----------------------------------------------------------------------
1363 
1364 void ToolBox::SetImageList( const ImageList& rImageList )
1365 {
1366 	maImageList = rImageList;
1367 
1368     sal_uInt16 nCount = (sal_uInt16)mpData->m_aItems.size();
1369     for( sal_uInt16 i = 0; i < nCount; i++ )
1370     {
1371 		Image aImage;
1372 		if ( mpData->m_aItems[i].mnId )
1373 			aImage = maImageList.GetImage( mpData->m_aItems[i].mnId );
1374 		if( !!aImage )
1375 			SetItemImage( mpData->m_aItems[i].mnId, aImage );
1376 	}
1377 }
1378 
1379 // -----------------------------------------------------------------------
1380 
1381 static Image ImplRotImage( const Image& rImage, long nAngle10 )
1382 {
1383     Image 		aRet;
1384     BitmapEx	aRotBitmapEx( rImage.GetBitmapEx() );
1385 
1386     aRotBitmapEx.Rotate( nAngle10, Color( COL_WHITE ) );
1387 
1388     return Image( aRotBitmapEx );
1389 }
1390 
1391 void ToolBox::SetItemImageAngle( sal_uInt16 nItemId, long nAngle10 )
1392 {
1393 	sal_uInt16 nPos = GetItemPos( nItemId );
1394 
1395 	if ( nPos != TOOLBOX_ITEM_NOTFOUND )
1396 	{
1397 		ImplToolItem* pItem = &mpData->m_aItems[nPos];
1398         Size aOldSize = pItem->maImage.GetSizePixel();
1399 
1400         long nDeltaAngle = (nAngle10 - pItem->mnImageAngle) % 3600;
1401         while( nDeltaAngle < 0 )
1402             nDeltaAngle += 3600;
1403 
1404         pItem->mnImageAngle = nAngle10;
1405         if( nDeltaAngle && !!pItem->maImage )
1406         {
1407             pItem->maImage = ImplRotImage( pItem->maImage, nDeltaAngle );
1408             if( !!pItem->maHighImage )
1409                 pItem->maHighImage = ImplRotImage( pItem->maHighImage, nDeltaAngle );
1410         }
1411 
1412 		if ( !mbCalc )
1413 		{
1414 			if ( aOldSize != pItem->maImage.GetSizePixel() )
1415 				ImplInvalidate( sal_True );
1416 			else
1417 				ImplUpdateItem( nPos );
1418 		}
1419 	}
1420 }
1421 
1422 // -----------------------------------------------------------------------
1423 
1424 static Image ImplMirrorImage( const Image& rImage )
1425 {
1426     Image 		aRet;
1427     BitmapEx	aMirrBitmapEx( rImage.GetBitmapEx() );
1428 
1429     aMirrBitmapEx.Mirror( BMP_MIRROR_HORZ );
1430 
1431     return Image( aMirrBitmapEx );
1432 }
1433 
1434 void ToolBox::SetItemImageMirrorMode( sal_uInt16 nItemId, sal_Bool bMirror )
1435 {
1436 	sal_uInt16 nPos = GetItemPos( nItemId );
1437 
1438 	if ( nPos != TOOLBOX_ITEM_NOTFOUND )
1439 	{
1440 		ImplToolItem* pItem = &mpData->m_aItems[nPos];
1441 
1442         if( ( pItem->mbMirrorMode && ! bMirror ) ||
1443             ( ! pItem->mbMirrorMode && bMirror )
1444             )
1445         {
1446             pItem->mbMirrorMode = bMirror ? true : false;
1447             if( !!pItem->maImage )
1448             {
1449                 pItem->maImage = ImplMirrorImage( pItem->maImage );
1450                 if( !!pItem->maHighImage )
1451                     pItem->maHighImage = ImplMirrorImage( pItem->maHighImage );
1452             }
1453 
1454             if ( !mbCalc )
1455                 ImplUpdateItem( nPos );
1456         }
1457     }
1458 }
1459 
1460 // -----------------------------------------------------------------------
1461 
1462 Image ToolBox::GetItemImage( sal_uInt16 nItemId ) const
1463 {
1464 	ImplToolItem* pItem = ImplGetItem( nItemId );
1465 
1466 	if ( pItem )
1467 		return pItem->maImage;
1468 	else
1469 		return Image();
1470 }
1471 
1472 // -----------------------------------------------------------------------
1473 
1474 long ToolBox::GetItemImageAngle( sal_uInt16 nItemId ) const
1475 {
1476 	ImplToolItem* pItem = ImplGetItem( nItemId );
1477 
1478 	if ( pItem )
1479 		return pItem->mnImageAngle;
1480 	else
1481 		return 0;
1482 }
1483 
1484 // -----------------------------------------------------------------------
1485 
1486 sal_Bool ToolBox::GetItemImageMirrorMode( sal_uInt16 nItemId ) const
1487 {
1488 	ImplToolItem* pItem = ImplGetItem( nItemId );
1489 
1490 	if ( pItem )
1491 		return pItem->mbMirrorMode;
1492 	else
1493 		return sal_False;
1494 }
1495 
1496 // -----------------------------------------------------------------------
1497 
1498 void ToolBox::SetItemHighImage( sal_uInt16 nItemId, const Image& rImage )
1499 {
1500 	ImplToolItem* pItem = ImplGetItem( nItemId );
1501 	if ( pItem )
1502 	{
1503 		DBG_ASSERT( (pItem->maImage.GetSizePixel() == rImage.GetSizePixel()) ||
1504 					((!rImage) == sal_True), "ToolBox::SetItemHighImage() - ImageSize != HighImageSize" );
1505 		pItem->maHighImage = rImage;
1506 	}
1507 }
1508 
1509 // -----------------------------------------------------------------------
1510 
1511 Image ToolBox::GetItemHighImage( sal_uInt16 nItemId ) const
1512 {
1513 	ImplToolItem* pItem = ImplGetItem( nItemId );
1514 
1515 	if ( pItem )
1516 		return pItem->maHighImage;
1517 	else
1518 		return Image();
1519 }
1520 
1521 // -----------------------------------------------------------------------
1522 
1523 void ToolBox::SetItemText( sal_uInt16 nItemId, const XubString& rText )
1524 {
1525 	sal_uInt16 nPos = GetItemPos( nItemId );
1526 
1527 	if ( nPos != TOOLBOX_ITEM_NOTFOUND )
1528 	{
1529 		ImplToolItem* pItem = &mpData->m_aItems[nPos];
1530 		// Nur wenn alles berechnet ist, mehr Aufwand treiben
1531 		if ( !mbCalc &&
1532 			 ((meButtonType != BUTTON_SYMBOL) || !pItem->maImage) )
1533 		{
1534 			long nOldWidth = GetCtrlTextWidth( pItem->maText );
1535 			pItem->maText = ImplConvertMenuString( rText );
1536             mpData->ImplClearLayoutData();
1537 			if ( nOldWidth != GetCtrlTextWidth( pItem->maText ) )
1538 				ImplInvalidate( sal_True );
1539 			else
1540 				ImplUpdateItem( nPos );
1541 		}
1542 		else
1543 			pItem->maText = ImplConvertMenuString( rText );
1544 
1545         // Notify button changed event to prepare accessibility bridge
1546         ImplCallEventListeners( VCLEVENT_TOOLBOX_BUTTONSTATECHANGED, reinterpret_cast< void* >( nPos ) );
1547 
1548         // Notify
1549         ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMTEXTCHANGED, reinterpret_cast< void* >( nPos ) );
1550 	}
1551 }
1552 
1553 // -----------------------------------------------------------------------
1554 
1555 const XubString& ToolBox::GetItemText( sal_uInt16 nItemId ) const
1556 {
1557 	ImplToolItem* pItem = ImplGetItem( nItemId );
1558 
1559 	if ( pItem )
1560 		return pItem->maText;
1561 	else
1562 		return ImplGetSVEmptyStr();
1563 }
1564 
1565 // -----------------------------------------------------------------------
1566 
1567 void ToolBox::SetItemWindow( sal_uInt16 nItemId, Window* pNewWindow )
1568 {
1569 	sal_uInt16 nPos = GetItemPos( nItemId );
1570 
1571 	if ( nPos != TOOLBOX_ITEM_NOTFOUND )
1572 	{
1573 		ImplToolItem* pItem = &mpData->m_aItems[nPos];
1574 		pItem->mpWindow = pNewWindow;
1575 		if ( pNewWindow )
1576 			pNewWindow->Hide();
1577 		ImplInvalidate( sal_True );
1578 		ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMWINDOWCHANGED, reinterpret_cast< void* >( nPos ) );
1579 	}
1580 }
1581 
1582 // -----------------------------------------------------------------------
1583 
1584 Window* ToolBox::GetItemWindow( sal_uInt16 nItemId ) const
1585 {
1586 	ImplToolItem* pItem = ImplGetItem( nItemId );
1587 
1588 	if ( pItem )
1589 		return pItem->mpWindow;
1590 	else
1591 		return NULL;
1592 }
1593 
1594 // -----------------------------------------------------------------------
1595 
1596 void ToolBox::StartSelection()
1597 {
1598 	if ( mbDrag )
1599 		EndSelection();
1600 
1601 	if ( !mbSelection )
1602 	{
1603 		mbSelection  = sal_True;
1604 		mnCurPos	 = TOOLBOX_ITEM_NOTFOUND;
1605 		mnCurItemId  = 0;
1606 		Activate();
1607 	}
1608 }
1609 
1610 // -----------------------------------------------------------------------
1611 
1612 void ToolBox::EndSelection()
1613 {
1614 	mbCommandDrag = sal_False;
1615 
1616 	if ( mbDrag || mbSelection )
1617 	{
1618 		// Daten zuruecksetzen
1619 		mbDrag = sal_False;
1620 		mbSelection = sal_False;
1621 		if ( mnCurPos != TOOLBOX_ITEM_NOTFOUND )
1622 			ImplDrawItem( mnCurPos );
1623 		EndTracking();
1624 		ReleaseMouse();
1625 		Deactivate();
1626 	}
1627 
1628 	mnCurPos		= TOOLBOX_ITEM_NOTFOUND;
1629 	mnCurItemId 	= 0;
1630 	mnDownItemId	= 0;
1631 	mnMouseClicks	= 0;
1632 	mnMouseModifier = 0;
1633 }
1634 
1635 // -----------------------------------------------------------------------
1636 
1637 void ToolBox::SetItemDown( sal_uInt16 nItemId, sal_Bool bDown, sal_Bool bRelease )
1638 {
1639 	sal_uInt16 nPos = GetItemPos( nItemId );
1640 
1641 	if ( nPos != TOOLBOX_ITEM_NOTFOUND )
1642 	{
1643 		if ( bDown )
1644 		{
1645 			if ( nPos != mnCurPos )
1646 			{
1647 				mnCurPos = nPos;
1648 				ImplDrawItem( mnCurPos, sal_True );
1649                 Flush();
1650 			}
1651 		}
1652 		else
1653 		{
1654 			if ( nPos == mnCurPos )
1655 			{
1656 				ImplDrawItem( mnCurPos, sal_False );
1657                 Flush();
1658 				mnCurPos = TOOLBOX_ITEM_NOTFOUND;
1659 			}
1660 		}
1661 
1662 		if ( bRelease )
1663 		{
1664 			if ( mbDrag || mbSelection )
1665 			{
1666 				mbDrag = sal_False;
1667 				mbSelection = sal_False;
1668 				EndTracking();
1669 				ReleaseMouse();
1670 				Deactivate();
1671 			}
1672 
1673 			mnCurItemId 	= 0;
1674 			mnDownItemId	= 0;
1675 			mnMouseClicks	= 0;
1676 			mnMouseModifier = 0;
1677 		}
1678 	}
1679 }
1680 
1681 // -----------------------------------------------------------------------
1682 
1683 sal_Bool ToolBox::IsItemDown( sal_uInt16 nItemId ) const
1684 {
1685 	sal_uInt16 nPos = GetItemPos( nItemId );
1686 
1687 	if ( nPos != TOOLBOX_ITEM_NOTFOUND )
1688 		return (nPos == mnCurPos);
1689 	else
1690 		return sal_False;
1691 }
1692 
1693 // -----------------------------------------------------------------------
1694 
1695 void ToolBox::SetItemState( sal_uInt16 nItemId, TriState eState )
1696 {
1697 	sal_uInt16 nPos = GetItemPos( nItemId );
1698 
1699 	if ( nPos != TOOLBOX_ITEM_NOTFOUND )
1700 	{
1701 		ImplToolItem* pItem = &mpData->m_aItems[nPos];
1702 
1703 		// Hat sich der Status geaendert
1704 		if ( pItem->meState != eState )
1705 		{
1706 			// Wenn RadioCheck, dann vorherigen unchecken
1707 			if ( (eState == STATE_CHECK) && (pItem->mnBits & TIB_AUTOCHECK) &&
1708 				 (pItem->mnBits & TIB_RADIOCHECK) )
1709 			{
1710 				ImplToolItem*	 pGroupItem;
1711 				sal_uInt16			nGroupPos;
1712 				sal_uInt16			nItemCount = GetItemCount();
1713 
1714 				nGroupPos = nPos;
1715 				while ( nGroupPos )
1716 				{
1717                     pGroupItem = &mpData->m_aItems[nGroupPos-1];
1718 					if ( pGroupItem->mnBits & TIB_RADIOCHECK )
1719 					{
1720 						if ( pGroupItem->meState != STATE_NOCHECK )
1721 							SetItemState( pGroupItem->mnId, STATE_NOCHECK );
1722 					}
1723 					else
1724 						break;
1725 					nGroupPos--;
1726 				}
1727 
1728 				nGroupPos = nPos+1;
1729 				while ( nGroupPos < nItemCount )
1730 				{
1731                     pGroupItem = &mpData->m_aItems[nGroupPos];
1732 					if ( pGroupItem->mnBits & TIB_RADIOCHECK )
1733 					{
1734 						if ( pGroupItem->meState != STATE_NOCHECK )
1735 							SetItemState( pGroupItem->mnId, STATE_NOCHECK );
1736 					}
1737 					else
1738 						break;
1739 					nGroupPos++;
1740 				}
1741 			}
1742 
1743 			pItem->meState = eState;
1744 			ImplUpdateItem( nPos );
1745 
1746             // Notify button changed event to prepare accessibility bridge
1747             ImplCallEventListeners( VCLEVENT_TOOLBOX_BUTTONSTATECHANGED, reinterpret_cast< void* >( nPos ) );
1748 
1749             // Notify
1750 		    ImplCallEventListeners( VCLEVENT_TOOLBOX_CLICK, reinterpret_cast< void* >( nPos ) );
1751 		}
1752 	}
1753 }
1754 
1755 // -----------------------------------------------------------------------
1756 
1757 TriState ToolBox::GetItemState( sal_uInt16 nItemId ) const
1758 {
1759 	ImplToolItem* pItem = ImplGetItem( nItemId );
1760 
1761 	if ( pItem )
1762 		return pItem->meState;
1763 	else
1764 		return STATE_NOCHECK;
1765 }
1766 
1767 // -----------------------------------------------------------------------
1768 
1769 void ToolBox::EnableItem( sal_uInt16 nItemId, sal_Bool bEnable )
1770 {
1771 	sal_uInt16 nPos = GetItemPos( nItemId );
1772 
1773 	if ( nPos != TOOLBOX_ITEM_NOTFOUND )
1774 	{
1775 		ImplToolItem* pItem = &mpData->m_aItems[nPos];
1776 		if ( bEnable )
1777 			bEnable = sal_True;
1778 		if ( pItem->mbEnabled != bEnable )
1779 		{
1780 			pItem->mbEnabled = bEnable;
1781 
1782 			// Gegebenenfalls das Fenster mit updaten
1783 			if ( pItem->mpWindow )
1784 				pItem->mpWindow->Enable( pItem->mbEnabled );
1785 
1786 			// Item updaten
1787 			ImplUpdateItem( nPos );
1788 
1789 			ImplUpdateInputEnable();
1790 
1791             // Notify button changed event to prepare accessibility bridge
1792             ImplCallEventListeners( VCLEVENT_TOOLBOX_BUTTONSTATECHANGED, reinterpret_cast< void* >( nPos ) );
1793 
1794             ImplCallEventListeners( bEnable ? VCLEVENT_TOOLBOX_ITEMENABLED : VCLEVENT_TOOLBOX_ITEMDISABLED, reinterpret_cast< void* >( nPos ) );
1795 		}
1796 	}
1797 }
1798 
1799 // -----------------------------------------------------------------------
1800 
1801 sal_Bool ToolBox::IsItemEnabled( sal_uInt16 nItemId ) const
1802 {
1803 	ImplToolItem* pItem = ImplGetItem( nItemId );
1804 
1805 	if ( pItem )
1806 		return pItem->mbEnabled;
1807 	else
1808 		return sal_False;
1809 }
1810 
1811 // -----------------------------------------------------------------------
1812 
1813 void ToolBox::ShowItem( sal_uInt16 nItemId, sal_Bool bVisible )
1814 {
1815 	sal_uInt16 nPos = GetItemPos( nItemId );
1816     mpData->ImplClearLayoutData();
1817 
1818 	if ( nPos != TOOLBOX_ITEM_NOTFOUND )
1819 	{
1820 		ImplToolItem* pItem = &mpData->m_aItems[nPos];
1821 		if ( pItem->mbVisible != bVisible )
1822 		{
1823 			pItem->mbVisible = bVisible;
1824 			ImplInvalidate( sal_False );
1825 		}
1826 	}
1827 }
1828 
1829 // -----------------------------------------------------------------------
1830 
1831 sal_Bool ToolBox::IsItemVisible( sal_uInt16 nItemId ) const
1832 {
1833     ImplToolItem* pItem = ImplGetItem( nItemId );
1834 
1835     if ( pItem )
1836         return pItem->mbVisible;
1837     else
1838         return sal_False;
1839 }
1840 
1841 // -----------------------------------------------------------------------
1842 
1843 sal_Bool ToolBox::IsItemReallyVisible( sal_uInt16 nItemId ) const
1844 {
1845     // is the item on the visible area of the toolbox?
1846     sal_Bool bRet = sal_False;
1847     Rectangle aRect( mnLeftBorder, mnTopBorder, mnDX-mnRightBorder, mnDY-mnBottomBorder );
1848     ImplToolItem* pItem = ImplGetItem( nItemId );
1849 
1850     if ( pItem && pItem->mbVisible &&
1851          !pItem->maRect.IsEmpty() && aRect.IsOver( pItem->maRect ) )
1852     {
1853         bRet = sal_True;
1854     }
1855 
1856     return bRet;
1857 }
1858 
1859 // -----------------------------------------------------------------------
1860 
1861 void ToolBox::SetItemCommand( sal_uInt16 nItemId, const XubString& rCommand )
1862 {
1863 	ImplToolItem* pItem = ImplGetItem( nItemId );
1864 
1865 	if ( pItem )
1866 		pItem->maCommandStr = rCommand;
1867 }
1868 
1869 // -----------------------------------------------------------------------
1870 
1871 const XubString& ToolBox::GetItemCommand( sal_uInt16 nItemId ) const
1872 {
1873 	ImplToolItem* pItem = ImplGetItem( nItemId );
1874 
1875 	if ( pItem )
1876 		return pItem->maCommandStr;
1877 	else
1878 		return ImplGetSVEmptyStr();
1879 }
1880 
1881 // -----------------------------------------------------------------------
1882 
1883 void ToolBox::SetQuickHelpText( sal_uInt16 nItemId, const XubString& rText )
1884 {
1885 	ImplToolItem* pItem = ImplGetItem( nItemId );
1886 
1887 	if ( pItem )
1888 		pItem->maQuickHelpText = rText;
1889 }
1890 
1891 // -----------------------------------------------------------------------
1892 
1893 const XubString& ToolBox::GetQuickHelpText( sal_uInt16 nItemId ) const
1894 {
1895 	ImplToolItem* pItem = ImplGetItem( nItemId );
1896 
1897 	if ( pItem )
1898 		return pItem->maQuickHelpText;
1899 	else
1900 		return ImplGetSVEmptyStr();
1901 }
1902 
1903 // -----------------------------------------------------------------------
1904 
1905 void ToolBox::SetHelpText( sal_uInt16 nItemId, const XubString& rText )
1906 {
1907 	ImplToolItem* pItem = ImplGetItem( nItemId );
1908 
1909 	if ( pItem )
1910 		pItem->maHelpText = rText;
1911 }
1912 
1913 // -----------------------------------------------------------------------
1914 
1915 const XubString& ToolBox::GetHelpText( sal_uInt16 nItemId ) const
1916 {
1917     return ImplGetHelpText( nItemId );
1918 }
1919 
1920 // -----------------------------------------------------------------------
1921 
1922 void ToolBox::SetHelpId( sal_uInt16 nItemId, const rtl::OString& rHelpId )
1923 {
1924 	ImplToolItem* pItem = ImplGetItem( nItemId );
1925 
1926 	if ( pItem )
1927 		pItem->maHelpId = rHelpId;
1928 }
1929 
1930 // -----------------------------------------------------------------------
1931 
1932 rtl::OString ToolBox::GetHelpId( sal_uInt16 nItemId ) const
1933 {
1934     rtl::OString aRet;
1935 
1936 	ImplToolItem* pItem = ImplGetItem( nItemId );
1937 
1938 	if ( pItem )
1939     {
1940         if ( pItem->maHelpId.getLength() )
1941             aRet = pItem->maHelpId;
1942         else
1943             aRet = ::rtl::OUStringToOString( pItem->maCommandStr, RTL_TEXTENCODING_UTF8 );
1944     }
1945 
1946 	return aRet;
1947 }
1948 
1949 // -----------------------------------------------------------------------
1950 
1951 void ToolBox::SetBorder( long nX, long nY )
1952 {
1953 	mnBorderX = nX;
1954 	mnBorderY = nY;
1955 
1956 	ImplInvalidate( sal_True, sal_True );
1957 }
1958 
1959 // -----------------------------------------------------------------------
1960 
1961 void ToolBox::SetOutStyle( sal_uInt16 nNewStyle )
1962 {
1963     // always force flat looking toolbars since NWF
1964     nNewStyle |= TOOLBOX_STYLE_FLAT;
1965 
1966 	if ( mnOutStyle != nNewStyle )
1967 	{
1968 		mnOutStyle = nNewStyle;
1969 		ImplDisableFlatButtons();
1970 
1971 		// Damit das ButtonDevice neu angelegt wird
1972 		if ( !(mnOutStyle & TOOLBOX_STYLE_FLAT) )
1973 		{
1974 			mnMaxItemWidth  = 1;
1975 			mnMaxItemHeight = 1;
1976 		}
1977 
1978 		ImplInvalidate( sal_True, sal_True );
1979 	}
1980 }
1981 
1982 // -----------------------------------------------------------------------
1983 
1984 void ToolBox::RecalcItems()
1985 {
1986 	ImplInvalidate( sal_True );
1987 }
1988 
1989 // -----------------------------------------------------------------------
1990 
1991 // disable key input if all items are disabled
1992 
1993 void ToolBox::ImplUpdateInputEnable()
1994 {
1995     for( std::vector< ImplToolItem >::const_iterator it = mpData->m_aItems.begin();
1996          it != mpData->m_aItems.end(); ++it )
1997     {
1998 		if( it->mbEnabled )
1999 		{
2000 			// at least one useful entry
2001 			mpData->mbKeyInputDisabled = sal_False;
2002 			return;
2003 		}
2004     }
2005 	mpData->mbKeyInputDisabled = sal_True;
2006 }
2007 
2008 // -----------------------------------------------------------------------
2009 
2010 void ToolBox::ImplFillLayoutData() const
2011 {
2012     mpData->m_pLayoutData = new ToolBoxLayoutData();
2013 
2014     sal_uInt16 nCount = (sal_uInt16)mpData->m_aItems.size();
2015     for( sal_uInt16 i = 0; i < nCount; i++ )
2016     {
2017         ImplToolItem* pItem = &mpData->m_aItems[i];
2018 
2019         // Nur malen, wenn Rechteck im PaintRectangle liegt
2020         if ( !pItem->maRect.IsEmpty() )
2021             const_cast<ToolBox*>(this)->ImplDrawItem( i, sal_False, sal_False, sal_True );
2022     }
2023 }
2024 
2025 // -----------------------------------------------------------------------
2026 
2027 String ToolBox::GetDisplayText() const
2028 {
2029     if( ! mpData->m_pLayoutData )
2030         ImplFillLayoutData();
2031     return mpData->m_pLayoutData ? mpData->m_pLayoutData->m_aDisplayText : String();
2032 }
2033 
2034 // -----------------------------------------------------------------------
2035 
2036 Rectangle ToolBox::GetCharacterBounds( sal_uInt16 nItemID, long nIndex ) const
2037 {
2038     long nItemIndex = -1;
2039     if( ! mpData->m_pLayoutData )
2040         ImplFillLayoutData();
2041     if( mpData->m_pLayoutData )
2042     {
2043         for( sal_uLong i = 0; i < mpData->m_pLayoutData->m_aLineItemIds.size(); i++ )
2044         {
2045             if( mpData->m_pLayoutData->m_aLineItemIds[i] == nItemID )
2046             {
2047                 nItemIndex = mpData->m_pLayoutData->m_aLineIndices[i];
2048                 break;
2049             }
2050         }
2051     }
2052     return (mpData->m_pLayoutData && nItemIndex != -1) ? mpData->m_pLayoutData->GetCharacterBounds( nItemIndex+nIndex ) : Rectangle();
2053 }
2054 
2055 // -----------------------------------------------------------------------
2056 
2057 long ToolBox::GetIndexForPoint( const Point& rPoint, sal_uInt16& rItemID ) const
2058 {
2059     long nIndex = -1;
2060     rItemID = 0;
2061     if( ! mpData->m_pLayoutData )
2062         ImplFillLayoutData();
2063     if( mpData->m_pLayoutData )
2064     {
2065         nIndex = mpData->m_pLayoutData->GetIndexForPoint( rPoint );
2066         for( sal_uLong i = 0; i < mpData->m_pLayoutData->m_aLineIndices.size(); i++ )
2067         {
2068             if( mpData->m_pLayoutData->m_aLineIndices[i] <= nIndex &&
2069                 (i == mpData->m_pLayoutData->m_aLineIndices.size()-1 || mpData->m_pLayoutData->m_aLineIndices[i+1] > nIndex) )
2070             {
2071                 rItemID = mpData->m_pLayoutData->m_aLineItemIds[i];
2072                 break;
2073             }
2074         }
2075     }
2076     return nIndex;
2077 }
2078 
2079 // -----------------------------------------------------------------------
2080 
2081 long ToolBox::GetTextCount() const
2082 {
2083     if( ! mpData->m_pLayoutData )
2084         ImplFillLayoutData();
2085     return mpData->m_pLayoutData ? mpData->m_pLayoutData->GetLineCount() : 0;
2086 }
2087 
2088 // -----------------------------------------------------------------------
2089 
2090 Pair ToolBox::GetTextStartEnd( long nText ) const
2091 {
2092     if( ! mpData->m_pLayoutData )
2093         ImplFillLayoutData();
2094     return mpData->m_pLayoutData ? mpData->m_pLayoutData->GetLineStartEnd( nText ) : Pair( -1, -1 );
2095 }
2096 
2097 // -----------------------------------------------------------------------
2098 
2099 sal_uInt16 ToolBox::GetDisplayItemId( long nText ) const
2100 {
2101     sal_uInt16 nItemId = 0;
2102     if( ! mpData->m_pLayoutData )
2103         ImplFillLayoutData();
2104     if( mpData->m_pLayoutData && nText >= 0 && (sal_uLong)nText < mpData->m_pLayoutData->m_aLineItemIds.size() )
2105         nItemId = mpData->m_pLayoutData->m_aLineItemIds[nText];
2106     return nItemId;
2107 }
2108 
2109 
2110 // -----------------------------------------------------------------------
2111 
2112 void ToolBox::SetDropdownClickHdl( const Link& rLink )
2113 {
2114     mpData->maDropdownClickHdl = rLink;
2115 }
2116 
2117 const Link& ToolBox::GetDropdownClickHdl() const
2118 {
2119     return mpData->maDropdownClickHdl;
2120 }
2121 
2122 // -----------------------------------------------------------------------
2123 
2124 void ToolBox::SetMenuType( sal_uInt16 aType )
2125 {
2126     if( aType != mpData->maMenuType )
2127     {
2128         mpData->maMenuType = aType;
2129         if( IsFloatingMode() )
2130         {
2131             // the menu button may have to be moved into the decoration which changes the layout
2132             ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
2133             if( pWrapper )
2134                 pWrapper->ShowTitleButton( TITLE_BUTTON_MENU, ( aType & TOOLBOX_MENUTYPE_CUSTOMIZE) ? sal_True : sal_False );
2135 
2136             mbFormat = sal_True;
2137             ImplFormat();
2138             ImplSetMinMaxFloatSize( this );
2139         }
2140         else
2141         {
2142             // trigger redraw of menu button
2143             if( !mpData->maMenubuttonItem.maRect.IsEmpty() )
2144                 Invalidate(mpData->maMenubuttonItem.maRect);
2145         }
2146     }
2147 }
2148 
2149 sal_uInt16 ToolBox::GetMenuType() const
2150 {
2151     return mpData->maMenuType;
2152 }
2153 
2154 sal_Bool ToolBox::IsMenuEnabled() const
2155 {
2156     return mpData->maMenuType != TOOLBOX_MENUTYPE_NONE;
2157 }
2158 
2159 PopupMenu* ToolBox::GetMenu() const
2160 {
2161     return mpData->mpMenu;
2162 }
2163 
2164 void ToolBox::SetMenuButtonHdl( const Link& rLink )
2165 {
2166     mpData->maMenuButtonHdl = rLink;
2167 }
2168 
2169 const Link& ToolBox::GetMenuButtonHdl() const
2170 {
2171     return mpData->maMenuButtonHdl;
2172 }
2173 
2174 // -----------------------------------------------------------------------
2175 
2176 sal_Bool ToolBox::ImplHasClippedItems()
2177 {
2178     // are any items currently clipped ?
2179     ImplFormat();
2180     std::vector< ImplToolItem >::const_iterator it = mpData->m_aItems.begin();
2181     while ( it != mpData->m_aItems.end() )
2182     {
2183         if( it->IsClipped() )
2184             return sal_True;
2185         it++;
2186     }
2187     return sal_False;
2188 }
2189 
2190 void ToolBox::ImplUpdateCustomMenu()
2191 {
2192     // fill clipped items into menu
2193     if( !IsMenuEnabled() )
2194         return;
2195 
2196     PopupMenu *pMenu = GetMenu();
2197 
2198     sal_uInt16 i = 0;
2199     // remove old entries
2200     while( i < pMenu->GetItemCount() )
2201     {
2202         if( pMenu->GetItemId( i ) >= TOOLBOX_MENUITEM_START )
2203         {
2204             pMenu->RemoveItem( i );
2205             i = 0;
2206         }
2207         else
2208             i++;
2209     }
2210 
2211     // add menu items, starting from the end and inserting at pos 0
2212     if ( !mpData->m_aItems.empty() )
2213     {
2214         for ( std::vector< ImplToolItem >::reverse_iterator it(mpData->m_aItems.rbegin());
2215                 it != mpData->m_aItems.rend(); ++it)
2216         {
2217             if( it->IsClipped() )
2218             {
2219                 sal_uInt16 id = it->mnId + TOOLBOX_MENUITEM_START;
2220                 pMenu->InsertItem( id, it->maText, it->maImage, 0, 0 );
2221                 pMenu->EnableItem( id, it->mbEnabled );
2222                 pMenu->CheckItem( id, it->meState == STATE_CHECK );
2223             }
2224         }
2225     }
2226 }
2227 
2228 IMPL_LINK( ToolBox, ImplCustomMenuListener, VclMenuEvent*, pEvent )
2229 {
2230     if( pEvent->GetMenu() == GetMenu() && pEvent->GetId() == VCLEVENT_MENU_SELECT )
2231     {
2232         sal_uInt16 id = GetMenu()->GetItemId( pEvent->GetItemPos() );
2233         if( id >= TOOLBOX_MENUITEM_START )
2234             TriggerItem( id - TOOLBOX_MENUITEM_START, sal_False, sal_False );
2235     }
2236     return 0;
2237 }
2238 
2239 IMPL_LINK( ToolBox, ImplCallExecuteCustomMenu, void*, EMPTYARG )
2240 {
2241     mpData->mnEventId = 0;
2242     ImplExecuteCustomMenu();
2243     return 0;
2244 }
2245 
2246 void ToolBox::ImplExecuteCustomMenu()
2247 {
2248     if( IsMenuEnabled() )
2249     {
2250         if( GetMenuType() & TOOLBOX_MENUTYPE_CUSTOMIZE )
2251             // call button handler to allow for menu customization
2252             mpData->maMenuButtonHdl.Call( this );
2253 
2254         // register handler
2255         GetMenu()->AddEventListener( LINK( this, ToolBox, ImplCustomMenuListener ) );
2256 
2257         // make sure all disabled entries will be shown
2258         GetMenu()->SetMenuFlags(
2259             GetMenu()->GetMenuFlags() | MENU_FLAG_ALWAYSSHOWDISABLEDENTRIES );
2260 
2261         // toolbox might be destroyed during execute
2262         ImplDelData aDelData;
2263         ImplAddDel( &aDelData );
2264         ImplDelData aBorderDel;
2265         bool bBorderDel = false;
2266 
2267         Window *pWin = this;
2268         Rectangle aMenuRect = mpData->maMenubuttonItem.maRect;
2269         if( IsFloatingMode() )
2270         {
2271             // custom menu is placed in the decoration
2272             ImplBorderWindow *pBorderWin = dynamic_cast<ImplBorderWindow*>( GetWindow( WINDOW_BORDER ) );
2273             if( pBorderWin && !pBorderWin->GetMenuRect().IsEmpty() )
2274             {
2275                 pWin = pBorderWin;
2276                 aMenuRect = pBorderWin->GetMenuRect();
2277                 pWin->ImplAddDel( &aBorderDel );
2278                 bBorderDel = true;
2279             }
2280         }
2281 
2282         sal_uInt16 uId = GetMenu()->Execute( pWin, Rectangle( ImplGetPopupPosition( aMenuRect, Size() ), Size() ),
2283                                 POPUPMENU_EXECUTE_DOWN | POPUPMENU_NOMOUSEUPCLOSE );
2284 
2285         if ( aDelData.IsDelete() )
2286             return;
2287         ImplRemoveDel( &aDelData );
2288 
2289         if( GetMenu() )
2290             GetMenu()->RemoveEventListener( LINK( this, ToolBox, ImplCustomMenuListener ) );
2291         if( bBorderDel )
2292         {
2293             if( aBorderDel.IsDelete() )
2294                 return;
2295             pWin->ImplRemoveDel( &aBorderDel );
2296         }
2297 
2298         pWin->Invalidate( aMenuRect );
2299 
2300         if( uId )
2301             GrabFocusToDocument();
2302     }
2303 }
2304 
2305 void ToolBox::ExecuteCustomMenu()
2306 {
2307     if( IsMenuEnabled() )
2308     {
2309         // handle custom menu asynchronously
2310         // to avoid problems if the toolbox is closed during menu execute
2311         ImplUpdateCustomMenu();
2312         Application::PostUserEvent( mpData->mnEventId, LINK( this, ToolBox, ImplCallExecuteCustomMenu ) );
2313     }
2314 }
2315 
2316 // -----------------------------------------------------------------------
2317 
2318 // checks override first, useful during calculation of sizes
2319 sal_Bool ToolBox::ImplIsFloatingMode() const
2320 {
2321     DBG_ASSERT( !(mpData->mbAssumeDocked && mpData->mbAssumeFloating),
2322         "ToolBox::ImplIsFloatingMode(): cannot assume docked and floating" );
2323 
2324     if( mpData->mbAssumeDocked )
2325         return sal_False;
2326     else if( mpData->mbAssumeFloating )
2327         return sal_True;
2328     else
2329         return IsFloatingMode();
2330 }
2331 
2332 // checks override first, useful during calculation of sizes
2333 sal_Bool ToolBox::ImplIsInPopupMode() const
2334 {
2335     if( mpData->mbAssumePopupMode )
2336         return sal_True;
2337     else
2338     {
2339         ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
2340         return ( pWrapper && pWrapper->GetFloatingWindow() && pWrapper->GetFloatingWindow()->IsInPopupMode() );
2341     }
2342 }
2343 
2344 // -----------------------------------------------------------------------
2345 
2346 void ToolBox::Lock( sal_Bool bLock )
2347 {
2348     ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
2349     if( !pWrapper )
2350         return;
2351     if( mpData->mbIsLocked != bLock )
2352     {
2353         mpData->mbIsLocked = bLock;
2354         if( !ImplIsFloatingMode() )
2355         {
2356             mbCalc = sal_True;
2357             mbFormat = sal_True;
2358             SetSizePixel( CalcWindowSizePixel(1) );
2359             Invalidate();
2360         }
2361     }
2362 }
2363 
2364 // -----------------------------------------------------------------------
2365 
2366 sal_Bool ToolBox::AlwaysLocked()
2367 {
2368     // read config item to determine toolbox behaviour, used for subtoolbars
2369 
2370     static int nAlwaysLocked = -1;
2371 
2372     if( nAlwaysLocked == -1 )
2373     {
2374         nAlwaysLocked = 0; // ask configuration only once
2375 
2376         utl::OConfigurationNode aNode = utl::OConfigurationTreeRoot::tryCreateWithServiceFactory(
2377             vcl::unohelper::GetMultiServiceFactory(),
2378             OUString::createFromAscii( "/org.openoffice.Office.UI.GlobalSettings/Toolbars" ) );    // note: case sensisitive !
2379         if ( aNode.isValid() )
2380         {
2381             // feature enabled ?
2382             sal_Bool bStatesEnabled = sal_Bool();
2383             ::com::sun::star::uno::Any aValue = aNode.getNodeValue( OUString::createFromAscii( "StatesEnabled" ) );
2384             if( aValue >>= bStatesEnabled )
2385             {
2386                 if( bStatesEnabled == sal_True )
2387                 {
2388                     // now read the locking state
2389                     utl::OConfigurationNode aNode2 = utl::OConfigurationTreeRoot::tryCreateWithServiceFactory(
2390                         vcl::unohelper::GetMultiServiceFactory(),
2391                         OUString::createFromAscii( "/org.openoffice.Office.UI.GlobalSettings/Toolbars/States" ) );    // note: case sensisitive !
2392 
2393                     sal_Bool bLocked = sal_Bool();
2394                     ::com::sun::star::uno::Any aValue2 = aNode2.getNodeValue( OUString::createFromAscii( "Locked" ) );
2395                     if( aValue2 >>= bLocked )
2396                         nAlwaysLocked = (bLocked == sal_True) ? 1 : 0;
2397                 }
2398             }
2399         }
2400     }
2401 
2402     return nAlwaysLocked == 1 ? sal_True : sal_False;
2403 }
2404 
2405 sal_Bool ToolBox::WillUsePopupMode() const
2406 {
2407     return mpData->mbWillUsePopupMode;
2408 }
2409 
2410 void ToolBox::WillUsePopupMode( sal_Bool b )
2411 {
2412     mpData->mbWillUsePopupMode = b;
2413 }
2414 
2415 void ToolBox::ImplUpdateImageList()
2416 {
2417     if (mpData->mpImageListProvider != NULL)
2418     {
2419         sal_Bool bHC = GetSettings().GetStyleSettings().GetHighContrastMode();
2420         try
2421         {
2422             ImageListType eType = bHC ? vcl::HIGHCONTRAST_YES : vcl::HIGHCONTRAST_NO;
2423 
2424             if (eType != mpData->meImageListType)
2425             {
2426                 vcl::IImageListProvider* pImageListProvider = mpData->mpImageListProvider;
2427                 SetImageList( pImageListProvider->getImageList(eType) );
2428                 mpData->meImageListType = eType;
2429             }
2430         }
2431         catch (com::sun::star::lang::IllegalArgumentException &) {}
2432     }
2433 }
2434 
2435 void ToolBox::SetImageListProvider(vcl::IImageListProvider* _pProvider)
2436 {
2437     mpData->mpImageListProvider = _pProvider;
2438     ImplUpdateImageList();
2439 }
2440 // -----------------------------------------------------------------------
2441