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/resourcemenucontroller.cxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
11
 *   Licensed to the Apache Software Foundation (ASF) under one or more
12
 *   contributor license agreements. See the NOTICE file distributed
13
 *   with this work for additional information regarding copyright
14
 *   ownership. The ASF licenses this file to you under the Apache
15
 *   License, Version 2.0 (the "License"); you may not use this file
16
 *   except in compliance with the License. You may obtain a copy of
17
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18
 */
19
20
#include <uielement/menubarmanager.hxx>
21
22
#include <cppuhelper/implbase.hxx>
23
#include <svtools/popupmenucontrollerbase.hxx>
24
#include <toolkit/awt/vclxmenu.hxx>
25
#include <toolkit/helper/vclunohelper.hxx>
26
#include <vcl/svapp.hxx>
27
#include <vcl/window.hxx>
28
#include <sal/log.hxx>
29
30
#include <com/sun/star/embed/VerbAttributes.hpp>
31
#include <com/sun/star/embed/VerbDescriptor.hpp>
32
#include <com/sun/star/frame/Desktop.hpp>
33
#include <com/sun/star/frame/ModuleManager.hpp>
34
#include <com/sun/star/frame/XStorable.hpp>
35
#include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
36
#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
37
#include <com/sun/star/util/URL.hpp>
38
39
namespace {
40
41
class ResourceMenuController : public cppu::ImplInheritanceHelper< svt::PopupMenuControllerBase, css::ui::XUIConfigurationListener >
42
{
43
public:
44
    ResourceMenuController( const css::uno::Reference< css::uno::XComponentContext >& rxContext,
45
                            const css::uno::Sequence< css::uno::Any >& rxArgs, bool bToolbarContainer );
46
47
    // XPopupMenuController
48
    virtual void SAL_CALL updatePopupMenu() override;
49
50
    // XStatusListener
51
    virtual void SAL_CALL statusChanged( const css::frame::FeatureStateEvent& rEvent ) override;
52
53
    // XEventListener
54
    virtual void SAL_CALL disposing( const css::lang::EventObject& rEvent ) override;
55
56
    // XUIConfigurationListener
57
    virtual void SAL_CALL elementInserted( const css::ui::ConfigurationEvent& rEvent ) override;
58
    virtual void SAL_CALL elementRemoved( const css::ui::ConfigurationEvent& rEvent ) override;
59
    virtual void SAL_CALL elementReplaced( const css::ui::ConfigurationEvent& rEvent ) override;
60
61
    // XMenuListener
62
    virtual void SAL_CALL itemActivated( const css::awt::MenuEvent& rEvent ) override;
63
    virtual void SAL_CALL itemSelected( const css::awt::MenuEvent& rEvent ) override;
64
65
    // XServiceInfo
66
    virtual OUString SAL_CALL getImplementationName() override;
67
    virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
68
69
private:
70
    OUString m_aMenuURL;
71
    bool m_bContextMenu;
72
    bool m_bInToolbar;
73
    bool m_bToolbarContainer;
74
    sal_uInt16 m_nNewMenuId;
75
    rtl::Reference< framework::MenuBarManager > m_xMenuBarManager;
76
    css::uno::Reference< css::frame::XDispatchProvider > m_xDispatchProvider;
77
    css::uno::Reference< css::container::XIndexAccess > m_xMenuContainer;
78
    css::uno::Reference< css::ui::XUIConfigurationManager > m_xConfigManager, m_xModuleConfigManager;
79
    void addVerbs( const css::uno::Sequence< css::embed::VerbDescriptor >& rVerbs );
80
    virtual void disposing(std::unique_lock<std::mutex>& rGuard) override;
81
82
protected:
83
    css::uno::Reference< css::uno::XComponentContext > m_xContext;
84
};
85
86
ResourceMenuController::ResourceMenuController( const css::uno::Reference< css::uno::XComponentContext >& rxContext,
87
                                                const css::uno::Sequence< css::uno::Any >& rxArgs, bool bToolbarContainer ) :
88
0
    ImplInheritanceHelper( rxContext ),
89
0
    m_bContextMenu( false ),
90
0
    m_bInToolbar( false ),
91
0
    m_bToolbarContainer( bToolbarContainer ),
92
0
    m_nNewMenuId( 1 ),
93
0
    m_xContext( rxContext )
94
0
{
95
0
    for ( const auto& arg: rxArgs )
96
0
    {
97
0
        css::beans::PropertyValue aPropValue;
98
0
        if ( arg >>= aPropValue )
99
0
        {
100
0
            if ( aPropValue.Name == "Value" )
101
0
            {
102
0
                OUString aMenuName;
103
0
                aPropValue.Value >>= aMenuName;
104
0
                if ( aMenuName.isEmpty() )
105
0
                    continue;
106
107
0
                if ( m_bToolbarContainer )
108
0
                    m_aMenuURL = "private:resource/toolbar/" + aMenuName;
109
0
                else
110
0
                    m_aMenuURL = "private:resource/popupmenu/" + aMenuName;
111
0
            }
112
0
            else if ( aPropValue.Name == "ResourceURL" )
113
0
                aPropValue.Value >>= m_aMenuURL;
114
0
            else if ( aPropValue.Name == "Frame" )
115
0
                aPropValue.Value >>= m_xFrame;
116
0
            else if ( aPropValue.Name == "ModuleIdentifier" )
117
0
                aPropValue.Value >>= m_aModuleName;
118
0
            else if ( aPropValue.Name == "DispatchProvider" )
119
0
                aPropValue.Value >>= m_xDispatchProvider;
120
0
            else if ( aPropValue.Name == "IsContextMenu" )
121
0
                aPropValue.Value >>= m_bContextMenu;
122
0
            else if ( aPropValue.Name == "InToolbar" )
123
0
                aPropValue.Value >>= m_bInToolbar;
124
0
        }
125
0
    }
126
0
    if ( m_xFrame.is() )
127
        // No need to initialize again through initialize method.
128
0
        m_bInitialized = true;
129
0
}
Unexecuted instantiation: resourcemenucontroller.cxx:(anonymous namespace)::ResourceMenuController::ResourceMenuController(com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext> const&, com::sun::star::uno::Sequence<com::sun::star::uno::Any> const&, bool)
Unexecuted instantiation: resourcemenucontroller.cxx:(anonymous namespace)::ResourceMenuController::ResourceMenuController(com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext> const&, com::sun::star::uno::Sequence<com::sun::star::uno::Any> const&, bool)
130
131
void ResourceMenuController::updatePopupMenu()
132
0
{
133
0
    if ( ( m_xMenuContainer.is() && !m_bContextMenu ) || m_aMenuURL.isEmpty() )
134
0
        return;
135
136
0
    if ( m_aModuleName.isEmpty() )
137
0
    {
138
0
        try
139
0
        {
140
0
            css::uno::Reference< css::frame::XModuleManager > xModuleManager( css::frame::ModuleManager::create( m_xContext ) );
141
0
            m_aModuleName = xModuleManager->identify( m_xFrame );
142
0
        }
143
0
        catch( const css::uno::Exception& )
144
0
        {}
145
0
    }
146
147
0
    if ( !m_xConfigManager.is() )
148
0
    {
149
0
        try
150
0
        {
151
0
            css::uno::Reference< css::frame::XController > xController( m_xFrame->getController() );
152
0
            css::uno::Reference< css::frame::XModel > xModel( xController->getModel() );
153
0
            css::uno::Reference< css::ui::XUIConfigurationManagerSupplier > xSupplier( xModel, css::uno::UNO_QUERY_THROW );
154
0
            m_xConfigManager.set( xSupplier->getUIConfigurationManager() );
155
0
            css::uno::Reference< css::ui::XUIConfiguration > xConfig( m_xConfigManager, css::uno::UNO_QUERY_THROW );
156
0
            xConfig->addConfigurationListener( this );
157
0
        }
158
0
        catch( const css::uno::RuntimeException& )
159
0
        {}
160
0
    }
161
162
0
    if ( !m_xModuleConfigManager.is() )
163
0
    {
164
0
        try
165
0
        {
166
0
            css::uno::Reference< css::ui::XModuleUIConfigurationManagerSupplier > xModuleCfgMgrSupplier(
167
0
                css::ui::theModuleUIConfigurationManagerSupplier::get( m_xContext ) );
168
0
            m_xModuleConfigManager.set( xModuleCfgMgrSupplier->getUIConfigurationManager( m_aModuleName ) );
169
0
            css::uno::Reference< css::ui::XUIConfiguration > xConfig( m_xModuleConfigManager, css::uno::UNO_QUERY_THROW );
170
0
            xConfig->addConfigurationListener( this );
171
0
        }
172
0
        catch ( const css::container::NoSuchElementException& )
173
0
        {
174
0
            SAL_WARN( "fwk.uielement", "Invalid module identifier: " << m_aModuleName );
175
0
        }
176
0
        catch( const css::uno::RuntimeException& )
177
0
        {}
178
0
    }
179
180
0
    if ( !m_xMenuContainer.is() && m_xConfigManager.is() )
181
0
    {
182
0
        try
183
0
        {
184
0
            m_xMenuContainer.set( m_xConfigManager->getSettings( m_aMenuURL, false ) );
185
0
        }
186
0
        catch ( const css::container::NoSuchElementException& )
187
0
        {
188
            // Not an error - element may exist only in the module.
189
0
        }
190
0
        catch ( const css::lang::IllegalArgumentException& )
191
0
        {
192
0
            SAL_WARN( "fwk.uielement", "The given URL is not valid: " << m_aMenuURL );
193
0
            return;
194
0
        }
195
0
    }
196
197
0
    if ( !m_xMenuContainer.is() && m_xModuleConfigManager.is() )
198
0
    {
199
0
        try
200
0
        {
201
0
            m_xMenuContainer.set( m_xModuleConfigManager->getSettings( m_aMenuURL, false ) );
202
0
        }
203
0
        catch ( const css::container::NoSuchElementException& )
204
0
        {
205
0
            SAL_WARN( "fwk.uielement", "Can not find settings for " << m_aMenuURL );
206
0
            return;
207
0
        }
208
0
        catch ( const css::lang::IllegalArgumentException& )
209
0
        {
210
0
            SAL_WARN( "fwk.uielement", "The given URL is not valid: " << m_aMenuURL );
211
0
            return;
212
0
        }
213
0
    }
214
215
0
    if ( !m_xMenuContainer.is() )
216
0
        return;
217
218
    // Clear previous content.
219
0
    if ( m_xMenuBarManager.is() )
220
0
    {
221
0
        m_xMenuBarManager->dispose();
222
0
        m_xMenuBarManager.clear();
223
0
    }
224
0
    resetPopupMenu( m_xPopupMenu );
225
0
    m_nNewMenuId = 1;
226
227
    // Now fill the menu with the configuration data.
228
0
    framework::MenuBarManager::FillMenu( m_nNewMenuId, m_xPopupMenu->GetMenu(), m_aModuleName, m_xMenuContainer, m_xDispatchProvider );
229
230
    // For context menus, add object verbs.
231
0
    if ( !m_bContextMenu )
232
0
        return;
233
234
0
    css::util::URL aObjectMenuURL;
235
0
    aObjectMenuURL.Complete = ".uno:ObjectMenue";
236
0
    m_xURLTransformer->parseStrict( aObjectMenuURL );
237
0
    css::uno::Reference< css::frame::XDispatchProvider > xDispatchProvider( m_xFrame, css::uno::UNO_QUERY );
238
0
    css::uno::Reference< css::frame::XDispatch > xDispatch( xDispatchProvider->queryDispatch( aObjectMenuURL, OUString(), 0 ) );
239
0
    if ( xDispatch.is() )
240
0
    {
241
0
        xDispatch->addStatusListener( this, aObjectMenuURL );
242
0
        xDispatch->removeStatusListener( this, aObjectMenuURL );
243
0
    }
244
0
}
245
246
void ResourceMenuController::statusChanged( const css::frame::FeatureStateEvent& rEvent )
247
0
{
248
0
    css::uno::Sequence< css::embed::VerbDescriptor > aVerbs;
249
0
    if ( rEvent.IsEnabled && ( rEvent.State >>= aVerbs ) )
250
0
        addVerbs( aVerbs );
251
0
}
252
253
void ResourceMenuController::addVerbs( const css::uno::Sequence< css::embed::VerbDescriptor >& rVerbs )
254
0
{
255
    // Check if the document is read-only.
256
0
    css::uno::Reference< css::frame::XController > xController( m_xFrame->getController() );
257
0
    css::uno::Reference< css::frame::XStorable > xStorable;
258
0
    if ( xController.is() )
259
0
        xStorable.set( xController->getModel(), css::uno::UNO_QUERY );
260
261
0
    bool bReadOnly = xStorable.is() && xStorable->isReadonly();
262
0
    Menu* pVCLMenu = m_xPopupMenu->GetMenu();
263
264
0
    for ( const auto& rVerb : rVerbs )
265
0
    {
266
0
        if ( !( rVerb.VerbAttributes & css::embed::VerbAttributes::MS_VERBATTR_ONCONTAINERMENU ) ||
267
0
            ( bReadOnly && !( rVerb.VerbAttributes & css::embed::VerbAttributes::MS_VERBATTR_NEVERDIRTIES ) ) )
268
0
            continue;
269
270
0
        pVCLMenu->InsertItem( m_nNewMenuId, rVerb.VerbName );
271
0
        pVCLMenu->SetItemCommand( m_nNewMenuId, ".uno:ObjectMenue?VerbID:short=" + OUString::number( rVerb.VerbID ) );
272
0
        ++m_nNewMenuId;
273
0
    }
274
0
}
275
276
void ResourceMenuController::itemActivated( const css::awt::MenuEvent& /*rEvent*/ )
277
0
{
278
    // Must initialize MenuBarManager here, because we want to let the app do context menu interception before.
279
0
    if ( !m_xMenuBarManager.is() )
280
0
    {
281
0
        m_xMenuBarManager.set( new framework::MenuBarManager(
282
0
            m_xContext, m_xFrame, m_xURLTransformer, m_xDispatchProvider, m_aModuleName, m_xPopupMenu->GetMenu(), false, !m_bContextMenu && !m_bInToolbar ) );
283
0
        m_xFrame->addFrameActionListener( m_xMenuBarManager );
284
0
    }
285
0
}
286
287
void ResourceMenuController::itemSelected( const css::awt::MenuEvent& /*rEvent*/ )
288
0
{
289
    // Must override this, because we are managed by MenuBarManager, so don't want the handler found in the base class.
290
0
}
291
292
void ResourceMenuController::elementInserted( const css::ui::ConfigurationEvent& rEvent )
293
0
{
294
0
    if ( rEvent.ResourceURL == m_aMenuURL )
295
0
        m_xMenuContainer.clear();
296
0
}
297
298
void ResourceMenuController::elementRemoved( const css::ui::ConfigurationEvent& rEvent )
299
0
{
300
0
    elementInserted( rEvent );
301
0
}
302
303
void ResourceMenuController::elementReplaced( const css::ui::ConfigurationEvent& rEvent )
304
0
{
305
0
    elementInserted( rEvent );
306
0
}
307
308
void ResourceMenuController::disposing( const css::lang::EventObject& rEvent )
309
0
{
310
0
    if ( rEvent.Source == m_xConfigManager )
311
0
        m_xConfigManager.clear();
312
0
    else if ( rEvent.Source == m_xModuleConfigManager )
313
0
        m_xModuleConfigManager.clear();
314
0
    else
315
0
    {
316
0
        if ( m_xMenuBarManager.is() )
317
0
        {
318
0
            if (m_xFrame.is())
319
0
                m_xFrame->removeFrameActionListener( m_xMenuBarManager );
320
321
0
            m_xMenuBarManager->dispose();
322
0
            m_xMenuBarManager.clear();
323
0
        }
324
0
        svt::PopupMenuControllerBase::disposing( rEvent );
325
0
    }
326
0
}
327
328
void ResourceMenuController::disposing(std::unique_lock<std::mutex>& rGuard)
329
0
{
330
0
    css::uno::Reference< css::ui::XUIConfiguration > xConfig( m_xConfigManager, css::uno::UNO_QUERY );
331
0
    if ( xConfig.is() )
332
0
        xConfig->removeConfigurationListener( this );
333
334
0
    css::uno::Reference< css::ui::XUIConfiguration > xModuleConfig( m_xModuleConfigManager, css::uno::UNO_QUERY );
335
0
    if ( xModuleConfig.is() )
336
0
        xModuleConfig->removeConfigurationListener( this );
337
338
0
    m_xConfigManager.clear();
339
0
    m_xModuleConfigManager.clear();
340
0
    m_xMenuContainer.clear();
341
0
    m_xDispatchProvider.clear();
342
0
    if ( m_xMenuBarManager.is() )
343
0
    {
344
0
        if (m_xFrame.is())
345
0
            m_xFrame->removeFrameActionListener( m_xMenuBarManager );
346
347
0
        m_xMenuBarManager->dispose();
348
0
        m_xMenuBarManager.clear();
349
0
    }
350
351
0
    svt::PopupMenuControllerBase::disposing(rGuard);
352
0
}
353
354
OUString ResourceMenuController::getImplementationName()
355
0
{
356
0
    if ( m_bToolbarContainer )
357
0
        return u"com.sun.star.comp.framework.ToolbarAsMenuController"_ustr;
358
359
0
    return u"com.sun.star.comp.framework.ResourceMenuController"_ustr;
360
0
}
361
362
css::uno::Sequence< OUString > ResourceMenuController::getSupportedServiceNames()
363
0
{
364
0
    return { u"com.sun.star.frame.PopupMenuController"_ustr };
365
0
}
366
367
class SaveAsMenuController : public ResourceMenuController
368
{
369
public:
370
    SaveAsMenuController( const css::uno::Reference< css::uno::XComponentContext >& rContext,
371
                          const css::uno::Sequence< css::uno::Any >& rArgs );
372
373
    // XServiceInfo
374
    virtual OUString SAL_CALL getImplementationName() override;
375
376
private:
377
    virtual void impl_setPopupMenu(std::unique_lock<std::mutex>& rGuard) override;
378
};
379
380
SaveAsMenuController::SaveAsMenuController( const css::uno::Reference< css::uno::XComponentContext >& rContext,
381
                                            const css::uno::Sequence< css::uno::Any >& rArgs )
382
0
    : ResourceMenuController( rContext, rArgs, false )
383
0
{
384
0
}
385
386
void InsertItem(const css::uno::Reference<css::awt::XPopupMenu>& rPopupMenu,
387
                const OUString& rCommand)
388
0
{
389
0
    sal_uInt16 nItemId = rPopupMenu->getItemCount() + 1;
390
0
    rPopupMenu->insertItem(nItemId, OUString(), 0, -1);
391
0
    rPopupMenu->setCommand(nItemId, rCommand);
392
0
}
393
394
void SaveAsMenuController::impl_setPopupMenu(std::unique_lock<std::mutex>& /*rGuard*/)
395
0
{
396
0
    SolarMutexGuard aGuard;
397
398
0
    InsertItem(m_xPopupMenu, u".uno:SaveAs"_ustr);
399
0
    InsertItem(m_xPopupMenu, u".uno:ExportTo"_ustr);
400
0
    InsertItem(m_xPopupMenu, u".uno:SaveACopy"_ustr);
401
0
    InsertItem(m_xPopupMenu, u".uno:SaveAsTemplate"_ustr);
402
0
    m_xPopupMenu->insertSeparator(-1);
403
0
    InsertItem(m_xPopupMenu, u".uno:SaveAsRemote"_ustr);
404
0
}
405
406
OUString SaveAsMenuController::getImplementationName()
407
0
{
408
0
    return u"com.sun.star.comp.framework.SaveAsMenuController"_ustr;
409
0
}
410
411
class WindowListMenuController : public ResourceMenuController
412
{
413
public:
414
    WindowListMenuController( const css::uno::Reference< css::uno::XComponentContext >& rxContext,
415
                              const css::uno::Sequence< css::uno::Any >& rxArgs )
416
0
        : ResourceMenuController(rxContext, rxArgs, false) {}
417
418
    // XMenuListener
419
    void SAL_CALL itemActivated( const css::awt::MenuEvent& rEvent ) override;
420
    void SAL_CALL itemSelected( const css::awt::MenuEvent& rEvent ) override;
421
422
    // XServiceInfo
423
    OUString SAL_CALL getImplementationName() override;
424
425
private:
426
    void impl_setPopupMenu(std::unique_lock<std::mutex>& /*rGuard*/) override;
427
};
428
429
constexpr sal_uInt16 START_ITEMID_WINDOWLIST    = 4600;
430
constexpr sal_uInt16 END_ITEMID_WINDOWLIST      = 4699;
431
432
void WindowListMenuController::itemActivated( const css::awt::MenuEvent& rEvent )
433
0
{
434
0
    ResourceMenuController::itemActivated( rEvent );
435
436
    // update window list
437
0
    ::std::vector< OUString > aNewWindowListVector;
438
439
0
    css::uno::Reference< css::frame::XDesktop2 > xDesktop = css::frame::Desktop::create( m_xContext );
440
441
0
    sal_uInt16  nActiveItemId = 0;
442
0
    sal_uInt16  nItemId = START_ITEMID_WINDOWLIST;
443
444
0
    css::uno::Reference< css::frame::XFrame > xCurrentFrame = xDesktop->getCurrentFrame();
445
0
    css::uno::Reference< css::container::XIndexAccess > xList = xDesktop->getFrames();
446
0
    sal_Int32 nFrameCount = xList->getCount();
447
0
    aNewWindowListVector.reserve(nFrameCount);
448
0
    for (sal_Int32 i=0; i<nFrameCount; ++i )
449
0
    {
450
0
        css::uno::Reference< css::frame::XFrame > xFrame;
451
0
        xList->getByIndex(i) >>= xFrame;
452
453
0
        if (xFrame.is())
454
0
        {
455
0
            if ( xFrame == xCurrentFrame )
456
0
                nActiveItemId = nItemId;
457
458
0
            VclPtr<vcl::Window> pWin = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() );
459
0
            OUString sWindowTitle;
460
0
            if ( pWin && pWin->IsVisible() )
461
0
                sWindowTitle = pWin->GetText();
462
463
            // tdf#101658 In case the frame is embedded somewhere, LO has no control over it.
464
            // So we just skip it.
465
0
            if ( sWindowTitle.isEmpty() )
466
0
                continue;
467
468
0
            aNewWindowListVector.push_back( sWindowTitle );
469
0
            ++nItemId;
470
0
        }
471
0
    }
472
473
0
    {
474
0
        SolarMutexGuard g;
475
476
0
        Menu* pVCLMenu = m_xPopupMenu->GetMenu();
477
0
        int nItemCount = pVCLMenu->GetItemCount();
478
479
0
        if ( nItemCount > 0 )
480
0
        {
481
            // remove all old window list entries from menu
482
0
            sal_uInt16 nPos = pVCLMenu->GetItemPos( START_ITEMID_WINDOWLIST );
483
0
            for ( sal_uInt16 n = nPos; n < pVCLMenu->GetItemCount(); )
484
0
                pVCLMenu->RemoveItem( n );
485
486
0
            if ( pVCLMenu->GetItemType( pVCLMenu->GetItemCount()-1 ) == MenuItemType::SEPARATOR )
487
0
                pVCLMenu->RemoveItem( pVCLMenu->GetItemCount()-1 );
488
0
        }
489
490
0
        if ( !aNewWindowListVector.empty() )
491
0
        {
492
            // append new window list entries to menu
493
0
            pVCLMenu->InsertSeparator();
494
0
            nItemId = START_ITEMID_WINDOWLIST;
495
0
            const sal_uInt32 nCount = aNewWindowListVector.size();
496
0
            for ( sal_uInt32 i = 0; i < nCount; i++ )
497
0
            {
498
0
                pVCLMenu->InsertItem( nItemId, aNewWindowListVector.at( i ), MenuItemBits::RADIOCHECK );
499
0
                pVCLMenu->SetHelpId( nItemId, u"HID_WINDOW_DOC_LIST"_ustr );
500
0
                if ( nItemId == nActiveItemId )
501
0
                    pVCLMenu->CheckItem( nItemId );
502
0
                ++nItemId;
503
0
            }
504
0
        }
505
0
    }
506
0
}
507
508
void WindowListMenuController::itemSelected( const css::awt::MenuEvent& rEvent )
509
0
{
510
0
    if ( rEvent.MenuId < START_ITEMID_WINDOWLIST || rEvent.MenuId > END_ITEMID_WINDOWLIST )
511
0
        return;
512
513
    // window list menu item selected
514
0
    css::uno::Reference< css::frame::XDesktop2 > xDesktop = css::frame::Desktop::create( m_xContext );
515
516
0
    sal_uInt16 nTaskId = START_ITEMID_WINDOWLIST;
517
0
    css::uno::Reference< css::container::XIndexAccess > xList = xDesktop->getFrames();
518
0
    sal_Int32 nCount = xList->getCount();
519
0
    for ( sal_Int32 i=0; i<nCount; ++i )
520
0
    {
521
0
        css::uno::Reference< css::frame::XFrame > xFrame;
522
0
        xList->getByIndex(i) >>= xFrame;
523
0
        if ( xFrame.is() && nTaskId == rEvent.MenuId )
524
0
        {
525
0
            VclPtr<vcl::Window> pWin = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() );
526
0
            pWin->GrabFocus();
527
0
            pWin->ToTop( ToTopFlags::RestoreWhenMin );
528
0
            break;
529
0
        }
530
531
0
        nTaskId++;
532
0
    }
533
0
}
534
535
void WindowListMenuController::impl_setPopupMenu(std::unique_lock<std::mutex>& /*rGuard*/)
536
0
{
537
    // Make this controller work also with initially empty
538
    // menu, which PopupMenu::ImplExecute doesn't allow.
539
0
    if (m_xPopupMenu.is() && !m_xPopupMenu->getItemCount())
540
0
        m_xPopupMenu->insertSeparator(0);
541
0
}
542
543
OUString WindowListMenuController::getImplementationName()
544
0
{
545
0
    return u"com.sun.star.comp.framework.WindowListMenuController"_ustr;
546
0
}
547
548
}
549
550
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
551
com_sun_star_comp_framework_ResourceMenuController_get_implementation(
552
    css::uno::XComponentContext* context,
553
    css::uno::Sequence< css::uno::Any > const & args )
554
0
{
555
0
    return cppu::acquire( new ResourceMenuController( context, args, false ) );
556
0
}
557
558
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
559
com_sun_star_comp_framework_ToolbarAsMenuController_get_implementation(
560
    css::uno::XComponentContext* context,
561
    css::uno::Sequence< css::uno::Any > const & args )
562
0
{
563
0
    return cppu::acquire( new ResourceMenuController( context, args, true ) );
564
0
}
565
566
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
567
com_sun_star_comp_framework_WindowListMenuController_get_implementation(
568
    css::uno::XComponentContext* context,
569
    css::uno::Sequence< css::uno::Any > const & args )
570
0
{
571
0
    return cppu::acquire( new WindowListMenuController( context, args ) );
572
0
}
573
574
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
575
com_sun_star_comp_framework_SaveAsMenuController_get_implementation(
576
    css::uno::XComponentContext* context,
577
    css::uno::Sequence< css::uno::Any > const & args )
578
0
{
579
0
    return cppu::acquire( new SaveAsMenuController( context, args ) );
580
0
}
581
582
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */