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