update dev300-m58
[ooovba.git] / vcl / source / window / toolbox2.cxx
blob31e061d5fc7f8b636e05e147eafbabc66420fed8
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: toolbox2.cxx,v $
10 * $Revision: 1.55 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
33 #include <tools/list.hxx>
34 #include <tools/debug.hxx>
36 #ifndef _SV_RC_H
37 #include <tools/rc.h>
38 #endif
39 #include <vcl/svdata.hxx>
40 #include <vcl/svapp.hxx>
41 #include <vcl/help.hxx>
42 #include <vcl/bitmap.hxx>
43 #include <vcl/toolbox.hxx>
44 #include <vcl/toolbox.h>
45 #include <vcl/mnemonic.hxx>
46 #include <vcl/menu.hxx>
47 #include <vcl/brdwin.hxx>
49 #include <vcl/unohelp.hxx>
50 #include <unotools/confignode.hxx>
52 #include <vcl/ImageListProvider.hxx>
53 #include <com/sun/star/lang/IllegalArgumentException.hpp>
55 using namespace vcl;
56 using namespace rtl;
58 // =======================================================================
60 #define TB_SEP_SIZE 8
62 ButtonType determineButtonType( ImplToolItem* pItem, ButtonType defaultType );
64 // -----------------------------------------------------------------------
66 ImplToolBoxPrivateData::ImplToolBoxPrivateData() :
67 m_pLayoutData( NULL ),
68 mpImageListProvider( NULL ),
69 meImageListType( vcl::IMAGELISTTYPE_UNKNOWN )
71 meButtonSize = TOOLBOX_BUTTONSIZE_DONTCARE;
72 mpMenu = new PopupMenu();
73 mnEventId = 0;
75 maMenuType = TOOLBOX_MENUTYPE_NONE;
76 maMenubuttonItem.maItemSize = Size( TB_MENUBUTTON_SIZE+TB_MENUBUTTON_OFFSET, TB_MENUBUTTON_SIZE+TB_MENUBUTTON_OFFSET );
77 maMenubuttonItem.meState = STATE_NOCHECK;
78 mnMenuButtonWidth = TB_MENUBUTTON_SIZE;
81 mbIsLocked = FALSE;
82 mbNativeButtons = FALSE;
83 mbIsPaintLocked = FALSE;
84 mbAssumeDocked = FALSE;
85 mbAssumePopupMode = FALSE;
86 mbAssumeFloating = FALSE;
87 mbKeyInputDisabled = FALSE;
88 mbMenubuttonSelected = FALSE;
89 mbPageScroll = FALSE;
90 mbWillUsePopupMode = FALSE;
91 mbDropDownByKeyboard = FALSE;
94 ImplToolBoxPrivateData::~ImplToolBoxPrivateData()
96 if( m_pLayoutData )
97 delete m_pLayoutData;
98 delete mpMenu;
101 // -----------------------------------------------------------------------
102 ImplToolItem::ImplToolItem()
104 mnId = 0;
105 mpWindow = NULL;
106 mpUserData = NULL;
107 mnHelpId = 0;
108 meType = TOOLBOXITEM_BUTTON;
109 mnBits = 0;
110 meState = STATE_NOCHECK;
111 mbEnabled = TRUE;
112 mbVisible = TRUE;
113 mbEmptyBtn = TRUE;
114 mbShowWindow = FALSE;
115 mbBreak = FALSE;
116 mnSepSize = TB_SEP_SIZE;
117 mnDropDownArrowWidth = TB_DROPDOWNARROWWIDTH;
118 mnImageAngle = 0;
119 mbMirrorMode = FALSE;
120 mbVisibleText = FALSE;
123 // -----------------------------------------------------------------------
125 ImplToolItem::ImplToolItem( USHORT nItemId, const Image& rImage,
126 ToolBoxItemBits nItemBits ) :
127 maImage( rImage )
129 mnId = nItemId;
130 mpWindow = NULL;
131 mpUserData = NULL;
132 mnHelpId = 0;
133 meType = TOOLBOXITEM_BUTTON;
134 mnBits = nItemBits;
135 meState = STATE_NOCHECK;
136 mbEnabled = TRUE;
137 mbVisible = TRUE;
138 mbEmptyBtn = FALSE;
139 mbShowWindow = FALSE;
140 mbBreak = FALSE;
141 mnSepSize = TB_SEP_SIZE;
142 mnDropDownArrowWidth = TB_DROPDOWNARROWWIDTH;
143 mnImageAngle = 0;
144 mbMirrorMode = false;
145 mbVisibleText = false;
148 // -----------------------------------------------------------------------
150 ImplToolItem::ImplToolItem( USHORT nItemId, const XubString& rText,
151 ToolBoxItemBits nItemBits ) :
152 maText( rText )
154 mnId = nItemId;
155 mpWindow = NULL;
156 mpUserData = NULL;
157 mnHelpId = 0;
158 meType = TOOLBOXITEM_BUTTON;
159 mnBits = nItemBits;
160 meState = STATE_NOCHECK;
161 mbEnabled = TRUE;
162 mbVisible = TRUE;
163 mbEmptyBtn = FALSE;
164 mbShowWindow = FALSE;
165 mbBreak = FALSE;
166 mnSepSize = TB_SEP_SIZE;
167 mnDropDownArrowWidth = TB_DROPDOWNARROWWIDTH;
168 mnImageAngle = 0;
169 mbMirrorMode = false;
170 mbVisibleText = false;
173 // -----------------------------------------------------------------------
175 ImplToolItem::ImplToolItem( USHORT nItemId, const Image& rImage,
176 const XubString& rText, ToolBoxItemBits nItemBits ) :
177 maImage( rImage ),
178 maText( rText )
180 mnId = nItemId;
181 mpWindow = NULL;
182 mpUserData = NULL;
183 mnHelpId = 0;
184 meType = TOOLBOXITEM_BUTTON;
185 mnBits = nItemBits;
186 meState = STATE_NOCHECK;
187 mbEnabled = TRUE;
188 mbVisible = TRUE;
189 mbEmptyBtn = FALSE;
190 mbShowWindow = FALSE;
191 mbBreak = FALSE;
192 mnSepSize = TB_SEP_SIZE;
193 mnDropDownArrowWidth = TB_DROPDOWNARROWWIDTH;
194 mnImageAngle = 0;
195 mbMirrorMode = false;
196 mbVisibleText = false;
199 // -----------------------------------------------------------------------
201 ImplToolItem::ImplToolItem( const ImplToolItem& rItem ) :
202 mpWindow ( rItem.mpWindow ),
203 mpUserData ( rItem.mpUserData ),
204 maImage ( rItem.maImage ),
205 maHighImage ( rItem.maHighImage ),
206 mnImageAngle ( rItem.mnImageAngle ),
207 mbMirrorMode ( rItem.mbMirrorMode ),
208 maText ( rItem.maText ),
209 maQuickHelpText ( rItem.maQuickHelpText ),
210 maHelpText ( rItem.maHelpText ),
211 maCommandStr ( rItem.maCommandStr ),
212 mnHelpId ( rItem.mnHelpId ),
213 maRect ( rItem.maRect ),
214 maCalcRect ( rItem.maCalcRect ),
215 maItemSize ( rItem.maItemSize ),
216 mnSepSize ( rItem.mnSepSize ),
217 mnDropDownArrowWidth ( rItem.mnDropDownArrowWidth ),
218 meType ( rItem.meType ),
219 mnBits ( rItem.mnBits ),
220 meState ( rItem.meState ),
221 mnId ( rItem.mnId ),
222 mbEnabled ( rItem.mbEnabled ),
223 mbVisible ( rItem.mbVisible ),
224 mbEmptyBtn ( rItem.mbEmptyBtn ),
225 mbShowWindow ( rItem.mbShowWindow ),
226 mbBreak ( rItem.mbBreak ),
227 mbVisibleText ( rItem.mbVisibleText )
231 // -----------------------------------------------------------------------
233 ImplToolItem::~ImplToolItem()
237 // -----------------------------------------------------------------------
239 ImplToolItem& ImplToolItem::operator=( const ImplToolItem& rItem )
241 mpWindow = rItem.mpWindow;
242 mpUserData = rItem.mpUserData;
243 maImage = rItem.maImage;
244 maHighImage = rItem.maHighImage;
245 mnImageAngle = rItem.mnImageAngle;
246 mbMirrorMode = rItem.mbMirrorMode;
247 maText = rItem.maText;
248 maQuickHelpText = rItem.maQuickHelpText;
249 maHelpText = rItem.maHelpText;
250 maCommandStr = rItem.maCommandStr;
251 mnHelpId = rItem.mnHelpId;
252 maRect = rItem.maRect;
253 maCalcRect = rItem.maCalcRect;
254 mnSepSize = rItem.mnSepSize;
255 mnDropDownArrowWidth = rItem.mnDropDownArrowWidth;
256 maItemSize = rItem.maItemSize;
257 mbVisibleText = rItem.mbVisibleText;
258 meType = rItem.meType;
259 mnBits = rItem.mnBits;
260 meState = rItem.meState;
261 mnId = rItem.mnId;
262 mbEnabled = rItem.mbEnabled;
263 mbVisible = rItem.mbVisible;
264 mbEmptyBtn = rItem.mbEmptyBtn;
265 mbShowWindow = rItem.mbShowWindow;
266 mbBreak = rItem.mbBreak;
267 return *this;
270 // -----------------------------------------------------------------------
272 Size ImplToolItem::GetSize( BOOL bHorz, BOOL bCheckMaxWidth, long maxWidth, const Size& rDefaultSize )
274 Size aSize( rDefaultSize ); // the size of 'standard' toolbox items
275 // non-standard items are eg windows or buttons with text
277 if ( (meType == TOOLBOXITEM_BUTTON) || (meType == TOOLBOXITEM_SPACE) )
279 aSize = maItemSize;
281 if ( mpWindow && bHorz )
283 // get size of item window and check if it fits
284 // no windows in vertical toolbars (the default is mbShowWindow=FALSE)
285 Size aWinSize = mpWindow->GetSizePixel();
286 if ( !bCheckMaxWidth || (aWinSize.Width() <= maxWidth) )
288 aSize.Width() = aWinSize.Width();
289 aSize.Height() = aWinSize.Height();
290 mbShowWindow = TRUE;
292 else
294 if ( mbEmptyBtn )
296 aSize.Width() = 0;
297 aSize.Height() = 0;
302 else if ( meType == TOOLBOXITEM_SEPARATOR )
304 if ( bHorz )
306 aSize.Width() = mnSepSize;
307 aSize.Height() = rDefaultSize.Height();
309 else
311 aSize.Width() = rDefaultSize.Width();
312 aSize.Height() = mnSepSize;
315 else if ( meType == TOOLBOXITEM_BREAK )
317 aSize.Width() = 0;
318 aSize.Height() = 0;
321 return aSize;
324 // -----------------------------------------------------------------------
326 void ImplToolItem::DetermineButtonDrawStyle( ButtonType eButtonType, BOOL& rbImage, BOOL& rbText ) const
328 if ( meType != TOOLBOXITEM_BUTTON )
330 // no button -> draw nothing
331 rbImage = rbText = FALSE;
332 return;
335 BOOL bHasImage;
336 BOOL bHasText;
338 // check for image and/or text
339 if ( !(maImage) )
340 bHasImage = FALSE;
341 else
342 bHasImage = TRUE;
343 if ( !maText.Len() )
344 bHasText = FALSE;
345 else
346 bHasText = TRUE;
348 // prefer images if symbolonly buttons are drawn
349 // prefer texts if textonly buttons are dreawn
351 if ( eButtonType == BUTTON_SYMBOL ) // drawing icons only
353 if( bHasImage || !bHasText )
355 rbImage = TRUE;
356 rbText = FALSE;
358 else
360 rbImage = FALSE;
361 rbText = TRUE;
364 else if ( eButtonType == BUTTON_TEXT ) // drawing text only
366 if( bHasText || !bHasImage )
368 rbImage = FALSE;
369 rbText = TRUE;
371 else
373 rbImage = TRUE;
374 rbText = FALSE;
377 else // drawing icons and text both
379 rbImage = TRUE;
380 rbText = TRUE;
384 // -----------------------------------------------------------------------
386 Rectangle ImplToolItem::GetDropDownRect( BOOL bHorz ) const
388 Rectangle aRect;
389 if( (mnBits & TIB_DROPDOWN) && !maRect.IsEmpty() )
391 aRect = maRect;
392 if( mbVisibleText && !bHorz )
393 // item will be rotated -> place dropdown to the bottom
394 aRect.Top() = aRect.Bottom() - mnDropDownArrowWidth;
395 else
396 // place dropdown to the right
397 aRect.Left() = aRect.Right() - mnDropDownArrowWidth;
399 return aRect;
402 // -----------------------------------------------------------------------
404 BOOL ImplToolItem::IsClipped() const
406 return ( meType == TOOLBOXITEM_BUTTON && mbVisible && maRect.IsEmpty() );
409 // -----------------------------------------------------------------------
410 // -----------------------------------------------------------------------
412 const XubString& ToolBox::ImplConvertMenuString( const XubString& rStr )
414 maCvtStr = rStr;
415 if ( mbMenuStrings )
416 maCvtStr.EraseTrailingChars( '.' );
417 maCvtStr = MnemonicGenerator::EraseAllMnemonicChars( maCvtStr );
418 return maCvtStr;
421 // -----------------------------------------------------------------------
423 void ToolBox::ImplInvalidate( BOOL bNewCalc, BOOL bFullPaint )
425 ImplUpdateInputEnable();
427 if ( bNewCalc )
428 mbCalc = TRUE;
430 if ( bFullPaint )
432 mbFormat = TRUE;
434 // Muss ueberhaupt eine neue Ausgabe erfolgen
435 if ( IsReallyVisible() && IsUpdateMode() )
437 Invalidate( Rectangle( mnLeftBorder, mnTopBorder,
438 mnDX-mnRightBorder-1, mnDY-mnBottomBorder-1 ) );
439 maTimer.Stop();
442 else
444 if ( !mbFormat )
446 mbFormat = TRUE;
448 // Muss ueberhaupt eine neue Ausgabe erfolgen
449 if ( IsReallyVisible() && IsUpdateMode() )
450 maTimer.Start();
454 // request new layout by layoutmanager
455 ImplCallEventListeners( VCLEVENT_TOOLBOX_FORMATCHANGED );
458 // -----------------------------------------------------------------------
460 void ToolBox::ImplUpdateItem( USHORT nIndex )
462 // Muss ueberhaupt eine neue Ausgabe erfolgen
463 if ( IsReallyVisible() && IsUpdateMode() )
465 if ( nIndex == 0xFFFF )
467 // #i52217# no immediate draw as this might lead to paint problems
468 Invalidate( Rectangle( mnLeftBorder, mnTopBorder,
469 mnDX-mnRightBorder-1, mnDY-mnBottomBorder-1 ) );
471 else
473 if ( !mbFormat )
475 // #i52217# no immediate draw as this might lead to paint problems
476 Invalidate( mpData->m_aItems[nIndex].maRect );
478 else
479 maPaintRect.Union( mpData->m_aItems[nIndex].maRect );
484 // -----------------------------------------------------------------------
486 void ToolBox::Click()
488 ImplCallEventListeners( VCLEVENT_TOOLBOX_CLICK );
489 maClickHdl.Call( this );
492 // -----------------------------------------------------------------------
494 void ToolBox::DoubleClick()
496 ImplCallEventListeners( VCLEVENT_TOOLBOX_DOUBLECLICK );
497 maDoubleClickHdl.Call( this );
500 // -----------------------------------------------------------------------
502 void ToolBox::Activate()
504 mnActivateCount++;
505 ImplCallEventListeners( VCLEVENT_TOOLBOX_ACTIVATE );
506 maActivateHdl.Call( this );
509 // -----------------------------------------------------------------------
511 void ToolBox::Deactivate()
513 mnActivateCount--;
514 ImplCallEventListeners( VCLEVENT_TOOLBOX_DEACTIVATE );
515 maDeactivateHdl.Call( this );
517 if ( mbHideStatusText )
519 GetpApp()->HideHelpStatusText();
520 mbHideStatusText = FALSE;
524 // -----------------------------------------------------------------------
526 void ToolBox::Highlight()
528 ImplCallEventListeners( VCLEVENT_TOOLBOX_HIGHLIGHT );
529 maHighlightHdl.Call( this );
531 XubString aStr = GetHelpText( mnCurItemId );
532 if ( aStr.Len() || mbHideStatusText )
534 GetpApp()->ShowHelpStatusText( aStr );
535 mbHideStatusText = TRUE;
539 // -----------------------------------------------------------------------
541 void ToolBox::Select()
543 ImplDelData aDelData;
544 ImplAddDel( &aDelData );
546 ImplCallEventListeners( VCLEVENT_TOOLBOX_SELECT );
547 maSelectHdl.Call( this );
549 if ( aDelData.IsDelete() )
550 return;
551 ImplRemoveDel( &aDelData );
553 // TODO: GetFloatingWindow in DockingWindow is currently inline, change it to check dockingwrapper
554 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
555 if( pWrapper && pWrapper->GetFloatingWindow() && pWrapper->GetFloatingWindow()->IsInPopupMode() )
556 pWrapper->GetFloatingWindow()->EndPopupMode();
559 // -----------------------------------------------------------------------
561 void ToolBox::NextToolBox()
563 maNextToolBoxHdl.Call( this );
566 // -----------------------------------------------------------------------
568 void ToolBox::Customize( const ToolBoxCustomizeEvent& )
572 // -----------------------------------------------------------------------
574 void ToolBox::UserDraw( const UserDrawEvent& )
578 // -----------------------------------------------------------------------
580 void ToolBox::InsertItem( const ResId& rResId, USHORT nPos )
582 ULONG nObjMask;
583 BOOL bImage = FALSE; // Wurde Image gesetzt
585 // Item anlegen
586 ImplToolItem aItem;
588 GetRes( rResId.SetRT( RSC_TOOLBOXITEM ) );
589 nObjMask = ReadLongRes();
591 if ( nObjMask & RSC_TOOLBOXITEM_ID )
592 aItem.mnId = sal::static_int_cast<USHORT>(ReadLongRes());
593 else
594 aItem.mnId = 1;
596 if ( nObjMask & RSC_TOOLBOXITEM_TYPE )
597 aItem.meType = (ToolBoxItemType)ReadLongRes();
599 if ( nObjMask & RSC_TOOLBOXITEM_STATUS )
600 aItem.mnBits = (ToolBoxItemBits)ReadLongRes();
602 if( nObjMask & RSC_TOOLBOXITEM_HELPID )
603 aItem.mnHelpId = ReadLongRes();
605 if ( nObjMask & RSC_TOOLBOXITEM_TEXT )
607 aItem.maText = ReadStringRes();
608 aItem.maText = ImplConvertMenuString( aItem.maText );
610 if ( nObjMask & RSC_TOOLBOXITEM_HELPTEXT )
611 aItem.maHelpText = ReadStringRes();
613 if ( nObjMask & RSC_TOOLBOXITEM_BITMAP )
615 Bitmap aBmp = Bitmap( ResId( (RSHEADER_TYPE*)GetClassRes(), *rResId.GetResMgr() ) );
616 IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) );
617 aItem.maImage = Image( aBmp, IMAGE_STDBTN_COLOR );
618 bImage = TRUE;
620 if ( nObjMask & RSC_TOOLBOXITEM_IMAGE )
622 aItem.maImage = Image( ResId( (RSHEADER_TYPE*)GetClassRes(), *rResId.GetResMgr() ) );
623 IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) );
624 bImage = TRUE;
626 if ( nObjMask & RSC_TOOLBOXITEM_DISABLE )
627 aItem.mbEnabled = !(BOOL)ReadShortRes();
629 if ( nObjMask & RSC_TOOLBOXITEM_STATE )
630 aItem.meState = (TriState)ReadLongRes();
632 if ( nObjMask & RSC_TOOLBOXITEM_HIDE )
633 aItem.mbVisible = !((BOOL)ReadShortRes());
635 if ( nObjMask & RSC_TOOLBOXITEM_COMMAND )
636 aItem.maCommandStr = ReadStringRes();
638 // Wenn kein Image geladen wurde, versuchen wir das Image aus der
639 // Image-Liste zu holen
640 if ( !bImage && aItem.mnId )
641 aItem.maImage = maImageList.GetImage( aItem.mnId );
643 // Wenn es sich um ein ButtonItem handelt, die ID ueberpruefen
644 BOOL bNewCalc;
645 if ( aItem.meType != TOOLBOXITEM_BUTTON )
647 bNewCalc = FALSE;
648 aItem.mnId = 0;
650 else
652 bNewCalc = TRUE;
654 DBG_ASSERT( aItem.mnId, "ToolBox::InsertItem(): ItemId == 0" );
655 DBG_ASSERT( GetItemPos( aItem.mnId ) == TOOLBOX_ITEM_NOTFOUND,
656 "ToolBox::InsertItem(): ItemId already exists" );
659 // Item anlegen und in die Liste einfuegen
660 mpData->m_aItems.insert( (nPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nPos : mpData->m_aItems.end(), aItem );
661 mpData->ImplClearLayoutData();
663 // ToolBox neu brechnen und neu ausgeben
664 ImplInvalidate( bNewCalc );
666 // Notify
667 USHORT nNewPos = sal::static_int_cast<USHORT>(( nPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nPos);
668 ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >( nNewPos ) );
671 // -----------------------------------------------------------------------
673 void ToolBox::InsertItem( USHORT nItemId, const Image& rImage,
674 ToolBoxItemBits nBits, USHORT nPos )
676 DBG_ASSERT( nItemId, "ToolBox::InsertItem(): ItemId == 0" );
677 DBG_ASSERT( GetItemPos( nItemId ) == TOOLBOX_ITEM_NOTFOUND,
678 "ToolBox::InsertItem(): ItemId already exists" );
680 // Item anlegen und in die Liste einfuegen
681 mpData->m_aItems.insert( (nPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nPos : mpData->m_aItems.end(), ImplToolItem( nItemId, rImage, nBits ) );
682 mpData->ImplClearLayoutData();
684 ImplInvalidate( TRUE );
686 // Notify
687 USHORT nNewPos = sal::static_int_cast<USHORT>(( nPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nPos);
688 ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >(nNewPos ) );
691 // -----------------------------------------------------------------------
693 void ToolBox::InsertItem( USHORT nItemId, const Image& rImage,
694 const XubString& rText,
695 ToolBoxItemBits nBits, USHORT nPos )
697 DBG_ASSERT( nItemId, "ToolBox::InsertItem(): ItemId == 0" );
698 DBG_ASSERT( GetItemPos( nItemId ) == TOOLBOX_ITEM_NOTFOUND,
699 "ToolBox::InsertItem(): ItemId already exists" );
701 // Item anlegen und in die Liste einfuegen
702 mpData->m_aItems.insert( (nPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nPos : mpData->m_aItems.end(), ImplToolItem( nItemId, rImage, ImplConvertMenuString( rText ), nBits ) );
703 mpData->ImplClearLayoutData();
705 ImplInvalidate( TRUE );
707 // Notify
708 USHORT nNewPos = sal::static_int_cast<USHORT>(( nPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nPos);
709 ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >( nNewPos ) );
712 // -----------------------------------------------------------------------
714 void ToolBox::InsertItem( USHORT nItemId, const XubString& rText,
715 ToolBoxItemBits nBits, USHORT nPos )
717 DBG_ASSERT( nItemId, "ToolBox::InsertItem(): ItemId == 0" );
718 DBG_ASSERT( GetItemPos( nItemId ) == TOOLBOX_ITEM_NOTFOUND,
719 "ToolBox::InsertItem(): ItemId already exists" );
721 // Item anlegen und in die Liste einfuegen
722 mpData->m_aItems.insert( (nPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nPos : mpData->m_aItems.end(), ImplToolItem( nItemId, ImplConvertMenuString( rText ), nBits ) );
723 mpData->ImplClearLayoutData();
725 ImplInvalidate( TRUE );
727 // Notify
728 USHORT nNewPos = sal::static_int_cast<USHORT>(( nPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nPos);
729 ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >( nNewPos ) );
732 // -----------------------------------------------------------------------
734 void ToolBox::InsertWindow( USHORT nItemId, Window* pWindow,
735 ToolBoxItemBits nBits, USHORT nPos )
737 DBG_ASSERT( nItemId, "ToolBox::InsertWindow(): ItemId == 0" );
738 DBG_ASSERT( GetItemPos( nItemId ) == TOOLBOX_ITEM_NOTFOUND,
739 "ToolBox::InsertWindow(): ItemId already exists" );
741 // Item anlegen und in die Liste einfuegen
742 ImplToolItem aItem;
743 aItem.mnId = nItemId;
744 aItem.meType = TOOLBOXITEM_BUTTON;
745 aItem.mnBits = nBits;
746 aItem.mpWindow = pWindow;
747 mpData->m_aItems.insert( (nPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nPos : mpData->m_aItems.end(), aItem );
748 mpData->ImplClearLayoutData();
750 if ( pWindow )
751 pWindow->Hide();
753 ImplInvalidate( TRUE );
755 // Notify
756 USHORT nNewPos = sal::static_int_cast<USHORT>(( nPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nPos);
757 ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >( nNewPos ) );
760 // -----------------------------------------------------------------------
762 void ToolBox::InsertSpace( USHORT nPos )
764 // Item anlegen und in die Liste einfuegen
765 ImplToolItem aItem;
766 aItem.meType = TOOLBOXITEM_SPACE;
767 aItem.mbEnabled = FALSE;
768 mpData->m_aItems.insert( (nPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nPos : mpData->m_aItems.end(), aItem );
769 mpData->ImplClearLayoutData();
771 ImplInvalidate( FALSE );
773 // Notify
774 USHORT nNewPos = sal::static_int_cast<USHORT>(( nPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nPos);
775 ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >( nNewPos ) );
778 // -----------------------------------------------------------------------
780 void ToolBox::InsertSeparator( USHORT nPos, USHORT nPixSize )
782 // Item anlegen und in die Liste einfuegen
783 ImplToolItem aItem;
784 aItem.meType = TOOLBOXITEM_SEPARATOR;
785 aItem.mbEnabled = FALSE;
786 if ( nPixSize )
787 aItem.mnSepSize = nPixSize;
788 mpData->m_aItems.insert( (nPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nPos : mpData->m_aItems.end(), aItem );
789 mpData->ImplClearLayoutData();
791 ImplInvalidate( FALSE );
793 // Notify
794 USHORT nNewPos = sal::static_int_cast<USHORT>(( nPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nPos);
795 ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >( nNewPos ) );
798 // -----------------------------------------------------------------------
800 void ToolBox::InsertBreak( USHORT nPos )
802 // Item anlegen und in die Liste einfuegen
803 ImplToolItem aItem;
804 aItem.meType = TOOLBOXITEM_BREAK;
805 aItem.mbEnabled = FALSE;
806 mpData->m_aItems.insert( (nPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nPos : mpData->m_aItems.end(), aItem );
807 mpData->ImplClearLayoutData();
809 ImplInvalidate( FALSE );
811 // Notify
812 USHORT nNewPos = sal::static_int_cast<USHORT>(( nPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nPos);
813 ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >( nNewPos ) );
816 // -----------------------------------------------------------------------
818 void ToolBox::RemoveItem( USHORT nPos )
820 if( nPos < mpData->m_aItems.size() )
822 BOOL bMustCalc;
823 if ( mpData->m_aItems[nPos].meType == TOOLBOXITEM_BUTTON )
824 bMustCalc = TRUE;
825 else
826 bMustCalc = FALSE;
828 if ( mpData->m_aItems[nPos].mpWindow )
829 mpData->m_aItems[nPos].mpWindow->Hide();
831 // PaintRect um das removete Item erweitern
832 maPaintRect.Union( mpData->m_aItems[nPos].maRect );
834 // Absichern gegen das Loeschen im Select-Handler
835 if ( mpData->m_aItems[nPos].mnId == mnCurItemId )
836 mnCurItemId = 0;
837 if ( mpData->m_aItems[nPos].mnId == mnHighItemId )
838 mnHighItemId = 0;
840 ImplInvalidate( bMustCalc );
842 mpData->m_aItems.erase( mpData->m_aItems.begin()+nPos );
843 mpData->ImplClearLayoutData();
845 // Notify
846 ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMREMOVED, reinterpret_cast< void* >( nPos ) );
850 // -----------------------------------------------------------------------
852 void ToolBox::MoveItem( USHORT nItemId, USHORT nNewPos )
854 USHORT nPos = GetItemPos( nItemId );
856 if ( nPos == nNewPos )
857 return;
859 if ( nPos < nNewPos )
860 nNewPos--;
862 // Existiert Item
863 if ( nPos != TOOLBOX_ITEM_NOTFOUND )
865 // ToolBox-Item in der Liste verschieben
866 ImplToolItem aItem = mpData->m_aItems[nPos];
867 mpData->m_aItems.erase( mpData->m_aItems.begin()+nPos );
868 mpData->m_aItems.insert( (nNewPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nNewPos : mpData->m_aItems.end(), aItem );
869 mpData->ImplClearLayoutData();
871 // ToolBox neu ausgeben
872 ImplInvalidate( FALSE );
874 // Notify
875 if( nPos < nNewPos ) // only send one event, all indices above this item are invalid anyway
876 ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMREMOVED, reinterpret_cast< void* >( nPos ) );
877 else
879 USHORT nNewPos2 = sal::static_int_cast<USHORT>(( nNewPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nNewPos);
880 ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >( nNewPos2 ) );
885 // -----------------------------------------------------------------------
887 void ToolBox::CopyItem( const ToolBox& rToolBox, USHORT nItemId,
888 USHORT nNewPos )
890 DBG_ASSERT( GetItemPos( nItemId ) == TOOLBOX_ITEM_NOTFOUND,
891 "ToolBox::CopyItem(): ItemId already exists" );
893 USHORT nPos = rToolBox.GetItemPos( nItemId );
895 // Existiert Item
896 if ( nPos != TOOLBOX_ITEM_NOTFOUND )
898 // ToolBox-Item in der Liste verschieben
899 ImplToolItem aNewItem = rToolBox.mpData->m_aItems[nPos];
900 // Bestimme Daten zuruecksetzen
901 aNewItem.mpWindow = NULL;
902 aNewItem.mbShowWindow = FALSE;
904 mpData->m_aItems.insert( (nNewPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nNewPos : mpData->m_aItems.end(), aNewItem );
905 mpData->ImplClearLayoutData();
906 // ToolBox neu ausgeben
907 ImplInvalidate( FALSE );
909 // Notify
910 USHORT nNewPos2 = sal::static_int_cast<USHORT>(( nNewPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nNewPos);
911 ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >( nNewPos2 ) );
915 // -----------------------------------------------------------------------
917 void ToolBox::CopyItems( const ToolBox& rToolBox )
919 mpData->ImplClearLayoutData();
920 mpData->m_aItems = rToolBox.mpData->m_aItems;
921 // Absichern gegen das Loeschen im Select-Handler
922 mnCurItemId = 0;
923 mnHighItemId = 0;
925 for( std::vector< ImplToolItem >::iterator it = mpData->m_aItems.begin();
926 it != mpData->m_aItems.end(); ++it )
928 it->mpWindow = NULL;
929 it->mbShowWindow = FALSE;
932 ImplInvalidate( TRUE, TRUE );
934 // Notify
935 ImplCallEventListeners( VCLEVENT_TOOLBOX_ALLITEMSCHANGED );
938 // -----------------------------------------------------------------------
940 void ToolBox::Clear()
942 mpData->m_aItems.clear();
943 mpData->ImplClearLayoutData();
945 // Absichern gegen das Loeschen im Select-Handler
946 mnCurItemId = 0;
947 mnHighItemId = 0;
949 ImplInvalidate( TRUE, TRUE );
951 // Notify
952 ImplCallEventListeners( VCLEVENT_TOOLBOX_ALLITEMSCHANGED );
955 // -----------------------------------------------------------------------
957 void ToolBox::SetButtonType( ButtonType eNewType )
959 if ( meButtonType != eNewType )
961 meButtonType = eNewType;
963 // Hier besser alles neu ausgeben, da es ansonsten zu Problemen
964 // mit den per CopyBits kopierten Bereichen geben kann
965 ImplInvalidate( TRUE );
969 // -----------------------------------------------------------------------
971 void ToolBox::SetToolboxButtonSize( ToolBoxButtonSize eSize )
973 if( mpData->meButtonSize != eSize )
975 mpData->meButtonSize = eSize;
976 mbCalc = TRUE;
977 mbFormat = TRUE;
981 ToolBoxButtonSize ToolBox::GetToolboxButtonSize() const
983 return mpData->meButtonSize;
986 // -----------------------------------------------------------------------
988 const Size& ToolBox::GetDefaultImageSize() const
990 static Size aSmallButtonSize( TB_SMALLIMAGESIZE, TB_SMALLIMAGESIZE );
992 static ULONG s_nSymbolsStyle = STYLE_SYMBOLS_DEFAULT;
993 static Size aLargeButtonSize( TB_LARGEIMAGESIZE, TB_LARGEIMAGESIZE );
995 ULONG nSymbolsStyle = Application::GetSettings().GetStyleSettings().GetCurrentSymbolsStyle();
996 if ( s_nSymbolsStyle != nSymbolsStyle )
998 s_nSymbolsStyle = nSymbolsStyle;
999 switch ( nSymbolsStyle )
1001 case STYLE_SYMBOLS_INDUSTRIAL:
1002 aLargeButtonSize = Size( TB_LARGEIMAGESIZE_INDUSTRIAL, TB_LARGEIMAGESIZE_INDUSTRIAL );
1003 break;
1004 case STYLE_SYMBOLS_CRYSTAL:
1005 aLargeButtonSize = Size( TB_LARGEIMAGESIZE_CRYSTAL, TB_LARGEIMAGESIZE_CRYSTAL );
1006 break;
1007 default:
1008 aLargeButtonSize = Size( TB_LARGEIMAGESIZE, TB_LARGEIMAGESIZE );
1012 return GetToolboxButtonSize() == TOOLBOX_BUTTONSIZE_LARGE ? aLargeButtonSize : aSmallButtonSize;
1015 // -----------------------------------------------------------------------
1017 void ToolBox::SetAlign( WindowAlign eNewAlign )
1019 if ( meAlign != eNewAlign )
1021 meAlign = eNewAlign;
1023 if ( !ImplIsFloatingMode() )
1025 // Setzen, ob Items horizontal oder vertikal angeordnet werden sollen
1026 if ( (eNewAlign == WINDOWALIGN_LEFT) || (eNewAlign == WINDOWALIGN_RIGHT) )
1027 mbHorz = FALSE;
1028 else
1029 mbHorz = TRUE;
1031 // Hier alles neu ausgeben, da sich Border auch aendert
1032 mbCalc = TRUE;
1033 mbFormat = TRUE;
1034 if ( IsReallyVisible() && IsUpdateMode() )
1035 Invalidate();
1040 // -----------------------------------------------------------------------
1042 void ToolBox::SetLineCount( USHORT nNewLines )
1044 if ( !nNewLines )
1045 nNewLines = 1;
1047 if ( mnLines != nNewLines )
1049 mnLines = nNewLines;
1051 // Hier besser alles neu ausgeben, da es ansonsten zu Problemen
1052 // mit den per CopyBits kopierten Bereichen geben kann
1053 ImplInvalidate( FALSE );
1057 // -----------------------------------------------------------------------
1059 void ToolBox::SetPageScroll( BOOL b )
1061 mpData->mbPageScroll = b;
1064 BOOL ToolBox::GetPageScroll()
1066 return mpData->mbPageScroll;
1069 // -----------------------------------------------------------------------
1071 void ToolBox::SetNextToolBox( const XubString& rStr )
1073 BOOL bCalcNew = (!maNextToolBoxStr.Len() != !rStr.Len());
1074 maNextToolBoxStr = rStr;
1075 if ( bCalcNew )
1076 ImplInvalidate( TRUE, FALSE );
1079 // -----------------------------------------------------------------------
1081 USHORT ToolBox::GetItemCount() const
1083 return (USHORT)mpData->m_aItems.size();
1086 // -----------------------------------------------------------------------
1088 ToolBoxItemType ToolBox::GetItemType( USHORT nPos ) const
1090 return (nPos < mpData->m_aItems.size()) ? mpData->m_aItems[nPos].meType : TOOLBOXITEM_DONTKNOW;
1093 // -----------------------------------------------------------------------
1095 USHORT ToolBox::GetItemPos( USHORT nItemId ) const
1097 int nCount = mpData->m_aItems.size();
1098 for( int nPos = 0; nPos < nCount; nPos++ )
1099 if( mpData->m_aItems[nPos].mnId == nItemId )
1100 return (USHORT)nPos;
1102 return TOOLBOX_ITEM_NOTFOUND;
1105 // -----------------------------------------------------------------------
1107 USHORT ToolBox::GetItemPos( const Point& rPos ) const
1109 // search the item position on the given point
1110 USHORT nRet = TOOLBOX_ITEM_NOTFOUND;
1111 USHORT nPos = 0;
1112 std::vector< ImplToolItem >::const_iterator it = mpData->m_aItems.begin();
1113 while( it != mpData->m_aItems.end() )
1115 if ( it->maRect.IsInside( rPos ) )
1117 // item found -> save position and break
1118 nRet = nPos;
1119 break;
1122 ++it;
1123 ++nPos;
1126 return nRet;
1129 // -----------------------------------------------------------------------
1131 USHORT ToolBox::GetItemId( USHORT nPos ) const
1133 return (nPos < mpData->m_aItems.size()) ? mpData->m_aItems[nPos].mnId : 0;
1136 // -----------------------------------------------------------------------
1138 USHORT ToolBox::GetItemId( const Point& rPos ) const
1140 // Item suchen, das geklickt wurde
1141 std::vector< ImplToolItem >::const_iterator it = mpData->m_aItems.begin();
1142 while( it != mpData->m_aItems.end() )
1144 // Ist es dieses Item
1145 if ( it->maRect.IsInside( rPos ) )
1147 if ( it->meType == TOOLBOXITEM_BUTTON )
1148 return it->mnId;
1149 else
1150 return 0;
1153 ++it;
1156 return 0;
1159 // -----------------------------------------------------------------------
1161 Point ToolBox::ImplGetPopupPosition( const Rectangle& rRect, const Size& rSize ) const
1163 Point aPos;
1164 if( !rRect.IsEmpty() )
1166 Rectangle aScreen = GetDesktopRectPixel();
1168 // the popup should be positioned so that it will not cover
1169 // the item rect and that it fits the desktop
1170 // the preferred direction is always towards the center of
1171 // the application window
1173 Point devPos; // the position in device coordinates for screen comparison
1174 switch( meAlign )
1176 case WINDOWALIGN_TOP:
1177 aPos = rRect.BottomLeft();
1178 aPos.Y()++;
1179 devPos = OutputToAbsoluteScreenPixel( aPos );
1180 if( devPos.Y() + rSize.Height() >= aScreen.Bottom() )
1181 aPos.Y() = rRect.Top() - rSize.Height();
1182 break;
1183 case WINDOWALIGN_BOTTOM:
1184 aPos = rRect.TopLeft();
1185 aPos.Y()--;
1186 devPos = OutputToAbsoluteScreenPixel( aPos );
1187 if( devPos.Y() - rSize.Height() > aScreen.Top() )
1188 aPos.Y() -= rSize.Height();
1189 else
1190 aPos.Y() = rRect.Bottom();
1191 break;
1192 case WINDOWALIGN_LEFT:
1193 aPos = rRect.TopRight();
1194 aPos.X()++;
1195 devPos = OutputToAbsoluteScreenPixel( aPos );
1196 if( devPos.X() + rSize.Width() >= aScreen.Right() )
1197 aPos.X() = rRect.Left() - rSize.Width();
1198 break;
1199 case WINDOWALIGN_RIGHT:
1200 aPos = rRect.TopLeft();
1201 aPos.X()--;
1202 devPos = OutputToAbsoluteScreenPixel( aPos );
1203 if( devPos.X() - rSize.Width() > aScreen.Left() )
1204 aPos.X() -= rSize.Width();
1205 else
1206 aPos.X() = rRect.Right();
1207 break;
1208 default:
1209 break;
1212 return aPos;
1216 Point ToolBox::GetItemPopupPosition( USHORT nItemId, const Size& rSize ) const
1218 return ImplGetPopupPosition( GetItemRect( nItemId ), rSize );
1221 // -----------------------------------------------------------------------
1223 Rectangle ToolBox::GetItemRect( USHORT nItemId ) const
1225 if ( mbCalc || mbFormat )
1226 ((ToolBox*)this)->ImplFormat();
1228 USHORT nPos = GetItemPos( nItemId );
1229 return GetItemPosRect( nPos );
1232 // -----------------------------------------------------------------------
1234 Rectangle ToolBox::GetItemPosRect( USHORT nPos ) const
1236 if ( mbCalc || mbFormat )
1237 ((ToolBox*)this)->ImplFormat();
1239 if ( nPos < mpData->m_aItems.size() )
1240 return mpData->m_aItems[nPos].maRect;
1241 else
1242 return Rectangle();
1245 // -----------------------------------------------------------------------
1246 Rectangle ToolBox::GetItemDropDownRect( USHORT nItemId ) const
1248 if ( mbCalc || mbFormat )
1249 ((ToolBox*)this)->ImplFormat();
1251 USHORT nPos = GetItemPos( nItemId );
1252 return GetItemPosDropDownRect( nPos );
1255 // -----------------------------------------------------------------------
1257 Rectangle ToolBox::GetItemPosDropDownRect( USHORT nPos ) const
1259 if ( mbCalc || mbFormat )
1260 ((ToolBox*)this)->ImplFormat();
1262 if ( nPos < mpData->m_aItems.size() )
1263 return mpData->m_aItems[nPos].GetDropDownRect( mbHorz );
1264 else
1265 return Rectangle();
1268 // -----------------------------------------------------------------------
1270 Rectangle ToolBox::GetMenubuttonRect() const
1272 return mpData->maMenubuttonItem.maRect;
1275 BOOL ToolBox::ImplHasExternalMenubutton()
1277 // check if the borderwindow (i.e. the decoration) provides the menu button
1278 BOOL bRet = FALSE;
1279 if( ImplIsFloatingMode() )
1281 // custom menu is placed in the decoration
1282 ImplBorderWindow *pBorderWin = dynamic_cast<ImplBorderWindow*>( GetWindow( WINDOW_BORDER ) );
1283 if( pBorderWin && !pBorderWin->GetMenuRect().IsEmpty() )
1284 bRet = TRUE;
1286 return bRet;
1288 // -----------------------------------------------------------------------
1290 void ToolBox::SetItemBits( USHORT nItemId, ToolBoxItemBits nBits )
1292 USHORT nPos = GetItemPos( nItemId );
1294 if ( nPos < mpData->m_aItems.size() )
1296 ToolBoxItemBits nOldBits = mpData->m_aItems[nPos].mnBits;
1297 mpData->m_aItems[nPos].mnBits = nBits;
1298 nBits &= TIB_LEFT | TIB_AUTOSIZE | TIB_DROPDOWN;
1299 nOldBits &= TIB_LEFT | TIB_AUTOSIZE | TIB_DROPDOWN;
1300 // trigger reformat when the item width has changed (dropdown arrow)
1301 BOOL bFormat = (nBits & TIB_DROPDOWN) != (nOldBits & TIB_DROPDOWN);
1302 if ( nBits != nOldBits )
1303 ImplInvalidate( TRUE, bFormat );
1307 // -----------------------------------------------------------------------
1309 ToolBoxItemBits ToolBox::GetItemBits( USHORT nItemId ) const
1311 ImplToolItem* pItem = ImplGetItem( nItemId );
1313 if ( pItem )
1314 return pItem->mnBits;
1315 else
1316 return 0;
1319 // -----------------------------------------------------------------------
1321 void ToolBox::SetItemData( USHORT nItemId, void* pNewData )
1323 USHORT nPos = GetItemPos( nItemId );
1325 if ( nPos < mpData->m_aItems.size() )
1327 mpData->m_aItems[nPos].mpUserData = pNewData;
1328 ImplUpdateItem( nPos );
1332 // -----------------------------------------------------------------------
1334 void* ToolBox::GetItemData( USHORT nItemId ) const
1336 ImplToolItem* pItem = ImplGetItem( nItemId );
1338 if ( pItem )
1339 return pItem->mpUserData;
1340 else
1341 return NULL;
1344 // -----------------------------------------------------------------------
1346 void ToolBox::SetItemImage( USHORT nItemId, const Image& rImage )
1348 USHORT nPos = GetItemPos( nItemId );
1350 if ( nPos != TOOLBOX_ITEM_NOTFOUND )
1352 ImplToolItem* pItem = &mpData->m_aItems[nPos];
1353 // Nur wenn alles berechnet ist, mehr Aufwand treiben
1354 if ( !mbCalc )
1356 Size aOldSize = pItem->maImage.GetSizePixel();
1357 pItem->maImage = rImage;
1358 if ( aOldSize != pItem->maImage.GetSizePixel() )
1359 ImplInvalidate( TRUE );
1360 else
1361 ImplUpdateItem( nPos );
1363 else
1364 pItem->maImage = rImage;
1368 // -----------------------------------------------------------------------
1370 void ToolBox::SetImageList( const ImageList& rImageList )
1372 maImageList = rImageList;
1374 USHORT nCount = (USHORT)mpData->m_aItems.size();
1375 for( USHORT i = 0; i < nCount; i++ )
1377 Image aImage;
1378 if ( mpData->m_aItems[i].mnId )
1379 aImage = maImageList.GetImage( mpData->m_aItems[i].mnId );
1380 if( !!aImage )
1381 SetItemImage( mpData->m_aItems[i].mnId, aImage );
1385 // -----------------------------------------------------------------------
1387 static Image ImplRotImage( const Image& rImage, long nAngle10 )
1389 Image aRet;
1390 BitmapEx aRotBitmapEx( rImage.GetBitmapEx() );
1392 aRotBitmapEx.Rotate( nAngle10, Color( COL_WHITE ) );
1394 return Image( aRotBitmapEx );
1397 void ToolBox::SetItemImageAngle( USHORT nItemId, long nAngle10 )
1399 USHORT nPos = GetItemPos( nItemId );
1401 if ( nPos != TOOLBOX_ITEM_NOTFOUND )
1403 ImplToolItem* pItem = &mpData->m_aItems[nPos];
1404 Size aOldSize = pItem->maImage.GetSizePixel();
1406 long nDeltaAngle = (nAngle10 - pItem->mnImageAngle) % 3600;
1407 while( nDeltaAngle < 0 )
1408 nDeltaAngle += 3600;
1410 pItem->mnImageAngle = nAngle10;
1411 if( nDeltaAngle && !!pItem->maImage )
1413 pItem->maImage = ImplRotImage( pItem->maImage, nDeltaAngle );
1414 if( !!pItem->maHighImage )
1415 pItem->maHighImage = ImplRotImage( pItem->maHighImage, nDeltaAngle );
1418 if ( !mbCalc )
1420 if ( aOldSize != pItem->maImage.GetSizePixel() )
1421 ImplInvalidate( TRUE );
1422 else
1423 ImplUpdateItem( nPos );
1428 // -----------------------------------------------------------------------
1430 static Image ImplMirrorImage( const Image& rImage )
1432 Image aRet;
1433 BitmapEx aMirrBitmapEx( rImage.GetBitmapEx() );
1435 aMirrBitmapEx.Mirror( BMP_MIRROR_HORZ );
1437 return Image( aMirrBitmapEx );
1440 void ToolBox::SetItemImageMirrorMode( USHORT nItemId, BOOL bMirror )
1442 USHORT nPos = GetItemPos( nItemId );
1444 if ( nPos != TOOLBOX_ITEM_NOTFOUND )
1446 ImplToolItem* pItem = &mpData->m_aItems[nPos];
1448 if( ( pItem->mbMirrorMode && ! bMirror ) ||
1449 ( ! pItem->mbMirrorMode && bMirror )
1452 pItem->mbMirrorMode = bMirror ? true : false;
1453 if( !!pItem->maImage )
1455 pItem->maImage = ImplMirrorImage( pItem->maImage );
1456 if( !!pItem->maHighImage )
1457 pItem->maHighImage = ImplMirrorImage( pItem->maHighImage );
1460 if ( !mbCalc )
1461 ImplUpdateItem( nPos );
1466 // -----------------------------------------------------------------------
1468 Image ToolBox::GetItemImage( USHORT nItemId ) const
1470 ImplToolItem* pItem = ImplGetItem( nItemId );
1472 if ( pItem )
1473 return pItem->maImage;
1474 else
1475 return Image();
1478 // -----------------------------------------------------------------------
1480 long ToolBox::GetItemImageAngle( USHORT nItemId ) const
1482 ImplToolItem* pItem = ImplGetItem( nItemId );
1484 if ( pItem )
1485 return pItem->mnImageAngle;
1486 else
1487 return 0;
1490 // -----------------------------------------------------------------------
1492 BOOL ToolBox::GetItemImageMirrorMode( USHORT nItemId ) const
1494 ImplToolItem* pItem = ImplGetItem( nItemId );
1496 if ( pItem )
1497 return pItem->mbMirrorMode;
1498 else
1499 return FALSE;
1502 // -----------------------------------------------------------------------
1504 void ToolBox::SetItemHighImage( USHORT nItemId, const Image& rImage )
1506 ImplToolItem* pItem = ImplGetItem( nItemId );
1507 if ( pItem )
1509 DBG_ASSERT( (pItem->maImage.GetSizePixel() == rImage.GetSizePixel()) ||
1510 ((!rImage) == TRUE), "ToolBox::SetItemHighImage() - ImageSize != HighImageSize" );
1511 pItem->maHighImage = rImage;
1515 // -----------------------------------------------------------------------
1517 Image ToolBox::GetItemHighImage( USHORT nItemId ) const
1519 ImplToolItem* pItem = ImplGetItem( nItemId );
1521 if ( pItem )
1522 return pItem->maHighImage;
1523 else
1524 return Image();
1527 // -----------------------------------------------------------------------
1529 void ToolBox::SetItemText( USHORT nItemId, const XubString& rText )
1531 USHORT nPos = GetItemPos( nItemId );
1533 if ( nPos != TOOLBOX_ITEM_NOTFOUND )
1535 ImplToolItem* pItem = &mpData->m_aItems[nPos];
1536 // Nur wenn alles berechnet ist, mehr Aufwand treiben
1537 if ( !mbCalc &&
1538 ((meButtonType != BUTTON_SYMBOL) || !pItem->maImage) )
1540 long nOldWidth = GetCtrlTextWidth( pItem->maText );
1541 pItem->maText = ImplConvertMenuString( rText );
1542 mpData->ImplClearLayoutData();
1543 if ( nOldWidth != GetCtrlTextWidth( pItem->maText ) )
1544 ImplInvalidate( TRUE );
1545 else
1546 ImplUpdateItem( nPos );
1548 else
1549 pItem->maText = ImplConvertMenuString( rText );
1551 // Notify button changed event to prepare accessibility bridge
1552 ImplCallEventListeners( VCLEVENT_TOOLBOX_BUTTONSTATECHANGED, reinterpret_cast< void* >( nPos ) );
1554 // Notify
1555 ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMTEXTCHANGED, reinterpret_cast< void* >( nPos ) );
1559 // -----------------------------------------------------------------------
1561 const XubString& ToolBox::GetItemText( USHORT nItemId ) const
1563 ImplToolItem* pItem = ImplGetItem( nItemId );
1565 if ( pItem )
1566 return pItem->maText;
1567 else
1568 return ImplGetSVEmptyStr();
1571 // -----------------------------------------------------------------------
1573 void ToolBox::SetItemWindow( USHORT nItemId, Window* pNewWindow )
1575 USHORT nPos = GetItemPos( nItemId );
1577 if ( nPos != TOOLBOX_ITEM_NOTFOUND )
1579 ImplToolItem* pItem = &mpData->m_aItems[nPos];
1580 pItem->mpWindow = pNewWindow;
1581 if ( pNewWindow )
1582 pNewWindow->Hide();
1583 ImplInvalidate( TRUE );
1584 ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMWINDOWCHANGED, reinterpret_cast< void* >( nPos ) );
1588 // -----------------------------------------------------------------------
1590 Window* ToolBox::GetItemWindow( USHORT nItemId ) const
1592 ImplToolItem* pItem = ImplGetItem( nItemId );
1594 if ( pItem )
1595 return pItem->mpWindow;
1596 else
1597 return NULL;
1600 // -----------------------------------------------------------------------
1602 void ToolBox::StartSelection()
1604 if ( mbDrag )
1605 EndSelection();
1607 if ( !mbSelection )
1609 mbSelection = TRUE;
1610 mnCurPos = TOOLBOX_ITEM_NOTFOUND;
1611 mnCurItemId = 0;
1612 Activate();
1616 // -----------------------------------------------------------------------
1618 void ToolBox::EndSelection()
1620 mbCommandDrag = FALSE;
1622 if ( mbDrag || mbSelection )
1624 // Daten zuruecksetzen
1625 mbDrag = FALSE;
1626 mbSelection = FALSE;
1627 if ( mnCurPos != TOOLBOX_ITEM_NOTFOUND )
1628 ImplDrawItem( mnCurPos );
1629 EndTracking();
1630 ReleaseMouse();
1631 Deactivate();
1634 mnCurPos = TOOLBOX_ITEM_NOTFOUND;
1635 mnCurItemId = 0;
1636 mnDownItemId = 0;
1637 mnMouseClicks = 0;
1638 mnMouseModifier = 0;
1641 // -----------------------------------------------------------------------
1643 void ToolBox::SetItemDown( USHORT nItemId, BOOL bDown, BOOL bRelease )
1645 USHORT nPos = GetItemPos( nItemId );
1647 if ( nPos != TOOLBOX_ITEM_NOTFOUND )
1649 if ( bDown )
1651 if ( nPos != mnCurPos )
1653 mnCurPos = nPos;
1654 ImplDrawItem( mnCurPos, TRUE );
1655 Flush();
1658 else
1660 if ( nPos == mnCurPos )
1662 ImplDrawItem( mnCurPos, FALSE );
1663 Flush();
1664 mnCurPos = TOOLBOX_ITEM_NOTFOUND;
1668 if ( bRelease )
1670 if ( mbDrag || mbSelection )
1672 mbDrag = FALSE;
1673 mbSelection = FALSE;
1674 EndTracking();
1675 ReleaseMouse();
1676 Deactivate();
1679 mnCurItemId = 0;
1680 mnDownItemId = 0;
1681 mnMouseClicks = 0;
1682 mnMouseModifier = 0;
1687 // -----------------------------------------------------------------------
1689 BOOL ToolBox::IsItemDown( USHORT nItemId ) const
1691 USHORT nPos = GetItemPos( nItemId );
1693 if ( nPos != TOOLBOX_ITEM_NOTFOUND )
1694 return (nPos == mnCurPos);
1695 else
1696 return FALSE;
1699 // -----------------------------------------------------------------------
1701 void ToolBox::SetItemState( USHORT nItemId, TriState eState )
1703 USHORT nPos = GetItemPos( nItemId );
1705 if ( nPos != TOOLBOX_ITEM_NOTFOUND )
1707 ImplToolItem* pItem = &mpData->m_aItems[nPos];
1709 // Hat sich der Status geaendert
1710 if ( pItem->meState != eState )
1712 // Wenn RadioCheck, dann vorherigen unchecken
1713 if ( (eState == STATE_CHECK) && (pItem->mnBits & TIB_AUTOCHECK) &&
1714 (pItem->mnBits & TIB_RADIOCHECK) )
1716 ImplToolItem* pGroupItem;
1717 USHORT nGroupPos;
1718 USHORT nItemCount = GetItemCount();
1720 nGroupPos = nPos;
1721 while ( nGroupPos )
1723 pGroupItem = &mpData->m_aItems[nGroupPos-1];
1724 if ( pGroupItem->mnBits & TIB_RADIOCHECK )
1726 if ( pGroupItem->meState != STATE_NOCHECK )
1727 SetItemState( pGroupItem->mnId, STATE_NOCHECK );
1729 else
1730 break;
1731 nGroupPos--;
1734 nGroupPos = nPos+1;
1735 while ( nGroupPos < nItemCount )
1737 pGroupItem = &mpData->m_aItems[nGroupPos];
1738 if ( pGroupItem->mnBits & TIB_RADIOCHECK )
1740 if ( pGroupItem->meState != STATE_NOCHECK )
1741 SetItemState( pGroupItem->mnId, STATE_NOCHECK );
1743 else
1744 break;
1745 nGroupPos++;
1749 pItem->meState = eState;
1750 ImplUpdateItem( nPos );
1752 // Notify button changed event to prepare accessibility bridge
1753 ImplCallEventListeners( VCLEVENT_TOOLBOX_BUTTONSTATECHANGED, reinterpret_cast< void* >( nPos ) );
1755 // Notify
1756 ImplCallEventListeners( VCLEVENT_TOOLBOX_CLICK, reinterpret_cast< void* >( nPos ) );
1761 // -----------------------------------------------------------------------
1763 TriState ToolBox::GetItemState( USHORT nItemId ) const
1765 ImplToolItem* pItem = ImplGetItem( nItemId );
1767 if ( pItem )
1768 return pItem->meState;
1769 else
1770 return STATE_NOCHECK;
1773 // -----------------------------------------------------------------------
1775 void ToolBox::EnableItem( USHORT nItemId, BOOL bEnable )
1777 USHORT nPos = GetItemPos( nItemId );
1779 if ( nPos != TOOLBOX_ITEM_NOTFOUND )
1781 ImplToolItem* pItem = &mpData->m_aItems[nPos];
1782 if ( bEnable )
1783 bEnable = TRUE;
1784 if ( pItem->mbEnabled != bEnable )
1786 pItem->mbEnabled = bEnable;
1788 // Gegebenenfalls das Fenster mit updaten
1789 if ( pItem->mpWindow )
1790 pItem->mpWindow->Enable( pItem->mbEnabled );
1792 // Item updaten
1793 ImplUpdateItem( nPos );
1795 ImplUpdateInputEnable();
1797 // Notify button changed event to prepare accessibility bridge
1798 ImplCallEventListeners( VCLEVENT_TOOLBOX_BUTTONSTATECHANGED, reinterpret_cast< void* >( nPos ) );
1800 ImplCallEventListeners( bEnable ? VCLEVENT_TOOLBOX_ITEMENABLED : VCLEVENT_TOOLBOX_ITEMDISABLED, reinterpret_cast< void* >( nPos ) );
1805 // -----------------------------------------------------------------------
1807 BOOL ToolBox::IsItemEnabled( USHORT nItemId ) const
1809 ImplToolItem* pItem = ImplGetItem( nItemId );
1811 if ( pItem )
1812 return pItem->mbEnabled;
1813 else
1814 return FALSE;
1817 // -----------------------------------------------------------------------
1819 void ToolBox::ShowItem( USHORT nItemId, BOOL bVisible )
1821 USHORT nPos = GetItemPos( nItemId );
1822 mpData->ImplClearLayoutData();
1824 if ( nPos != TOOLBOX_ITEM_NOTFOUND )
1826 ImplToolItem* pItem = &mpData->m_aItems[nPos];
1827 if ( pItem->mbVisible != bVisible )
1829 pItem->mbVisible = bVisible;
1830 ImplInvalidate( FALSE );
1835 // -----------------------------------------------------------------------
1837 BOOL ToolBox::IsItemVisible( USHORT nItemId ) const
1839 ImplToolItem* pItem = ImplGetItem( nItemId );
1841 if ( pItem )
1842 return pItem->mbVisible;
1843 else
1844 return FALSE;
1847 // -----------------------------------------------------------------------
1849 BOOL ToolBox::IsItemReallyVisible( USHORT nItemId ) const
1851 // is the item on the visible area of the toolbox?
1852 BOOL bRet = FALSE;
1853 Rectangle aRect( mnLeftBorder, mnTopBorder, mnDX-mnRightBorder, mnDY-mnBottomBorder );
1854 ImplToolItem* pItem = ImplGetItem( nItemId );
1856 if ( pItem && pItem->mbVisible &&
1857 !pItem->maRect.IsEmpty() && aRect.IsOver( pItem->maRect ) )
1859 bRet = TRUE;
1862 return bRet;
1865 // -----------------------------------------------------------------------
1867 void ToolBox::SetItemCommand( USHORT nItemId, const XubString& rCommand )
1869 ImplToolItem* pItem = ImplGetItem( nItemId );
1871 if ( pItem )
1872 pItem->maCommandStr = rCommand;
1875 // -----------------------------------------------------------------------
1877 const XubString& ToolBox::GetItemCommand( USHORT nItemId ) const
1879 ImplToolItem* pItem = ImplGetItem( nItemId );
1881 if ( pItem )
1882 return pItem->maCommandStr;
1883 else
1884 return ImplGetSVEmptyStr();
1887 // -----------------------------------------------------------------------
1889 void ToolBox::SetQuickHelpText( USHORT nItemId, const XubString& rText )
1891 ImplToolItem* pItem = ImplGetItem( nItemId );
1893 if ( pItem )
1894 pItem->maQuickHelpText = rText;
1897 // -----------------------------------------------------------------------
1899 const XubString& ToolBox::GetQuickHelpText( USHORT nItemId ) const
1901 ImplToolItem* pItem = ImplGetItem( nItemId );
1903 if ( pItem )
1904 return pItem->maQuickHelpText;
1905 else
1906 return ImplGetSVEmptyStr();
1909 // -----------------------------------------------------------------------
1911 void ToolBox::SetHelpText( USHORT nItemId, const XubString& rText )
1913 ImplToolItem* pItem = ImplGetItem( nItemId );
1915 if ( pItem )
1916 pItem->maHelpText = rText;
1919 // -----------------------------------------------------------------------
1921 const XubString& ToolBox::GetHelpText( USHORT nItemId ) const
1923 return ImplGetHelpText( nItemId );
1926 // -----------------------------------------------------------------------
1928 void ToolBox::SetHelpId( USHORT nItemId, ULONG nHelpId )
1930 ImplToolItem* pItem = ImplGetItem( nItemId );
1932 if ( pItem )
1933 pItem->mnHelpId = nHelpId;
1936 // -----------------------------------------------------------------------
1938 ULONG ToolBox::GetHelpId( USHORT nItemId ) const
1940 ImplToolItem* pItem = ImplGetItem( nItemId );
1942 if ( pItem )
1943 return pItem->mnHelpId;
1944 else
1945 return 0;
1948 // -----------------------------------------------------------------------
1950 void ToolBox::SetBorder( long nX, long nY )
1952 mnBorderX = nX;
1953 mnBorderY = nY;
1955 ImplInvalidate( TRUE, TRUE );
1958 // -----------------------------------------------------------------------
1960 void ToolBox::SetOutStyle( USHORT nNewStyle )
1962 // always force flat looking toolbars since NWF
1963 nNewStyle |= TOOLBOX_STYLE_FLAT;
1965 if ( mnOutStyle != nNewStyle )
1967 mnOutStyle = nNewStyle;
1968 ImplDisableFlatButtons();
1970 // Damit das ButtonDevice neu angelegt wird
1971 if ( !(mnOutStyle & TOOLBOX_STYLE_FLAT) )
1973 mnMaxItemWidth = 1;
1974 mnMaxItemHeight = 1;
1977 ImplInvalidate( TRUE, TRUE );
1981 // -----------------------------------------------------------------------
1983 void ToolBox::RecalcItems()
1985 ImplInvalidate( TRUE );
1988 // -----------------------------------------------------------------------
1990 // disable key input if all items are disabled
1992 void ToolBox::ImplUpdateInputEnable()
1994 for( std::vector< ImplToolItem >::const_iterator it = mpData->m_aItems.begin();
1995 it != mpData->m_aItems.end(); ++it )
1997 if( it->mbEnabled )
1999 // at least one useful entry
2000 mpData->mbKeyInputDisabled = FALSE;
2001 return;
2004 mpData->mbKeyInputDisabled = TRUE;
2007 // -----------------------------------------------------------------------
2009 void ToolBox::ImplFillLayoutData() const
2011 mpData->m_pLayoutData = new ToolBoxLayoutData();
2013 USHORT nCount = (USHORT)mpData->m_aItems.size();
2014 for( USHORT i = 0; i < nCount; i++ )
2016 ImplToolItem* pItem = &mpData->m_aItems[i];
2018 // Nur malen, wenn Rechteck im PaintRectangle liegt
2019 if ( !pItem->maRect.IsEmpty() )
2020 const_cast<ToolBox*>(this)->ImplDrawItem( i, FALSE, FALSE, TRUE );
2024 // -----------------------------------------------------------------------
2026 String ToolBox::GetDisplayText() const
2028 if( ! mpData->m_pLayoutData )
2029 ImplFillLayoutData();
2030 return mpData->m_pLayoutData ? mpData->m_pLayoutData->m_aDisplayText : String();
2033 // -----------------------------------------------------------------------
2035 Rectangle ToolBox::GetCharacterBounds( USHORT nItemID, long nIndex ) const
2037 long nItemIndex = -1;
2038 if( ! mpData->m_pLayoutData )
2039 ImplFillLayoutData();
2040 if( mpData->m_pLayoutData )
2042 for( ULONG i = 0; i < mpData->m_pLayoutData->m_aLineItemIds.size(); i++ )
2044 if( mpData->m_pLayoutData->m_aLineItemIds[i] == nItemID )
2046 nItemIndex = mpData->m_pLayoutData->m_aLineIndices[i];
2047 break;
2051 return (mpData->m_pLayoutData && nItemIndex != -1) ? mpData->m_pLayoutData->GetCharacterBounds( nItemIndex+nIndex ) : Rectangle();
2054 // -----------------------------------------------------------------------
2056 long ToolBox::GetIndexForPoint( const Point& rPoint, USHORT& rItemID ) const
2058 long nIndex = -1;
2059 rItemID = 0;
2060 if( ! mpData->m_pLayoutData )
2061 ImplFillLayoutData();
2062 if( mpData->m_pLayoutData )
2064 nIndex = mpData->m_pLayoutData->GetIndexForPoint( rPoint );
2065 for( ULONG i = 0; i < mpData->m_pLayoutData->m_aLineIndices.size(); i++ )
2067 if( mpData->m_pLayoutData->m_aLineIndices[i] <= nIndex &&
2068 (i == mpData->m_pLayoutData->m_aLineIndices.size()-1 || mpData->m_pLayoutData->m_aLineIndices[i+1] > nIndex) )
2070 rItemID = mpData->m_pLayoutData->m_aLineItemIds[i];
2071 break;
2075 return nIndex;
2078 // -----------------------------------------------------------------------
2080 long ToolBox::GetTextCount() const
2082 if( ! mpData->m_pLayoutData )
2083 ImplFillLayoutData();
2084 return mpData->m_pLayoutData ? mpData->m_pLayoutData->GetLineCount() : 0;
2087 // -----------------------------------------------------------------------
2089 Pair ToolBox::GetTextStartEnd( long nText ) const
2091 if( ! mpData->m_pLayoutData )
2092 ImplFillLayoutData();
2093 return mpData->m_pLayoutData ? mpData->m_pLayoutData->GetLineStartEnd( nText ) : Pair( -1, -1 );
2096 // -----------------------------------------------------------------------
2098 USHORT ToolBox::GetDisplayItemId( long nText ) const
2100 USHORT nItemId = 0;
2101 if( ! mpData->m_pLayoutData )
2102 ImplFillLayoutData();
2103 if( mpData->m_pLayoutData && nText >= 0 && (ULONG)nText < mpData->m_pLayoutData->m_aLineItemIds.size() )
2104 nItemId = mpData->m_pLayoutData->m_aLineItemIds[nText];
2105 return nItemId;
2109 // -----------------------------------------------------------------------
2111 void ToolBox::SetDropdownClickHdl( const Link& rLink )
2113 mpData->maDropdownClickHdl = rLink;
2116 const Link& ToolBox::GetDropdownClickHdl() const
2118 return mpData->maDropdownClickHdl;
2121 // -----------------------------------------------------------------------
2123 void ToolBox::SetMenuType( USHORT aType )
2125 if( aType != mpData->maMenuType )
2127 mpData->maMenuType = aType;
2128 if( IsFloatingMode() )
2130 // the menu button may have to be moved into the decoration which changes the layout
2131 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
2132 if( pWrapper )
2133 pWrapper->ShowTitleButton( TITLE_BUTTON_MENU, ( aType & TOOLBOX_MENUTYPE_CUSTOMIZE) ? TRUE : FALSE );
2135 mbFormat = TRUE;
2136 ImplFormat();
2137 ImplSetMinMaxFloatSize( this );
2139 else
2141 // trigger redraw of menu button
2142 if( !mpData->maMenubuttonItem.maRect.IsEmpty() )
2143 Invalidate(mpData->maMenubuttonItem.maRect);
2148 USHORT ToolBox::GetMenuType() const
2150 return mpData->maMenuType;
2153 BOOL ToolBox::IsMenuEnabled() const
2155 return mpData->maMenuType != TOOLBOX_MENUTYPE_NONE;
2158 PopupMenu* ToolBox::GetMenu() const
2160 return mpData->mpMenu;
2163 void ToolBox::SetMenuButtonHdl( const Link& rLink )
2165 mpData->maMenuButtonHdl = rLink;
2168 const Link& ToolBox::GetMenuButtonHdl() const
2170 return mpData->maMenuButtonHdl;
2173 // -----------------------------------------------------------------------
2175 BOOL ToolBox::ImplHasClippedItems()
2177 // are any items currently clipped ?
2178 ImplFormat();
2179 std::vector< ImplToolItem >::const_iterator it = mpData->m_aItems.begin();
2180 while ( it != mpData->m_aItems.end() )
2182 if( it->IsClipped() )
2183 return TRUE;
2184 it++;
2186 return FALSE;
2189 void ToolBox::ImplUpdateCustomMenu()
2191 // fill clipped items into menu
2192 if( !IsMenuEnabled() )
2193 return;
2195 PopupMenu *pMenu = GetMenu();
2197 USHORT i = 0;
2198 // remove old entries
2199 while( i < pMenu->GetItemCount() )
2201 if( pMenu->GetItemId( i ) >= TOOLBOX_MENUITEM_START )
2203 pMenu->RemoveItem( i );
2204 i = 0;
2206 else
2207 i++;
2210 // add menu items, starting from the end and inserting at pos 0
2211 if ( !mpData->m_aItems.empty() )
2213 for ( std::vector< ImplToolItem >::reverse_iterator it(mpData->m_aItems.rbegin());
2214 it != mpData->m_aItems.rend(); ++it)
2216 if( it->IsClipped() )
2218 USHORT id = it->mnId + TOOLBOX_MENUITEM_START;
2219 pMenu->InsertItem( id, it->maText, it->maImage, 0, 0 );
2220 pMenu->EnableItem( id, it->mbEnabled );
2221 pMenu->CheckItem( id, it->meState == STATE_CHECK );
2227 IMPL_LINK( ToolBox, ImplCustomMenuListener, VclMenuEvent*, pEvent )
2229 if( pEvent->GetMenu() == GetMenu() && pEvent->GetId() == VCLEVENT_MENU_SELECT )
2231 USHORT id = GetMenu()->GetItemId( pEvent->GetItemPos() );
2232 if( id >= TOOLBOX_MENUITEM_START )
2233 TriggerItem( id - TOOLBOX_MENUITEM_START, FALSE, FALSE );
2235 return 0;
2238 IMPL_LINK( ToolBox, ImplCallExecuteCustomMenu, void*, EMPTYARG )
2240 mpData->mnEventId = 0;
2241 ImplExecuteCustomMenu();
2242 return 0;
2245 void ToolBox::ImplExecuteCustomMenu()
2247 if( IsMenuEnabled() )
2249 if( GetMenuType() & TOOLBOX_MENUTYPE_CUSTOMIZE )
2250 // call button handler to allow for menu customization
2251 mpData->maMenuButtonHdl.Call( this );
2253 // register handler
2254 GetMenu()->AddEventListener( LINK( this, ToolBox, ImplCustomMenuListener ) );
2256 // make sure all disabled entries will be shown
2257 GetMenu()->SetMenuFlags(
2258 GetMenu()->GetMenuFlags() | MENU_FLAG_ALWAYSSHOWDISABLEDENTRIES );
2260 // toolbox might be destroyed during execute
2261 ImplDelData aDelData;
2262 ImplAddDel( &aDelData );
2263 ImplDelData aBorderDel;
2264 bool bBorderDel = false;
2266 Window *pWin = this;
2267 Rectangle aMenuRect = mpData->maMenubuttonItem.maRect;
2268 if( IsFloatingMode() )
2270 // custom menu is placed in the decoration
2271 ImplBorderWindow *pBorderWin = dynamic_cast<ImplBorderWindow*>( GetWindow( WINDOW_BORDER ) );
2272 if( pBorderWin && !pBorderWin->GetMenuRect().IsEmpty() )
2274 pWin = pBorderWin;
2275 aMenuRect = pBorderWin->GetMenuRect();
2276 pWin->ImplAddDel( &aBorderDel );
2277 bBorderDel = true;
2281 USHORT uId = GetMenu()->Execute( pWin, Rectangle( ImplGetPopupPosition( aMenuRect, Size() ), Size() ),
2282 POPUPMENU_EXECUTE_DOWN | POPUPMENU_NOMOUSEUPCLOSE );
2284 if ( aDelData.IsDelete() )
2285 return;
2286 ImplRemoveDel( &aDelData );
2288 if( GetMenu() )
2289 GetMenu()->RemoveEventListener( LINK( this, ToolBox, ImplCustomMenuListener ) );
2290 if( bBorderDel )
2292 if( aBorderDel.IsDelete() )
2293 return;
2294 pWin->ImplRemoveDel( &aBorderDel );
2297 pWin->Invalidate( aMenuRect );
2299 if( uId )
2300 GrabFocusToDocument();
2304 void ToolBox::ExecuteCustomMenu()
2306 if( IsMenuEnabled() )
2308 // handle custom menu asynchronously
2309 // to avoid problems if the toolbox is closed during menu execute
2310 ImplUpdateCustomMenu();
2311 Application::PostUserEvent( mpData->mnEventId, LINK( this, ToolBox, ImplCallExecuteCustomMenu ) );
2315 // -----------------------------------------------------------------------
2317 // checks override first, useful during calculation of sizes
2318 BOOL ToolBox::ImplIsFloatingMode() const
2320 DBG_ASSERT( !(mpData->mbAssumeDocked && mpData->mbAssumeFloating),
2321 "ToolBox::ImplIsFloatingMode(): cannot assume docked and floating" );
2323 if( mpData->mbAssumeDocked )
2324 return FALSE;
2325 else if( mpData->mbAssumeFloating )
2326 return TRUE;
2327 else
2328 return IsFloatingMode();
2331 // checks override first, useful during calculation of sizes
2332 BOOL ToolBox::ImplIsInPopupMode() const
2334 if( mpData->mbAssumePopupMode )
2335 return TRUE;
2336 else
2338 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
2339 return ( pWrapper && pWrapper->GetFloatingWindow() && pWrapper->GetFloatingWindow()->IsInPopupMode() );
2343 // -----------------------------------------------------------------------
2345 void ToolBox::Lock( BOOL bLock )
2347 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
2348 if( !pWrapper )
2349 return;
2350 if( mpData->mbIsLocked != bLock )
2352 mpData->mbIsLocked = bLock;
2353 if( !ImplIsFloatingMode() )
2355 mbCalc = TRUE;
2356 mbFormat = TRUE;
2357 SetSizePixel( CalcWindowSizePixel(1) );
2358 Invalidate();
2363 // -----------------------------------------------------------------------
2365 BOOL ToolBox::AlwaysLocked()
2367 // read config item to determine toolbox behaviour, used for subtoolbars
2369 static int nAlwaysLocked = -1;
2371 if( nAlwaysLocked == -1 )
2373 nAlwaysLocked = 0; // ask configuration only once
2375 utl::OConfigurationNode aNode = utl::OConfigurationTreeRoot::tryCreateWithServiceFactory(
2376 vcl::unohelper::GetMultiServiceFactory(),
2377 OUString::createFromAscii( "/org.openoffice.Office.UI.GlobalSettings/Toolbars" ) ); // note: case sensisitive !
2378 if ( aNode.isValid() )
2380 // feature enabled ?
2381 BOOL bStatesEnabled = BOOL();
2382 ::com::sun::star::uno::Any aValue = aNode.getNodeValue( OUString::createFromAscii( "StatesEnabled" ) );
2383 if( aValue >>= bStatesEnabled )
2385 if( bStatesEnabled == TRUE )
2387 // now read the locking state
2388 utl::OConfigurationNode aNode2 = utl::OConfigurationTreeRoot::tryCreateWithServiceFactory(
2389 vcl::unohelper::GetMultiServiceFactory(),
2390 OUString::createFromAscii( "/org.openoffice.Office.UI.GlobalSettings/Toolbars/States" ) ); // note: case sensisitive !
2392 BOOL bLocked = BOOL();
2393 ::com::sun::star::uno::Any aValue2 = aNode2.getNodeValue( OUString::createFromAscii( "Locked" ) );
2394 if( aValue2 >>= bLocked )
2395 nAlwaysLocked = (bLocked == TRUE) ? 1 : 0;
2401 return nAlwaysLocked == 1 ? TRUE : FALSE;
2404 BOOL ToolBox::WillUsePopupMode() const
2406 return mpData->mbWillUsePopupMode;
2409 void ToolBox::WillUsePopupMode( BOOL b )
2411 mpData->mbWillUsePopupMode = b;
2414 void ToolBox::ImplUpdateImageList()
2416 if (mpData->mpImageListProvider != NULL)
2418 BOOL bIsDark = GetSettings().GetStyleSettings().GetFaceColor().IsDark();
2421 ImageListType eType = bIsDark ? vcl::HIGHCONTRAST_YES : vcl::HIGHCONTRAST_NO;
2423 if (eType != mpData->meImageListType)
2425 vcl::IImageListProvider* pImageListProvider = mpData->mpImageListProvider;
2426 SetImageList( pImageListProvider->getImageList(eType) );
2427 mpData->meImageListType = eType;
2430 catch (com::sun::star::lang::IllegalArgumentException &) {}
2434 void ToolBox::SetImageListProvider(vcl::IImageListProvider* _pProvider)
2436 mpData->mpImageListProvider = _pProvider;
2437 ImplUpdateImageList();
2439 // -----------------------------------------------------------------------