Coverage Report

Created: 2026-05-16 09:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/framework/source/uielement/menubarwrapper.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/menubarwrapper.hxx>
21
22
#include <com/sun/star/beans/XPropertySet.hpp>
23
#include <com/sun/star/container/XNameAccess.hpp>
24
#include <com/sun/star/ui/UIElementType.hpp>
25
#include <com/sun/star/frame/ModuleManager.hpp>
26
#include <com/sun/star/util/URLTransformer.hpp>
27
28
#include <comphelper/sequence.hxx>
29
#include <cppuhelper/typeprovider.hxx>
30
#include <cppuhelper/queryinterface.hxx>
31
#include <toolkit/awt/vclxmenu.hxx>
32
#include <utility>
33
#include <vcl/svapp.hxx>
34
35
using namespace com::sun::star;
36
using namespace com::sun::star::uno;
37
using namespace com::sun::star::beans;
38
using namespace com::sun::star::frame;
39
using namespace com::sun::star::lang;
40
using namespace com::sun::star::container;
41
using namespace com::sun::star::awt;
42
using namespace com::sun::star::util;
43
using namespace ::com::sun::star::ui;
44
45
namespace framework
46
{
47
48
MenuBarWrapper::MenuBarWrapper(
49
    css::uno::Reference< css::uno::XComponentContext > xContext
50
    )
51
0
:    MenuBarWrapper_Base( UIElementType::MENUBAR ),
52
0
     m_bRefreshPopupControllerCache( true ),
53
0
     m_xContext(std::move( xContext ))
54
0
{
55
0
}
56
57
MenuBarWrapper::~MenuBarWrapper()
58
0
{
59
0
}
60
61
void SAL_CALL MenuBarWrapper::dispose()
62
0
{
63
0
    Reference< XComponent > xThis(this);
64
65
0
    css::lang::EventObject aEvent( xThis );
66
0
    m_aListenerContainer.disposeAndClear( aEvent );
67
68
0
    SolarMutexGuard g;
69
70
0
    m_xMenuBarManager->dispose();
71
0
    m_xMenuBarManager.clear();
72
0
    m_xConfigSource.clear();
73
0
    m_xConfigData.clear();
74
75
0
    m_xMenuBar.clear();
76
0
    m_bDisposed = true;
77
0
}
78
79
// XInitialization
80
void SAL_CALL MenuBarWrapper::initialize( const Sequence< Any >& aArguments )
81
0
{
82
0
    SolarMutexGuard g;
83
84
0
    if ( m_bDisposed )
85
0
        throw DisposedException();
86
87
0
    if ( m_bInitialized )
88
0
        return;
89
90
0
    OUString aModuleIdentifier;
91
0
    UIConfigElementWrapperBase::initialize( aArguments );
92
93
0
    Reference< XFrame > xFrame( m_xWeakFrame );
94
0
    if ( !(xFrame.is() && m_xConfigSource.is()) )
95
0
        return;
96
97
    // Create VCL menubar which will be filled with settings data
98
0
    VclPtr<MenuBar> pVCLMenuBar;
99
0
    {
100
0
        SolarMutexGuard aSolarMutexGuard;
101
0
        pVCLMenuBar = VclPtr<MenuBar>::Create();
102
0
    }
103
104
0
    Reference< XModuleManager2 > xModuleManager = ModuleManager::create( m_xContext );
105
106
0
    try
107
0
    {
108
0
        aModuleIdentifier = xModuleManager->identify( xFrame );
109
0
    }
110
0
    catch( const Exception& )
111
0
    {
112
0
    }
113
114
0
    Reference< XURLTransformer > xTrans;
115
0
    try
116
0
    {
117
0
        xTrans.set( URLTransformer::create(m_xContext) );
118
0
        m_xConfigData = m_xConfigSource->getSettings( m_aResourceURL, false );
119
0
        if ( m_xConfigData.is() )
120
0
        {
121
            // Fill menubar with container contents
122
0
            sal_uInt16 nId = 1;
123
0
            MenuBarManager::FillMenuWithConfiguration( nId, pVCLMenuBar, aModuleIdentifier, m_xConfigData, xTrans );
124
0
        }
125
0
    }
126
0
    catch ( const NoSuchElementException& )
127
0
    {
128
0
    }
129
130
0
    bool bMenuOnly( false );
131
0
    for ( const Any& rArg : aArguments )
132
0
    {
133
0
        PropertyValue aPropValue;
134
0
        if ( rArg >>= aPropValue )
135
0
        {
136
0
            if ( aPropValue.Name == "MenuOnly" )
137
0
                aPropValue.Value >>= bMenuOnly;
138
0
        }
139
0
    }
140
141
0
    if ( !bMenuOnly )
142
0
    {
143
        // Initialize menubar manager with our vcl menu bar. There are some situations where we only want to get the menu without any
144
        // interaction which is done by the menu bar manager. This must be requested by a special property called "MenuOnly". Be careful
145
        // a menu bar created with this property is not fully supported. It must be attached to a real menu bar manager to have full
146
        // support. This feature is currently used for "Inplace editing"!
147
0
        Reference< XDispatchProvider > xDispatchProvider;
148
149
0
        m_xMenuBarManager = new MenuBarManager( m_xContext,
150
0
                                                              xFrame,
151
0
                                                              xTrans,
152
0
                                                              xDispatchProvider,
153
0
                                                              aModuleIdentifier,
154
0
                                                              pVCLMenuBar,
155
0
                                                              false );
156
0
    }
157
158
    // Initialize toolkit menu bar implementation to have awt::XMenuBar for data exchange.
159
    // Don't use this toolkit menu bar or one of its functions. It is only used as a data container!
160
0
    m_xMenuBar = new VCLXMenuBar( pVCLMenuBar );
161
0
}
162
163
// XUIElementSettings
164
void SAL_CALL MenuBarWrapper::updateSettings()
165
0
{
166
0
    SolarMutexGuard g;
167
168
0
    if ( m_bDisposed )
169
0
        throw DisposedException();
170
171
0
    if ( !m_xMenuBarManager.is() )
172
0
        return;
173
174
0
    if ( m_xConfigSource.is() && m_bPersistent )
175
0
    {
176
0
        try
177
0
        {
178
0
            m_xConfigData = m_xConfigSource->getSettings( m_aResourceURL, false );
179
0
            if ( m_xConfigData.is() )
180
0
                m_xMenuBarManager->SetItemContainer( m_xConfigData );
181
0
        }
182
0
        catch ( const NoSuchElementException& )
183
0
        {
184
0
        }
185
0
    }
186
0
    else if ( !m_bPersistent )
187
0
    {
188
        // Transient menubar: do nothing
189
0
    }
190
0
}
191
void MenuBarWrapper::impl_fillNewData()
192
0
{
193
    // Transient menubar => Fill menubar with new data
194
0
    if ( m_xMenuBarManager )
195
0
        m_xMenuBarManager->SetItemContainer( m_xConfigData );
196
0
}
197
198
void MenuBarWrapper::fillPopupControllerCache()
199
0
{
200
0
    if ( m_bRefreshPopupControllerCache )
201
0
    {
202
0
        if ( m_xMenuBarManager )
203
0
            m_xMenuBarManager->GetPopupController( m_aPopupControllerCache );
204
0
        if ( !m_aPopupControllerCache.empty() )
205
0
            m_bRefreshPopupControllerCache = false;
206
0
    }
207
0
}
208
209
// XElementAccess
210
Type SAL_CALL MenuBarWrapper::getElementType()
211
0
{
212
0
    return cppu::UnoType<XDispatchProvider>::get();
213
0
}
214
215
sal_Bool SAL_CALL MenuBarWrapper::hasElements()
216
0
{
217
0
    SolarMutexGuard g;
218
219
0
    if ( m_bDisposed )
220
0
        throw DisposedException();
221
222
0
    fillPopupControllerCache();
223
0
    return ( !m_aPopupControllerCache.empty() );
224
0
}
225
226
// XNameAccess
227
Any SAL_CALL MenuBarWrapper::getByName(
228
    const OUString& aName )
229
0
{
230
0
    SolarMutexGuard g;
231
232
0
    if ( m_bDisposed )
233
0
        throw DisposedException();
234
235
0
    fillPopupControllerCache();
236
237
0
    PopupControllerCache::const_iterator pIter = m_aPopupControllerCache.find( aName );
238
0
    if ( pIter == m_aPopupControllerCache.end() )
239
0
        throw container::NoSuchElementException();
240
241
0
    uno::Reference< frame::XDispatchProvider > xDispatchProvider = pIter->second.m_xDispatchProvider;
242
0
    return uno::Any( xDispatchProvider );
243
0
}
244
245
Sequence< OUString > SAL_CALL MenuBarWrapper::getElementNames()
246
0
{
247
0
    SolarMutexGuard g;
248
249
0
    if ( m_bDisposed )
250
0
        throw DisposedException();
251
252
0
    fillPopupControllerCache();
253
254
0
    return comphelper::mapKeysToSequence( m_aPopupControllerCache );
255
0
}
256
257
sal_Bool SAL_CALL MenuBarWrapper::hasByName(
258
    const OUString& aName )
259
0
{
260
0
    SolarMutexGuard g;
261
262
0
    if ( m_bDisposed )
263
0
        throw DisposedException();
264
265
0
    fillPopupControllerCache();
266
267
0
    PopupControllerCache::const_iterator pIter = m_aPopupControllerCache.find( aName );
268
0
    if ( pIter != m_aPopupControllerCache.end() )
269
0
        return true;
270
0
    else
271
0
        return false;
272
0
}
273
274
// XUIElement
275
Reference< XInterface > SAL_CALL MenuBarWrapper::getRealInterface()
276
0
{
277
0
    if ( m_bDisposed )
278
0
        throw DisposedException();
279
280
0
    return Reference< XInterface >( static_cast<cppu::OWeakObject*>(m_xMenuBarManager.get()), UNO_QUERY );
281
0
}
282
283
} // namespace framework
284
285
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */