Coverage Report

Created: 2026-11-06 11:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/framework/source/uielement/toolbarmanager.cxx
Line
Count
Source
1
/*
2
 * This file is part of the LibreOffice project.
3
 *
4
 * This Source Code Form is subject to the terms of the Mozilla Public
5
 * License, v. 2.0. If a copy of the MPL was not distributed with this
6
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7
 *
8
 * This file incorporates work covered by the following license notice:
9
 *
10
 *   Licensed to the Apache Software Foundation (ASF) under one or more
11
 *   contributor license agreements. See the NOTICE file distributed
12
 *   with this work for additional information regarding copyright
13
 *   ownership. The ASF licenses this file to you under the Apache
14
 *   License, Version 2.0 (the "License"); you may not use this file
15
 *   except in compliance with the License. You may obtain a copy of
16
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
17
 */
18
19
#include <sal/config.h>
20
#include <sal/log.hxx>
21
22
#include <cassert>
23
24
#include <uielement/toolbarmanager.hxx>
25
#include <uielement/popuptoolbarcontroller.hxx>
26
27
#include <framework/generictoolbarcontroller.hxx>
28
#include <officecfg/Office/Common.hxx>
29
#include <uielement/styletoolbarcontroller.hxx>
30
#include <properties.h>
31
#include <framework/sfxhelperfunctions.hxx>
32
#include <classes/fwkresid.hxx>
33
#include <classes/resource.hxx>
34
#include <strings.hrc>
35
#include <uielement/toolbarmerger.hxx>
36
37
#include <com/sun/star/ui/ItemType.hpp>
38
#include <com/sun/star/frame/XDispatchProvider.hpp>
39
#include <com/sun/star/beans/XPropertySet.hpp>
40
#include <com/sun/star/awt/XDockableWindow.hpp>
41
#include <com/sun/star/frame/XLayoutManager.hpp>
42
#include <com/sun/star/ui/DockingArea.hpp>
43
#include <com/sun/star/graphic/XGraphic.hpp>
44
#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
45
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
46
#include <com/sun/star/frame/ModuleManager.hpp>
47
#include <com/sun/star/frame/theToolbarControllerFactory.hpp>
48
#include <com/sun/star/ui/ItemStyle.hpp>
49
#include <com/sun/star/ui/XUIElementSettings.hpp>
50
#include <com/sun/star/ui/XUIConfigurationPersistence.hpp>
51
#include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
52
#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
53
#include <com/sun/star/ui/ImageType.hpp>
54
#include <com/sun/star/ui/UIElementType.hpp>
55
#include <com/sun/star/lang/DisposedException.hpp>
56
#include <com/sun/star/util/URLTransformer.hpp>
57
58
#include <svtools/toolboxcontroller.hxx>
59
#include <unotools/cmdoptions.hxx>
60
#include <toolkit/helper/vclunohelper.hxx>
61
#include <unotools/mediadescriptor.hxx>
62
#include <comphelper/propertyvalue.hxx>
63
#include <comphelper/propertysequence.hxx>
64
#include <comphelper/sequenceashashmap.hxx>
65
#include <svtools/miscopt.hxx>
66
#include <svtools/imgdef.hxx>
67
#include <utility>
68
#include <vcl/event.hxx>
69
#include <vcl/graph.hxx>
70
#include <vcl/image.hxx>
71
#include <vcl/svapp.hxx>
72
#include <vcl/menu.hxx>
73
#include <vcl/syswin.hxx>
74
#include <vcl/taskpanelist.hxx>
75
#include <vcl/toolbox.hxx>
76
#include <vcl/settings.hxx>
77
#include <vcl/commandinfoprovider.hxx>
78
#include <vcl/vclevent.hxx>
79
#include <vcl/weld/TransportAsXWindow.hxx>
80
#include <tools/debug.hxx>
81
82
//  namespaces
83
84
using namespace ::com::sun::star::awt;
85
using namespace ::com::sun::star::beans;
86
using namespace ::com::sun::star::uno;
87
using namespace ::com::sun::star::lang;
88
using namespace ::com::sun::star::frame;
89
using namespace ::com::sun::star::graphic;
90
using namespace ::com::sun::star::util;
91
using namespace ::com::sun::star::container;
92
using namespace ::com::sun::star::ui;
93
using namespace ::com::sun::star;
94
95
namespace framework
96
{
97
98
const char ITEM_DESCRIPTOR_COMMANDURL[] = "CommandURL";
99
const char ITEM_DESCRIPTOR_VISIBLE[]    = "IsVisible";
100
101
const sal_uInt16 STARTID_CUSTOMIZE_POPUPMENU = 1000;
102
103
static css::uno::Reference< css::frame::XLayoutManager > getLayoutManagerFromFrame(
104
    css::uno::Reference< css::frame::XFrame > const & rFrame )
105
0
{
106
0
    css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
107
108
0
    Reference< XPropertySet > xPropSet( rFrame, UNO_QUERY );
109
0
    if ( xPropSet.is() )
110
0
    {
111
0
        try
112
0
        {
113
0
            xPropSet->getPropertyValue(u"LayoutManager"_ustr) >>= xLayoutManager;
114
0
        }
115
0
        catch (const RuntimeException&)
116
0
        {
117
0
            throw;
118
0
        }
119
0
        catch (const Exception&)
120
0
        {
121
0
        }
122
0
    }
123
124
0
    return xLayoutManager;
125
0
}
126
namespace
127
{
128
129
sal_Int16 getCurrentImageType()
130
0
{
131
0
    sal_Int16 nImageType = css::ui::ImageType::SIZE_DEFAULT;
132
0
    sal_Int16 nCurrentSymbolSize = SvtMiscOptions::GetCurrentSymbolsSize();
133
0
    if (nCurrentSymbolSize == SFX_SYMBOLS_SIZE_LARGE)
134
0
        nImageType |= css::ui::ImageType::SIZE_LARGE;
135
0
    else if (nCurrentSymbolSize == SFX_SYMBOLS_SIZE_32)
136
0
        nImageType |= css::ui::ImageType::SIZE_32;
137
0
    return nImageType;
138
0
}
139
140
class VclToolBarManager : public ToolBarManagerImpl
141
{
142
    DECL_LINK(Click, ToolBox*, void);
143
144
public:
145
    VclToolBarManager(VclPtr<ToolBox> pToolbar)
146
0
    : m_pToolBar(std::move(pToolbar))
147
0
    , m_bAddedToTaskPaneList(true)
148
0
    , m_pManager(nullptr)
149
0
    {}
150
151
    ~VclToolBarManager()
152
0
    {
153
0
        OSL_ASSERT( !m_bAddedToTaskPaneList );
154
0
    }
155
156
    virtual void Init() override
157
0
    {
158
0
        vcl::Window* pWindow = m_pToolBar;
159
0
        while ( pWindow && !pWindow->IsSystemWindow() )
160
0
            pWindow = pWindow->GetParent();
161
162
0
        if ( pWindow )
163
0
            static_cast<SystemWindow *>(pWindow)->GetTaskPaneList()->AddWindow( m_pToolBar );
164
0
    }
165
166
    virtual void Destroy() override
167
0
    {
168
0
        OSL_ASSERT( m_pToolBar != nullptr );
169
0
        SolarMutexGuard g;
170
0
        if ( m_bAddedToTaskPaneList )
171
0
        {
172
0
            vcl::Window* pWindow = m_pToolBar;
173
0
            while ( pWindow && !pWindow->IsSystemWindow() )
174
0
                pWindow = pWindow->GetParent();
175
176
0
            if ( pWindow )
177
0
                static_cast<SystemWindow *>(pWindow)->GetTaskPaneList()->RemoveWindow( m_pToolBar );
178
0
            m_bAddedToTaskPaneList = false;
179
0
        }
180
181
        // Delete the additional add-ons data
182
0
        for ( ToolBox::ImplToolItems::size_type i = 0; i < m_pToolBar->GetItemCount(); i++ )
183
0
        {
184
0
            ToolBoxItemId nItemId = m_pToolBar->GetItemId( i );
185
0
            if ( nItemId > ToolBoxItemId(0) )
186
0
                delete static_cast< AddonsParams* >( m_pToolBar->GetItemData( nItemId ));
187
0
        }
188
189
        // #i93173# note we can still be in one of the toolbar's handlers
190
0
        m_pToolBar->SetSelectHdl( Link<ToolBox *, void>() );
191
0
        m_pToolBar->SetActivateHdl( Link<ToolBox *, void>() );
192
0
        m_pToolBar->SetDeactivateHdl( Link<ToolBox *, void>() );
193
0
        m_pToolBar->SetClickHdl( Link<ToolBox *, void>() );
194
0
        m_pToolBar->SetDropdownClickHdl( Link<ToolBox *, void>() );
195
0
        m_pToolBar->SetDoubleClickHdl( Link<ToolBox *, void>() );
196
0
        m_pToolBar->SetStateChangedHdl( Link<StateChangedType const *, void>() );
197
0
        m_pToolBar->SetDataChangedHdl( Link<DataChangedEvent const *, void>() );
198
199
0
        m_pToolBar.disposeAndClear();
200
0
    }
201
202
    virtual css::uno::Reference<css::awt::XWindow> GetInterface() override
203
0
    {
204
0
        return VCLUnoHelper::GetInterface(m_pToolBar);
205
0
    }
206
207
    virtual void ConnectCallbacks(ToolBarManager* pManager) override
208
0
    {
209
0
        m_pManager = pManager;
210
0
        m_pToolBar->SetSelectHdl( LINK( pManager, ToolBarManager, Select) );
211
0
        m_pToolBar->SetClickHdl( LINK( this, VclToolBarManager, Click ) );
212
0
        m_pToolBar->SetDropdownClickHdl( LINK( pManager, ToolBarManager, DropdownClick ) );
213
0
        m_pToolBar->SetDoubleClickHdl( LINK( pManager, ToolBarManager, DoubleClick ) );
214
0
        m_pToolBar->SetStateChangedHdl( LINK( pManager, ToolBarManager, StateChanged ) );
215
0
        m_pToolBar->SetDataChangedHdl( LINK( pManager, ToolBarManager, DataChanged ) );
216
217
0
        m_pToolBar->SetMenuButtonHdl( LINK( pManager, ToolBarManager, MenuButton ) );
218
0
        m_pToolBar->SetMenuExecuteHdl( LINK( pManager, ToolBarManager, MenuPreExecute ) );
219
0
        m_pToolBar->GetMenu()->SetSelectHdl( LINK( pManager, ToolBarManager, MenuSelect ) );
220
0
    }
221
222
    virtual void InsertItem(ToolBoxItemId nId,
223
                            const OUString& rCommandURL,
224
                            const OUString& rTooltip,
225
                            const OUString& rLabel,
226
                            ToolBoxItemBits nItemBits) override
227
0
    {
228
0
        m_pToolBar->InsertItem( nId, rLabel, rCommandURL, nItemBits );
229
0
        m_pToolBar->SetQuickHelpText(nId, rTooltip);
230
0
        m_pToolBar->EnableItem( nId );
231
0
        m_pToolBar->SetItemState( nId, TRISTATE_FALSE );
232
0
    }
233
234
    virtual void InsertSeparator() override
235
0
    {
236
0
        m_pToolBar->InsertSeparator();
237
0
    }
238
239
    virtual void InsertSpace() override
240
0
    {
241
0
        m_pToolBar->InsertSpace();
242
0
    }
243
244
    virtual void InsertBreak() override
245
0
    {
246
0
        m_pToolBar->InsertBreak();
247
0
    }
248
249
    virtual ToolBoxItemId GetItemId(sal_uInt16 nPos) override
250
0
    {
251
0
        return m_pToolBar->GetItemId(nPos);
252
0
    }
253
254
    virtual ToolBoxItemId GetCurItemId() override
255
0
    {
256
0
        return m_pToolBar->GetCurItemId();
257
0
    }
258
259
    virtual OUString GetItemCommand(ToolBoxItemId nId) override
260
0
    {
261
0
        return m_pToolBar->GetItemCommand(nId);
262
0
    }
263
264
    virtual sal_uInt16 GetItemCount() override
265
0
    {
266
0
        return m_pToolBar->GetItemCount();
267
0
    }
268
269
    virtual void SetItemCheckable(ToolBoxItemId nId) override
270
0
    {
271
0
        m_pToolBar->SetItemBits( nId, m_pToolBar->GetItemBits( nId ) | ToolBoxItemBits::CHECKABLE );
272
0
    }
273
274
    virtual void HideItem(ToolBoxItemId nId, const OUString& /*rCommandURL*/) override
275
0
    {
276
0
        m_pToolBar->HideItem( nId );
277
0
    }
278
279
    virtual bool IsItemVisible(ToolBoxItemId nId, const OUString& /*rCommandURL*/) override
280
0
    {
281
0
        return m_pToolBar->IsItemVisible(nId);
282
0
    }
283
284
    virtual void Clear() override
285
0
    {
286
0
        m_pToolBar->Clear();
287
0
    }
288
289
    virtual void SetName(const OUString& rName) override
290
0
    {
291
0
        m_pToolBar->SetText( rName );
292
0
    }
293
294
    virtual void SetHelpId(const OUString& rHelpId) override
295
0
    {
296
0
        m_pToolBar->SetHelpId( rHelpId );
297
0
    }
298
299
    virtual bool WillUsePopupMode() override
300
0
    {
301
0
        return m_pToolBar->WillUsePopupMode();
302
0
    }
303
304
    virtual bool IsReallyVisible() override
305
0
    {
306
0
        return m_pToolBar->IsReallyVisible();
307
0
    }
308
309
    virtual void SetIconSize(ToolBoxButtonSize eSize) override
310
0
    {
311
0
        m_pToolBar->SetToolboxButtonSize(eSize);
312
0
    }
313
314
    virtual vcl::ImageType GetImageSize() override
315
0
    {
316
0
        return m_pToolBar->GetImageSize();
317
0
    }
318
319
    virtual void SetMenuType(ToolBoxMenuType eType) override
320
0
    {
321
0
        m_pToolBar->SetMenuType( eType );
322
0
    }
323
324
    virtual void MergeToolbar(ToolBoxItemId & rItemId, sal_uInt16 nFirstItem,
325
                              const OUString& rModuleIdentifier,
326
                              CommandToInfoMap& rCommandMap,
327
                              MergeToolbarInstruction& rInstruction) override
328
0
    {
329
0
        ReferenceToolbarPathInfo aRefPoint = ToolBarMerger::FindReferencePoint( m_pToolBar, nFirstItem, rInstruction.aMergePoint );
330
331
        // convert the sequence< sequence< propertyvalue > > structure to
332
        // something we can better handle. A vector with item data
333
0
        AddonToolbarItemContainer aItems;
334
0
        ToolBarMerger::ConvertSeqSeqToVector( rInstruction.aMergeToolbarItems, aItems );
335
336
0
        if ( aRefPoint.bResult )
337
0
        {
338
0
            ToolBarMerger::ProcessMergeOperation( m_pToolBar,
339
0
                                                    aRefPoint.nPos,
340
0
                                                    rItemId,
341
0
                                                    rCommandMap,
342
0
                                                    rModuleIdentifier,
343
0
                                                    rInstruction.aMergeCommand,
344
0
                                                    rInstruction.aMergeCommandParameter,
345
0
                                                    aItems );
346
0
        }
347
0
        else
348
0
        {
349
0
            ToolBarMerger::ProcessMergeFallback( m_pToolBar,
350
0
                                                    rItemId,
351
0
                                                    rCommandMap,
352
0
                                                    rModuleIdentifier,
353
0
                                                    rInstruction.aMergeCommand,
354
0
                                                    rInstruction.aMergeFallback,
355
0
                                                    aItems );
356
0
        }
357
0
    }
358
359
    virtual void SetItemImage(ToolBoxItemId nId,
360
                              const OUString& /*rCommandURL*/,
361
                              const Image& rImage) override
362
0
    {
363
0
        m_pToolBar->SetItemImage(nId, rImage);
364
0
    }
365
366
    virtual void UpdateSize() override
367
0
    {
368
0
        ::Size aSize = m_pToolBar->CalcWindowSizePixel();
369
0
        m_pToolBar->SetOutputSizePixel( aSize );
370
0
    }
371
372
    virtual void SetItemWindow(ToolBoxItemId nItemId, vcl::Window* pNewWindow) override
373
0
    {
374
0
        m_pToolBar->SetItemWindow( nItemId, pNewWindow );
375
0
    }
376
377
private:
378
    VclPtr<ToolBox> m_pToolBar;
379
    bool m_bAddedToTaskPaneList;
380
    ToolBarManager* m_pManager;
381
};
382
383
IMPL_LINK_NOARG(VclToolBarManager, Click, ToolBox*, void)
384
0
{
385
0
    m_pManager->OnClick();
386
0
}
387
388
class WeldToolBarManager : public ToolBarManagerImpl
389
{
390
    DECL_LINK(Click, const OUString&, void);
391
    DECL_LINK(ToggleMenuHdl, const OUString&, void);
392
393
public:
394
    WeldToolBarManager(weld::Toolbar* pToolbar,
395
                       weld::Builder* pBuilder)
396
0
    : m_pWeldedToolBar(pToolbar)
397
0
    , m_pBuilder(pBuilder)
398
0
    , m_pManager(nullptr)
399
0
    , m_nCurrentId(0)
400
0
    {}
401
402
0
    virtual void Init() override {}
403
404
0
    virtual void Destroy() override {}
405
406
    virtual css::uno::Reference<css::awt::XWindow> GetInterface() override
407
0
    {
408
0
        return new weld::TransportAsXWindow(m_pWeldedToolBar, m_pBuilder);
409
0
    }
410
411
    virtual void ConnectCallbacks(ToolBarManager* pManager) override
412
0
    {
413
0
        m_pManager = pManager;
414
0
        m_pWeldedToolBar->connect_clicked(LINK(this, WeldToolBarManager, Click));
415
0
        m_pWeldedToolBar->connect_menu_toggled(LINK(this, WeldToolBarManager, ToggleMenuHdl));
416
0
    }
417
418
    virtual void InsertItem(ToolBoxItemId nId,
419
                            const OUString& rCommandURL,
420
                            const OUString& rTooltip,
421
                            const OUString& rLabel,
422
                            ToolBoxItemBits /*nItemBits*/) override
423
0
    {
424
0
        m_aCommandToId[rCommandURL] = nId;
425
0
        m_aIdToCommand[nId] = rCommandURL;
426
0
        m_aCommandOrder.push_back(rCommandURL);
427
428
0
        m_pWeldedToolBar->insert_item(m_aCommandOrder.size(), rCommandURL);
429
0
        m_pWeldedToolBar->set_item_tooltip_text(rCommandURL, rTooltip);
430
0
        m_pWeldedToolBar->set_item_label(rCommandURL, rLabel);
431
0
        m_pWeldedToolBar->set_item_sensitive(rCommandURL, true);
432
0
        m_pWeldedToolBar->set_item_active(rCommandURL, false);
433
0
    }
434
435
    virtual void InsertSeparator() override
436
0
    {
437
0
        m_pWeldedToolBar->append_separator(u""_ustr);
438
0
    }
439
440
0
    virtual void InsertSpace() override {}
441
442
0
    virtual void InsertBreak() override {}
443
444
    virtual ToolBoxItemId GetItemId(sal_uInt16 nPos) override
445
0
    {
446
0
        return m_aCommandToId[m_aCommandOrder[nPos]];
447
0
    }
448
449
    virtual ToolBoxItemId GetCurItemId() override
450
0
    {
451
0
        return m_nCurrentId;
452
0
    }
453
454
    virtual OUString GetItemCommand(ToolBoxItemId nId) override
455
0
    {
456
0
        return m_aIdToCommand[nId];
457
0
    }
458
459
    virtual sal_uInt16 GetItemCount() override
460
0
    {
461
0
        return m_aCommandOrder.size();
462
0
    }
463
464
0
    virtual void SetItemCheckable(ToolBoxItemId /*nId*/) override {}
465
466
    virtual void HideItem(ToolBoxItemId /*nId*/, const OUString& rCommandURL) override
467
0
    {
468
0
        m_pWeldedToolBar->set_item_visible(rCommandURL, false);
469
0
    }
470
471
    virtual bool IsItemVisible(ToolBoxItemId /*nId*/, const OUString& rCommandURL) override
472
0
    {
473
0
        return m_pWeldedToolBar->get_item_visible(rCommandURL);
474
0
    }
475
476
0
    virtual void Clear() override {}
477
478
0
    virtual void SetName(const OUString& /*rName*/) override {}
479
480
0
    virtual void SetHelpId(const OUString& /*rHelpId*/) override {}
481
482
0
    virtual bool WillUsePopupMode() override { return true; }
483
484
0
    virtual bool IsReallyVisible() override { return true; }
485
486
0
    virtual void SetIconSize(ToolBoxButtonSize /*eSize*/) override {}
487
488
    virtual vcl::ImageType GetImageSize() override
489
0
    {
490
0
        return vcl::ImageType::Size32;
491
0
    }
492
493
0
    virtual void SetMenuType(ToolBoxMenuType /*eType*/) override {}
494
495
    virtual void MergeToolbar(ToolBoxItemId & /*rItemId*/,
496
                              sal_uInt16 /*nFirstItem*/,
497
                              const OUString& /*rModuleIdentifier*/,
498
                              CommandToInfoMap& /*rCommandMap*/,
499
0
                              MergeToolbarInstruction& /*rInstruction*/) override {}
500
501
    virtual void SetItemImage(ToolBoxItemId /*nId*/,
502
                              const OUString& rCommandURL,
503
                              const Image& rImage) override
504
0
    {
505
0
        m_pWeldedToolBar->set_item_image(rCommandURL, Graphic(rImage).GetXGraphic());
506
0
    }
507
508
0
    virtual void UpdateSize() override {}
509
510
0
    virtual void SetItemWindow(ToolBoxItemId /*nItemId*/, vcl::Window* /*pNewWindow*/) override {}
511
512
private:
513
    weld::Toolbar* m_pWeldedToolBar;
514
    weld::Builder* m_pBuilder;
515
    ToolBarManager* m_pManager;
516
    ToolBoxItemId m_nCurrentId;
517
    std::map<const OUString, ToolBoxItemId> m_aCommandToId;
518
    std::map<ToolBoxItemId, OUString> m_aIdToCommand;
519
    std::vector<OUString> m_aCommandOrder;
520
};
521
522
IMPL_LINK(WeldToolBarManager, Click, const OUString&, rCommand, void)
523
0
{
524
0
    m_nCurrentId = m_aCommandToId[rCommand];
525
0
    m_pManager->OnClick(true);
526
0
}
527
528
IMPL_LINK(WeldToolBarManager, ToggleMenuHdl, const OUString&, rCommand, void)
529
0
{
530
0
    m_nCurrentId = m_aCommandToId[rCommand];
531
0
    m_pManager->OnDropdownClick(false);
532
0
}
533
534
} // end anonymous namespace
535
536
//  XInterface, XTypeProvider, XServiceInfo
537
538
ToolBarManager::ToolBarManager( const Reference< XComponentContext >& rxContext,
539
                                const Reference< XFrame >& rFrame,
540
                                OUString aResourceName,
541
                                ToolBox* pToolBar ) :
542
0
    m_bDisposed( false ),
543
0
    m_bFrameActionRegistered( false ),
544
0
    m_bUpdateControllers( false ),
545
0
    m_eSymbolSize(SvtMiscOptions::GetCurrentSymbolsSize()),
546
0
    m_nContextMinPos(0),
547
0
    m_pImpl( new VclToolBarManager( pToolBar ) ),
548
0
    m_pToolBar( pToolBar ),
549
0
    m_pWeldedToolBar( nullptr ),
550
0
    m_aResourceName(std::move( aResourceName )),
551
0
    m_xFrame( rFrame ),
552
0
    m_xContext( rxContext ),
553
0
    m_aAsyncUpdateControllersTimer( "framework::ToolBarManager m_aAsyncUpdateControllersTimer" ),
554
0
    m_sIconTheme( SvtMiscOptions::GetIconTheme() )
555
0
{
556
0
    Init();
557
0
}
558
559
ToolBarManager::ToolBarManager( const Reference< XComponentContext >& rxContext,
560
                                const Reference< XFrame >& rFrame,
561
                                OUString aResourceName,
562
                                weld::Toolbar* pToolBar,
563
                                weld::Builder* pBuilder ) :
564
0
    m_bDisposed( false ),
565
0
    m_bFrameActionRegistered( false ),
566
0
    m_bUpdateControllers( false ),
567
0
    m_eSymbolSize( SvtMiscOptions::GetCurrentSymbolsSize() ),
568
0
    m_nContextMinPos(0),
569
0
    m_pImpl( new WeldToolBarManager( pToolBar, pBuilder ) ),
570
0
    m_pWeldedToolBar( pToolBar ),
571
0
    m_aResourceName(std::move( aResourceName )),
572
0
    m_xFrame( rFrame ),
573
0
    m_xContext( rxContext ),
574
0
    m_aAsyncUpdateControllersTimer( "framework::ToolBarManager m_aAsyncUpdateControllersTimer" ),
575
0
    m_sIconTheme( SvtMiscOptions::GetIconTheme() )
576
0
{
577
0
    Init();
578
0
}
579
580
void ToolBarManager::Init()
581
0
{
582
0
    OSL_ASSERT( m_xContext.is() );
583
584
0
    m_pImpl->Init();
585
586
0
    m_xToolbarControllerFactory = frame::theToolbarControllerFactory::get( m_xContext );
587
0
    m_xURLTransformer = URLTransformer::create( m_xContext );
588
589
0
    m_pImpl->ConnectCallbacks(this);
590
591
0
    if (m_eSymbolSize == SFX_SYMBOLS_SIZE_LARGE)
592
0
        m_pImpl->SetIconSize(ToolBoxButtonSize::Large);
593
0
    else if (m_eSymbolSize == SFX_SYMBOLS_SIZE_32)
594
0
        m_pImpl->SetIconSize(ToolBoxButtonSize::Size32);
595
0
    else
596
0
        m_pImpl->SetIconSize(ToolBoxButtonSize::Small);
597
598
    // enables a menu for clipped items and customization
599
0
    SvtCommandOptions aCmdOptions;
600
0
    ToolBoxMenuType nMenuType = ToolBoxMenuType::ClippedItems;
601
0
    if ( !aCmdOptions.LookupDisabled( u"CreateDialog"_ustr))
602
0
         nMenuType |= ToolBoxMenuType::Customize;
603
604
0
    m_pImpl->SetMenuType( nMenuType );
605
606
    // set name for testtool, the useful part is after the last '/'
607
0
    sal_Int32 idx = m_aResourceName.lastIndexOf('/');
608
0
    idx++; // will become 0 if '/' not found: use full string
609
0
    std::u16string_view aToolbarName = m_aResourceName.subView( idx );
610
0
    OUString aHelpIdAsString = ".HelpId:" + OUString::Concat(aToolbarName);
611
0
    m_pImpl->SetHelpId( aHelpIdAsString );
612
613
0
    m_aAsyncUpdateControllersTimer.SetTimeout( 50 );
614
0
    m_aAsyncUpdateControllersTimer.SetInvokeHandler( LINK( this, ToolBarManager, AsyncUpdateControllersHdl ) );
615
616
0
    SvtMiscOptions().AddListenerLink( LINK( this, ToolBarManager, MiscOptionsChanged ) );
617
0
}
618
619
ToolBarManager::~ToolBarManager()
620
0
{
621
0
    assert(!m_aAsyncUpdateControllersTimer.IsActive());
622
0
    assert(!m_pToolBar); // must be disposed by ToolbarLayoutManager
623
0
}
624
625
void ToolBarManager::Destroy()
626
0
{
627
0
    m_pImpl->Destroy();
628
629
0
    SvtMiscOptions().RemoveListenerLink( LINK( this, ToolBarManager, MiscOptionsChanged ) );
630
0
}
631
632
ToolBox* ToolBarManager::GetToolBar() const
633
0
{
634
0
    SolarMutexGuard g;
635
0
    return m_pToolBar;
636
0
}
637
638
void ToolBarManager::CheckAndUpdateImages()
639
0
{
640
0
    SolarMutexGuard g;
641
0
    bool bRefreshImages = false;
642
643
0
    sal_Int16 eNewSymbolSize = SvtMiscOptions::GetCurrentSymbolsSize();
644
645
0
    if (m_eSymbolSize != eNewSymbolSize )
646
0
    {
647
0
        bRefreshImages = true;
648
0
        m_eSymbolSize = eNewSymbolSize;
649
0
    }
650
651
0
    const OUString sCurrentIconTheme = SvtMiscOptions::GetIconTheme();
652
0
    if ( m_sIconTheme != sCurrentIconTheme )
653
0
    {
654
0
        bRefreshImages = true;
655
0
        m_sIconTheme = sCurrentIconTheme;
656
0
    }
657
658
    // Refresh images if requested
659
0
    if ( bRefreshImages )
660
0
        RefreshImages();
661
0
}
662
663
void ToolBarManager::RefreshImages()
664
0
{
665
0
    SolarMutexGuard g;
666
667
0
    if (m_eSymbolSize == SFX_SYMBOLS_SIZE_LARGE)
668
0
        m_pImpl->SetIconSize(ToolBoxButtonSize::Large);
669
0
    else if (m_eSymbolSize == SFX_SYMBOLS_SIZE_32)
670
0
        m_pImpl->SetIconSize(ToolBoxButtonSize::Size32);
671
0
    else
672
0
        m_pImpl->SetIconSize(ToolBoxButtonSize::Small);
673
674
0
    for ( auto const& it : m_aControllerMap )
675
0
    {
676
0
        Reference< XSubToolbarController > xController( it.second, UNO_QUERY );
677
0
        if ( xController.is() && xController->opensSubToolbar() )
678
0
        {
679
            // The button should show the last function that was selected from the
680
            // dropdown. The controller should know better than us what it was.
681
0
            xController->updateImage();
682
0
        }
683
0
        else
684
0
        {
685
0
            OUString aCommandURL = m_pImpl->GetItemCommand( it.first );
686
0
            vcl::ImageType eImageType = m_pImpl->GetImageSize();
687
0
            Image aImage = vcl::CommandInfoProvider::GetImageForCommand(aCommandURL, m_xFrame, eImageType);
688
            // Try also to query for add-on images before giving up and use an
689
            // empty image.
690
0
            bool bBigImages = eImageType != vcl::ImageType::Size16;
691
0
            if ( !aImage )
692
0
                aImage = Image(framework::AddonsOptions().GetImageFromURL(aCommandURL, bBigImages));
693
0
            m_pImpl->SetItemImage( it.first, aCommandURL, aImage );
694
0
        }
695
0
    }
696
697
0
    m_pImpl->UpdateSize();
698
0
}
699
700
void ToolBarManager::UpdateControllers()
701
0
{
702
703
0
    if( officecfg::Office::Common::Misc::DisableUICustomization::get() )
704
0
    {
705
0
        Any a;
706
0
        Reference< XLayoutManager > xLayoutManager;
707
0
        Reference< XPropertySet > xFramePropSet( m_xFrame, UNO_QUERY );
708
0
        if ( xFramePropSet.is() )
709
0
            a = xFramePropSet->getPropertyValue(u"LayoutManager"_ustr);
710
0
        a >>= xLayoutManager;
711
0
        Reference< XDockableWindow > xDockable( m_pImpl->GetInterface(), UNO_QUERY );
712
0
        if ( xLayoutManager.is() && xDockable.is() )
713
0
        {
714
0
            css::awt::Point aPoint;
715
0
            aPoint.X = aPoint.Y = SAL_MAX_INT32;
716
0
            xLayoutManager->dockWindow( m_aResourceName, DockingArea_DOCKINGAREA_DEFAULT, aPoint );
717
0
            xLayoutManager->lockWindow( m_aResourceName );
718
0
        }
719
0
    }
720
721
0
    if ( !m_bUpdateControllers )
722
0
    {
723
0
        m_bUpdateControllers = true;
724
0
        for (auto const& controller : m_aControllerMap)
725
0
        {
726
0
            try
727
0
            {
728
0
                Reference< XUpdatable > xUpdatable( controller.second, UNO_QUERY );
729
0
                if ( xUpdatable.is() )
730
0
                    xUpdatable->update();
731
0
            }
732
0
            catch (const Exception&)
733
0
            {
734
0
            }
735
0
        }
736
0
    }
737
0
    m_bUpdateControllers = false;
738
0
}
739
740
//for update toolbar controller via Support Visible
741
void ToolBarManager::UpdateController( const css::uno::Reference< css::frame::XToolbarController >& xController)
742
0
{
743
744
0
    if ( !m_bUpdateControllers )
745
0
    {
746
0
        m_bUpdateControllers = true;
747
0
        try
748
0
        {   if(xController.is())
749
0
            {
750
0
                Reference< XUpdatable > xUpdatable( xController, UNO_QUERY );
751
0
                if ( xUpdatable.is() )
752
0
                    xUpdatable->update();
753
0
            }
754
0
         }
755
0
         catch (const Exception&)
756
0
         {
757
0
         }
758
759
0
    }
760
0
    m_bUpdateControllers = false;
761
0
}
762
763
void ToolBarManager::frameAction( const FrameActionEvent& Action )
764
0
{
765
0
    SolarMutexGuard g;
766
0
    if ( Action.Action == FrameAction_CONTEXT_CHANGED && !m_bDisposed )
767
0
    {
768
0
        if (m_aImageController)
769
0
            m_aImageController->update();
770
0
        m_aAsyncUpdateControllersTimer.Start();
771
0
    }
772
0
}
773
774
void SAL_CALL ToolBarManager::disposing( const EventObject& Source )
775
0
{
776
0
    SolarMutexGuard g;
777
778
0
    if ( m_bDisposed )
779
0
        return;
780
781
0
    RemoveControllers();
782
783
0
    if ( m_xDocImageManager.is() )
784
0
    {
785
0
        try
786
0
        {
787
0
            m_xDocImageManager->removeConfigurationListener(
788
0
                Reference< XUIConfigurationListener >(this) );
789
0
        }
790
0
        catch (const Exception&)
791
0
        {
792
0
        }
793
0
    }
794
795
0
    if ( m_xModuleImageManager.is() )
796
0
    {
797
0
        try
798
0
        {
799
0
            m_xModuleImageManager->removeConfigurationListener(
800
0
                Reference< XUIConfigurationListener >(this) );
801
0
        }
802
0
        catch (const Exception&)
803
0
        {
804
0
        }
805
0
    }
806
807
0
    m_xDocImageManager.clear();
808
0
    m_xModuleImageManager.clear();
809
810
0
    if ( Source.Source == Reference< XInterface >( m_xFrame, UNO_QUERY ))
811
0
        m_xFrame.clear();
812
813
0
    m_xContext.clear();
814
0
}
815
816
// XComponent
817
void SAL_CALL ToolBarManager::dispose()
818
0
{
819
0
    Reference< XComponent > xThis(this);
820
821
0
    {
822
0
        EventObject aEvent( xThis );
823
0
        std::unique_lock aGuard(m_mutex);
824
0
        m_aListenerContainer.disposeAndClear( aGuard, aEvent );
825
0
    }
826
0
    {
827
0
        SolarMutexGuard g;
828
829
0
        if (m_bDisposed)
830
0
        {
831
0
            return;
832
0
        }
833
834
0
        RemoveControllers();
835
836
0
        if ( m_xDocImageManager.is() )
837
0
        {
838
0
            try
839
0
            {
840
0
                m_xDocImageManager->removeConfigurationListener(
841
0
                    Reference< XUIConfigurationListener >(this) );
842
0
            }
843
0
            catch (const Exception&)
844
0
            {
845
0
            }
846
0
        }
847
0
        m_xDocImageManager.clear();
848
0
        if ( m_xModuleImageManager.is() )
849
0
        {
850
0
            try
851
0
            {
852
0
                m_xModuleImageManager->removeConfigurationListener(
853
0
                    Reference< XUIConfigurationListener >(this) );
854
0
            }
855
0
            catch (const Exception&)
856
0
            {
857
0
            }
858
0
        }
859
0
        m_xModuleImageManager.clear();
860
861
0
        if ( m_aOverflowManager.is() )
862
0
        {
863
0
            m_aOverflowManager->dispose();
864
0
            m_aOverflowManager.clear();
865
0
        }
866
867
        // We have to destroy our toolbar instance now.
868
0
        Destroy();
869
0
        m_pToolBar.reset();
870
871
0
        if ( m_bFrameActionRegistered && m_xFrame.is() )
872
0
        {
873
0
            try
874
0
            {
875
0
                m_xFrame->removeFrameActionListener( Reference< XFrameActionListener >(this) );
876
0
            }
877
0
            catch (const Exception&)
878
0
            {
879
0
            }
880
0
        }
881
882
0
        m_xFrame.clear();
883
0
        m_xContext.clear();
884
885
        // stop timer to prevent timer events after dispose
886
        // do it last because other calls could restart timer in StateChanged()
887
0
        m_aAsyncUpdateControllersTimer.Stop();
888
889
0
        m_bDisposed = true;
890
0
    }
891
0
}
892
893
void SAL_CALL ToolBarManager::addEventListener( const Reference< XEventListener >& xListener )
894
0
{
895
0
    SolarMutexGuard g;
896
897
    /* SAFE AREA ----------------------------------------------------------------------------------------------- */
898
0
    if ( m_bDisposed )
899
0
        throw DisposedException();
900
901
0
    std::unique_lock aGuard(m_mutex);
902
0
    m_aListenerContainer.addInterface( aGuard, xListener );
903
0
}
904
905
void SAL_CALL ToolBarManager::removeEventListener( const Reference< XEventListener >& xListener )
906
0
{
907
0
    std::unique_lock aGuard(m_mutex);
908
0
    m_aListenerContainer.removeInterface( aGuard, xListener );
909
0
}
910
911
// XUIConfigurationListener
912
void SAL_CALL ToolBarManager::elementInserted( const css::ui::ConfigurationEvent& Event )
913
0
{
914
0
    impl_elementChanged(false,Event);
915
0
}
916
917
void SAL_CALL ToolBarManager::elementRemoved( const css::ui::ConfigurationEvent& Event )
918
0
{
919
0
    impl_elementChanged(true,Event);
920
0
}
921
void ToolBarManager::impl_elementChanged(bool const isRemove,
922
        const css::ui::ConfigurationEvent& Event)
923
0
{
924
0
    SolarMutexGuard g;
925
926
    /* SAFE AREA ----------------------------------------------------------------------------------------------- */
927
0
    if ( m_bDisposed )
928
0
        return;
929
930
0
    Reference< XNameAccess > xNameAccess;
931
0
    sal_Int16                nImageType = sal_Int16();
932
0
    sal_Int16                nCurrentImageType = getCurrentImageType();
933
934
0
    if (!(( Event.aInfo >>= nImageType ) &&
935
0
        ( nImageType == nCurrentImageType ) &&
936
0
        ( Event.Element >>= xNameAccess )))
937
0
        return;
938
939
0
    sal_Int16 nImageInfo( 1 );
940
0
    Reference< XInterface > xIfacDocImgMgr( m_xDocImageManager, UNO_QUERY );
941
0
    if ( xIfacDocImgMgr == Event.Source )
942
0
        nImageInfo = 0;
943
944
0
    const Sequence< OUString > aSeq = xNameAccess->getElementNames();
945
0
    for ( OUString const & commandName : aSeq )
946
0
    {
947
0
        CommandToInfoMap::iterator pIter = m_aCommandMap.find( commandName );
948
0
        if ( pIter != m_aCommandMap.end() && ( pIter->second.nImageInfo >= nImageInfo ))
949
0
        {
950
0
            if (isRemove)
951
0
            {
952
0
                Image aImage;
953
0
                if (( pIter->second.nImageInfo == 0 ) && ( pIter->second.nImageInfo == nImageInfo ))
954
0
                {
955
                    // Special case: An image from the document image manager has been removed.
956
                    // It is possible that we have an image at our module image manager. Before
957
                    // we can remove our image we have to ask our module image manager.
958
0
                    Sequence< OUString > aCmdURLSeq{ pIter->first };
959
0
                    Sequence< Reference< XGraphic > > aGraphicSeq;
960
0
                    aGraphicSeq = m_xModuleImageManager->getImages( nImageType, aCmdURLSeq );
961
0
                    aImage = Image( aGraphicSeq[0] );
962
0
                }
963
964
0
                setToolBarImage(aImage,pIter);
965
0
            } // if (isRemove)
966
0
            else
967
0
            {
968
0
                Reference< XGraphic > xGraphic;
969
0
                if ( xNameAccess->getByName( commandName ) >>= xGraphic )
970
0
                {
971
0
                    Image aImage( xGraphic );
972
0
                    setToolBarImage(aImage,pIter);
973
0
                }
974
0
                pIter->second.nImageInfo = nImageInfo;
975
0
            }
976
0
        }
977
0
    }
978
0
}
979
void ToolBarManager::setToolBarImage(const Image& rImage,
980
        const CommandToInfoMap::const_iterator& rIter)
981
0
{
982
0
    const ::std::vector<ToolBoxItemId>& rIDs = rIter->second.aIds;
983
0
    m_pImpl->SetItemImage( rIter->second.nId, rIter->first, rImage );
984
0
    for (auto const& it : rIDs)
985
0
    {
986
0
        m_pImpl->SetItemImage(it, rIter->first, rImage);
987
0
    }
988
0
}
989
990
void SAL_CALL ToolBarManager::elementReplaced( const css::ui::ConfigurationEvent& Event )
991
0
{
992
0
    impl_elementChanged(false,Event);
993
0
}
994
995
void ToolBarManager::RemoveControllers()
996
0
{
997
0
    DBG_TESTSOLARMUTEX();
998
0
    assert(!m_bDisposed);
999
1000
0
    m_aSubToolBarControllerMap.clear();
1001
1002
0
    if (m_aImageController)
1003
0
        m_aImageController->dispose();
1004
0
    m_aImageController.clear();
1005
1006
    // i90033
1007
    // Remove item window pointers from the toolbar. They were
1008
    // destroyed by the dispose() at the XComponent. This is needed
1009
    // as VCL code later tries to access the item window data in certain
1010
    // dtors where the item window is already invalid!
1011
0
    for ( ToolBox::ImplToolItems::size_type i = 0; i < m_pImpl->GetItemCount(); i++ )
1012
0
    {
1013
0
        ToolBoxItemId nItemId = m_pImpl->GetItemId( i );
1014
0
        if ( nItemId > ToolBoxItemId(0) )
1015
0
        {
1016
0
            Reference< XComponent > xComponent( m_aControllerMap[ nItemId ], UNO_QUERY );
1017
0
            if ( xComponent.is() )
1018
0
            {
1019
0
                try
1020
0
                {
1021
0
                    xComponent->dispose();
1022
0
                }
1023
0
                catch (const Exception&)
1024
0
                {
1025
0
                }
1026
0
            }
1027
0
            m_pImpl->SetItemWindow(nItemId, nullptr);
1028
0
        }
1029
0
    }
1030
0
    m_aControllerMap.clear();
1031
0
}
1032
1033
void ToolBarManager::CreateControllers()
1034
0
{
1035
0
    Reference< XWindow > xToolbarWindow = m_pImpl->GetInterface();
1036
1037
0
    css::util::URL      aURL;
1038
0
    bool                bHasDisabledEntries = SvtCommandOptions().HasEntriesDisabled();
1039
0
    SvtCommandOptions   aCmdOptions;
1040
1041
0
    for ( ToolBox::ImplToolItems::size_type i = 0; i < m_pImpl->GetItemCount(); i++ )
1042
0
    {
1043
0
        ToolBoxItemId nId = m_pImpl->GetItemId( i );
1044
0
        if ( nId == ToolBoxItemId(0) )
1045
0
            continue;
1046
1047
0
        bool                     bInit( true );
1048
0
        bool                     bCreate( true );
1049
0
        Reference< XStatusListener > xController;
1050
1051
0
        OUString aCommandURL( m_pImpl->GetItemCommand( nId ) );
1052
        // Command can be just an alias to another command.
1053
0
        auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(aCommandURL, m_aModuleIdentifier);
1054
0
        OUString aRealCommandURL( vcl::CommandInfoProvider::GetRealCommandForCommand(aProperties) );
1055
0
        if ( !aRealCommandURL.isEmpty() )
1056
0
            aCommandURL = aRealCommandURL;
1057
1058
0
        if ( bHasDisabledEntries )
1059
0
        {
1060
0
            aURL.Complete = aCommandURL;
1061
0
            m_xURLTransformer->parseStrict( aURL );
1062
0
            if ( aCmdOptions.LookupDisabled( aURL.Path ))
1063
0
            {
1064
0
                m_aControllerMap[ nId ] = xController;
1065
0
                m_pImpl->HideItem( nId, aCommandURL );
1066
0
                continue;
1067
0
            }
1068
0
        }
1069
1070
0
        if ( m_xToolbarControllerFactory.is() &&
1071
0
             m_xToolbarControllerFactory->hasController( aCommandURL, m_aModuleIdentifier ))
1072
0
        {
1073
0
            Reference<XMultiServiceFactory> xMSF(m_xContext->getServiceManager(), UNO_QUERY_THROW);
1074
0
            Sequence< Any > aArgs( comphelper::InitAnyPropertySequence( {
1075
0
                { "ModuleIdentifier", Any(m_aModuleIdentifier) },
1076
0
                { "Frame", Any(m_xFrame) },
1077
0
                { "ServiceManager", Any(xMSF) },
1078
0
                { "ParentWindow", Any(xToolbarWindow) },
1079
0
                { "Identifier", Any(sal_uInt16(nId)) },
1080
0
            } ));
1081
0
            xController.set( m_xToolbarControllerFactory->createInstanceWithArgumentsAndContext( aCommandURL, aArgs, m_xContext ),
1082
0
                             UNO_QUERY );
1083
0
            bInit = false; // Initialization is done through the factory service
1084
0
        }
1085
1086
0
        if (( aCommandURL == ".uno:OpenUrl" ) && ( !m_pImpl->IsItemVisible(nId, aCommandURL)))
1087
0
            bCreate = false;
1088
1089
0
        if ( !xController.is() && bCreate )
1090
0
        {
1091
0
            if ( m_pToolBar )
1092
0
                xController = CreateToolBoxController( m_xFrame, m_pToolBar, nId, aCommandURL );
1093
0
            if ( !xController )
1094
0
            {
1095
0
                if ( aCommandURL.startsWith( ".uno:StyleApply?" ) )
1096
0
                {
1097
0
                    xController.set( new StyleToolbarController( m_xContext, m_xFrame, aCommandURL ));
1098
0
                    m_pImpl->SetItemCheckable( nId );
1099
0
                }
1100
0
                else if ( aCommandURL.startsWith( "private:resource/" ) )
1101
0
                {
1102
0
                    xController.set( new framework::GenericPopupToolbarController(m_xContext, {}) );
1103
0
                }
1104
0
                else if ( m_pToolBar && m_pToolBar->GetItemData( nId ) != nullptr )
1105
0
                {
1106
                    // retrieve additional parameters
1107
0
                    OUString aControlType = static_cast< AddonsParams* >( m_pToolBar->GetItemData( nId ))->aControlType;
1108
0
                    sal_uInt16 nWidth = static_cast< AddonsParams* >( m_pToolBar->GetItemData( nId ))->nWidth;
1109
1110
0
                    xController.set(
1111
0
                        ToolBarMerger::CreateController( m_xContext,
1112
0
                                                         m_xFrame,
1113
0
                                                         m_pToolBar,
1114
0
                                                         aCommandURL,
1115
0
                                                         nId,
1116
0
                                                         nWidth,
1117
0
                                                         aControlType ).get(), UNO_QUERY );
1118
1119
0
                }
1120
0
                else
1121
0
                {
1122
0
                    if ( m_pToolBar )
1123
0
                        xController.set( new GenericToolbarController( m_xContext, m_xFrame, m_pToolBar, nId, aCommandURL ));
1124
0
                    else
1125
0
                        xController.set( new GenericToolbarController( m_xContext, m_xFrame, *m_pWeldedToolBar, aCommandURL ));
1126
0
                }
1127
0
            }
1128
0
        }
1129
1130
        // Accessibility support: Set toggle button role for specific commands
1131
0
        const sal_Int32 nProps = vcl::CommandInfoProvider::GetPropertiesForCommand(aCommandURL, m_aModuleIdentifier);
1132
0
        if (nProps & UICOMMANDDESCRIPTION_PROPERTIES_TOGGLEBUTTON)
1133
0
            m_pImpl->SetItemCheckable(nId);
1134
1135
        // Associate ID and controller to be able to retrieve
1136
        // the controller from the ID later.
1137
0
        m_aControllerMap[ nId ] = xController;
1138
1139
        // Fill sub-toolbars into our hash-map
1140
0
        Reference< XSubToolbarController > xSubToolBar( xController, UNO_QUERY );
1141
0
        if ( xSubToolBar.is() && xSubToolBar->opensSubToolbar() )
1142
0
        {
1143
0
            OUString aSubToolBarName = xSubToolBar->getSubToolbarName();
1144
0
            if ( !aSubToolBarName.isEmpty() )
1145
0
            {
1146
0
                SubToolBarToSubToolBarControllerMap::iterator pIter =
1147
0
                    m_aSubToolBarControllerMap.find( aSubToolBarName );
1148
0
                if ( pIter == m_aSubToolBarControllerMap.end() )
1149
0
                {
1150
0
                    SubToolBarControllerVector aSubToolBarVector;
1151
0
                    aSubToolBarVector.push_back( xSubToolBar );
1152
0
                    m_aSubToolBarControllerMap.emplace(
1153
0
                            aSubToolBarName, aSubToolBarVector );
1154
0
                }
1155
0
                else
1156
0
                    pIter->second.push_back( xSubToolBar );
1157
0
            }
1158
0
        }
1159
1160
0
        Reference< XInitialization > xInit( xController, UNO_QUERY );
1161
0
        if ( xInit.is() )
1162
0
        {
1163
0
            if ( bInit )
1164
0
            {
1165
0
                Reference<XMultiServiceFactory> xMSF(m_xContext->getServiceManager(), UNO_QUERY_THROW);
1166
0
                Sequence< Any > aArgs( comphelper::InitAnyPropertySequence( {
1167
0
                    { "Frame", Any(m_xFrame) },
1168
0
                    { "CommandURL", Any(aCommandURL) },
1169
0
                    { "ServiceManager", Any(xMSF) },
1170
0
                    { "ParentWindow", Any(xToolbarWindow) },
1171
0
                    { "ModuleIdentifier", Any(m_aModuleIdentifier) },
1172
0
                    { "Identifier", Any(sal_uInt16(nId)) },
1173
0
                } ));
1174
1175
0
                xInit->initialize( aArgs );
1176
0
            }
1177
1178
            // Request an item window from the toolbar controller and set it at the VCL toolbar
1179
0
            Reference< XToolbarController > xTbxController( xController, UNO_QUERY );
1180
0
            if ( xTbxController.is() && xToolbarWindow.is() )
1181
0
            {
1182
0
                Reference< XWindow > xWindow = xTbxController->createItemWindow( xToolbarWindow );
1183
0
                if ( xWindow.is() )
1184
0
                {
1185
0
                    VclPtr<vcl::Window> pItemWin = VCLUnoHelper::GetWindow( xWindow );
1186
0
                    if ( pItemWin )
1187
0
                    {
1188
0
                        WindowType eType = pItemWin->GetType();
1189
0
                        if ( m_pToolBar && (eType == WindowType::LISTBOX || eType == WindowType::MULTILISTBOX || eType == WindowType::COMBOBOX) )
1190
0
                            pItemWin->SetAccessibleName( m_pToolBar->GetItemText( nId ) );
1191
0
                        m_pImpl->SetItemWindow( nId, pItemWin );
1192
0
                    }
1193
0
                }
1194
0
            }
1195
0
        }
1196
1197
        //for update Controller via support visible state
1198
0
        Reference< XPropertySet > xPropSet( xController, UNO_QUERY );
1199
0
        if ( xPropSet.is() )
1200
0
        {
1201
0
            try
1202
0
            {
1203
0
                bool bSupportVisible = true;
1204
0
                Any a( xPropSet->getPropertyValue(u"SupportsVisible"_ustr) );
1205
0
                a >>= bSupportVisible;
1206
0
                if (bSupportVisible)
1207
0
                {
1208
0
                    Reference< XToolbarController > xTbxController( xController, UNO_QUERY );
1209
0
                    UpdateController(xTbxController);
1210
0
                }
1211
0
            }
1212
0
            catch (const RuntimeException&)
1213
0
            {
1214
0
                throw;
1215
0
            }
1216
0
            catch (const Exception&)
1217
0
            {
1218
0
            }
1219
0
        }
1220
0
    }
1221
1222
0
    AddFrameActionListener();
1223
0
}
1224
1225
void ToolBarManager::AddFrameActionListener()
1226
0
{
1227
0
    if ( !m_bFrameActionRegistered && m_xFrame.is() )
1228
0
    {
1229
0
        m_bFrameActionRegistered = true;
1230
0
        m_xFrame->addFrameActionListener( Reference< XFrameActionListener >(this) );
1231
0
    }
1232
0
}
1233
1234
// static
1235
ToolBoxItemBits ToolBarManager::ConvertStyleToToolboxItemBits( sal_Int32 nStyle )
1236
0
{
1237
0
    ToolBoxItemBits nItemBits( ToolBoxItemBits::NONE );
1238
0
    if ( nStyle & css::ui::ItemStyle::RADIO_CHECK )
1239
0
        nItemBits |= ToolBoxItemBits::RADIOCHECK;
1240
0
    if ( nStyle & css::ui::ItemStyle::ALIGN_LEFT )
1241
0
        nItemBits |= ToolBoxItemBits::LEFT;
1242
0
    if ( nStyle & css::ui::ItemStyle::AUTO_SIZE )
1243
0
        nItemBits |= ToolBoxItemBits::AUTOSIZE;
1244
0
    if ( nStyle & css::ui::ItemStyle::DROP_DOWN )
1245
0
        nItemBits |= ToolBoxItemBits::DROPDOWN;
1246
0
    if ( nStyle & css::ui::ItemStyle::REPEAT )
1247
0
        nItemBits |= ToolBoxItemBits::REPEAT;
1248
0
    if ( nStyle & css::ui::ItemStyle::DROPDOWN_ONLY )
1249
0
        nItemBits |= ToolBoxItemBits::DROPDOWNONLY;
1250
0
    if ( nStyle & css::ui::ItemStyle::TEXT )
1251
0
        nItemBits |= ToolBoxItemBits::TEXT_ONLY;
1252
0
    if ( nStyle & css::ui::ItemStyle::ICON )
1253
0
        nItemBits |= ToolBoxItemBits::ICON_ONLY;
1254
1255
0
    return nItemBits;
1256
0
}
1257
1258
void ToolBarManager::InitImageManager()
1259
0
{
1260
0
    Reference< XModuleManager2 > xModuleManager = ModuleManager::create( m_xContext );
1261
0
    if ( !m_xDocImageManager.is() )
1262
0
    {
1263
0
        Reference< XModel > xModel( GetModelFromFrame() );
1264
0
        if ( xModel.is() )
1265
0
        {
1266
0
            Reference< XUIConfigurationManagerSupplier > xSupplier( xModel, UNO_QUERY );
1267
0
            if ( xSupplier.is() )
1268
0
            {
1269
0
                Reference< XUIConfigurationManager > xDocUICfgMgr = xSupplier->getUIConfigurationManager();
1270
0
                m_xDocImageManager.set( xDocUICfgMgr->getImageManager(), UNO_QUERY );
1271
0
                m_xDocImageManager->addConfigurationListener(
1272
0
                                        Reference< XUIConfigurationListener >(this) );
1273
0
            }
1274
0
        }
1275
0
    }
1276
1277
0
    try
1278
0
    {
1279
0
        m_aModuleIdentifier = xModuleManager->identify( Reference< XInterface >( m_xFrame, UNO_QUERY ) );
1280
0
    }
1281
0
    catch (const Exception&)
1282
0
    {
1283
0
    }
1284
1285
0
    if ( !m_xModuleImageManager.is() )
1286
0
    {
1287
0
        Reference< XModuleUIConfigurationManagerSupplier > xModuleCfgMgrSupplier =
1288
0
            theModuleUIConfigurationManagerSupplier::get( m_xContext );
1289
0
        Reference< XUIConfigurationManager > xUICfgMgr = xModuleCfgMgrSupplier->getUIConfigurationManager( m_aModuleIdentifier );
1290
0
        m_xModuleImageManager.set( xUICfgMgr->getImageManager(), UNO_QUERY );
1291
0
        m_xModuleImageManager->addConfigurationListener( Reference< XUIConfigurationListener >(this) );
1292
0
    }
1293
0
}
1294
1295
void ToolBarManager::FillToolbar( const Reference< XIndexAccess >& rItemContainer,
1296
                                  const Reference< XIndexAccess >& rContextData,
1297
                                  const OUString& rContextToolbarName )
1298
0
{
1299
0
    OString aTbxName = OUStringToOString( m_aResourceName, RTL_TEXTENCODING_ASCII_US );
1300
0
    SAL_INFO( "fwk.uielement", "framework (cd100003) ::ToolBarManager::FillToolbar " << aTbxName );
1301
1302
0
    SolarMutexGuard g;
1303
1304
0
    if ( m_bDisposed )
1305
0
        return;
1306
1307
0
    InitImageManager();
1308
1309
0
    RemoveControllers();
1310
1311
    // reset and fill command map
1312
0
    m_pImpl->Clear();
1313
0
    m_aControllerMap.clear();
1314
0
    m_aCommandMap.clear();
1315
1316
0
    ToolBoxItemId nId(1), nAddonId(1000);
1317
0
    FillToolbarFromContainer( rItemContainer, m_aResourceName, nId, nAddonId );
1318
0
    m_aContextResourceName = rContextToolbarName;
1319
0
    if ( rContextData.is() )
1320
0
    {
1321
0
        m_pImpl->InsertSeparator();
1322
0
        FillToolbarFromContainer( rContextData, m_aContextResourceName, nId, nAddonId );
1323
0
    }
1324
1325
    // Request images for all toolbar items. Must be done before CreateControllers as
1326
    // some controllers need access to the image.
1327
0
    RequestImages();
1328
1329
    // Create controllers after we set the images. There are controllers which needs
1330
    // an image at the toolbar at creation time!
1331
0
    CreateControllers();
1332
1333
    // Notify controllers that they are now correctly initialized and can start listening
1334
    // toolbars that will open in popup mode will be updated immediately to avoid flickering
1335
0
    if( m_pImpl->WillUsePopupMode() )
1336
0
        UpdateControllers();
1337
0
    else if ( m_pImpl->IsReallyVisible() )
1338
0
    {
1339
0
        m_aAsyncUpdateControllersTimer.Start();
1340
0
    }
1341
1342
    // Try to retrieve UIName from the container property set and set it as the title
1343
    // if it is not empty.
1344
0
    Reference< XPropertySet > xPropSet( rItemContainer, UNO_QUERY );
1345
0
    if ( !xPropSet.is() )
1346
0
        return;
1347
1348
0
    try
1349
0
    {
1350
0
        OUString aUIName;
1351
0
        xPropSet->getPropertyValue(u"UIName"_ustr) >>= aUIName;
1352
0
        if ( !aUIName.isEmpty() )
1353
0
            m_pImpl->SetName( aUIName );
1354
0
    }
1355
0
    catch (const Exception&)
1356
0
    {
1357
0
    }
1358
0
}
1359
1360
void ToolBarManager::FillToolbarFromContainer( const Reference< XIndexAccess >& rItemContainer,
1361
                                               const OUString& rResourceName, ToolBoxItemId& nId, ToolBoxItemId& nAddonId )
1362
0
{
1363
0
    m_nContextMinPos = m_pImpl->GetItemCount();
1364
0
    CommandInfo aCmdInfo;
1365
0
    for ( sal_Int32 n = 0; n < rItemContainer->getCount(); n++ )
1366
0
    {
1367
0
        Sequence< PropertyValue >   aProps;
1368
0
        OUString                    aCommandURL;
1369
0
        OUString                    aLabel;
1370
0
        OUString                    aTooltip;
1371
0
        sal_uInt16                  nType( css::ui::ItemType::DEFAULT );
1372
0
        sal_uInt32                  nStyle( 0 );
1373
1374
0
        try
1375
0
        {
1376
0
            if ( rItemContainer->getByIndex( n ) >>= aProps )
1377
0
            {
1378
0
                bool bIsVisible( true );
1379
0
                for (PropertyValue const& prop : aProps)
1380
0
                {
1381
0
                    if ( prop.Name == ITEM_DESCRIPTOR_COMMANDURL )
1382
0
                        prop.Value >>= aCommandURL;
1383
0
                    else if ( prop.Name == "Label" )
1384
0
                        prop.Value >>= aLabel;
1385
0
                    else if ( prop.Name == "Tooltip" )
1386
0
                        prop.Value >>= aTooltip;
1387
0
                    else if ( prop.Name == "Type" )
1388
0
                        prop.Value >>= nType;
1389
0
                    else if ( prop.Name == ITEM_DESCRIPTOR_VISIBLE )
1390
0
                        prop.Value >>= bIsVisible;
1391
0
                    else if ( prop.Name == "Style" )
1392
0
                        prop.Value >>= nStyle;
1393
0
                }
1394
1395
0
                if (!aCommandURL.isEmpty() && vcl::CommandInfoProvider::IsExperimental(aCommandURL, m_aModuleIdentifier) &&
1396
0
                    !officecfg::Office::Common::Misc::ExperimentalMode::get())
1397
0
                {
1398
0
                    continue;
1399
0
                }
1400
1401
0
                if (( nType == css::ui::ItemType::DEFAULT ) && !aCommandURL.isEmpty() )
1402
0
                {
1403
0
                    auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(aCommandURL, m_aModuleIdentifier);
1404
0
                    if (!aProperties.hasElements()) // E.g., user-provided macro command?
1405
0
                        aProperties = std::move(aProps); // Use existing info, including user-provided Label
1406
1407
0
                    ToolBoxItemBits nItemBits = ConvertStyleToToolboxItemBits( nStyle );
1408
1409
0
                    if ( aTooltip.isEmpty() )
1410
0
                        aTooltip = vcl::CommandInfoProvider::GetTooltipForCommand(aCommandURL, aProperties, m_xFrame);
1411
1412
0
                    if ( aLabel.isEmpty() )
1413
0
                        aLabel = vcl::CommandInfoProvider::GetLabelForCommand(aProperties);
1414
1415
0
                    m_pImpl->InsertItem(nId, aCommandURL, aTooltip, aLabel, nItemBits);
1416
1417
                    // Fill command map. It stores all our commands and from what
1418
                    // image manager we got our image. So we can decide if we have to use an
1419
                    // image from a notification message.
1420
0
                    auto pIter = m_aCommandMap.emplace( aCommandURL, aCmdInfo );
1421
0
                    if ( pIter.second )
1422
0
                    {
1423
0
                        aCmdInfo.nId = nId;
1424
0
                        pIter.first->second.nId = nId;
1425
0
                    }
1426
0
                    else
1427
0
                    {
1428
0
                        pIter.first->second.aIds.push_back( nId );
1429
0
                    }
1430
1431
0
                    if ( !bIsVisible )
1432
0
                        m_pImpl->HideItem( nId, aCommandURL );
1433
1434
0
                    ++nId;
1435
0
                }
1436
0
                else if ( nType == css::ui::ItemType::SEPARATOR_LINE )
1437
0
                {
1438
0
                    m_pImpl->InsertSeparator();
1439
0
                }
1440
0
                else if ( nType == css::ui::ItemType::SEPARATOR_SPACE )
1441
0
                {
1442
0
                    m_pImpl->InsertSpace();
1443
0
                }
1444
0
                else if ( nType == css::ui::ItemType::SEPARATOR_LINEBREAK )
1445
0
                {
1446
0
                    m_pImpl->InsertBreak();
1447
0
                }
1448
0
            }
1449
0
        }
1450
0
        catch (const css::lang::IndexOutOfBoundsException&)
1451
0
        {
1452
0
            break;
1453
0
        }
1454
0
    }
1455
1456
    // Support add-on toolbar merging here. Working directly on the toolbar object is much
1457
    // simpler and faster.
1458
0
    MergeToolbarInstructionContainer aMergeInstructionContainer;
1459
1460
    // Retrieve the toolbar name from the resource name
1461
0
    OUString aToolbarName( rResourceName );
1462
0
    sal_Int32 nIndex = aToolbarName.lastIndexOf( '/' );
1463
0
    if (( nIndex > 0 ) && ( nIndex < aToolbarName.getLength() ))
1464
0
        aToolbarName = aToolbarName.copy( nIndex+1 );
1465
1466
0
    AddonsOptions().GetMergeToolbarInstructions( aToolbarName, aMergeInstructionContainer );
1467
1468
0
    if ( !aMergeInstructionContainer.empty() )
1469
0
    {
1470
0
        const sal_uInt32 nCount = aMergeInstructionContainer.size();
1471
0
        for ( sal_uInt32 i=0; i < nCount; i++ )
1472
0
        {
1473
0
            MergeToolbarInstruction& rInstruction = aMergeInstructionContainer[i];
1474
0
            if ( ToolBarMerger::IsCorrectContext( rInstruction.aMergeContext, m_aModuleIdentifier ))
1475
0
            {
1476
0
                m_pImpl->MergeToolbar(nAddonId, m_nContextMinPos, m_aModuleIdentifier, m_aCommandMap, rInstruction);
1477
0
            }
1478
0
        }
1479
0
    }
1480
0
}
1481
1482
void ToolBarManager::FillAddonToolbar( const Sequence< Sequence< PropertyValue > >& rAddonToolbar )
1483
0
{
1484
0
    if (!m_pToolBar)
1485
0
        return;
1486
1487
0
    SolarMutexGuard g;
1488
1489
0
    if ( m_bDisposed )
1490
0
        return;
1491
1492
0
    InitImageManager();
1493
1494
0
    RemoveControllers();
1495
1496
    // reset and fill command map
1497
0
    m_pToolBar->Clear();
1498
0
    m_aControllerMap.clear();
1499
0
    m_aCommandMap.clear();
1500
1501
0
    ToolBoxItemId nId( 1 );
1502
0
    CommandInfo aCmdInfo;
1503
0
    for ( const Sequence< PropertyValue >& rSeq : rAddonToolbar )
1504
0
    {
1505
0
        OUString   aURL;
1506
0
        OUString   aTitle;
1507
0
        OUString   aContext;
1508
0
        OUString   aTarget;
1509
0
        OUString   aControlType;
1510
0
        sal_uInt16 nWidth( 0 );
1511
1512
0
        ToolBarMerger::ConvertSequenceToValues( rSeq, aURL, aTitle, aTarget, aContext, aControlType, nWidth );
1513
1514
0
        if ( ToolBarMerger::IsCorrectContext( aContext, m_aModuleIdentifier ) )
1515
0
        {
1516
0
            if ( aURL == "private:separator" )
1517
0
            {
1518
0
                ToolBox::ImplToolItems::size_type nCount = m_pToolBar->GetItemCount();
1519
0
                if ( nCount > 0 && m_pToolBar->GetItemType( nCount-1 ) != ToolBoxItemType::SEPARATOR )
1520
0
                    m_pToolBar->InsertSeparator();
1521
0
            }
1522
0
            else
1523
0
            {
1524
0
                m_pToolBar->InsertItem( nId, aTitle, aURL );
1525
1526
0
                OUString aShortcut(vcl::CommandInfoProvider::GetCommandShortcut(aURL, m_xFrame));
1527
0
                if (!aShortcut.isEmpty())
1528
0
                    m_pToolBar->SetQuickHelpText(nId, aTitle + " (" + aShortcut + ")");
1529
1530
                // Create AddonsParams to hold additional information we will need in the future
1531
0
                AddonsParams* pRuntimeItemData = new AddonsParams;
1532
0
                pRuntimeItemData->aControlType = aControlType;
1533
0
                pRuntimeItemData->nWidth = nWidth;
1534
0
                m_pToolBar->SetItemData( nId, pRuntimeItemData );
1535
1536
                // Fill command map. It stores all our commands and from what
1537
                // image manager we got our image. So we can decide if we have to use an
1538
                // image from a notification message.
1539
0
                auto pIter = m_aCommandMap.emplace( aURL, aCmdInfo );
1540
0
                if ( pIter.second )
1541
0
                {
1542
0
                    aCmdInfo.nId = nId;
1543
0
                    pIter.first->second.nId = nId;
1544
0
                }
1545
0
                else
1546
0
                {
1547
0
                    pIter.first->second.aIds.push_back( nId );
1548
0
                }
1549
0
                ++nId;
1550
0
            }
1551
0
        }
1552
0
    }
1553
1554
    // Don't setup images yet, AddonsToolbarWrapper::populateImages does that.
1555
    // (But some controllers might need an image at the toolbar at creation time!)
1556
0
    CreateControllers();
1557
1558
    // Notify controllers that they are now correctly initialized and can start listening.
1559
0
    UpdateControllers();
1560
0
}
1561
1562
void ToolBarManager::FillOverflowToolbar( ToolBox const * pParent )
1563
0
{
1564
0
    if (!m_pToolBar)
1565
0
        return;
1566
1567
0
    CommandInfo aCmdInfo;
1568
0
    bool bInsertSeparator = false;
1569
0
    for ( ToolBox::ImplToolItems::size_type i = 0; i < pParent->GetItemCount(); ++i )
1570
0
    {
1571
0
        ToolBoxItemId nId = pParent->GetItemId( i );
1572
0
        if ( pParent->IsItemClipped( nId ) )
1573
0
        {
1574
0
            if ( bInsertSeparator )
1575
0
            {
1576
0
                m_pToolBar->InsertSeparator();
1577
0
                bInsertSeparator = false;
1578
0
            }
1579
1580
0
            const OUString aCommandURL( pParent->GetItemCommand( nId ) );
1581
0
            m_pToolBar->InsertItem( nId, pParent->GetItemText( nId ), aCommandURL );
1582
0
            m_pToolBar->SetQuickHelpText( nId, pParent->GetQuickHelpText( nId ) );
1583
1584
            // Handle possible add-on controls.
1585
0
            AddonsParams* pAddonParams = static_cast< AddonsParams* >( pParent->GetItemData( nId ) );
1586
0
            if ( pAddonParams )
1587
0
                m_pToolBar->SetItemData( nId, new AddonsParams( *pAddonParams ) );
1588
1589
            // Fill command map. It stores all our commands and from what
1590
            // image manager we got our image. So we can decide if we have to use an
1591
            // image from a notification message.
1592
0
            auto pIter = m_aCommandMap.emplace( aCommandURL, aCmdInfo );
1593
0
            if ( pIter.second )
1594
0
            {
1595
0
                aCmdInfo.nId = nId;
1596
0
                pIter.first->second.nId = nId;
1597
0
            }
1598
0
            else
1599
0
            {
1600
0
                pIter.first->second.aIds.push_back( nId );
1601
0
            }
1602
0
        }
1603
0
        else
1604
0
        {
1605
0
            ToolBoxItemType eType = pParent->GetItemType( i );
1606
0
            if ( m_pToolBar->GetItemCount() &&
1607
0
                ( eType == ToolBoxItemType::SEPARATOR || eType == ToolBoxItemType::BREAK ) )
1608
0
                bInsertSeparator = true;
1609
0
        }
1610
0
    }
1611
1612
0
    InitImageManager();
1613
1614
    // Request images for all toolbar items. Must be done before CreateControllers as
1615
    // some controllers need access to the image.
1616
0
    RequestImages();
1617
1618
    // Create controllers after we set the images. There are controllers which needs
1619
    // an image at the toolbar at creation time!
1620
0
    CreateControllers();
1621
1622
    // Notify controllers that they are now correctly initialized and can start listening
1623
    // toolbars that will open in popup mode will be updated immediately to avoid flickering
1624
0
    UpdateControllers();
1625
0
}
1626
1627
void ToolBarManager::RequestImages()
1628
0
{
1629
1630
    // Request images from image manager
1631
0
    Sequence< OUString > aCmdURLSeq( comphelper::mapKeysToSequence(m_aCommandMap) );
1632
0
    Sequence< Reference< XGraphic > > aDocGraphicSeq;
1633
0
    Sequence< Reference< XGraphic > > aModGraphicSeq;
1634
1635
0
    sal_Int16 nImageType = getCurrentImageType();
1636
1637
0
    if ( m_xDocImageManager.is() )
1638
0
        aDocGraphicSeq = m_xDocImageManager->getImages(nImageType, aCmdURLSeq);
1639
0
    aModGraphicSeq = m_xModuleImageManager->getImages(nImageType, aCmdURLSeq);
1640
1641
0
    sal_uInt32 i = 0;
1642
0
    CommandToInfoMap::iterator pIter = m_aCommandMap.begin();
1643
0
    CommandToInfoMap::iterator pEnd = m_aCommandMap.end();
1644
0
    while ( pIter != pEnd )
1645
0
    {
1646
0
        Image aImage;
1647
0
        if ( aDocGraphicSeq.hasElements() )
1648
0
            aImage = Image( aDocGraphicSeq[i] );
1649
0
        if ( !aImage )
1650
0
        {
1651
0
            aImage = Image( aModGraphicSeq[i] );
1652
            // Try also to query for add-on images before giving up and use an
1653
            // empty image.
1654
0
            if ( !aImage )
1655
0
                aImage = Image(framework::AddonsOptions().GetImageFromURL(aCmdURLSeq[i], SvtMiscOptions::AreCurrentSymbolsLarge()));
1656
1657
0
            pIter->second.nImageInfo = 1; // mark image as module based
1658
0
        }
1659
0
        else
1660
0
        {
1661
0
            pIter->second.nImageInfo = 0; // mark image as document based
1662
0
        }
1663
0
        setToolBarImage(aImage,pIter);
1664
0
        ++pIter;
1665
0
        ++i;
1666
0
    }
1667
1668
0
    assert(!m_aImageController); // an existing one isn't disposed here
1669
0
    m_aImageController = new ImageOrientationController(m_xContext, m_xFrame, m_pImpl->GetInterface(), m_aModuleIdentifier);
1670
0
    m_aImageController->update();
1671
0
}
1672
1673
void ToolBarManager::notifyRegisteredControllers( const OUString& aUIElementName, const OUString& aCommand )
1674
0
{
1675
0
    SolarMutexClearableGuard aGuard;
1676
0
    if ( m_aSubToolBarControllerMap.empty() )
1677
0
        return;
1678
1679
0
    SubToolBarToSubToolBarControllerMap::const_iterator pIter =
1680
0
        m_aSubToolBarControllerMap.find( aUIElementName );
1681
1682
0
    if ( pIter == m_aSubToolBarControllerMap.end() )
1683
0
        return;
1684
1685
0
    const SubToolBarControllerVector& rSubToolBarVector = pIter->second;
1686
0
    if ( rSubToolBarVector.empty() )
1687
0
        return;
1688
1689
0
    SubToolBarControllerVector aNotifyVector = rSubToolBarVector;
1690
0
    aGuard.clear();
1691
1692
0
    const sal_uInt32 nCount = aNotifyVector.size();
1693
0
    for ( sal_uInt32 i=0; i < nCount; i++ )
1694
0
    {
1695
0
        try
1696
0
        {
1697
0
            const Reference< XSubToolbarController >& xController = aNotifyVector[i];
1698
0
            if ( xController.is() )
1699
0
                xController->functionSelected( aCommand );
1700
0
        }
1701
0
        catch (const RuntimeException&)
1702
0
        {
1703
0
            throw;
1704
0
        }
1705
0
        catch (const Exception&)
1706
0
        {
1707
0
        }
1708
0
    }
1709
0
}
1710
1711
void ToolBarManager::HandleClick(ClickAction eClickAction)
1712
0
{
1713
0
    SolarMutexGuard g;
1714
1715
0
    if ( m_bDisposed )
1716
0
        return;
1717
1718
0
    ToolBoxItemId nId( m_pImpl->GetCurItemId() );
1719
0
    ToolBarControllerMap::const_iterator pIter = m_aControllerMap.find( nId );
1720
0
    if ( pIter == m_aControllerMap.end() )
1721
0
        return;
1722
1723
0
    Reference< XToolbarController > xController( pIter->second, UNO_QUERY );
1724
1725
0
    if ( xController.is() )
1726
0
    {
1727
0
        switch (eClickAction)
1728
0
        {
1729
0
            case ClickAction::Click:
1730
0
                xController->click();
1731
0
                break;
1732
1733
0
            case ClickAction::DblClick:
1734
0
                xController->doubleClick();
1735
0
                break;
1736
1737
0
            case ClickAction::Execute:
1738
0
                xController->execute(0);
1739
0
                break;
1740
0
        }
1741
0
    }
1742
0
}
1743
1744
void ToolBarManager::OnClick(bool bUseExecute)
1745
0
{
1746
0
    if (bUseExecute)
1747
0
        HandleClick(ClickAction::Execute);
1748
0
    else
1749
0
        HandleClick(ClickAction::Click);
1750
0
}
1751
1752
IMPL_LINK_NOARG(ToolBarManager, DropdownClick, ToolBox *, void)
1753
0
{
1754
0
    OnDropdownClick(true);
1755
0
}
1756
1757
void ToolBarManager::OnDropdownClick(bool bCreatePopupWindow)
1758
0
{
1759
0
    SolarMutexGuard g;
1760
1761
0
    if ( m_bDisposed )
1762
0
        return;
1763
1764
0
    ToolBoxItemId nId( m_pImpl->GetCurItemId() );
1765
0
    ToolBarControllerMap::const_iterator pIter = m_aControllerMap.find( nId );
1766
0
    if ( pIter == m_aControllerMap.end() )
1767
0
        return;
1768
1769
0
    Reference< XToolbarController > xController( pIter->second, UNO_QUERY );
1770
1771
0
    if ( xController.is() )
1772
0
    {
1773
0
        if (bCreatePopupWindow)
1774
0
        {
1775
0
            Reference< XWindow > xWin = xController->createPopupWindow();
1776
0
            if ( xWin.is() )
1777
0
                xWin->setFocus();
1778
0
        }
1779
0
        else
1780
0
        {
1781
0
            xController->click();
1782
0
        }
1783
0
    }
1784
0
}
1785
1786
IMPL_LINK_NOARG(ToolBarManager, DoubleClick, ToolBox *, void)
1787
0
{
1788
0
    HandleClick(ClickAction::DblClick);
1789
0
}
1790
1791
Reference< XModel > ToolBarManager::GetModelFromFrame() const
1792
0
{
1793
0
    Reference< XController > xController = m_xFrame->getController();
1794
0
    Reference< XModel > xModel;
1795
0
    if ( xController.is() )
1796
0
        xModel = xController->getModel();
1797
1798
0
    return xModel;
1799
0
}
1800
1801
bool ToolBarManager::IsPluginMode() const
1802
0
{
1803
0
    bool bPluginMode( false );
1804
1805
0
    if ( m_xFrame.is() )
1806
0
    {
1807
0
        Reference< XModel > xModel = GetModelFromFrame();
1808
0
        if ( xModel.is() )
1809
0
        {
1810
0
            Sequence< PropertyValue > aSeq = xModel->getArgs();
1811
0
            comphelper::SequenceAsHashMap aMediaDescriptor(aSeq);
1812
0
            bPluginMode = aMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_VIEWONLY, false );
1813
0
        }
1814
0
    }
1815
1816
0
    return bPluginMode;
1817
0
}
1818
1819
void ToolBarManager::AddCustomizeMenuItems(PopupMenu& rMenu)
1820
0
{
1821
0
    if (!m_pToolBar)
1822
0
        return;
1823
1824
    // No config menu entries if command ".uno:ConfigureDialog" is not enabled
1825
0
    Reference< XDispatch > xDisp;
1826
0
    css::util::URL aURL;
1827
0
    if ( m_xFrame.is() )
1828
0
    {
1829
0
        Reference< XDispatchProvider > xProv( m_xFrame, UNO_QUERY );
1830
0
        aURL.Complete = ".uno:ConfigureDialog";
1831
0
        m_xURLTransformer->parseStrict( aURL );
1832
0
        if ( xProv.is() )
1833
0
            xDisp = xProv->queryDispatch( aURL, OUString(), 0 );
1834
1835
0
        if ( !xDisp.is() || IsPluginMode() )
1836
0
            return;
1837
0
    }
1838
1839
    // popup menu for quick customization
1840
0
    bool bHideDisabledEntries = !officecfg::Office::Common::View::Menu::DontHideDisabledEntry::get();
1841
1842
    // copy all menu items 'Visible buttons, Customize toolbar, Dock toolbar,
1843
    // Dock all Toolbars) from the loaded resource into the toolbar menu
1844
0
    sal_uInt16 nGroupLen = rMenu.GetItemCount();
1845
0
    if (nGroupLen)
1846
0
        rMenu.InsertSeparator();
1847
1848
0
    VclPtr<PopupMenu> xVisibleItemsPopupMenu;
1849
1850
0
    if (!m_aResourceName.startsWith("private:resource/toolbar/addon_"))
1851
0
    {
1852
0
        rMenu.InsertItem(MENUITEM_TOOLBAR_VISIBLEBUTTON, FwkResId(STR_TOOLBAR_VISIBLE_BUTTONS));
1853
0
        xVisibleItemsPopupMenu = VclPtr<PopupMenu>::Create();
1854
0
        rMenu.SetPopupMenu(MENUITEM_TOOLBAR_VISIBLEBUTTON, xVisibleItemsPopupMenu);
1855
1856
0
        if (m_pToolBar->IsCustomize())
1857
0
        {
1858
0
            rMenu.InsertItem(MENUITEM_TOOLBAR_CUSTOMIZETOOLBAR,
1859
0
                             FwkResId(STR_TOOLBAR_CUSTOMIZE_TOOLBAR));
1860
0
            rMenu.SetItemCommand(MENUITEM_TOOLBAR_CUSTOMIZETOOLBAR,
1861
0
                                 u".uno:ConfigureToolboxVisible"_ustr);
1862
0
        }
1863
0
        rMenu.InsertSeparator();
1864
0
    }
1865
1866
0
    if (m_pToolBar->IsFloatingMode())
1867
0
    {
1868
0
        rMenu.InsertItem(MENUITEM_TOOLBAR_DOCKTOOLBAR, FwkResId(STR_TOOLBAR_DOCK_TOOLBAR));
1869
0
        rMenu.SetAccelKey(MENUITEM_TOOLBAR_DOCKTOOLBAR,
1870
0
                          vcl::KeyCode(KEY_F10, true, true, false, false));
1871
0
    }
1872
0
    else
1873
0
    {
1874
0
        rMenu.InsertItem(MENUITEM_TOOLBAR_UNDOCKTOOLBAR, FwkResId(STR_TOOLBAR_UNDOCK_TOOLBAR));
1875
0
        rMenu.SetAccelKey(MENUITEM_TOOLBAR_UNDOCKTOOLBAR,
1876
0
                          vcl::KeyCode(KEY_F10, true, true, false, false));
1877
0
    }
1878
1879
0
    rMenu.InsertItem(MENUITEM_TOOLBAR_DOCKALLTOOLBAR, FwkResId(STR_TOOLBAR_DOCK_ALL_TOOLBARS));
1880
0
    rMenu.InsertSeparator();
1881
0
    rMenu.InsertItem(MENUITEM_TOOLBAR_LOCKTOOLBARPOSITION, FwkResId(STR_TOOLBAR_LOCK_TOOLBAR),
1882
0
                     MenuItemBits::CHECKABLE);
1883
0
    rMenu.InsertItem(MENUITEM_TOOLBAR_CLOSE, FwkResId(STR_TOOLBAR_CLOSE_TOOLBAR));
1884
1885
0
    if (m_pToolBar->IsCustomize())
1886
0
    {
1887
0
        bool    bIsFloating( false );
1888
1889
0
        DockingManager* pDockMgr = vcl::Window::GetDockingManager();
1890
0
        if ( pDockMgr )
1891
0
            bIsFloating = pDockMgr->IsFloating( m_pToolBar );
1892
1893
0
        if ( !bIsFloating )
1894
0
        {
1895
0
            rMenu.EnableItem(MENUITEM_TOOLBAR_DOCKALLTOOLBAR, false);
1896
0
            Reference< XDockableWindow > xDockable( VCLUnoHelper::GetInterface( m_pToolBar ), UNO_QUERY );
1897
0
            if( xDockable.is() )
1898
0
            {
1899
0
                rMenu.CheckItem(MENUITEM_TOOLBAR_LOCKTOOLBARPOSITION, xDockable->isLocked());
1900
0
                rMenu.EnableItem(MENUITEM_TOOLBAR_UNDOCKTOOLBAR, !xDockable->isLocked());
1901
0
            }
1902
0
        }
1903
0
        else
1904
0
            rMenu.EnableItem(MENUITEM_TOOLBAR_LOCKTOOLBARPOSITION, false);
1905
1906
0
        if (officecfg::Office::Common::Misc::DisableUICustomization::get())
1907
0
        {
1908
0
            rMenu.EnableItem(MENUITEM_TOOLBAR_VISIBLEBUTTON, false);
1909
0
            rMenu.EnableItem(MENUITEM_TOOLBAR_CUSTOMIZETOOLBAR, false);
1910
0
            rMenu.EnableItem(MENUITEM_TOOLBAR_LOCKTOOLBARPOSITION, false);
1911
0
        }
1912
1913
        // Disable menu item CLOSE if the toolbar has no closer
1914
0
        if (!(m_pToolBar->GetFloatStyle() & WB_CLOSEABLE))
1915
0
            rMenu.EnableItem(MENUITEM_TOOLBAR_CLOSE, false);
1916
1917
        // Temporary stores a Command --> Url map to update contextual menu with the
1918
        // correct icons. The popup icons are by default the same as those in the
1919
        // toolbar. They are not correct for contextual popup menu.
1920
0
        std::map< OUString, Image > commandToImage;
1921
1922
0
        if (xVisibleItemsPopupMenu)
1923
0
        {
1924
            // Go through all toolbar items and add them to the context menu
1925
0
            for ( ToolBox::ImplToolItems::size_type nPos = 0; nPos < m_pToolBar->GetItemCount(); ++nPos )
1926
0
            {
1927
0
                if ( m_pToolBar->GetItemType(nPos) == ToolBoxItemType::BUTTON )
1928
0
                {
1929
0
                    ToolBoxItemId nId = m_pToolBar->GetItemId(nPos);
1930
0
                    OUString aCommandURL = m_pToolBar->GetItemCommand( nId );
1931
0
                    xVisibleItemsPopupMenu->InsertItem( STARTID_CUSTOMIZE_POPUPMENU+nPos, m_pToolBar->GetItemText( nId ), MenuItemBits::CHECKABLE );
1932
0
                    xVisibleItemsPopupMenu->CheckItem( STARTID_CUSTOMIZE_POPUPMENU+nPos, m_pToolBar->IsItemVisible( nId ) );
1933
0
                    xVisibleItemsPopupMenu->SetItemCommand( STARTID_CUSTOMIZE_POPUPMENU+nPos, aCommandURL );
1934
0
                    Image aImage(vcl::CommandInfoProvider::GetImageForCommand(aCommandURL, m_xFrame));
1935
0
                    commandToImage[aCommandURL] = aImage;
1936
0
                    xVisibleItemsPopupMenu->SetItemImage( STARTID_CUSTOMIZE_POPUPMENU+nPos, aImage );
1937
0
                    vcl::KeyCode aKeyCodeShortCut = vcl::CommandInfoProvider::GetCommandKeyCodeShortcut( aCommandURL, m_xFrame );
1938
0
                    xVisibleItemsPopupMenu->SetAccelKey( STARTID_CUSTOMIZE_POPUPMENU+nPos, aKeyCodeShortCut );
1939
0
                }
1940
0
                else
1941
0
                {
1942
0
                    xVisibleItemsPopupMenu->InsertSeparator();
1943
0
                }
1944
0
            }
1945
0
        }
1946
1947
        // Now we go through all the contextual menu to update the icons
1948
        // and accelerator key shortcuts
1949
0
        std::map< OUString, Image >::iterator it;
1950
0
        for (sal_uInt16 nPos = 0; nPos < rMenu.GetItemCount(); ++nPos)
1951
0
        {
1952
0
            sal_uInt16 nId = rMenu.GetItemId(nPos);
1953
0
            OUString cmdUrl = rMenu.GetItemCommand(nId);
1954
0
            it = commandToImage.find( cmdUrl );
1955
0
            if (it != commandToImage.end()) {
1956
0
                rMenu.SetItemImage(nId, it->second);
1957
0
            }
1958
0
            vcl::KeyCode aKeyCodeShortCut = vcl::CommandInfoProvider::GetCommandKeyCodeShortcut( cmdUrl, m_xFrame );
1959
0
            if ( aKeyCodeShortCut.GetFullCode() != 0 )
1960
0
                rMenu.SetAccelKey(nId, aKeyCodeShortCut);
1961
0
        }
1962
0
    }
1963
1964
    // Set the title of the menu
1965
0
    rMenu.SetText(m_pToolBar->GetText());
1966
1967
0
    if ( bHideDisabledEntries )
1968
0
        rMenu.RemoveDisabledEntries();
1969
0
}
1970
1971
void ToolBarManager::ToggleButton( const OUString& rResourceName, std::u16string_view rCommand )
1972
0
{
1973
0
    Reference< XLayoutManager > xLayoutManager = getLayoutManagerFromFrame( m_xFrame );
1974
0
    if ( !xLayoutManager.is() )
1975
0
        return;
1976
1977
0
    Reference< XUIElementSettings > xUIElementSettings( xLayoutManager->getElement( rResourceName ), UNO_QUERY );
1978
0
    if ( !xUIElementSettings.is() )
1979
0
        return;
1980
1981
0
    Reference< XIndexContainer > xItemContainer( xUIElementSettings->getSettings( true ), UNO_QUERY );
1982
0
    sal_Int32 nCount = xItemContainer->getCount();
1983
0
    for ( sal_Int32 i = 0; i < nCount; i++ )
1984
0
    {
1985
0
        Sequence< PropertyValue > aProp;
1986
0
        sal_Int32 nVisibleIndex( -1 );
1987
0
        OUString aCommandURL;
1988
0
        bool bVisible( false );
1989
1990
0
        if ( xItemContainer->getByIndex( i ) >>= aProp )
1991
0
        {
1992
0
            for ( sal_Int32 j = 0; j < aProp.getLength(); j++ )
1993
0
            {
1994
0
                if ( aProp[j].Name == ITEM_DESCRIPTOR_COMMANDURL )
1995
0
                {
1996
0
                    aProp[j].Value >>= aCommandURL;
1997
0
                }
1998
0
                else if ( aProp[j].Name == ITEM_DESCRIPTOR_VISIBLE )
1999
0
                {
2000
0
                    aProp[j].Value >>= bVisible;
2001
0
                    nVisibleIndex = j;
2002
0
                }
2003
0
            }
2004
2005
0
            if (( aCommandURL == rCommand ) && ( nVisibleIndex >= 0 ))
2006
0
            {
2007
                // We have found the requested item, toggle the visible flag
2008
                // and write back the configuration settings to the toolbar
2009
0
                aProp.getArray()[nVisibleIndex].Value <<= !bVisible;
2010
0
                try
2011
0
                {
2012
0
                    xItemContainer->replaceByIndex( i, Any( aProp ));
2013
0
                    xUIElementSettings->setSettings( xItemContainer );
2014
0
                    Reference< XPropertySet > xPropSet( xUIElementSettings, UNO_QUERY );
2015
0
                    if ( xPropSet.is() )
2016
0
                    {
2017
0
                        Reference< XUIConfigurationPersistence > xUICfgMgr;
2018
0
                        if (( xPropSet->getPropertyValue(u"ConfigurationSource"_ustr) >>= xUICfgMgr ) && ( xUICfgMgr.is() ))
2019
0
                            xUICfgMgr->store();
2020
0
                    }
2021
0
                }
2022
0
                catch (const Exception&)
2023
0
                {
2024
0
                }
2025
0
                break;
2026
0
            }
2027
0
        }
2028
0
    }
2029
0
}
2030
2031
IMPL_LINK( ToolBarManager, MenuButton, ToolBox*, pToolBar, void )
2032
0
{
2033
0
    SolarMutexGuard g;
2034
2035
0
    if ( m_bDisposed )
2036
0
        return;
2037
2038
0
    assert( !m_aOverflowManager.is() );
2039
2040
0
    VclPtrInstance<ToolBox> pOverflowToolBar( pToolBar, WB_BORDER | WB_SCROLL );
2041
0
    pOverflowToolBar->SetLineSpacing(true);
2042
0
    m_aOverflowManager.set( new ToolBarManager( m_xContext, m_xFrame, OUString(), pOverflowToolBar ) );
2043
0
    m_aOverflowManager->FillOverflowToolbar( pToolBar );
2044
2045
0
    ::Size aActSize( pOverflowToolBar->GetSizePixel() );
2046
0
    ::Size aSize( pOverflowToolBar->CalcWindowSizePixel() );
2047
0
    aSize.setWidth( aActSize.Width() );
2048
0
    pOverflowToolBar->SetOutputSizePixel( aSize );
2049
2050
0
    aSize = pOverflowToolBar->CalcPopupWindowSizePixel();
2051
0
    pOverflowToolBar->SetSizePixel( aSize );
2052
2053
0
    pOverflowToolBar->EnableDocking();
2054
0
    pOverflowToolBar->AddEventListener( LINK( this, ToolBarManager, OverflowEventListener ) );
2055
0
    vcl::Window::GetDockingManager()->StartPopupMode( pToolBar, pOverflowToolBar, FloatWinPopupFlags::AllMouseButtonClose );
2056
2057
    // send HOME key to subtoolbar in order to select first item if keyboard activated
2058
0
    if(pToolBar->IsKeyEvent() )
2059
0
    {
2060
0
        ::KeyEvent aEvent( 0, vcl::KeyCode( KEY_HOME ) );
2061
0
        pOverflowToolBar->KeyInput(aEvent);
2062
0
    }
2063
0
}
2064
2065
IMPL_LINK( ToolBarManager, OverflowEventListener, VclWindowEvent&, rWindowEvent, void )
2066
0
{
2067
0
    if ( rWindowEvent.GetId() != VclEventId::WindowEndPopupMode )
2068
0
        return;
2069
2070
0
    if ( m_aOverflowManager.is() )
2071
0
    {
2072
0
        m_aOverflowManager->dispose();
2073
0
        m_aOverflowManager.clear();
2074
0
    }
2075
0
}
2076
2077
IMPL_LINK(ToolBarManager, MenuPreExecute, PopupMenu&, rMenu, void)
2078
0
{
2079
0
    SolarMutexGuard g;
2080
2081
0
    if ( m_bDisposed )
2082
0
        return;
2083
2084
0
    AddCustomizeMenuItems(rMenu);
2085
0
}
2086
2087
IMPL_LINK( ToolBarManager, MenuSelect, Menu*, pMenu, bool )
2088
0
{
2089
    // We have to hold a reference to ourself as it is possible that we will be disposed and
2090
    // our refcount could be zero (destruction) otherwise.
2091
0
    rtl::Reference<ToolBarManager> pKeepAlive(this);
2092
2093
0
    {
2094
        // The guard must be in its own context as the we can get destroyed when our
2095
        // own xInterface reference get destroyed!
2096
0
        SolarMutexGuard g;
2097
2098
0
        if ( m_bDisposed )
2099
0
            return true;
2100
2101
0
        switch ( pMenu->GetCurItemId() )
2102
0
        {
2103
0
            case MENUITEM_TOOLBAR_CUSTOMIZETOOLBAR:
2104
0
            {
2105
0
                Reference< XDispatch > xDisp;
2106
0
                css::util::URL aURL;
2107
0
                if ( m_xFrame.is() )
2108
0
                {
2109
0
                    Reference< XDispatchProvider > xProv( m_xFrame, UNO_QUERY );
2110
0
                    aURL.Complete = ".uno:ConfigureDialog";
2111
0
                    m_xURLTransformer->parseStrict( aURL );
2112
0
                    if ( xProv.is() )
2113
0
                        xDisp = xProv->queryDispatch( aURL, OUString(), 0 );
2114
0
                }
2115
2116
0
                if ( xDisp.is() )
2117
0
                {
2118
0
                    Sequence< PropertyValue > aPropSeq{ comphelper::makePropertyValue(
2119
0
                        u"ResourceURL"_ustr, m_aResourceName) };
2120
2121
0
                    xDisp->dispatch( aURL, aPropSeq );
2122
0
                }
2123
0
                break;
2124
0
            }
2125
2126
0
            case MENUITEM_TOOLBAR_UNDOCKTOOLBAR:
2127
0
            {
2128
0
                ExecuteInfo* pExecuteInfo = new ExecuteInfo;
2129
2130
0
                pExecuteInfo->aToolbarResName = m_aResourceName;
2131
0
                pExecuteInfo->nCmd            = EXEC_CMD_UNDOCKTOOLBAR;
2132
0
                pExecuteInfo->xLayoutManager  = getLayoutManagerFromFrame( m_xFrame );
2133
2134
0
                Application::PostUserEvent( LINK(nullptr, ToolBarManager, ExecuteHdl_Impl), pExecuteInfo );
2135
0
                break;
2136
0
            }
2137
2138
0
            case MENUITEM_TOOLBAR_DOCKTOOLBAR:
2139
0
            {
2140
0
                ExecuteInfo* pExecuteInfo = new ExecuteInfo;
2141
2142
0
                pExecuteInfo->aToolbarResName = m_aResourceName;
2143
0
                pExecuteInfo->nCmd            = EXEC_CMD_DOCKTOOLBAR;
2144
0
                pExecuteInfo->xLayoutManager  = getLayoutManagerFromFrame( m_xFrame );
2145
2146
0
                Application::PostUserEvent( LINK(nullptr, ToolBarManager, ExecuteHdl_Impl), pExecuteInfo );
2147
0
                break;
2148
0
            }
2149
2150
0
            case MENUITEM_TOOLBAR_DOCKALLTOOLBAR:
2151
0
            {
2152
0
                ExecuteInfo* pExecuteInfo = new ExecuteInfo;
2153
2154
0
                pExecuteInfo->aToolbarResName = m_aResourceName;
2155
0
                pExecuteInfo->nCmd            = EXEC_CMD_DOCKALLTOOLBARS;
2156
0
                pExecuteInfo->xLayoutManager  = getLayoutManagerFromFrame( m_xFrame );
2157
2158
0
                Application::PostUserEvent( LINK(nullptr, ToolBarManager, ExecuteHdl_Impl), pExecuteInfo );
2159
0
                break;
2160
0
            }
2161
2162
0
            case MENUITEM_TOOLBAR_LOCKTOOLBARPOSITION:
2163
0
            {
2164
0
                Reference< XLayoutManager > xLayoutManager = getLayoutManagerFromFrame( m_xFrame );
2165
0
                if ( xLayoutManager.is() )
2166
0
                {
2167
0
                    Reference< XDockableWindow > xDockable( VCLUnoHelper::GetInterface( m_pToolBar ), UNO_QUERY );
2168
2169
0
                    if( xDockable->isLocked() )
2170
0
                        xLayoutManager->unlockWindow( m_aResourceName );
2171
0
                    else
2172
0
                        xLayoutManager->lockWindow( m_aResourceName );
2173
0
                }
2174
0
                break;
2175
0
            }
2176
2177
0
            case MENUITEM_TOOLBAR_CLOSE:
2178
0
            {
2179
0
                ExecuteInfo* pExecuteInfo = new ExecuteInfo;
2180
2181
0
                pExecuteInfo->aToolbarResName = m_aResourceName;
2182
0
                pExecuteInfo->nCmd            = EXEC_CMD_CLOSETOOLBAR;
2183
0
                pExecuteInfo->xLayoutManager  = getLayoutManagerFromFrame( m_xFrame );
2184
0
                pExecuteInfo->xWindow         = VCLUnoHelper::GetInterface( m_pToolBar );
2185
2186
0
                Application::PostUserEvent( LINK(nullptr, ToolBarManager, ExecuteHdl_Impl), pExecuteInfo );
2187
0
                break;
2188
0
            }
2189
2190
0
            default:
2191
0
            {
2192
0
                sal_uInt16 nId = pMenu->GetCurItemId();
2193
0
                if(( nId > 0 ) && ( nId < TOOLBOX_MENUITEM_START ))
2194
                // Items in the "enable/disable" sub-menu
2195
0
                {
2196
                    // toggle toolbar button visibility
2197
0
                    OUString aCommand = pMenu->GetItemCommand( nId );
2198
0
                    if (m_aContextResourceName.isEmpty() ||
2199
0
                        nId - STARTID_CUSTOMIZE_POPUPMENU < m_nContextMinPos)
2200
0
                        ToggleButton(m_aResourceName, aCommand);
2201
0
                    else
2202
0
                        ToggleButton(m_aContextResourceName, aCommand);
2203
0
                }
2204
0
                break;
2205
0
            }
2206
0
        }
2207
0
    }
2208
2209
0
    return true;
2210
0
}
2211
2212
IMPL_LINK_NOARG(ToolBarManager, Select, ToolBox *, void)
2213
0
{
2214
0
    if ( m_bDisposed )
2215
0
        return;
2216
2217
0
    sal_Int16   nKeyModifier( static_cast<sal_Int16>(m_pToolBar->GetModifier()) );
2218
0
    ToolBoxItemId nId( m_pToolBar->GetCurItemId() );
2219
2220
0
    ToolBarControllerMap::const_iterator pIter = m_aControllerMap.find( nId );
2221
0
    if ( pIter != m_aControllerMap.end() )
2222
0
    {
2223
0
        Reference< XToolbarController > xController( pIter->second, UNO_QUERY );
2224
2225
0
        if ( xController.is() )
2226
0
            xController->execute( nKeyModifier );
2227
0
    }
2228
0
}
2229
2230
IMPL_LINK( ToolBarManager, StateChanged, StateChangedType const *, pStateChangedType, void )
2231
0
{
2232
0
    if ( m_bDisposed )
2233
0
        return;
2234
2235
0
    if ( *pStateChangedType == StateChangedType::ControlBackground )
2236
0
    {
2237
0
        CheckAndUpdateImages();
2238
0
    }
2239
0
    else if ( *pStateChangedType == StateChangedType::Visible )
2240
0
    {
2241
0
        if ( m_pToolBar->IsReallyVisible() )
2242
0
        {
2243
0
            m_aAsyncUpdateControllersTimer.Start();
2244
0
        }
2245
0
    }
2246
0
    else if ( *pStateChangedType == StateChangedType::InitShow )
2247
0
    {
2248
0
        m_aAsyncUpdateControllersTimer.Start();
2249
0
    }
2250
0
}
2251
2252
IMPL_LINK( ToolBarManager, DataChanged, DataChangedEvent const *, pDataChangedEvent, void )
2253
0
{
2254
0
    if ((( pDataChangedEvent->GetType() == DataChangedEventType::SETTINGS )   ||
2255
0
        (  pDataChangedEvent->GetType() == DataChangedEventType::DISPLAY  ))  &&
2256
0
        ( pDataChangedEvent->GetFlags() & AllSettingsFlags::STYLE        ))
2257
0
    {
2258
0
        CheckAndUpdateImages();
2259
0
    }
2260
2261
0
    for ( ToolBox::ImplToolItems::size_type nPos = 0; nPos < m_pToolBar->GetItemCount(); ++nPos )
2262
0
    {
2263
0
        const ToolBoxItemId nId = m_pToolBar->GetItemId(nPos);
2264
0
        vcl::Window* pWindow = m_pToolBar->GetItemWindow( nId );
2265
0
        if ( pWindow )
2266
0
        {
2267
0
            const DataChangedEvent& rDCEvt( *pDataChangedEvent );
2268
0
            pWindow->DataChanged( rDCEvt );
2269
0
        }
2270
0
    }
2271
2272
0
    if ( !m_pToolBar->IsFloatingMode() &&
2273
0
         m_pToolBar->IsVisible() )
2274
0
    {
2275
        // Resize toolbar, layout manager is resize listener and will calc
2276
        // the layout automatically.
2277
0
        ::Size aSize( m_pToolBar->CalcWindowSizePixel() );
2278
0
        m_pToolBar->SetOutputSizePixel( aSize );
2279
0
    }
2280
0
}
2281
2282
IMPL_LINK_NOARG(ToolBarManager, MiscOptionsChanged, LinkParamNone*, void)
2283
0
{
2284
0
    CheckAndUpdateImages();
2285
0
}
2286
2287
IMPL_LINK_NOARG(ToolBarManager, AsyncUpdateControllersHdl, Timer *, void)
2288
0
{
2289
    // The guard must be in its own context as the we can get destroyed when our
2290
    // own xInterface reference get destroyed!
2291
0
    Reference< XComponent > xThis(this);
2292
2293
0
    SolarMutexGuard g;
2294
2295
0
    if ( m_bDisposed )
2296
0
        return;
2297
2298
    // Request to update our controllers
2299
0
    m_aAsyncUpdateControllersTimer.Stop();
2300
0
    UpdateControllers();
2301
0
}
2302
2303
IMPL_STATIC_LINK( ToolBarManager, ExecuteHdl_Impl, void*, p, void )
2304
0
{
2305
0
    ExecuteInfo* pExecuteInfo = static_cast<ExecuteInfo*>(p);
2306
0
    try
2307
0
    {
2308
        // Asynchronous execution as this can lead to our own destruction!
2309
0
        if (( pExecuteInfo->nCmd == EXEC_CMD_CLOSETOOLBAR ) &&
2310
0
            ( pExecuteInfo->xLayoutManager.is() ) &&
2311
0
            ( pExecuteInfo->xWindow.is() ))
2312
0
        {
2313
            // Use docking window close to close the toolbar. The toolbar layout manager is
2314
            // listener and will react correctly according to the context sensitive
2315
            // flag of our toolbar.
2316
0
            VclPtr<vcl::Window> pWin = VCLUnoHelper::GetWindow( pExecuteInfo->xWindow );
2317
0
            DockingWindow* pDockWin = dynamic_cast< DockingWindow* >( pWin.get() );
2318
0
            if ( pDockWin )
2319
0
                pDockWin->Close();
2320
0
        }
2321
0
        else if (( pExecuteInfo->nCmd == EXEC_CMD_UNDOCKTOOLBAR ) &&
2322
0
                 ( pExecuteInfo->xLayoutManager.is() ))
2323
0
        {
2324
0
            pExecuteInfo->xLayoutManager->floatWindow( pExecuteInfo->aToolbarResName );
2325
0
        }
2326
0
        else if (( pExecuteInfo->nCmd == EXEC_CMD_DOCKTOOLBAR ) &&
2327
0
                 ( pExecuteInfo->xLayoutManager.is() ))
2328
0
        {
2329
0
            css::awt::Point aPoint;
2330
0
            aPoint.X = aPoint.Y = SAL_MAX_INT32;
2331
0
            pExecuteInfo->xLayoutManager->dockWindow( pExecuteInfo->aToolbarResName,
2332
0
                                                      DockingArea_DOCKINGAREA_DEFAULT,
2333
0
                                                      aPoint );
2334
0
        }
2335
0
        else if (( pExecuteInfo->nCmd == EXEC_CMD_DOCKALLTOOLBARS ) &&
2336
0
                 ( pExecuteInfo->xLayoutManager.is() ))
2337
0
        {
2338
0
            pExecuteInfo->xLayoutManager->dockAllWindows( UIElementType::TOOLBAR );
2339
0
        }
2340
0
    }
2341
0
    catch (const Exception&)
2342
0
    {
2343
0
    }
2344
2345
0
    delete pExecuteInfo;
2346
0
}
2347
}
2348
2349
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */