Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "sal/config.h"
21 :
22 : #include <comphelper/processfactory.hxx>
23 : #include <comphelper/string.hxx>
24 : #include <tools/debug.hxx>
25 : #include <tools/rc.h>
26 :
27 : #include <vcl/svapp.hxx>
28 : #include <vcl/help.hxx>
29 : #include <vcl/bitmap.hxx>
30 : #include <vcl/toolbox.hxx>
31 : #include <vcl/mnemonic.hxx>
32 : #include <vcl/menu.hxx>
33 : #include <vcl/ImageListProvider.hxx>
34 : #include <vcl/settings.hxx>
35 : #include <vcl/IconThemeInfo.hxx>
36 :
37 : #include <svdata.hxx>
38 : #include <brdwin.hxx>
39 : #include <toolbox.h>
40 :
41 : #include <unotools/confignode.hxx>
42 :
43 : #include <com/sun/star/frame/ModuleManager.hpp>
44 : #include <com/sun/star/frame/XController.hpp>
45 : #include <com/sun/star/frame/XModel.hpp>
46 : #include <com/sun/star/frame/XModuleManager2.hpp>
47 : #include <com/sun/star/lang/IllegalArgumentException.hpp>
48 :
49 : using namespace vcl;
50 : using namespace com::sun::star;
51 :
52 : #define TB_SEP_SIZE 8
53 :
54 58331 : ImplToolBoxPrivateData::ImplToolBoxPrivateData() :
55 : m_pLayoutData( NULL ),
56 : mpImageListProvider( NULL ),
57 58331 : meImageListType( vcl::IMAGELISTTYPE_UNKNOWN )
58 : {
59 58331 : meButtonSize = TOOLBOX_BUTTONSIZE_DONTCARE;
60 58331 : mpMenu = new PopupMenu();
61 58331 : mnEventId = 0;
62 :
63 58331 : maMenuType = TOOLBOX_MENUTYPE_NONE;
64 58331 : maMenubuttonItem.maItemSize = Size( TB_MENUBUTTON_SIZE+TB_MENUBUTTON_OFFSET, TB_MENUBUTTON_SIZE+TB_MENUBUTTON_OFFSET );
65 58331 : maMenubuttonItem.meState = TRISTATE_FALSE;
66 58331 : mnMenuButtonWidth = TB_MENUBUTTON_SIZE;
67 :
68 58331 : mbIsLocked = false;
69 58331 : mbNativeButtons = false;
70 58331 : mbIsPaintLocked = false;
71 58331 : mbAssumeDocked = false;
72 58331 : mbAssumePopupMode = false;
73 58331 : mbAssumeFloating = false;
74 58331 : mbKeyInputDisabled = false;
75 58331 : mbMenubuttonSelected = false;
76 58331 : mbPageScroll = false;
77 58331 : mbWillUsePopupMode = false;
78 58331 : mbDropDownByKeyboard = false;
79 58331 : }
80 :
81 116634 : ImplToolBoxPrivateData::~ImplToolBoxPrivateData()
82 : {
83 58317 : if( m_pLayoutData )
84 0 : delete m_pLayoutData;
85 58317 : delete mpMenu;
86 58317 : }
87 :
88 293347 : void ImplToolItem::init(sal_uInt16 nItemId, ToolBoxItemBits nItemBits,
89 : bool bEmptyBtn)
90 : {
91 293347 : mnId = nItemId;
92 293347 : mpWindow = NULL;
93 293347 : mpUserData = NULL;
94 293347 : meType = TOOLBOXITEM_BUTTON;
95 293347 : mnBits = nItemBits;
96 293347 : meState = TRISTATE_FALSE;
97 293347 : mbEnabled = true;
98 293347 : mbVisible = true;
99 293347 : mbEmptyBtn = bEmptyBtn;
100 293347 : mbShowWindow = false;
101 293347 : mbBreak = false;
102 293347 : mnSepSize = TB_SEP_SIZE;
103 293347 : mnDropDownArrowWidth = TB_DROPDOWNARROWWIDTH;
104 293347 : mnImageAngle = 0;
105 293347 : mbMirrorMode = false;
106 293347 : mbVisibleText = false;
107 293347 : mbExpand = false;
108 293347 : }
109 :
110 100007 : ImplToolItem::ImplToolItem()
111 : {
112 100007 : init(0, ToolBoxItemBits::NONE, true);
113 100007 : }
114 :
115 19628 : ImplToolItem::ImplToolItem( sal_uInt16 nItemId, const Image& rImage,
116 : ToolBoxItemBits nItemBits ) :
117 19628 : maImage( rImage )
118 : {
119 19628 : init(nItemId, nItemBits, false);
120 19628 : }
121 :
122 144176 : ImplToolItem::ImplToolItem( sal_uInt16 nItemId, const OUString& rText,
123 : ToolBoxItemBits nItemBits ) :
124 144176 : maText( rText )
125 : {
126 144176 : init(nItemId, nItemBits, false);
127 144176 : }
128 :
129 29536 : ImplToolItem::ImplToolItem( sal_uInt16 nItemId, const Image& rImage,
130 : const OUString& rText, ToolBoxItemBits nItemBits ) :
131 : maImage( rImage ),
132 29536 : maText( rText )
133 : {
134 29536 : init(nItemId, nItemBits, false);
135 29536 : }
136 :
137 548686 : ImplToolItem::ImplToolItem( const ImplToolItem& rItem ) :
138 : mpWindow ( rItem.mpWindow ),
139 : mpUserData ( rItem.mpUserData ),
140 : maImage ( rItem.maImage ),
141 : maHighImage ( rItem.maHighImage ),
142 : mnImageAngle ( rItem.mnImageAngle ),
143 : mbMirrorMode ( rItem.mbMirrorMode ),
144 : maText ( rItem.maText ),
145 : maQuickHelpText ( rItem.maQuickHelpText ),
146 : maHelpText ( rItem.maHelpText ),
147 : maCommandStr ( rItem.maCommandStr ),
148 : maHelpId ( rItem.maHelpId ),
149 : maRect ( rItem.maRect ),
150 : maCalcRect ( rItem.maCalcRect ),
151 : maMinimalItemSize ( rItem.maMinimalItemSize ),
152 : maItemSize ( rItem.maItemSize ),
153 : mnSepSize ( rItem.mnSepSize ),
154 : mnDropDownArrowWidth ( rItem.mnDropDownArrowWidth ),
155 : maContentSize ( rItem.maContentSize ),
156 : meType ( rItem.meType ),
157 : mnBits ( rItem.mnBits ),
158 : meState ( rItem.meState ),
159 : mnId ( rItem.mnId ),
160 : mbEnabled ( rItem.mbEnabled ),
161 : mbVisible ( rItem.mbVisible ),
162 : mbEmptyBtn ( rItem.mbEmptyBtn ),
163 : mbShowWindow ( rItem.mbShowWindow ),
164 : mbBreak ( rItem.mbBreak ),
165 : mbVisibleText ( rItem.mbVisibleText ),
166 548686 : mbExpand ( rItem.mbExpand )
167 : {
168 548686 : }
169 :
170 841991 : ImplToolItem::~ImplToolItem()
171 : {
172 841991 : }
173 :
174 7102 : ImplToolItem& ImplToolItem::operator=( const ImplToolItem& rItem )
175 : {
176 7102 : mpWindow = rItem.mpWindow;
177 7102 : mpUserData = rItem.mpUserData;
178 7102 : maImage = rItem.maImage;
179 7102 : maHighImage = rItem.maHighImage;
180 7102 : mnImageAngle = rItem.mnImageAngle;
181 7102 : mbMirrorMode = rItem.mbMirrorMode;
182 7102 : maText = rItem.maText;
183 7102 : maQuickHelpText = rItem.maQuickHelpText;
184 7102 : maHelpText = rItem.maHelpText;
185 7102 : maCommandStr = rItem.maCommandStr;
186 7102 : maHelpId = rItem.maHelpId;
187 7102 : maRect = rItem.maRect;
188 7102 : maCalcRect = rItem.maCalcRect;
189 7102 : mnSepSize = rItem.mnSepSize;
190 7102 : mnDropDownArrowWidth = rItem.mnDropDownArrowWidth;
191 7102 : maContentSize = rItem.maContentSize;
192 7102 : maMinimalItemSize = rItem.maMinimalItemSize;
193 7102 : maItemSize = rItem.maItemSize;
194 7102 : mbVisibleText = rItem.mbVisibleText;
195 7102 : mbExpand = rItem.mbExpand;
196 7102 : meType = rItem.meType;
197 7102 : mnBits = rItem.mnBits;
198 7102 : meState = rItem.meState;
199 7102 : mnId = rItem.mnId;
200 7102 : mbEnabled = rItem.mbEnabled;
201 7102 : mbVisible = rItem.mbVisible;
202 7102 : mbEmptyBtn = rItem.mbEmptyBtn;
203 7102 : mbShowWindow = rItem.mbShowWindow;
204 7102 : mbBreak = rItem.mbBreak;
205 7102 : return *this;
206 : }
207 :
208 174696 : Size ImplToolItem::GetSize( bool bHorz, bool bCheckMaxWidth, long maxWidth, const Size& rDefaultSize )
209 : {
210 174696 : Size aSize( rDefaultSize ); // the size of 'standard' toolbox items
211 : // non-standard items are eg windows or buttons with text
212 :
213 174696 : if ( (meType == TOOLBOXITEM_BUTTON) || (meType == TOOLBOXITEM_SPACE) )
214 : {
215 140796 : aSize = maItemSize;
216 :
217 140796 : if ( mpWindow && bHorz )
218 : {
219 : // get size of item window and check if it fits
220 : // no windows in vertical toolbars (the default is mbShowWindow=false)
221 9692 : Size aWinSize = mpWindow->GetSizePixel();
222 9692 : if ( !bCheckMaxWidth || (aWinSize.Width() <= maxWidth) )
223 : {
224 9692 : aSize.Width() = aWinSize.Width();
225 9692 : aSize.Height() = aWinSize.Height();
226 9692 : mbShowWindow = true;
227 : }
228 : else
229 : {
230 0 : if ( mbEmptyBtn )
231 : {
232 0 : aSize.Width() = 0;
233 0 : aSize.Height() = 0;
234 : }
235 : }
236 140796 : }
237 : }
238 33900 : else if ( meType == TOOLBOXITEM_SEPARATOR )
239 : {
240 33522 : if ( bHorz )
241 : {
242 33522 : aSize.Width() = mnSepSize;
243 33522 : aSize.Height() = rDefaultSize.Height();
244 : }
245 : else
246 : {
247 0 : aSize.Width() = rDefaultSize.Width();
248 0 : aSize.Height() = mnSepSize;
249 : }
250 : }
251 378 : else if ( meType == TOOLBOXITEM_BREAK )
252 : {
253 378 : aSize.Width() = 0;
254 378 : aSize.Height() = 0;
255 : }
256 :
257 174696 : return aSize;
258 : }
259 :
260 146431 : void ImplToolItem::DetermineButtonDrawStyle( ButtonType eButtonType, bool& rbImage, bool& rbText ) const
261 : {
262 146431 : if ( meType != TOOLBOXITEM_BUTTON )
263 : {
264 : // no button -> draw nothing
265 0 : rbImage = rbText = false;
266 146431 : return;
267 : }
268 :
269 : bool bHasImage;
270 : bool bHasText;
271 :
272 : // check for image and/or text
273 146431 : if ( !(maImage) )
274 107 : bHasImage = false;
275 : else
276 146324 : bHasImage = true;
277 146431 : if ( maText.isEmpty() )
278 21405 : bHasText = false;
279 : else
280 125026 : bHasText = true;
281 :
282 : // prefer images if symbolonly buttons are drawn
283 : // prefer texts if textonly buttons are dreawn
284 :
285 146431 : if ( eButtonType == BUTTON_SYMBOL ) // drawing icons only
286 : {
287 146431 : if( bHasImage || !bHasText )
288 : {
289 146324 : rbImage = true;
290 146324 : rbText = false;
291 : }
292 : else
293 : {
294 107 : rbImage = false;
295 107 : rbText = true;
296 : }
297 : }
298 0 : else if ( eButtonType == BUTTON_TEXT ) // drawing text only
299 : {
300 0 : if( bHasText || !bHasImage )
301 : {
302 0 : rbImage = false;
303 0 : rbText = true;
304 : }
305 : else
306 : {
307 0 : rbImage = true;
308 0 : rbText = false;
309 : }
310 : }
311 : else // drawing icons and text both
312 : {
313 0 : rbImage = true;
314 0 : rbText = true;
315 : }
316 : }
317 :
318 33693 : Rectangle ImplToolItem::GetDropDownRect( bool bHorz ) const
319 : {
320 33693 : Rectangle aRect;
321 33693 : if( (mnBits & ToolBoxItemBits::DROPDOWN) && !maRect.IsEmpty() )
322 : {
323 33693 : aRect = maRect;
324 33693 : if( mbVisibleText && !bHorz )
325 : // item will be rotated -> place dropdown to the bottom
326 0 : aRect.Top() = aRect.Bottom() - mnDropDownArrowWidth;
327 : else
328 : // place dropdown to the right
329 33693 : aRect.Left() = aRect.Right() - mnDropDownArrowWidth;
330 : }
331 33693 : return aRect;
332 : }
333 :
334 278317 : bool ImplToolItem::IsClipped() const
335 : {
336 278317 : return ( meType == TOOLBOXITEM_BUTTON && mbVisible && maRect.IsEmpty() );
337 : }
338 :
339 0 : bool ImplToolItem::IsItemHidden() const
340 : {
341 0 : return ( meType == TOOLBOXITEM_BUTTON && !mbVisible );
342 : }
343 :
344 283815 : const OUString ToolBox::ImplConvertMenuString( const OUString& rStr )
345 : {
346 283815 : OUString aCvtStr( rStr );
347 283815 : if ( mbMenuStrings )
348 6 : aCvtStr = comphelper::string::stripEnd(aCvtStr, '.');
349 283815 : aCvtStr = MnemonicGenerator::EraseAllMnemonicChars( aCvtStr );
350 283815 : return aCvtStr;
351 : }
352 :
353 498680 : void ToolBox::ImplInvalidate( bool bNewCalc, bool bFullPaint )
354 : {
355 498680 : ImplUpdateInputEnable();
356 :
357 498680 : if ( bNewCalc )
358 420015 : mbCalc = true;
359 :
360 498680 : if ( bFullPaint )
361 : {
362 24357 : mbFormat = true;
363 :
364 : // do we need to redraw?
365 24357 : if ( IsReallyVisible() && IsUpdateMode() )
366 : {
367 : Invalidate( Rectangle( mnLeftBorder, mnTopBorder,
368 0 : mnDX-mnRightBorder-1, mnDY-mnBottomBorder-1 ) );
369 0 : maTimer.Stop();
370 : }
371 : }
372 : else
373 : {
374 474323 : if ( !mbFormat )
375 : {
376 30056 : mbFormat = true;
377 :
378 : // do we need to redraw?
379 30056 : if ( IsReallyVisible() && IsUpdateMode() )
380 3162 : maTimer.Start();
381 : }
382 : }
383 :
384 : // request new layout by layoutmanager
385 498680 : ImplCallEventListeners( VCLEVENT_TOOLBOX_FORMATCHANGED );
386 498680 : }
387 :
388 212261 : void ToolBox::ImplUpdateItem( sal_uInt16 nIndex )
389 : {
390 : // do we need to redraw?
391 212261 : if ( IsReallyVisible() && IsUpdateMode() )
392 : {
393 26472 : if ( nIndex == 0xFFFF )
394 : {
395 : // #i52217# no immediate draw as this might lead to paint problems
396 : Invalidate( Rectangle( mnLeftBorder, mnTopBorder,
397 9106 : mnDX-mnRightBorder-1, mnDY-mnBottomBorder-1 ) );
398 : }
399 : else
400 : {
401 17366 : if ( !mbFormat )
402 : {
403 : // #i52217# no immediate draw as this might lead to paint problems
404 17366 : Invalidate( mpData->m_aItems[nIndex].maRect );
405 : }
406 : else
407 0 : maPaintRect.Union( mpData->m_aItems[nIndex].maRect );
408 : }
409 : }
410 212261 : }
411 :
412 4 : void ToolBox::Click()
413 : {
414 4 : ImplCallEventListeners( VCLEVENT_TOOLBOX_CLICK );
415 4 : maClickHdl.Call( this );
416 4 : }
417 :
418 0 : void ToolBox::DoubleClick()
419 : {
420 0 : ImplCallEventListeners( VCLEVENT_TOOLBOX_DOUBLECLICK );
421 0 : maDoubleClickHdl.Call( this );
422 0 : }
423 :
424 4 : void ToolBox::Activate()
425 : {
426 4 : mnActivateCount++;
427 4 : ImplCallEventListeners( VCLEVENT_TOOLBOX_ACTIVATE );
428 4 : maActivateHdl.Call( this );
429 4 : }
430 :
431 4 : void ToolBox::Deactivate()
432 : {
433 4 : mnActivateCount--;
434 4 : ImplCallEventListeners( VCLEVENT_TOOLBOX_DEACTIVATE );
435 4 : maDeactivateHdl.Call( this );
436 4 : }
437 :
438 0 : void ToolBox::Highlight()
439 : {
440 0 : ImplCallEventListeners( VCLEVENT_TOOLBOX_HIGHLIGHT );
441 0 : maHighlightHdl.Call( this );
442 0 : }
443 :
444 4 : void ToolBox::Select()
445 : {
446 4 : ImplDelData aDelData;
447 4 : ImplAddDel( &aDelData );
448 :
449 4 : ImplCallEventListeners( VCLEVENT_TOOLBOX_SELECT );
450 4 : maSelectHdl.Call( this );
451 :
452 4 : if ( aDelData.IsDead() )
453 4 : return;
454 4 : ImplRemoveDel( &aDelData );
455 :
456 : // TODO: GetFloatingWindow in DockingWindow is currently inline, change it to check dockingwrapper
457 4 : ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
458 4 : if( pWrapper && pWrapper->GetFloatingWindow() && pWrapper->GetFloatingWindow()->IsInPopupMode() )
459 0 : pWrapper->GetFloatingWindow()->EndPopupMode();
460 : }
461 :
462 0 : void ToolBox::Customize( const ToolBoxCustomizeEvent& )
463 : {
464 0 : }
465 :
466 0 : void ToolBox::UserDraw( const UserDrawEvent& )
467 : {
468 0 : }
469 :
470 11474 : void ToolBox::InsertItem( const ResId& rResId, sal_uInt16 nPos )
471 : {
472 : sal_uLong nObjMask;
473 11474 : bool bImage = false; // has image
474 :
475 : // create item
476 11474 : ImplToolItem aItem;
477 :
478 11474 : GetRes( rResId.SetRT( RSC_TOOLBOXITEM ) );
479 11474 : nObjMask = ReadLongRes();
480 :
481 11474 : if ( nObjMask & RSC_TOOLBOXITEM_ID )
482 8962 : aItem.mnId = sal::static_int_cast<sal_uInt16>(ReadLongRes());
483 : else
484 2512 : aItem.mnId = 1;
485 :
486 11474 : if ( nObjMask & RSC_TOOLBOXITEM_TYPE )
487 2512 : aItem.meType = (ToolBoxItemType)ReadLongRes();
488 :
489 11474 : if ( nObjMask & RSC_TOOLBOXITEM_STATUS )
490 366 : aItem.mnBits = (ToolBoxItemBits)ReadLongRes();
491 :
492 11474 : if( nObjMask & RSC_TOOLBOXITEM_HELPID )
493 8962 : aItem.maHelpId = ReadByteStringRes();
494 :
495 11474 : if ( nObjMask & RSC_TOOLBOXITEM_TEXT )
496 : {
497 8962 : aItem.maText = ReadStringRes();
498 8962 : aItem.maText = ImplConvertMenuString( aItem.maText );
499 : }
500 11474 : if ( nObjMask & RSC_TOOLBOXITEM_HELPTEXT )
501 0 : aItem.maHelpText = ReadStringRes();
502 :
503 11474 : if ( nObjMask & RSC_TOOLBOXITEM_BITMAP )
504 : {
505 0 : Bitmap aBmp = Bitmap( ResId( (RSHEADER_TYPE*)GetClassRes(), *rResId.GetResMgr() ) );
506 0 : IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) );
507 0 : aItem.maImage = Image( aBmp, IMAGE_STDBTN_COLOR );
508 0 : bImage = true;
509 : }
510 11474 : if ( nObjMask & RSC_TOOLBOXITEM_IMAGE )
511 : {
512 0 : aItem.maImage = Image( ResId( (RSHEADER_TYPE*)GetClassRes(), *rResId.GetResMgr() ) );
513 0 : IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) );
514 0 : bImage = true;
515 : }
516 11474 : if ( nObjMask & RSC_TOOLBOXITEM_DISABLE )
517 0 : aItem.mbEnabled = ReadShortRes() == 0;
518 :
519 11474 : if ( nObjMask & RSC_TOOLBOXITEM_STATE )
520 0 : aItem.meState = (TriState)ReadLongRes();
521 :
522 11474 : if ( nObjMask & RSC_TOOLBOXITEM_HIDE )
523 0 : aItem.mbVisible = ReadShortRes() == 0;
524 :
525 11474 : if ( nObjMask & RSC_TOOLBOXITEM_COMMAND )
526 0 : aItem.maCommandStr = ReadStringRes();
527 :
528 : // if no image is loaded, try to load one from the image list
529 11474 : if ( !bImage && aItem.mnId )
530 11474 : aItem.maImage = maImageList.GetImage( aItem.mnId );
531 :
532 : // if this is a ButtonItem, check ID
533 : bool bNewCalc;
534 11474 : if ( aItem.meType != TOOLBOXITEM_BUTTON )
535 : {
536 2512 : bNewCalc = false;
537 2512 : aItem.mnId = 0;
538 : }
539 : else
540 : {
541 8962 : bNewCalc = true;
542 :
543 : DBG_ASSERT( aItem.mnId, "ToolBox::InsertItem(): ItemId == 0" );
544 : DBG_ASSERT( GetItemPos( aItem.mnId ) == TOOLBOX_ITEM_NOTFOUND,
545 : "ToolBox::InsertItem(): ItemId already exists" );
546 : }
547 :
548 : // create item and add to list
549 11474 : mpData->m_aItems.insert( (nPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nPos : mpData->m_aItems.end(), aItem );
550 11474 : mpData->ImplClearLayoutData();
551 :
552 : // recalculate ToolBox and redraw
553 11474 : ImplInvalidate( bNewCalc );
554 :
555 : // Notify
556 11474 : sal_uInt16 nNewPos = sal::static_int_cast<sal_uInt16>(( nPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nPos);
557 11474 : ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >( nNewPos ) );
558 11474 : }
559 :
560 19628 : void ToolBox::InsertItem( sal_uInt16 nItemId, const Image& rImage,
561 : ToolBoxItemBits nBits, sal_uInt16 nPos )
562 : {
563 : DBG_ASSERT( nItemId, "ToolBox::InsertItem(): ItemId == 0" );
564 : DBG_ASSERT( GetItemPos( nItemId ) == TOOLBOX_ITEM_NOTFOUND,
565 : "ToolBox::InsertItem(): ItemId already exists" );
566 :
567 : // create item and add to list
568 19628 : mpData->m_aItems.insert( (nPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nPos : mpData->m_aItems.end(), ImplToolItem( nItemId, rImage, nBits ) );
569 19628 : SetItemImage(nItemId, rImage);
570 19628 : mpData->ImplClearLayoutData();
571 :
572 19628 : ImplInvalidate( true );
573 :
574 : // Notify
575 19628 : sal_uInt16 nNewPos = sal::static_int_cast<sal_uInt16>(( nPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nPos);
576 19628 : ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >(nNewPos ) );
577 19628 : }
578 :
579 29536 : void ToolBox::InsertItem( sal_uInt16 nItemId, const Image& rImage,
580 : const OUString& rText,
581 : ToolBoxItemBits nBits, sal_uInt16 nPos )
582 : {
583 : DBG_ASSERT( nItemId, "ToolBox::InsertItem(): ItemId == 0" );
584 : DBG_ASSERT( GetItemPos( nItemId ) == TOOLBOX_ITEM_NOTFOUND,
585 : "ToolBox::InsertItem(): ItemId already exists" );
586 :
587 : // create item and add to list
588 29536 : mpData->m_aItems.insert( (nPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nPos : mpData->m_aItems.end(), ImplToolItem( nItemId, rImage, ImplConvertMenuString( rText ), nBits ) );
589 29536 : SetItemImage(nItemId, rImage);
590 29536 : mpData->ImplClearLayoutData();
591 :
592 29536 : ImplInvalidate( true );
593 :
594 : // Notify
595 29536 : sal_uInt16 nNewPos = sal::static_int_cast<sal_uInt16>(( nPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nPos);
596 29536 : ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >( nNewPos ) );
597 29536 : }
598 :
599 144176 : void ToolBox::InsertItem( sal_uInt16 nItemId, const OUString& rText,
600 : ToolBoxItemBits nBits, sal_uInt16 nPos )
601 : {
602 : DBG_ASSERT( nItemId, "ToolBox::InsertItem(): ItemId == 0" );
603 : DBG_ASSERT( GetItemPos( nItemId ) == TOOLBOX_ITEM_NOTFOUND,
604 : "ToolBox::InsertItem(): ItemId already exists" );
605 :
606 : // create item and add to list
607 144176 : mpData->m_aItems.insert( (nPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nPos : mpData->m_aItems.end(), ImplToolItem( nItemId, ImplConvertMenuString( rText ), nBits ) );
608 144176 : mpData->ImplClearLayoutData();
609 :
610 144176 : ImplInvalidate( true );
611 :
612 : // Notify
613 144176 : sal_uInt16 nNewPos = sal::static_int_cast<sal_uInt16>(( nPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nPos);
614 144176 : ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >( nNewPos ) );
615 144176 : }
616 :
617 29536 : void ToolBox::InsertItem(const OUString& rCommand, const uno::Reference<frame::XFrame>& rFrame, ToolBoxItemBits nBits, const Size& rRequestedSize, sal_uInt16 nPos)
618 : {
619 29536 : uno::Reference<uno::XComponentContext> xContext(comphelper::getProcessComponentContext());
620 59072 : uno::Reference<frame::XModuleManager2> xModuleManager(frame::ModuleManager::create(xContext));
621 59072 : OUString aModuleId(xModuleManager->identify(rFrame));
622 :
623 59072 : OUString aLabel(VclBuilder::getCommandLabel(rCommand, xContext, aModuleId));
624 59072 : Image aImage(VclBuilder::getCommandImage(rCommand, (GetToolboxButtonSize() == TOOLBOX_BUTTONSIZE_LARGE), xContext, rFrame, aModuleId));
625 :
626 : // let's invent an ItemId
627 29536 : const sal_uInt16 COMMAND_ITEMID_START = 30000;
628 29536 : sal_uInt16 nItemId = COMMAND_ITEMID_START + GetItemCount();
629 :
630 29536 : InsertItem(nItemId, aImage, aLabel, nBits, nPos);
631 29536 : SetItemCommand(nItemId, rCommand);
632 :
633 : // set the minimal size
634 29536 : ImplToolItem* pItem = ImplGetItem( nItemId );
635 29536 : if ( pItem )
636 59072 : pItem->maMinimalItemSize = rRequestedSize;
637 29536 : }
638 :
639 1204 : void ToolBox::InsertWindow( sal_uInt16 nItemId, vcl::Window* pWindow,
640 : ToolBoxItemBits nBits, sal_uInt16 nPos )
641 : {
642 : DBG_ASSERT( nItemId, "ToolBox::InsertWindow(): ItemId == 0" );
643 : DBG_ASSERT( GetItemPos( nItemId ) == TOOLBOX_ITEM_NOTFOUND,
644 : "ToolBox::InsertWindow(): ItemId already exists" );
645 :
646 : // create item and add to list
647 1204 : ImplToolItem aItem;
648 1204 : aItem.mnId = nItemId;
649 1204 : aItem.meType = TOOLBOXITEM_BUTTON;
650 1204 : aItem.mnBits = nBits;
651 1204 : aItem.mpWindow = pWindow;
652 1204 : mpData->m_aItems.insert( (nPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nPos : mpData->m_aItems.end(), aItem );
653 1204 : mpData->ImplClearLayoutData();
654 :
655 1204 : if ( pWindow )
656 1204 : pWindow->Hide();
657 :
658 1204 : ImplInvalidate( true );
659 :
660 : // Notify
661 1204 : sal_uInt16 nNewPos = sal::static_int_cast<sal_uInt16>(( nPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nPos);
662 1204 : ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >( nNewPos ) );
663 1204 : }
664 :
665 34 : void ToolBox::InsertSpace( sal_uInt16 nPos )
666 : {
667 : // create item and add to list
668 34 : ImplToolItem aItem;
669 34 : aItem.meType = TOOLBOXITEM_SPACE;
670 34 : aItem.mbEnabled = false;
671 34 : mpData->m_aItems.insert( (nPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nPos : mpData->m_aItems.end(), aItem );
672 34 : mpData->ImplClearLayoutData();
673 :
674 34 : ImplInvalidate( false );
675 :
676 : // Notify
677 34 : sal_uInt16 nNewPos = sal::static_int_cast<sal_uInt16>(( nPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nPos);
678 34 : ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >( nNewPos ) );
679 34 : }
680 :
681 28928 : void ToolBox::InsertSeparator( sal_uInt16 nPos, sal_uInt16 nPixSize )
682 : {
683 : // create item and add to list
684 28928 : ImplToolItem aItem;
685 28928 : aItem.meType = TOOLBOXITEM_SEPARATOR;
686 28928 : aItem.mbEnabled = false;
687 28928 : if ( nPixSize )
688 0 : aItem.mnSepSize = nPixSize;
689 28928 : mpData->m_aItems.insert( (nPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nPos : mpData->m_aItems.end(), aItem );
690 28928 : mpData->ImplClearLayoutData();
691 :
692 28928 : ImplInvalidate( false );
693 :
694 : // Notify
695 28928 : sal_uInt16 nNewPos = sal::static_int_cast<sal_uInt16>(( nPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nPos);
696 28928 : ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >( nNewPos ) );
697 28928 : }
698 :
699 36 : void ToolBox::InsertBreak( sal_uInt16 nPos )
700 : {
701 : // create item and add to list
702 36 : ImplToolItem aItem;
703 36 : aItem.meType = TOOLBOXITEM_BREAK;
704 36 : aItem.mbEnabled = false;
705 36 : mpData->m_aItems.insert( (nPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nPos : mpData->m_aItems.end(), aItem );
706 36 : mpData->ImplClearLayoutData();
707 :
708 36 : ImplInvalidate( false );
709 :
710 : // Notify
711 36 : sal_uInt16 nNewPos = sal::static_int_cast<sal_uInt16>(( nPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nPos);
712 36 : ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >( nNewPos ) );
713 36 : }
714 :
715 2 : void ToolBox::RemoveItem( sal_uInt16 nPos )
716 : {
717 2 : if( nPos < mpData->m_aItems.size() )
718 : {
719 : bool bMustCalc;
720 2 : if ( mpData->m_aItems[nPos].meType == TOOLBOXITEM_BUTTON )
721 2 : bMustCalc = true;
722 : else
723 0 : bMustCalc = false;
724 :
725 2 : if ( mpData->m_aItems[nPos].mpWindow )
726 0 : mpData->m_aItems[nPos].mpWindow->Hide();
727 :
728 : // add the removed item to PaintRect
729 2 : maPaintRect.Union( mpData->m_aItems[nPos].maRect );
730 :
731 : // ensure not to delete in the Select-Handler
732 2 : if ( mpData->m_aItems[nPos].mnId == mnCurItemId )
733 0 : mnCurItemId = 0;
734 2 : if ( mpData->m_aItems[nPos].mnId == mnHighItemId )
735 0 : mnHighItemId = 0;
736 :
737 2 : ImplInvalidate( bMustCalc );
738 :
739 2 : mpData->m_aItems.erase( mpData->m_aItems.begin()+nPos );
740 2 : mpData->ImplClearLayoutData();
741 :
742 : // Notify
743 2 : ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMREMOVED, reinterpret_cast< void* >( nPos ) );
744 : }
745 2 : }
746 :
747 6703 : void ToolBox::CopyItem( const ToolBox& rToolBox, sal_uInt16 nItemId,
748 : sal_uInt16 nNewPos )
749 : {
750 : DBG_ASSERT( GetItemPos( nItemId ) == TOOLBOX_ITEM_NOTFOUND,
751 : "ToolBox::CopyItem(): ItemId already exists" );
752 :
753 6703 : sal_uInt16 nPos = rToolBox.GetItemPos( nItemId );
754 :
755 : // found item
756 6703 : if ( nPos != TOOLBOX_ITEM_NOTFOUND )
757 : {
758 : // push ToolBox item onto the list
759 6703 : ImplToolItem aNewItem = rToolBox.mpData->m_aItems[nPos];
760 : // reset state
761 6703 : aNewItem.mpWindow = NULL;
762 6703 : aNewItem.mbShowWindow = false;
763 :
764 6703 : mpData->m_aItems.insert( (nNewPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nNewPos : mpData->m_aItems.end(), aNewItem );
765 6703 : mpData->ImplClearLayoutData();
766 : // redraw ToolBox
767 6703 : ImplInvalidate( false );
768 :
769 : // Notify
770 6703 : sal_uInt16 nNewPos2 = sal::static_int_cast<sal_uInt16>(( nNewPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nNewPos);
771 6703 : ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >( nNewPos2 ) );
772 : }
773 6703 : }
774 :
775 10707 : void ToolBox::Clear()
776 : {
777 10707 : mpData->m_aItems.clear();
778 10707 : mpData->ImplClearLayoutData();
779 :
780 : // ensure not to delete in the Select-Handler
781 10707 : mnCurItemId = 0;
782 10707 : mnHighItemId = 0;
783 :
784 10707 : ImplInvalidate( true, true );
785 :
786 : // Notify
787 10707 : ImplCallEventListeners( VCLEVENT_TOOLBOX_ALLITEMSCHANGED );
788 10707 : }
789 :
790 16268 : void ToolBox::SetButtonType( ButtonType eNewType )
791 : {
792 16268 : if ( meButtonType != eNewType )
793 : {
794 0 : meButtonType = eNewType;
795 :
796 : // better redraw everything, as otherwise there might be problems
797 : // with regions that were copied with CopyBits
798 0 : ImplInvalidate( true );
799 : }
800 16268 : }
801 :
802 36776 : void ToolBox::SetToolboxButtonSize( ToolBoxButtonSize eSize )
803 : {
804 36776 : if( mpData->meButtonSize != eSize )
805 : {
806 36776 : mpData->meButtonSize = eSize;
807 36776 : mbCalc = true;
808 36776 : mbFormat = true;
809 : }
810 36776 : }
811 :
812 200018 : ToolBoxButtonSize ToolBox::GetToolboxButtonSize() const
813 : {
814 200018 : return mpData->meButtonSize;
815 : }
816 :
817 : /*static*/ Size
818 113899 : ToolBox::GetDefaultImageSize(bool bLarge)
819 : {
820 113899 : const long TB_SMALLIMAGESIZE = 16;
821 113899 : if (!bLarge) {
822 113899 : return Size(TB_SMALLIMAGESIZE, TB_SMALLIMAGESIZE);
823 : }
824 :
825 0 : OUString iconTheme = Application::GetSettings().GetStyleSettings().DetermineIconTheme();
826 0 : return vcl::IconThemeInfo::SizeByThemeName(iconTheme);
827 : }
828 :
829 113899 : Size ToolBox::GetDefaultImageSize() const
830 : {
831 113899 : return GetDefaultImageSize( GetToolboxButtonSize() == TOOLBOX_BUTTONSIZE_LARGE );
832 : }
833 :
834 18907 : void ToolBox::SetAlign( WindowAlign eNewAlign )
835 : {
836 18907 : if ( meAlign != eNewAlign )
837 : {
838 616 : meAlign = eNewAlign;
839 :
840 616 : if ( !ImplIsFloatingMode() )
841 : {
842 : // set horizontal/vertical alignment
843 616 : if ( (eNewAlign == WINDOWALIGN_LEFT) || (eNewAlign == WINDOWALIGN_RIGHT) )
844 0 : mbHorz = false;
845 : else
846 616 : mbHorz = true;
847 :
848 : // Update the background according to Persona if necessary
849 616 : ImplInitSettings( false, false, true );
850 :
851 : // redraw everything, as the border has changed
852 616 : mbCalc = true;
853 616 : mbFormat = true;
854 616 : if ( IsReallyVisible() && IsUpdateMode() )
855 0 : Invalidate();
856 : }
857 : }
858 18907 : }
859 :
860 16728 : void ToolBox::SetLineCount( sal_uInt16 nNewLines )
861 : {
862 16728 : if ( !nNewLines )
863 0 : nNewLines = 1;
864 :
865 16728 : if ( mnLines != nNewLines )
866 : {
867 460 : mnLines = nNewLines;
868 :
869 : // better redraw everything, as otherwise there might be problems
870 : // with regions that were copied with CopyBits
871 460 : ImplInvalidate( false );
872 : }
873 16728 : }
874 :
875 0 : void ToolBox::SetPageScroll( bool b )
876 : {
877 0 : mpData->mbPageScroll = b;
878 0 : }
879 :
880 833184 : sal_uInt16 ToolBox::GetItemCount() const
881 : {
882 833184 : return (sal_uInt16)mpData->m_aItems.size();
883 : }
884 :
885 2842 : ToolBoxItemType ToolBox::GetItemType( sal_uInt16 nPos ) const
886 : {
887 2842 : return (nPos < mpData->m_aItems.size()) ? mpData->m_aItems[nPos].meType : TOOLBOXITEM_DONTKNOW;
888 : }
889 :
890 1516253 : sal_uInt16 ToolBox::GetItemPos( sal_uInt16 nItemId ) const
891 : {
892 1516253 : int nCount = mpData->m_aItems.size();
893 23648414 : for( int nPos = 0; nPos < nCount; nPos++ )
894 23648084 : if( mpData->m_aItems[nPos].mnId == nItemId )
895 1515923 : return (sal_uInt16)nPos;
896 :
897 330 : return TOOLBOX_ITEM_NOTFOUND;
898 : }
899 :
900 0 : sal_uInt16 ToolBox::GetItemPos( const Point& rPos ) const
901 : {
902 : // search the item position on the given point
903 0 : sal_uInt16 nRet = TOOLBOX_ITEM_NOTFOUND;
904 0 : sal_uInt16 nPos = 0;
905 0 : std::vector< ImplToolItem >::const_iterator it = mpData->m_aItems.begin();
906 0 : while( it != mpData->m_aItems.end() )
907 : {
908 0 : if ( it->maRect.IsInside( rPos ) )
909 : {
910 : // item found -> save position and break
911 0 : nRet = nPos;
912 0 : break;
913 : }
914 :
915 0 : ++it;
916 0 : ++nPos;
917 : }
918 :
919 0 : return nRet;
920 : }
921 :
922 708140 : sal_uInt16 ToolBox::GetItemId( sal_uInt16 nPos ) const
923 : {
924 708140 : return (nPos < mpData->m_aItems.size()) ? mpData->m_aItems[nPos].mnId : 0;
925 : }
926 :
927 0 : sal_uInt16 ToolBox::GetItemId( const Point& rPos ) const
928 : {
929 : // find item that was clicked
930 0 : std::vector< ImplToolItem >::const_iterator it = mpData->m_aItems.begin();
931 0 : while( it != mpData->m_aItems.end() )
932 : {
933 : // is it this item?
934 0 : if ( it->maRect.IsInside( rPos ) )
935 : {
936 0 : if ( it->meType == TOOLBOXITEM_BUTTON )
937 0 : return it->mnId;
938 : else
939 0 : return 0;
940 : }
941 :
942 0 : ++it;
943 : }
944 :
945 0 : return 0;
946 : }
947 :
948 69842 : sal_uInt16 ToolBox::GetItemId(const OUString &rCommand) const
949 : {
950 120446 : for (std::vector<ImplToolItem>::const_iterator it = mpData->m_aItems.begin(); it != mpData->m_aItems.end(); ++it)
951 : {
952 120268 : if (it->maCommandStr == rCommand)
953 69664 : return it->mnId;
954 : }
955 :
956 178 : return 0;
957 : }
958 :
959 0 : Point ToolBox::ImplGetPopupPosition( const Rectangle& rRect, const Size& rSize ) const
960 : {
961 0 : Point aPos;
962 0 : if( !rRect.IsEmpty() )
963 : {
964 0 : Rectangle aScreen = GetDesktopRectPixel();
965 :
966 : // the popup should be positioned so that it will not cover
967 : // the item rect and that it fits the desktop
968 : // the preferred direction is always towards the center of
969 : // the application window
970 :
971 0 : Point devPos; // the position in device coordinates for screen comparison
972 0 : switch( meAlign )
973 : {
974 : case WINDOWALIGN_TOP:
975 0 : aPos = rRect.BottomLeft();
976 0 : aPos.Y()++;
977 0 : devPos = OutputToAbsoluteScreenPixel( aPos );
978 0 : if( devPos.Y() + rSize.Height() >= aScreen.Bottom() )
979 0 : aPos.Y() = rRect.Top() - rSize.Height();
980 0 : break;
981 : case WINDOWALIGN_BOTTOM:
982 0 : aPos = rRect.TopLeft();
983 0 : aPos.Y()--;
984 0 : devPos = OutputToAbsoluteScreenPixel( aPos );
985 0 : if( devPos.Y() - rSize.Height() > aScreen.Top() )
986 0 : aPos.Y() -= rSize.Height();
987 : else
988 0 : aPos.Y() = rRect.Bottom();
989 0 : break;
990 : case WINDOWALIGN_LEFT:
991 0 : aPos = rRect.TopRight();
992 0 : aPos.X()++;
993 0 : devPos = OutputToAbsoluteScreenPixel( aPos );
994 0 : if( devPos.X() + rSize.Width() >= aScreen.Right() )
995 0 : aPos.X() = rRect.Left() - rSize.Width();
996 0 : break;
997 : case WINDOWALIGN_RIGHT:
998 0 : aPos = rRect.TopLeft();
999 0 : aPos.X()--;
1000 0 : devPos = OutputToAbsoluteScreenPixel( aPos );
1001 0 : if( devPos.X() - rSize.Width() > aScreen.Left() )
1002 0 : aPos.X() -= rSize.Width();
1003 : else
1004 0 : aPos.X() = rRect.Right();
1005 0 : break;
1006 : default:
1007 0 : break;
1008 : }
1009 : }
1010 0 : return aPos;
1011 : }
1012 :
1013 0 : Point ToolBox::GetItemPopupPosition( sal_uInt16 nItemId, const Size& rSize ) const
1014 : {
1015 0 : return ImplGetPopupPosition( GetItemRect( nItemId ), rSize );
1016 : }
1017 :
1018 1571 : Rectangle ToolBox::GetItemRect( sal_uInt16 nItemId ) const
1019 : {
1020 1571 : if ( mbCalc || mbFormat )
1021 120 : ((ToolBox*)this)->ImplFormat();
1022 :
1023 1571 : sal_uInt16 nPos = GetItemPos( nItemId );
1024 1571 : return GetItemPosRect( nPos );
1025 : }
1026 :
1027 29128 : Rectangle ToolBox::GetItemPosRect( sal_uInt16 nPos ) const
1028 : {
1029 29128 : if ( mbCalc || mbFormat )
1030 6944 : ((ToolBox*)this)->ImplFormat();
1031 :
1032 29128 : if ( nPos < mpData->m_aItems.size() )
1033 29054 : return mpData->m_aItems[nPos].maRect;
1034 : else
1035 74 : return Rectangle();
1036 : }
1037 :
1038 7644 : Size ToolBox::GetItemContentSize( sal_uInt16 nItemId ) const
1039 : {
1040 7644 : if ( mbCalc || mbFormat )
1041 7104 : ((ToolBox*)this)->ImplFormat();
1042 :
1043 7644 : sal_uInt16 nPos = GetItemPos( nItemId );
1044 7644 : if ( nPos < mpData->m_aItems.size() )
1045 7644 : return mpData->m_aItems[nPos].maContentSize;
1046 : else
1047 0 : return Size();
1048 : }
1049 :
1050 4435 : bool ToolBox::ImplHasExternalMenubutton()
1051 : {
1052 : // check if the borderwindow (i.e. the decoration) provides the menu button
1053 4435 : bool bRet = false;
1054 4435 : if( ImplIsFloatingMode() )
1055 : {
1056 : // custom menu is placed in the decoration
1057 0 : ImplBorderWindow *pBorderWin = dynamic_cast<ImplBorderWindow*>( GetWindow( WINDOW_BORDER ) );
1058 0 : if( pBorderWin && !pBorderWin->GetMenuRect().IsEmpty() )
1059 0 : bRet = true;
1060 : }
1061 4435 : return bRet;
1062 : }
1063 :
1064 211679 : void ToolBox::SetItemBits( sal_uInt16 nItemId, ToolBoxItemBits nBits )
1065 : {
1066 211679 : sal_uInt16 nPos = GetItemPos( nItemId );
1067 :
1068 211679 : if ( nPos < mpData->m_aItems.size() )
1069 : {
1070 211679 : ToolBoxItemBits nOldBits = mpData->m_aItems[nPos].mnBits;
1071 211679 : mpData->m_aItems[nPos].mnBits = nBits;
1072 211679 : nBits &= ToolBoxItemBits::LEFT | ToolBoxItemBits::AUTOSIZE | ToolBoxItemBits::DROPDOWN;
1073 211679 : nOldBits &= ToolBoxItemBits::LEFT | ToolBoxItemBits::AUTOSIZE | ToolBoxItemBits::DROPDOWN;
1074 : // trigger reformat when the item width has changed (dropdown arrow)
1075 211679 : bool bFormat = ToolBoxItemBits(nBits & ToolBoxItemBits::DROPDOWN) != ToolBoxItemBits(nOldBits & ToolBoxItemBits::DROPDOWN);
1076 211679 : if ( nBits != nOldBits )
1077 12174 : ImplInvalidate( true, bFormat );
1078 : }
1079 211679 : }
1080 :
1081 202233 : ToolBoxItemBits ToolBox::GetItemBits( sal_uInt16 nItemId ) const
1082 : {
1083 202233 : ImplToolItem* pItem = ImplGetItem( nItemId );
1084 :
1085 202233 : if ( pItem )
1086 202233 : return pItem->mnBits;
1087 : else
1088 0 : return ToolBoxItemBits::NONE;
1089 : }
1090 :
1091 29842 : void ToolBox::SetItemExpand( sal_uInt16 nItemId, bool bExpand )
1092 : {
1093 29842 : ImplToolItem* pItem = ImplGetItem( nItemId );
1094 29842 : if (!pItem)
1095 29842 : return;
1096 :
1097 29842 : if (pItem->mbExpand != bExpand)
1098 : {
1099 1476 : pItem->mbExpand = bExpand;
1100 1476 : ImplInvalidate(true, true);
1101 : }
1102 : }
1103 :
1104 94100 : void ToolBox::SetItemData( sal_uInt16 nItemId, void* pNewData )
1105 : {
1106 94100 : sal_uInt16 nPos = GetItemPos( nItemId );
1107 :
1108 94100 : if ( nPos < mpData->m_aItems.size() )
1109 : {
1110 94100 : mpData->m_aItems[nPos].mpUserData = pNewData;
1111 94100 : ImplUpdateItem( nPos );
1112 : }
1113 94100 : }
1114 :
1115 258618 : void* ToolBox::GetItemData( sal_uInt16 nItemId ) const
1116 : {
1117 258618 : ImplToolItem* pItem = ImplGetItem( nItemId );
1118 :
1119 258618 : if ( pItem )
1120 258618 : return pItem->mpUserData;
1121 : else
1122 0 : return NULL;
1123 : }
1124 :
1125 184389 : void ToolBox::SetItemImage( sal_uInt16 nItemId, const Image& rImage )
1126 : {
1127 184389 : sal_uInt16 nPos = GetItemPos( nItemId );
1128 :
1129 184389 : if ( nPos != TOOLBOX_ITEM_NOTFOUND )
1130 : {
1131 184389 : Image aImage(rImage);
1132 :
1133 184389 : if ( GetDPIScaleFactor() > 1)
1134 : {
1135 0 : BitmapEx aBitmap(aImage.GetBitmapEx());
1136 :
1137 : // Some code calls this twice, so add a sanity check
1138 : // FIXME find out what that code is & fix accordingly
1139 0 : if (aBitmap.GetSizePixel().Width() < 32)
1140 : {
1141 0 : aBitmap.Scale(GetDPIScaleFactor(), GetDPIScaleFactor(), BMP_SCALE_FAST);
1142 0 : aImage = Image(aBitmap);
1143 0 : }
1144 : }
1145 :
1146 184389 : ImplToolItem* pItem = &mpData->m_aItems[nPos];
1147 : // only once all is calculated, do extra work
1148 184389 : if ( !mbCalc )
1149 : {
1150 15829 : Size aOldSize = pItem->maImage.GetSizePixel();
1151 15829 : pItem->maImage = aImage;
1152 15829 : if ( aOldSize != pItem->maImage.GetSizePixel() )
1153 746 : ImplInvalidate( true );
1154 : else
1155 15083 : ImplUpdateItem( nPos );
1156 : }
1157 : else
1158 168560 : pItem->maImage = aImage;
1159 : }
1160 184389 : }
1161 :
1162 36 : void ToolBox::SetImageList( const ImageList& rImageList )
1163 : {
1164 36 : maImageList = rImageList;
1165 :
1166 36 : sal_uInt16 nCount = (sal_uInt16)mpData->m_aItems.size();
1167 700 : for( sal_uInt16 i = 0; i < nCount; i++ )
1168 : {
1169 664 : Image aImage;
1170 664 : if ( mpData->m_aItems[i].mnId )
1171 558 : aImage = maImageList.GetImage( mpData->m_aItems[i].mnId );
1172 664 : if( !!aImage )
1173 558 : SetItemImage( mpData->m_aItems[i].mnId, aImage );
1174 664 : }
1175 36 : }
1176 :
1177 0 : static Image ImplRotImage( const Image& rImage, long nAngle10 )
1178 : {
1179 0 : Image aRet;
1180 0 : BitmapEx aRotBitmapEx( rImage.GetBitmapEx() );
1181 :
1182 0 : aRotBitmapEx.Rotate( nAngle10, Color( COL_WHITE ) );
1183 :
1184 0 : return Image( aRotBitmapEx );
1185 : }
1186 :
1187 25064 : void ToolBox::SetItemImageAngle( sal_uInt16 nItemId, long nAngle10 )
1188 : {
1189 25064 : sal_uInt16 nPos = GetItemPos( nItemId );
1190 :
1191 25064 : if ( nPos != TOOLBOX_ITEM_NOTFOUND )
1192 : {
1193 25064 : ImplToolItem* pItem = &mpData->m_aItems[nPos];
1194 25064 : Size aOldSize = pItem->maImage.GetSizePixel();
1195 :
1196 25064 : long nDeltaAngle = (nAngle10 - pItem->mnImageAngle) % 3600;
1197 50128 : while( nDeltaAngle < 0 )
1198 0 : nDeltaAngle += 3600;
1199 :
1200 25064 : pItem->mnImageAngle = nAngle10;
1201 25064 : if( nDeltaAngle && !!pItem->maImage )
1202 : {
1203 0 : pItem->maImage = ImplRotImage( pItem->maImage, nDeltaAngle );
1204 0 : if( !!pItem->maHighImage )
1205 0 : pItem->maHighImage = ImplRotImage( pItem->maHighImage, nDeltaAngle );
1206 : }
1207 :
1208 25064 : if ( !mbCalc )
1209 : {
1210 25064 : if ( aOldSize != pItem->maImage.GetSizePixel() )
1211 0 : ImplInvalidate( true );
1212 : else
1213 25064 : ImplUpdateItem( nPos );
1214 : }
1215 : }
1216 25064 : }
1217 :
1218 0 : static Image ImplMirrorImage( const Image& rImage )
1219 : {
1220 0 : Image aRet;
1221 0 : BitmapEx aMirrBitmapEx( rImage.GetBitmapEx() );
1222 :
1223 0 : aMirrBitmapEx.Mirror( BMP_MIRROR_HORZ );
1224 :
1225 0 : return Image( aMirrBitmapEx );
1226 : }
1227 :
1228 40488 : void ToolBox::SetItemImageMirrorMode( sal_uInt16 nItemId, bool bMirror )
1229 : {
1230 40488 : sal_uInt16 nPos = GetItemPos( nItemId );
1231 :
1232 40488 : if ( nPos != TOOLBOX_ITEM_NOTFOUND )
1233 : {
1234 40488 : ImplToolItem* pItem = &mpData->m_aItems[nPos];
1235 :
1236 80976 : if( ( pItem->mbMirrorMode && ! bMirror ) ||
1237 80976 : ( ! pItem->mbMirrorMode && bMirror )
1238 : )
1239 : {
1240 0 : pItem->mbMirrorMode = bMirror;
1241 0 : if( !!pItem->maImage )
1242 : {
1243 0 : pItem->maImage = ImplMirrorImage( pItem->maImage );
1244 0 : if( !!pItem->maHighImage )
1245 0 : pItem->maHighImage = ImplMirrorImage( pItem->maHighImage );
1246 : }
1247 :
1248 0 : if ( !mbCalc )
1249 0 : ImplUpdateItem( nPos );
1250 : }
1251 : }
1252 40488 : }
1253 :
1254 7644 : Image ToolBox::GetItemImage( sal_uInt16 nItemId ) const
1255 : {
1256 7644 : ImplToolItem* pItem = ImplGetItem( nItemId );
1257 :
1258 7644 : if ( pItem )
1259 7644 : return pItem->maImage;
1260 : else
1261 0 : return Image();
1262 : }
1263 :
1264 101141 : void ToolBox::SetItemText( sal_uInt16 nItemId, const OUString& rText )
1265 : {
1266 101141 : sal_uInt16 nPos = GetItemPos( nItemId );
1267 :
1268 101141 : if ( nPos != TOOLBOX_ITEM_NOTFOUND )
1269 : {
1270 101141 : ImplToolItem* pItem = &mpData->m_aItems[nPos];
1271 : // only once all is calculated, do extra work
1272 104624 : if ( !mbCalc &&
1273 6954 : ((meButtonType != BUTTON_SYMBOL) || !pItem->maImage) )
1274 : {
1275 6 : long nOldWidth = GetCtrlTextWidth( pItem->maText );
1276 6 : pItem->maText = ImplConvertMenuString( rText );
1277 6 : mpData->ImplClearLayoutData();
1278 6 : if ( nOldWidth != GetCtrlTextWidth( pItem->maText ) )
1279 0 : ImplInvalidate( true );
1280 : else
1281 6 : ImplUpdateItem( nPos );
1282 : }
1283 : else
1284 101135 : pItem->maText = ImplConvertMenuString( rText );
1285 :
1286 : // Notify button changed event to prepare accessibility bridge
1287 101141 : ImplCallEventListeners( VCLEVENT_TOOLBOX_BUTTONSTATECHANGED, reinterpret_cast< void* >( nPos ) );
1288 :
1289 : // Notify
1290 101141 : ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMTEXTCHANGED, reinterpret_cast< void* >( nPos ) );
1291 : }
1292 101141 : }
1293 :
1294 8948 : const OUString& ToolBox::GetItemText( sal_uInt16 nItemId ) const
1295 : {
1296 :
1297 8948 : ImplToolItem* pItem = ImplGetItem( nItemId );
1298 :
1299 : assert( pItem );
1300 :
1301 8948 : return pItem->maText;
1302 : }
1303 :
1304 191404 : void ToolBox::SetItemWindow( sal_uInt16 nItemId, vcl::Window* pNewWindow )
1305 : {
1306 191404 : sal_uInt16 nPos = GetItemPos( nItemId );
1307 :
1308 191404 : if ( nPos != TOOLBOX_ITEM_NOTFOUND )
1309 : {
1310 191404 : ImplToolItem* pItem = &mpData->m_aItems[nPos];
1311 191404 : pItem->mpWindow = pNewWindow;
1312 191404 : if ( pNewWindow )
1313 10948 : pNewWindow->Hide();
1314 191404 : ImplInvalidate( true );
1315 191404 : ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMWINDOWCHANGED, reinterpret_cast< void* >( nPos ) );
1316 : }
1317 191404 : }
1318 :
1319 64633 : vcl::Window* ToolBox::GetItemWindow( sal_uInt16 nItemId ) const
1320 : {
1321 64633 : ImplToolItem* pItem = ImplGetItem( nItemId );
1322 :
1323 64633 : if ( pItem )
1324 64633 : return pItem->mpWindow;
1325 : else
1326 0 : return NULL;
1327 : }
1328 :
1329 0 : void ToolBox::StartSelection()
1330 : {
1331 0 : if ( mbDrag )
1332 0 : EndSelection();
1333 :
1334 0 : if ( !mbSelection )
1335 : {
1336 0 : mbSelection = true;
1337 0 : mnCurPos = TOOLBOX_ITEM_NOTFOUND;
1338 0 : mnCurItemId = 0;
1339 0 : Activate();
1340 : }
1341 0 : }
1342 :
1343 0 : void ToolBox::EndSelection()
1344 : {
1345 0 : mbCommandDrag = false;
1346 :
1347 0 : if ( mbDrag || mbSelection )
1348 : {
1349 : // reset
1350 0 : mbDrag = false;
1351 0 : mbSelection = false;
1352 0 : if ( mnCurPos != TOOLBOX_ITEM_NOTFOUND )
1353 0 : ImplDrawItem( mnCurPos );
1354 0 : EndTracking();
1355 0 : ReleaseMouse();
1356 0 : Deactivate();
1357 : }
1358 :
1359 0 : mnCurPos = TOOLBOX_ITEM_NOTFOUND;
1360 0 : mnCurItemId = 0;
1361 0 : mnDownItemId = 0;
1362 0 : mnMouseClicks = 0;
1363 0 : mnMouseModifier = 0;
1364 0 : }
1365 :
1366 0 : void ToolBox::SetItemDown( sal_uInt16 nItemId, bool bDown, bool bRelease )
1367 : {
1368 0 : sal_uInt16 nPos = GetItemPos( nItemId );
1369 :
1370 0 : if ( nPos != TOOLBOX_ITEM_NOTFOUND )
1371 : {
1372 0 : if ( bDown )
1373 : {
1374 0 : if ( nPos != mnCurPos )
1375 : {
1376 0 : mnCurPos = nPos;
1377 0 : ImplDrawItem( mnCurPos, 1 );
1378 0 : Flush();
1379 : }
1380 : }
1381 : else
1382 : {
1383 0 : if ( nPos == mnCurPos )
1384 : {
1385 0 : ImplDrawItem( mnCurPos, 0 );
1386 0 : Flush();
1387 0 : mnCurPos = TOOLBOX_ITEM_NOTFOUND;
1388 : }
1389 : }
1390 :
1391 0 : if ( bRelease )
1392 : {
1393 0 : if ( mbDrag || mbSelection )
1394 : {
1395 0 : mbDrag = false;
1396 0 : mbSelection = false;
1397 0 : EndTracking();
1398 0 : ReleaseMouse();
1399 0 : Deactivate();
1400 : }
1401 :
1402 0 : mnCurItemId = 0;
1403 0 : mnDownItemId = 0;
1404 0 : mnMouseClicks = 0;
1405 0 : mnMouseModifier = 0;
1406 : }
1407 : }
1408 0 : }
1409 :
1410 307010 : void ToolBox::SetItemState( sal_uInt16 nItemId, TriState eState )
1411 : {
1412 307010 : sal_uInt16 nPos = GetItemPos( nItemId );
1413 :
1414 307010 : if ( nPos != TOOLBOX_ITEM_NOTFOUND )
1415 : {
1416 306874 : ImplToolItem* pItem = &mpData->m_aItems[nPos];
1417 :
1418 : // the state has changed
1419 306874 : if ( pItem->meState != eState )
1420 : {
1421 : // if RadioCheck, un-check the previous
1422 13940 : if ( (eState == TRISTATE_TRUE) && (pItem->mnBits & ToolBoxItemBits::AUTOCHECK) &&
1423 6970 : (pItem->mnBits & ToolBoxItemBits::RADIOCHECK) )
1424 : {
1425 : ImplToolItem* pGroupItem;
1426 : sal_uInt16 nGroupPos;
1427 0 : sal_uInt16 nItemCount = GetItemCount();
1428 :
1429 0 : nGroupPos = nPos;
1430 0 : while ( nGroupPos )
1431 : {
1432 0 : pGroupItem = &mpData->m_aItems[nGroupPos-1];
1433 0 : if ( pGroupItem->mnBits & ToolBoxItemBits::RADIOCHECK )
1434 : {
1435 0 : if ( pGroupItem->meState != TRISTATE_FALSE )
1436 0 : SetItemState( pGroupItem->mnId, TRISTATE_FALSE );
1437 : }
1438 : else
1439 0 : break;
1440 0 : nGroupPos--;
1441 : }
1442 :
1443 0 : nGroupPos = nPos+1;
1444 0 : while ( nGroupPos < nItemCount )
1445 : {
1446 0 : pGroupItem = &mpData->m_aItems[nGroupPos];
1447 0 : if ( pGroupItem->mnBits & ToolBoxItemBits::RADIOCHECK )
1448 : {
1449 0 : if ( pGroupItem->meState != TRISTATE_FALSE )
1450 0 : SetItemState( pGroupItem->mnId, TRISTATE_FALSE );
1451 : }
1452 : else
1453 0 : break;
1454 0 : nGroupPos++;
1455 : }
1456 : }
1457 :
1458 6970 : pItem->meState = eState;
1459 6970 : ImplUpdateItem( nPos );
1460 :
1461 : // Notify button changed event to prepare accessibility bridge
1462 6970 : ImplCallEventListeners( VCLEVENT_TOOLBOX_BUTTONSTATECHANGED, reinterpret_cast< void* >( nPos ) );
1463 :
1464 : // Notify
1465 : //Solution:Call accessible listener to notify state_changed event
1466 6970 : ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMUPDATED, reinterpret_cast< void* >(nPos) );
1467 : }
1468 : }
1469 307010 : }
1470 :
1471 3469 : TriState ToolBox::GetItemState( sal_uInt16 nItemId ) const
1472 : {
1473 3469 : ImplToolItem* pItem = ImplGetItem( nItemId );
1474 :
1475 3469 : if ( pItem )
1476 3152 : return pItem->meState;
1477 : else
1478 317 : return TRISTATE_FALSE;
1479 : }
1480 :
1481 304096 : void ToolBox::EnableItem( sal_uInt16 nItemId, bool bEnable )
1482 : {
1483 304096 : sal_uInt16 nPos = GetItemPos( nItemId );
1484 :
1485 304096 : if ( nPos != TOOLBOX_ITEM_NOTFOUND )
1486 : {
1487 303918 : ImplToolItem* pItem = &mpData->m_aItems[nPos];
1488 303918 : if ( bEnable )
1489 238253 : bEnable = true;
1490 303918 : if ( pItem->mbEnabled != bEnable )
1491 : {
1492 58010 : pItem->mbEnabled = bEnable;
1493 :
1494 : // if existing, also redraw the window
1495 58010 : if ( pItem->mpWindow )
1496 3966 : pItem->mpWindow->Enable( pItem->mbEnabled );
1497 :
1498 : // update item
1499 58010 : ImplUpdateItem( nPos );
1500 :
1501 58010 : ImplUpdateInputEnable();
1502 :
1503 : // Notify button changed event to prepare accessibility bridge
1504 58010 : ImplCallEventListeners( VCLEVENT_TOOLBOX_BUTTONSTATECHANGED, reinterpret_cast< void* >( nPos ) );
1505 :
1506 58010 : ImplCallEventListeners( bEnable ? VCLEVENT_TOOLBOX_ITEMENABLED : VCLEVENT_TOOLBOX_ITEMDISABLED, reinterpret_cast< void* >( nPos ) );
1507 : }
1508 : }
1509 304096 : }
1510 :
1511 500 : bool ToolBox::IsItemEnabled( sal_uInt16 nItemId ) const
1512 : {
1513 500 : ImplToolItem* pItem = ImplGetItem( nItemId );
1514 :
1515 500 : if ( pItem )
1516 500 : return pItem->mbEnabled;
1517 : else
1518 0 : return false;
1519 : }
1520 :
1521 40934 : void ToolBox::ShowItem( sal_uInt16 nItemId, bool bVisible )
1522 : {
1523 40934 : sal_uInt16 nPos = GetItemPos( nItemId );
1524 40934 : mpData->ImplClearLayoutData();
1525 :
1526 40934 : if ( nPos != TOOLBOX_ITEM_NOTFOUND )
1527 : {
1528 40918 : ImplToolItem* pItem = &mpData->m_aItems[nPos];
1529 40918 : if ( pItem->mbVisible != bVisible )
1530 : {
1531 39992 : pItem->mbVisible = bVisible;
1532 39992 : ImplInvalidate( false );
1533 : }
1534 : }
1535 40934 : }
1536 :
1537 1970 : bool ToolBox::IsItemVisible( sal_uInt16 nItemId ) const
1538 : {
1539 1970 : ImplToolItem* pItem = ImplGetItem( nItemId );
1540 :
1541 1970 : if ( pItem )
1542 1954 : return pItem->mbVisible;
1543 : else
1544 16 : return false;
1545 : }
1546 :
1547 488 : bool ToolBox::IsItemReallyVisible( sal_uInt16 nItemId ) const
1548 : {
1549 : // is the item on the visible area of the toolbox?
1550 488 : bool bRet = false;
1551 488 : Rectangle aRect( mnLeftBorder, mnTopBorder, mnDX-mnRightBorder, mnDY-mnBottomBorder );
1552 488 : ImplToolItem* pItem = ImplGetItem( nItemId );
1553 :
1554 1388 : if ( pItem && pItem->mbVisible &&
1555 1306 : !pItem->maRect.IsEmpty() && aRect.IsOver( pItem->maRect ) )
1556 : {
1557 406 : bRet = true;
1558 : }
1559 :
1560 488 : return bRet;
1561 : }
1562 :
1563 173624 : void ToolBox::SetItemCommand(sal_uInt16 nItemId, const OUString& rCommand)
1564 : {
1565 173624 : ImplToolItem* pItem = ImplGetItem( nItemId );
1566 :
1567 173624 : if (pItem)
1568 173624 : pItem->maCommandStr = rCommand;
1569 173624 : }
1570 :
1571 247258 : const OUString ToolBox::GetItemCommand( sal_uInt16 nItemId ) const
1572 : {
1573 247258 : ImplToolItem* pItem = ImplGetItem( nItemId );
1574 :
1575 247258 : if (pItem)
1576 247258 : return pItem->maCommandStr;
1577 :
1578 0 : return OUString();
1579 : }
1580 :
1581 145713 : void ToolBox::SetQuickHelpText( sal_uInt16 nItemId, const OUString& rText )
1582 : {
1583 145713 : ImplToolItem* pItem = ImplGetItem( nItemId );
1584 :
1585 145713 : if ( pItem )
1586 145713 : pItem->maQuickHelpText = rText;
1587 145713 : }
1588 :
1589 30 : const OUString& ToolBox::GetQuickHelpText( sal_uInt16 nItemId ) const
1590 : {
1591 30 : static const OUString sEmpty;
1592 :
1593 30 : ImplToolItem* pItem = ImplGetItem( nItemId );
1594 :
1595 30 : if ( pItem )
1596 30 : return pItem->maQuickHelpText;
1597 : else
1598 0 : return sEmpty;
1599 : }
1600 :
1601 1476 : void ToolBox::SetHelpText( sal_uInt16 nItemId, const OUString& rText )
1602 : {
1603 1476 : ImplToolItem* pItem = ImplGetItem( nItemId );
1604 :
1605 1476 : if ( pItem )
1606 1476 : pItem->maHelpText = rText;
1607 1476 : }
1608 :
1609 0 : const OUString& ToolBox::GetHelpText( sal_uInt16 nItemId ) const
1610 : {
1611 0 : return ImplGetHelpText( nItemId );
1612 : }
1613 :
1614 2052 : void ToolBox::SetHelpId( sal_uInt16 nItemId, const OString& rHelpId )
1615 : {
1616 2052 : ImplToolItem* pItem = ImplGetItem( nItemId );
1617 :
1618 2052 : if ( pItem )
1619 2052 : pItem->maHelpId = rHelpId;
1620 2052 : }
1621 :
1622 0 : OString ToolBox::GetHelpId( sal_uInt16 nItemId ) const
1623 : {
1624 0 : OString aRet;
1625 :
1626 0 : ImplToolItem* pItem = ImplGetItem( nItemId );
1627 :
1628 0 : if ( pItem )
1629 : {
1630 0 : if ( !pItem->maHelpId.isEmpty() )
1631 0 : aRet = pItem->maHelpId;
1632 : else
1633 0 : aRet = OUStringToOString( pItem->maCommandStr, RTL_TEXTENCODING_UTF8 );
1634 : }
1635 :
1636 0 : return aRet;
1637 : }
1638 :
1639 29620 : void ToolBox::SetOutStyle( sal_uInt16 nNewStyle )
1640 : {
1641 : // always force flat looking toolbars since NWF
1642 29620 : nNewStyle |= TOOLBOX_STYLE_FLAT;
1643 :
1644 29620 : if ( mnOutStyle != nNewStyle )
1645 : {
1646 0 : mnOutStyle = nNewStyle;
1647 0 : ImplDisableFlatButtons();
1648 :
1649 : // so as to redo the ButtonDevice
1650 0 : if ( !(mnOutStyle & TOOLBOX_STYLE_FLAT) )
1651 : {
1652 0 : mnMaxItemWidth = 1;
1653 0 : mnMaxItemHeight = 1;
1654 : }
1655 :
1656 0 : ImplInvalidate( true, true );
1657 : }
1658 29620 : }
1659 :
1660 : // disable key input if all items are disabled
1661 556690 : void ToolBox::ImplUpdateInputEnable()
1662 : {
1663 4388691 : for( std::vector< ImplToolItem >::const_iterator it = mpData->m_aItems.begin();
1664 2925794 : it != mpData->m_aItems.end(); ++it )
1665 : {
1666 1365743 : if( it->mbEnabled )
1667 : {
1668 : // at least one useful entry
1669 459536 : mpData->mbKeyInputDisabled = false;
1670 1016226 : return;
1671 : }
1672 : }
1673 97154 : mpData->mbKeyInputDisabled = true;
1674 : }
1675 :
1676 0 : void ToolBox::ImplFillLayoutData() const
1677 : {
1678 0 : mpData->m_pLayoutData = new ToolBoxLayoutData();
1679 :
1680 0 : sal_uInt16 nCount = (sal_uInt16)mpData->m_aItems.size();
1681 0 : for( sal_uInt16 i = 0; i < nCount; i++ )
1682 : {
1683 0 : ImplToolItem* pItem = &mpData->m_aItems[i];
1684 :
1685 : // only draw, if the rectangle is within PaintRectangle
1686 0 : if ( !pItem->maRect.IsEmpty() )
1687 0 : const_cast<ToolBox*>(this)->ImplDrawItem( i, 0, false, true );
1688 : }
1689 0 : }
1690 :
1691 0 : OUString ToolBox::GetDisplayText() const
1692 : {
1693 0 : if( ! mpData->m_pLayoutData )
1694 0 : ImplFillLayoutData();
1695 0 : return mpData->m_pLayoutData ? OUString(mpData->m_pLayoutData->m_aDisplayText) : OUString();
1696 : }
1697 :
1698 0 : Rectangle ToolBox::GetCharacterBounds( sal_uInt16 nItemID, long nIndex ) const
1699 : {
1700 0 : long nItemIndex = -1;
1701 0 : if( ! mpData->m_pLayoutData )
1702 0 : ImplFillLayoutData();
1703 0 : if( mpData->m_pLayoutData )
1704 : {
1705 0 : for( sal_uLong i = 0; i < mpData->m_pLayoutData->m_aLineItemIds.size(); i++ )
1706 : {
1707 0 : if( mpData->m_pLayoutData->m_aLineItemIds[i] == nItemID )
1708 : {
1709 0 : nItemIndex = mpData->m_pLayoutData->m_aLineIndices[i];
1710 0 : break;
1711 : }
1712 : }
1713 : }
1714 0 : return (mpData->m_pLayoutData && nItemIndex != -1) ? mpData->m_pLayoutData->GetCharacterBounds( nItemIndex+nIndex ) : Rectangle();
1715 : }
1716 :
1717 0 : long ToolBox::GetIndexForPoint( const Point& rPoint, sal_uInt16& rItemID ) const
1718 : {
1719 0 : long nIndex = -1;
1720 0 : rItemID = 0;
1721 0 : if( ! mpData->m_pLayoutData )
1722 0 : ImplFillLayoutData();
1723 0 : if( mpData->m_pLayoutData )
1724 : {
1725 0 : nIndex = mpData->m_pLayoutData->GetIndexForPoint( rPoint );
1726 0 : for( sal_uLong i = 0; i < mpData->m_pLayoutData->m_aLineIndices.size(); i++ )
1727 : {
1728 0 : if( mpData->m_pLayoutData->m_aLineIndices[i] <= nIndex &&
1729 0 : (i == mpData->m_pLayoutData->m_aLineIndices.size()-1 || mpData->m_pLayoutData->m_aLineIndices[i+1] > nIndex) )
1730 : {
1731 0 : rItemID = mpData->m_pLayoutData->m_aLineItemIds[i];
1732 0 : break;
1733 : }
1734 : }
1735 : }
1736 0 : return nIndex;
1737 : }
1738 :
1739 60856 : void ToolBox::SetDropdownClickHdl( const Link& rLink )
1740 : {
1741 60856 : mpData->maDropdownClickHdl = rLink;
1742 60856 : }
1743 :
1744 0 : const Link& ToolBox::GetDropdownClickHdl() const
1745 : {
1746 0 : return mpData->maDropdownClickHdl;
1747 : }
1748 :
1749 39881 : void ToolBox::SetMenuType( sal_uInt16 aType )
1750 : {
1751 39881 : if( aType != mpData->maMenuType )
1752 : {
1753 28319 : mpData->maMenuType = aType;
1754 28319 : if( IsFloatingMode() )
1755 : {
1756 : // the menu button may have to be moved into the decoration which changes the layout
1757 0 : ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
1758 0 : if( pWrapper )
1759 0 : pWrapper->ShowTitleButton( TITLE_BUTTON_MENU, ( aType & TOOLBOX_MENUTYPE_CUSTOMIZE) ? true : false );
1760 :
1761 0 : mbFormat = true;
1762 0 : ImplFormat();
1763 0 : ImplSetMinMaxFloatSize( this );
1764 : }
1765 : else
1766 : {
1767 : // trigger redraw of menu button
1768 28319 : if( !mpData->maMenubuttonItem.maRect.IsEmpty() )
1769 0 : Invalidate(mpData->maMenubuttonItem.maRect);
1770 : }
1771 : }
1772 39881 : }
1773 :
1774 14201 : sal_uInt16 ToolBox::GetMenuType() const
1775 : {
1776 14201 : return mpData->maMenuType;
1777 : }
1778 :
1779 1013919 : bool ToolBox::IsMenuEnabled() const
1780 : {
1781 1013919 : return mpData->maMenuType != TOOLBOX_MENUTYPE_NONE;
1782 : }
1783 :
1784 16262 : PopupMenu* ToolBox::GetMenu() const
1785 : {
1786 16262 : return mpData->mpMenu;
1787 : }
1788 :
1789 16268 : void ToolBox::SetMenuButtonHdl( const Link& rLink )
1790 : {
1791 16268 : mpData->maMenuButtonHdl = rLink;
1792 16268 : }
1793 :
1794 7435 : bool ToolBox::ImplHasClippedItems()
1795 : {
1796 : // are any items currently clipped ?
1797 7435 : ImplFormat();
1798 7435 : std::vector< ImplToolItem >::const_iterator it = mpData->m_aItems.begin();
1799 289051 : while ( it != mpData->m_aItems.end() )
1800 : {
1801 278297 : if( it->IsClipped() )
1802 4116 : return true;
1803 274181 : ++it;
1804 : }
1805 3319 : return false;
1806 : }
1807 :
1808 0 : void ToolBox::UpdateCustomMenu()
1809 : {
1810 : // fill clipped items into menu
1811 0 : if( !IsMenuEnabled() )
1812 0 : return;
1813 :
1814 0 : PopupMenu *pMenu = GetMenu();
1815 :
1816 0 : sal_uInt16 i = 0;
1817 : // remove old entries
1818 0 : while( i < pMenu->GetItemCount() )
1819 : {
1820 0 : if( pMenu->GetItemId( i ) >= TOOLBOX_MENUITEM_START )
1821 : {
1822 0 : pMenu->RemoveItem( i );
1823 0 : i = 0;
1824 : }
1825 : else
1826 0 : i++;
1827 : }
1828 :
1829 : // add menu items: first the overflow items, then hidden items, both in the
1830 : // order they would usually appear in the toolbar. Separators that would be
1831 : // in the toolbar are ignored as they would introduce too much clutter,
1832 : // instead we have a single separator to help distinguish between overflow
1833 : // and hidden items.
1834 0 : if ( !mpData->m_aItems.empty() )
1835 : {
1836 : // nStartPos will hold the number of clipped items appended from first loop
1837 0 : for ( std::vector< ImplToolItem >::iterator it(mpData->m_aItems.begin());
1838 0 : it != mpData->m_aItems.end(); ++it)
1839 : {
1840 0 : if( it->IsClipped() )
1841 : {
1842 0 : sal_uInt16 id = it->mnId + TOOLBOX_MENUITEM_START;
1843 0 : pMenu->InsertItem( id, it->maText, it->maImage, MenuItemBits::NONE, OString());
1844 0 : pMenu->EnableItem( id, it->mbEnabled );
1845 0 : pMenu->CheckItem ( id, it->meState == TRISTATE_TRUE );
1846 : }
1847 : }
1848 :
1849 : // add a separator below the inserted clipped-items
1850 0 : pMenu->InsertSeparator();
1851 :
1852 : // now append the items that are explicitly disabled
1853 0 : for ( std::vector< ImplToolItem >::iterator it(mpData->m_aItems.begin());
1854 0 : it != mpData->m_aItems.end(); ++it)
1855 : {
1856 0 : if( it->IsItemHidden() )
1857 : {
1858 0 : sal_uInt16 id = it->mnId + TOOLBOX_MENUITEM_START;
1859 0 : pMenu->InsertItem( id, it->maText, it->maImage, MenuItemBits::NONE, OString() );
1860 0 : pMenu->EnableItem( id, it->mbEnabled );
1861 0 : pMenu->CheckItem( id, it->meState == TRISTATE_TRUE );
1862 : }
1863 : }
1864 :
1865 : }
1866 : }
1867 :
1868 0 : IMPL_LINK( ToolBox, ImplCustomMenuListener, VclMenuEvent*, pEvent )
1869 : {
1870 0 : if( pEvent->GetMenu() == GetMenu() && pEvent->GetId() == VCLEVENT_MENU_SELECT )
1871 : {
1872 0 : sal_uInt16 id = GetMenu()->GetItemId( pEvent->GetItemPos() );
1873 0 : if( id >= TOOLBOX_MENUITEM_START )
1874 0 : TriggerItem( id - TOOLBOX_MENUITEM_START, false, false );
1875 : }
1876 0 : return 0;
1877 : }
1878 :
1879 0 : IMPL_LINK_NOARG(ToolBox, ImplCallExecuteCustomMenu)
1880 : {
1881 0 : mpData->mnEventId = 0;
1882 0 : ImplExecuteCustomMenu();
1883 0 : return 0;
1884 : }
1885 :
1886 0 : void ToolBox::ImplExecuteCustomMenu()
1887 : {
1888 0 : if( IsMenuEnabled() )
1889 : {
1890 0 : if( GetMenuType() & TOOLBOX_MENUTYPE_CUSTOMIZE )
1891 : // call button handler to allow for menu customization
1892 0 : mpData->maMenuButtonHdl.Call( this );
1893 :
1894 : // We specifically only register this event listener when executing our
1895 : // overflow menu (and remove it directly afterwards), as the same menu
1896 : // is reused for both the overflow menu (as managed here in ToolBox),
1897 : // but also by ToolBarManager for its context menu. If we leave event
1898 : // listeners alive beyond when the menu is showing in the desired mode
1899 : // then duplicate events can happen as the context menu "duplicates"
1900 : // items from the overflow menu, which both listeners would then act on.
1901 0 : GetMenu()->AddEventListener( LINK( this, ToolBox, ImplCustomMenuListener ) );
1902 :
1903 : // make sure all disabled entries will be shown
1904 0 : GetMenu()->SetMenuFlags(
1905 0 : GetMenu()->GetMenuFlags() | MENU_FLAG_ALWAYSSHOWDISABLEDENTRIES );
1906 :
1907 : // toolbox might be destroyed during execute
1908 0 : ImplDelData aDelData;
1909 0 : ImplAddDel( &aDelData );
1910 0 : ImplDelData aBorderDel;
1911 0 : bool bBorderDel = false;
1912 :
1913 0 : vcl::Window *pWin = this;
1914 0 : Rectangle aMenuRect = mpData->maMenubuttonItem.maRect;
1915 0 : if( IsFloatingMode() )
1916 : {
1917 : // custom menu is placed in the decoration
1918 0 : ImplBorderWindow *pBorderWin = dynamic_cast<ImplBorderWindow*>( GetWindow( WINDOW_BORDER ) );
1919 0 : if( pBorderWin && !pBorderWin->GetMenuRect().IsEmpty() )
1920 : {
1921 0 : pWin = pBorderWin;
1922 0 : aMenuRect = pBorderWin->GetMenuRect();
1923 0 : pWin->ImplAddDel( &aBorderDel );
1924 0 : bBorderDel = true;
1925 : }
1926 : }
1927 :
1928 0 : sal_uInt16 uId = GetMenu()->Execute( pWin, Rectangle( ImplGetPopupPosition( aMenuRect, Size() ), Size() ),
1929 0 : POPUPMENU_EXECUTE_DOWN | POPUPMENU_NOMOUSEUPCLOSE );
1930 :
1931 0 : if ( aDelData.IsDead() )
1932 0 : return;
1933 0 : ImplRemoveDel( &aDelData );
1934 :
1935 0 : if( GetMenu() )
1936 0 : GetMenu()->RemoveEventListener( LINK( this, ToolBox, ImplCustomMenuListener ) );
1937 0 : if( bBorderDel )
1938 : {
1939 0 : if( aBorderDel.IsDead() )
1940 0 : return;
1941 0 : pWin->ImplRemoveDel( &aBorderDel );
1942 : }
1943 :
1944 0 : pWin->Invalidate( aMenuRect );
1945 :
1946 0 : if( uId )
1947 0 : GrabFocusToDocument();
1948 : }
1949 : }
1950 :
1951 0 : void ToolBox::ExecuteCustomMenu()
1952 : {
1953 0 : if( IsMenuEnabled() )
1954 : {
1955 : // handle custom menu asynchronously
1956 : // to avoid problems if the toolbox is closed during menu execute
1957 0 : UpdateCustomMenu();
1958 0 : mpData->mnEventId = Application::PostUserEvent( LINK( this, ToolBox, ImplCallExecuteCustomMenu ) );
1959 : }
1960 0 : }
1961 :
1962 : // checks override first, useful during calculation of sizes
1963 1894291 : bool ToolBox::ImplIsFloatingMode() const
1964 : {
1965 : DBG_ASSERT( !(mpData->mbAssumeDocked && mpData->mbAssumeFloating),
1966 : "ToolBox::ImplIsFloatingMode(): cannot assume docked and floating" );
1967 :
1968 1894291 : if( mpData->mbAssumeDocked )
1969 0 : return false;
1970 1894291 : else if( mpData->mbAssumeFloating )
1971 0 : return true;
1972 : else
1973 1894291 : return IsFloatingMode();
1974 : }
1975 :
1976 : // checks override first, useful during calculation of sizes
1977 273543 : bool ToolBox::ImplIsInPopupMode() const
1978 : {
1979 273543 : if( mpData->mbAssumePopupMode )
1980 0 : return true;
1981 : else
1982 : {
1983 273543 : ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
1984 273543 : return ( pWrapper && pWrapper->GetFloatingWindow() && pWrapper->GetFloatingWindow()->IsInPopupMode() );
1985 : }
1986 : }
1987 :
1988 0 : void ToolBox::Lock( bool bLock )
1989 : {
1990 0 : ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
1991 0 : if( !pWrapper )
1992 0 : return;
1993 0 : if( mpData->mbIsLocked != bLock )
1994 : {
1995 0 : mpData->mbIsLocked = bLock;
1996 0 : if( !ImplIsFloatingMode() )
1997 : {
1998 0 : mbCalc = true;
1999 0 : mbFormat = true;
2000 0 : SetSizePixel( CalcWindowSizePixel(1) );
2001 0 : Invalidate();
2002 : }
2003 : }
2004 : }
2005 :
2006 0 : bool ToolBox::AlwaysLocked()
2007 : {
2008 : // read config item to determine toolbox behaviour, used for subtoolbars
2009 :
2010 : static int nAlwaysLocked = -1;
2011 :
2012 0 : if( nAlwaysLocked == -1 )
2013 : {
2014 0 : nAlwaysLocked = 0; // ask configuration only once
2015 :
2016 : utl::OConfigurationNode aNode = utl::OConfigurationTreeRoot::tryCreateWithComponentContext(
2017 : comphelper::getProcessComponentContext(),
2018 0 : OUString("/org.openoffice.Office.UI.GlobalSettings/Toolbars") ); // note: case sensitive !
2019 0 : if ( aNode.isValid() )
2020 : {
2021 : // feature enabled ?
2022 0 : bool bStatesEnabled = bool();
2023 0 : ::com::sun::star::uno::Any aValue = aNode.getNodeValue( OUString("StatesEnabled") );
2024 0 : if( aValue >>= bStatesEnabled )
2025 : {
2026 0 : if( bStatesEnabled )
2027 : {
2028 : // now read the locking state
2029 : utl::OConfigurationNode aNode2 = utl::OConfigurationTreeRoot::tryCreateWithComponentContext(
2030 : comphelper::getProcessComponentContext(),
2031 0 : OUString("/org.openoffice.Office.UI.GlobalSettings/Toolbars/States") ); // note: case sensitive !
2032 :
2033 0 : bool bLocked = bool();
2034 0 : ::com::sun::star::uno::Any aValue2 = aNode2.getNodeValue( OUString("Locked") );
2035 0 : if( aValue2 >>= bLocked )
2036 0 : nAlwaysLocked = bLocked ? 1 : 0;
2037 : }
2038 0 : }
2039 0 : }
2040 : }
2041 :
2042 0 : return nAlwaysLocked == 1;
2043 : }
2044 :
2045 3116 : bool ToolBox::WillUsePopupMode() const
2046 : {
2047 3116 : return mpData->mbWillUsePopupMode;
2048 : }
2049 :
2050 11562 : void ToolBox::WillUsePopupMode( bool b )
2051 : {
2052 11562 : mpData->mbWillUsePopupMode = b;
2053 11562 : }
2054 :
2055 59119 : void ToolBox::ImplUpdateImageList()
2056 : {
2057 59119 : if (mpData->mpImageListProvider != NULL)
2058 : {
2059 : try
2060 : {
2061 0 : ImageListType eType = vcl::HIGHCONTRAST_NO;
2062 0 : if (eType != mpData->meImageListType)
2063 : {
2064 0 : vcl::IImageListProvider* pImageListProvider = mpData->mpImageListProvider;
2065 0 : SetImageList( pImageListProvider->getImageList(eType) );
2066 0 : mpData->meImageListType = eType;
2067 : }
2068 : }
2069 0 : catch (com::sun::star::lang::IllegalArgumentException &) {}
2070 : }
2071 60352 : }
2072 :
2073 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|