Coverage Report

Created: 2025-11-16 09:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/toolkit/source/awt/vclxmenu.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 <toolkit/awt/vclxmenu.hxx>
21
#include <toolkit/helper/vclunohelper.hxx>
22
23
#include <com/sun/star/uno/XComponentContext.hpp>
24
#include <cppuhelper/supportsservice.hxx>
25
#include <cppuhelper/queryinterface.hxx>
26
#include <cppuhelper/typeprovider.hxx>
27
#include <tools/debug.hxx>
28
#include <vcl/dialoghelper.hxx>
29
#include <vcl/graph.hxx>
30
#include <vcl/menu.hxx>
31
#include <vcl/keycod.hxx>
32
#include <vcl/image.hxx>
33
#include <vcl/svapp.hxx>
34
#include <vcl/unohelp.hxx>
35
#include <vcl/window.hxx>
36
37
#include <com/sun/star/awt/KeyModifier.hpp>
38
39
VCLXMenu::VCLXMenu()
40
0
    : maMenuListeners( *this )
41
0
    , mnDefaultItem(0)
42
0
{
43
0
    mpMenu = nullptr;
44
0
}
45
46
VCLXMenu::VCLXMenu( Menu* pMenu )
47
0
    : maMenuListeners( *this )
48
0
    , mnDefaultItem(0)
49
0
{
50
0
    mpMenu = pMenu;
51
0
}
52
53
VCLXMenu::~VCLXMenu()
54
0
{
55
0
    maPopupMenuRefs.clear();
56
0
    if ( mpMenu )
57
0
    {
58
0
        SolarMutexGuard g;
59
0
        mpMenu->RemoveEventListener( LINK( this, VCLXMenu, MenuEventListener ) );
60
0
        mpMenu.disposeAndClear();
61
0
    }
62
0
}
63
64
bool VCLXMenu::IsPopupMenu() const
65
0
{
66
0
    return (mpMenu && ! mpMenu->IsMenuBar());
67
0
}
68
69
void VCLXMenu::ImplCreateMenu( bool bPopup )
70
0
{
71
0
    DBG_ASSERT( !mpMenu, "CreateMenu: Menu exists!" );
72
73
0
    if ( bPopup )
74
0
        mpMenu = VclPtr<PopupMenu>::Create();
75
0
    else
76
0
        mpMenu = VclPtr<MenuBar>::Create();
77
78
0
    mpMenu->AddEventListener( LINK( this, VCLXMenu, MenuEventListener ) );
79
0
}
80
81
void VCLXMenu::ImplAddListener()
82
0
{
83
0
    assert(mpMenu);
84
0
    mpMenu->AddEventListener( LINK( this, VCLXMenu, MenuEventListener ) );
85
0
}
86
87
IMPL_LINK( VCLXMenu, MenuEventListener, VclMenuEvent&, rMenuEvent, void )
88
0
{
89
0
    DBG_ASSERT( rMenuEvent.GetMenu() && mpMenu, "Menu???" );
90
91
0
    if ( rMenuEvent.GetMenu() != mpMenu )  // Also called for the root menu
92
0
        return;
93
94
0
    switch ( rMenuEvent.GetId() )
95
0
    {
96
0
        case VclEventId::MenuSelect:
97
0
        {
98
0
            if ( maMenuListeners.getLength() )
99
0
            {
100
0
                css::awt::MenuEvent aEvent;
101
0
                aEvent.Source = getXWeak();
102
0
                aEvent.MenuId = mpMenu->GetCurItemId();
103
0
                maMenuListeners.itemSelected( aEvent );
104
0
            }
105
0
        }
106
0
        break;
107
0
        case VclEventId::ObjectDying:
108
0
        {
109
0
            mpMenu = nullptr;
110
0
        }
111
0
        break;
112
0
        case VclEventId::MenuHighlight:
113
0
        {
114
0
            if ( maMenuListeners.getLength() )
115
0
            {
116
0
                css::awt::MenuEvent aEvent;
117
0
                aEvent.Source = getXWeak();
118
0
                aEvent.MenuId = mpMenu->GetCurItemId();
119
0
                maMenuListeners.itemHighlighted( aEvent );
120
0
            }
121
0
        }
122
0
        break;
123
0
        case VclEventId::MenuActivate:
124
0
        {
125
0
            if ( maMenuListeners.getLength() )
126
0
            {
127
0
                css::awt::MenuEvent aEvent;
128
0
                aEvent.Source = getXWeak();
129
0
                aEvent.MenuId = mpMenu->GetCurItemId();
130
0
                maMenuListeners.itemActivated( aEvent );
131
0
            }
132
0
        }
133
0
        break;
134
0
        case VclEventId::MenuDeactivate:
135
0
        {
136
0
            if ( maMenuListeners.getLength() )
137
0
            {
138
0
                css::awt::MenuEvent aEvent;
139
0
                aEvent.Source = getXWeak();
140
0
                aEvent.MenuId = mpMenu->GetCurItemId();
141
0
                maMenuListeners.itemDeactivated( aEvent );
142
0
            }
143
0
        }
144
0
        break;
145
146
        // ignore accessibility events
147
0
        case VclEventId::MenuEnable:
148
0
        case VclEventId::MenuInsertItem:
149
0
        case VclEventId::MenuRemoveItem:
150
0
        case VclEventId::MenuSubmenuActivate:
151
0
        case VclEventId::MenuSubmenuDeactivate:
152
0
        case VclEventId::MenuSubmenuChanged:
153
0
        case VclEventId::MenuDehighlight:
154
0
        case VclEventId::MenuDisable:
155
0
        case VclEventId::MenuItemRoleChanged:
156
0
        case VclEventId::MenuItemTextChanged:
157
0
        case VclEventId::MenuItemChecked:
158
0
        case VclEventId::MenuItemUnchecked:
159
0
        case VclEventId::MenuShow:
160
0
        case VclEventId::MenuHide:
161
0
        break;
162
163
0
        default:    OSL_FAIL( "MenuEventListener - Unknown event!" );
164
0
   }
165
0
}
166
167
168
OUString SAL_CALL VCLXMenu::getImplementationName(  )
169
0
{
170
0
    std::unique_lock aGuard( maMutex );
171
0
    const bool bIsPopupMenu = IsPopupMenu();
172
0
    aGuard.unlock();
173
174
0
    OUString implName( u"stardiv.Toolkit."_ustr );
175
0
    if ( bIsPopupMenu )
176
0
        implName += "VCLXPopupMenu";
177
0
    else
178
0
        implName += "VCLXMenuBar";
179
180
0
    return implName;
181
0
}
182
183
css::uno::Sequence< OUString > SAL_CALL VCLXMenu::getSupportedServiceNames(  )
184
0
{
185
0
    std::unique_lock aGuard( maMutex );
186
0
    const bool bIsPopupMenu = IsPopupMenu();
187
0
    aGuard.unlock();
188
189
0
    if ( bIsPopupMenu )
190
0
        return css::uno::Sequence<OUString>{
191
0
            u"com.sun.star.awt.PopupMenu"_ustr,
192
0
            u"stardiv.vcl.PopupMenu"_ustr};
193
0
    else
194
0
        return css::uno::Sequence<OUString>{
195
0
            u"com.sun.star.awt.MenuBar"_ustr,
196
0
            u"stardiv.vcl.MenuBar"_ustr};
197
0
}
198
199
sal_Bool SAL_CALL VCLXMenu::supportsService(const OUString& rServiceName )
200
0
{
201
0
    return cppu::supportsService(this, rServiceName);
202
0
}
203
204
css::uno::Any VCLXMenu::queryInterface(
205
    const css::uno::Type & rType )
206
0
{
207
0
    std::unique_lock aGuard( maMutex );
208
0
    const bool bIsPopupMenu = IsPopupMenu();
209
0
    aGuard.unlock();
210
211
0
    css::uno::Any aRet;
212
213
0
    if ( bIsPopupMenu )
214
0
        aRet = ::cppu::queryInterface(  rType,
215
0
                                        static_cast< css::awt::XMenu* >(static_cast<css::awt::XMenuBar*>(this)),
216
0
                                        static_cast< css::awt::XPopupMenu* >(this),
217
0
                                        static_cast< css::lang::XTypeProvider* >(this),
218
0
                                        static_cast< css::lang::XServiceInfo* >(this) );
219
0
    else
220
0
        aRet = ::cppu::queryInterface(  rType,
221
0
                                        static_cast< css::awt::XMenu* >(static_cast<css::awt::XMenuBar*>(this)),
222
0
                                        static_cast< css::awt::XMenuBar* >(this),
223
0
                                        static_cast< css::lang::XTypeProvider* >(this),
224
0
                                        static_cast< css::lang::XServiceInfo* >(this) );
225
226
0
    return (aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ));
227
0
}
228
229
230
css::uno::Sequence< css::uno::Type > VCLXMenu::getTypes()
231
0
{
232
0
    std::unique_lock aGuard( maMutex );
233
0
    const bool bIsPopupMenu = IsPopupMenu();
234
0
    aGuard.unlock();
235
236
0
    if ( bIsPopupMenu )
237
0
    {
238
0
        static cppu::OTypeCollection collectionPopupMenu(
239
0
            cppu::UnoType<css::lang::XTypeProvider>::get(), cppu::UnoType<css::awt::XMenu>::get(),
240
0
            cppu::UnoType<css::awt::XPopupMenu>::get(),
241
0
            cppu::UnoType<css::lang::XServiceInfo>::get());
242
0
        return collectionPopupMenu.getTypes();
243
0
    }
244
0
    else
245
0
    {
246
0
        static cppu::OTypeCollection collectionMenuBar(
247
0
            cppu::UnoType<css::lang::XTypeProvider>::get(), cppu::UnoType<css::awt::XMenu>::get(),
248
0
            cppu::UnoType<css::awt::XMenuBar>::get(),
249
0
            cppu::UnoType<css::lang::XServiceInfo>::get());
250
0
        return collectionMenuBar.getTypes();
251
0
    }
252
0
}
253
254
255
css::uno::Sequence< sal_Int8 > VCLXMenu::getImplementationId()
256
0
{
257
0
    return css::uno::Sequence<sal_Int8>();
258
0
}
259
260
void VCLXMenu::addMenuListener(
261
    const css::uno::Reference< css::awt::XMenuListener >& rxListener )
262
0
{
263
0
    std::unique_lock aGuard( maMutex );
264
265
0
    maMenuListeners.addInterface( rxListener );
266
0
}
267
268
void VCLXMenu::removeMenuListener(
269
    const css::uno::Reference< css::awt::XMenuListener >& rxListener )
270
0
{
271
0
    std::unique_lock aGuard( maMutex );
272
273
0
    maMenuListeners.removeInterface( rxListener );
274
0
}
275
276
void VCLXMenu::insertItem(
277
    sal_Int16 nItemId,
278
    const OUString& aText,
279
    sal_Int16 nItemStyle,
280
    sal_Int16 nPos )
281
0
{
282
0
    SolarMutexGuard aSolarGuard;
283
0
    std::unique_lock aGuard( maMutex );
284
285
0
    if ( mpMenu )
286
0
        mpMenu->InsertItem(nItemId, aText, static_cast<MenuItemBits>(nItemStyle), {}, nPos);
287
0
}
288
289
void VCLXMenu::removeItem(
290
    sal_Int16 nPos,
291
    sal_Int16 nCount )
292
0
{
293
0
    SolarMutexGuard aSolarGuard;
294
0
    std::unique_lock aGuard( maMutex );
295
296
0
    if (!mpMenu)
297
0
        return;
298
299
0
    sal_Int32 nItemCount = static_cast<sal_Int32>(mpMenu->GetItemCount());
300
0
    if ((nCount > 0) && (nPos >= 0) && (nPos < nItemCount))
301
0
    {
302
0
        sal_Int16 nP = sal::static_int_cast< sal_Int16 >(
303
0
            std::min( static_cast<int>(nPos+nCount), static_cast<int>(nItemCount) ));
304
0
        while( nP-nPos > 0 )
305
0
            mpMenu->RemoveItem( --nP );
306
0
    }
307
0
}
308
309
sal_Int16 VCLXMenu::getItemCount(  )
310
0
{
311
0
    SolarMutexGuard aSolarGuard;
312
0
    std::unique_lock aGuard( maMutex );
313
314
0
    return mpMenu ? mpMenu->GetItemCount() : 0;
315
0
}
316
317
sal_Int16 VCLXMenu::getItemId(
318
    sal_Int16 nPos )
319
0
{
320
0
    SolarMutexGuard aSolarGuard;
321
0
    std::unique_lock aGuard( maMutex );
322
323
0
    return mpMenu ? mpMenu->GetItemId( nPos ) : 0;
324
0
}
325
326
sal_Int16 VCLXMenu::getItemPos(
327
    sal_Int16 nId )
328
0
{
329
0
    SolarMutexGuard aSolarGuard;
330
0
    std::unique_lock aGuard( maMutex );
331
332
0
    return mpMenu ? mpMenu->GetItemPos( nId ) : 0;
333
0
}
334
335
void VCLXMenu::enableItem(
336
    sal_Int16 nItemId,
337
    sal_Bool bEnable )
338
0
{
339
0
    SolarMutexGuard aSolarGuard;
340
0
    std::unique_lock aGuard( maMutex );
341
342
0
    if ( mpMenu )
343
0
        mpMenu->EnableItem( nItemId, bEnable );
344
0
}
345
346
sal_Bool VCLXMenu::isItemEnabled(
347
    sal_Int16 nItemId )
348
0
{
349
0
    SolarMutexGuard aSolarGuard;
350
0
    std::unique_lock aGuard( maMutex );
351
352
0
    return mpMenu && mpMenu->IsItemEnabled( nItemId );
353
0
}
354
355
void VCLXMenu::setItemText(
356
    sal_Int16 nItemId,
357
    const OUString& aText )
358
0
{
359
0
    SolarMutexGuard aSolarGuard;
360
0
    std::unique_lock aGuard( maMutex );
361
362
0
    if ( mpMenu )
363
0
        mpMenu->SetItemText( nItemId, aText );
364
0
}
365
366
OUString VCLXMenu::getItemText(
367
    sal_Int16 nItemId )
368
0
{
369
0
    SolarMutexGuard aSolarGuard;
370
0
    std::unique_lock aGuard( maMutex );
371
372
0
    OUString aItemText;
373
0
    if ( mpMenu )
374
0
        aItemText = mpMenu->GetItemText( nItemId );
375
0
    return aItemText;
376
0
}
377
378
void VCLXMenu::setPopupMenu(
379
    sal_Int16 nItemId,
380
    const css::uno::Reference< css::awt::XPopupMenu >& rxPopupMenu )
381
0
{
382
0
    SolarMutexGuard aSolarGuard;
383
0
    std::unique_lock aGuard( maMutex );
384
385
0
    VCLXMenu* pVCLMenu = dynamic_cast<VCLXMenu*>( rxPopupMenu.get() );
386
0
    DBG_ASSERT( pVCLMenu && pVCLMenu->GetMenu() && pVCLMenu->IsPopupMenu(), "setPopupMenu: Invalid Menu!" );
387
388
0
    if ( mpMenu && pVCLMenu && pVCLMenu->GetMenu() && pVCLMenu->IsPopupMenu() )
389
0
    {
390
0
        maPopupMenuRefs.push_back( rxPopupMenu );
391
392
0
        mpMenu->SetPopupMenu( nItemId, static_cast<PopupMenu*>( pVCLMenu->GetMenu() ) );
393
0
    }
394
0
}
395
396
css::uno::Reference< css::awt::XPopupMenu > VCLXMenu::getPopupMenu(
397
    sal_Int16 nItemId )
398
0
{
399
0
    SolarMutexGuard aSolarGuard;
400
0
    std::unique_lock aGuard( maMutex );
401
402
0
    if ( !mpMenu )
403
0
        return nullptr;
404
0
    Menu* pMenu = mpMenu->GetPopupMenu( nItemId );
405
0
    if ( !pMenu )
406
0
        return nullptr;
407
408
0
    for ( size_t n = maPopupMenuRefs.size(); n; )
409
0
    {
410
0
        css::uno::Reference< css::awt::XPopupMenu >& rRef = maPopupMenuRefs[ --n ];
411
0
        Menu* pM = static_cast<VCLXMenu*>(rRef.get())->GetMenu();
412
0
        if ( pM == pMenu )
413
0
        {
414
0
            return rRef;
415
0
        }
416
0
    }
417
418
    /*
419
       If the popup menu is not inserted via setPopupMenu then
420
       maPopupMenuRefs won't have an entry for it, so create an XPopupMenu
421
       for it now.
422
423
       This means that this vcl PopupMenu "pMenu" either existed as a child
424
       of the vcl Menu "mpMenu" before the VCLXMenu was created for that or
425
       it was added directly via vcl.
426
    */
427
0
    rtl::Reference< VCLXPopupMenu > aRef = new VCLXPopupMenu( static_cast<PopupMenu*>(pMenu) );
428
    /*
429
       In any case, the VCLXMenu has ownership of "mpMenu" and will
430
       destroy it in the VCLXMenu dtor.
431
432
       Similarly because VCLXPopupMenu takes ownership of the vcl
433
       PopupMenu "pMenu", the underlying vcl popup will be destroyed
434
       when VCLXPopupMenu is, so we should add it now to
435
       maPopupMenuRefs to ensure its lifecycle is at least bound to
436
       the VCLXMenu that owns the parent "mpMenu" similarly to
437
       PopupMenus added via the more conventional setPopupMenu.
438
    */
439
0
    maPopupMenuRefs.push_back( aRef );
440
0
    return aRef;
441
0
}
442
443
// css::awt::XPopupMenu
444
void VCLXMenu::insertSeparator(
445
    sal_Int16 nPos )
446
0
{
447
0
    SolarMutexGuard aSolarGuard;
448
0
    std::unique_lock aGuard( maMutex );
449
450
0
    if ( mpMenu )
451
0
        mpMenu->InsertSeparator({}, nPos);
452
0
}
453
454
void VCLXMenu::setDefaultItem(
455
    sal_Int16 nItemId )
456
0
{
457
0
    std::unique_lock aGuard( maMutex );
458
459
0
    mnDefaultItem = nItemId;
460
0
}
461
462
sal_Int16 VCLXMenu::getDefaultItem(  )
463
0
{
464
0
    std::unique_lock aGuard( maMutex );
465
466
0
    return mnDefaultItem;
467
0
}
468
469
void VCLXMenu::checkItem(
470
    sal_Int16 nItemId,
471
    sal_Bool bCheck )
472
0
{
473
0
    SolarMutexGuard aSolarGuard;
474
0
    std::unique_lock aGuard( maMutex );
475
476
0
    if ( mpMenu )
477
0
        mpMenu->CheckItem( nItemId, bCheck );
478
0
}
479
480
sal_Bool VCLXMenu::isItemChecked(
481
    sal_Int16 nItemId )
482
0
{
483
0
    SolarMutexGuard aSolarGuard;
484
0
    std::unique_lock aGuard( maMutex );
485
486
0
    return mpMenu && mpMenu->IsItemChecked( nItemId );
487
0
}
488
489
sal_Int16 VCLXMenu::execute(
490
    const css::uno::Reference< css::awt::XWindowPeer >& rxWindowPeer,
491
    const css::awt::Rectangle& rPos,
492
    sal_Int16 nFlags )
493
0
{
494
0
    SolarMutexGuard aSolarGuard;
495
0
    auto pMenu = mpMenu;
496
0
    {
497
0
        std::unique_lock aGuard( maMutex );
498
0
        if ( !mpMenu || !IsPopupMenu() )
499
0
            return 0;
500
0
    }
501
0
    PopupMenu* pPopupMenu = static_cast<PopupMenu*>(pMenu.get());
502
0
    MenuFlags nMenuFlags = pPopupMenu->GetMenuFlags();
503
    // #102790# context menus shall never show disabled entries
504
0
    nMenuFlags |= MenuFlags::HideDisabledEntries;
505
0
    pPopupMenu->SetMenuFlags(nMenuFlags);
506
    // cannot call this with mutex locked because it will call back into us
507
0
    return pPopupMenu->Execute(
508
0
        VCLUnoHelper::GetWindow(rxWindowPeer), vcl::unohelper::ConvertToVCLRect(rPos),
509
0
        static_cast<PopupMenuFlags>(nFlags) | PopupMenuFlags::NoMouseUpClose);
510
0
}
511
512
513
void SAL_CALL VCLXMenu::setCommand(
514
    sal_Int16 nItemId,
515
    const OUString& aCommand )
516
0
{
517
0
    SolarMutexGuard aSolarGuard;
518
0
    std::unique_lock aGuard( maMutex );
519
520
0
    if ( mpMenu )
521
0
        mpMenu->SetItemCommand( nItemId, aCommand );
522
0
}
523
524
OUString SAL_CALL VCLXMenu::getCommand(
525
    sal_Int16 nItemId )
526
0
{
527
0
    SolarMutexGuard aSolarGuard;
528
0
    std::unique_lock aGuard( maMutex );
529
530
0
    OUString aItemCommand;
531
0
    if ( mpMenu )
532
0
        aItemCommand = mpMenu->GetItemCommand( nItemId );
533
0
    return aItemCommand;
534
0
}
535
536
void SAL_CALL VCLXMenu::setHelpCommand(
537
    sal_Int16 nItemId,
538
    const OUString& aHelp )
539
0
{
540
0
    SolarMutexGuard aSolarGuard;
541
0
    std::unique_lock aGuard( maMutex );
542
543
0
    if ( mpMenu )
544
0
        mpMenu->SetHelpCommand( nItemId, aHelp );
545
0
}
546
547
OUString SAL_CALL VCLXMenu::getHelpCommand(
548
    sal_Int16 nItemId )
549
0
{
550
0
    SolarMutexGuard aSolarGuard;
551
0
    std::unique_lock aGuard( maMutex );
552
553
0
    OUString aHelpCommand;
554
0
    if ( mpMenu )
555
0
        aHelpCommand = mpMenu->GetHelpCommand( nItemId );
556
0
    return aHelpCommand;
557
0
}
558
559
560
namespace
561
{
562
    Image lcl_XGraphic2VCLImage(
563
        const css::uno::Reference< css::graphic::XGraphic >& xGraphic,
564
        bool bResize )
565
0
    {
566
0
        Image aImage;
567
0
        if ( !xGraphic.is() )
568
0
            return aImage;
569
570
0
        aImage = Image( xGraphic );
571
0
        const ::Size aCurSize = aImage.GetSizePixel();
572
0
        const sal_Int32 nCurWidth = aCurSize.Width();
573
0
        const sal_Int32 nCurHeight = aCurSize.Height();
574
0
        constexpr sal_Int32 nIdeal( 16 );
575
576
0
        if ( nCurWidth > 0 && nCurHeight > 0 )
577
0
        {
578
0
            if ( bResize && ( nCurWidth > nIdeal || nCurHeight > nIdeal ) )
579
0
            {
580
0
                sal_Int32 nIdealWidth  = std::min(nCurWidth, nIdeal);
581
0
                sal_Int32 nIdealHeight = std::min(nCurHeight, nIdeal);
582
583
0
                ::Size aNewSize( nIdealWidth, nIdealHeight );
584
585
0
                bool bModified( false );
586
0
                Bitmap aBitmapEx = aImage.GetBitmap();
587
0
                bModified = aBitmapEx.Scale( aNewSize, BmpScaleFlag::BestQuality );
588
589
0
                if ( bModified )
590
0
                    aImage = Image( aBitmapEx );
591
0
            }
592
0
        }
593
0
        return aImage;
594
0
    }
595
596
    /** Copied from include/svtools/acceleratorexecute.hxx */
597
    css::awt::KeyEvent lcl_VCLKey2AWTKey(
598
        const vcl::KeyCode& aVCLKey)
599
0
    {
600
0
        css::awt::KeyEvent aAWTKey;
601
0
        aAWTKey.Modifiers = 0;
602
0
        aAWTKey.KeyCode   = static_cast<sal_Int16>(aVCLKey.GetCode());
603
604
0
        if (aVCLKey.IsShift())
605
0
            aAWTKey.Modifiers |= css::awt::KeyModifier::SHIFT;
606
0
        if (aVCLKey.IsMod1())
607
0
            aAWTKey.Modifiers |= css::awt::KeyModifier::MOD1;
608
0
        if (aVCLKey.IsMod2())
609
0
            aAWTKey.Modifiers |= css::awt::KeyModifier::MOD2;
610
0
        if (aVCLKey.IsMod3())
611
0
            aAWTKey.Modifiers |= css::awt::KeyModifier::MOD3;
612
613
0
        return aAWTKey;
614
0
    }
615
616
    vcl::KeyCode lcl_AWTKey2VCLKey(const css::awt::KeyEvent& aAWTKey)
617
0
    {
618
0
        bool bShift = ((aAWTKey.Modifiers & css::awt::KeyModifier::SHIFT) == css::awt::KeyModifier::SHIFT );
619
0
        bool bMod1  = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD1 ) == css::awt::KeyModifier::MOD1  );
620
0
        bool bMod2  = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD2 ) == css::awt::KeyModifier::MOD2  );
621
0
        bool bMod3  = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD3 ) == css::awt::KeyModifier::MOD3  );
622
0
        sal_uInt16   nKey   = static_cast<sal_uInt16>(aAWTKey.KeyCode);
623
624
0
        return vcl::KeyCode(nKey, bShift, bMod1, bMod2, bMod3);
625
0
    }
626
627
}
628
629
630
sal_Bool SAL_CALL VCLXMenu::isPopupMenu(  )
631
0
{
632
0
    SolarMutexGuard aSolarGuard;
633
0
    std::unique_lock aGuard( maMutex );
634
0
    return IsPopupMenu();
635
0
}
636
637
void SAL_CALL VCLXMenu::clear(  )
638
0
{
639
0
    SolarMutexGuard aSolarGuard;
640
0
    std::unique_lock aGuard( maMutex );
641
0
    if ( mpMenu )
642
0
        mpMenu->Clear();
643
0
}
644
645
646
css::awt::MenuItemType SAL_CALL VCLXMenu::getItemType(
647
    ::sal_Int16 nItemPos )
648
0
{
649
0
    SolarMutexGuard aSolarGuard;
650
0
    std::unique_lock aGuard( maMutex );
651
652
0
    css::awt::MenuItemType aMenuItemType =
653
0
        css::awt::MenuItemType_DONTKNOW;
654
0
    if ( mpMenu )
655
0
    {
656
0
        aMenuItemType = static_cast<css::awt::MenuItemType>(mpMenu->GetItemType( nItemPos ));
657
0
    }
658
659
0
    return aMenuItemType;
660
0
}
661
662
void SAL_CALL VCLXMenu::hideDisabledEntries(
663
    sal_Bool bHide )
664
0
{
665
0
    SolarMutexGuard aSolarGuard;
666
0
    std::unique_lock aGuard( maMutex );
667
0
    if ( mpMenu )
668
0
    {
669
0
        if ( bHide )
670
0
            mpMenu->SetMenuFlags( mpMenu->GetMenuFlags() | MenuFlags::HideDisabledEntries );
671
0
        else
672
0
            mpMenu->SetMenuFlags( mpMenu->GetMenuFlags() & ~MenuFlags::HideDisabledEntries );
673
0
    }
674
0
}
675
676
677
sal_Bool SAL_CALL VCLXMenu::isInExecute(  )
678
0
{
679
0
    SolarMutexGuard aSolarGuard;
680
0
    std::unique_lock aGuard( maMutex );
681
682
0
    if ( mpMenu && IsPopupMenu() )
683
0
        return vcl::IsInPopupMenuExecute();
684
0
    else
685
0
        return false;
686
0
}
687
688
689
void SAL_CALL VCLXMenu::endExecute()
690
0
{
691
0
    SolarMutexGuard aSolarGuard;
692
0
    std::unique_lock aGuard( maMutex );
693
694
0
    if ( mpMenu && IsPopupMenu() )
695
0
        static_cast<PopupMenu*>( mpMenu.get() )->EndExecute();
696
0
}
697
698
699
void SAL_CALL VCLXMenu::enableAutoMnemonics(
700
    sal_Bool bEnable )
701
0
{
702
0
    SolarMutexGuard aSolarGuard;
703
0
    std::unique_lock aGuard( maMutex );
704
0
    if ( mpMenu )
705
0
    {
706
0
        if ( !bEnable )
707
0
            mpMenu->SetMenuFlags( mpMenu->GetMenuFlags() | MenuFlags::NoAutoMnemonics );
708
0
        else
709
0
            mpMenu->SetMenuFlags( mpMenu->GetMenuFlags() & ~MenuFlags::NoAutoMnemonics );
710
0
    }
711
0
}
712
713
714
void SAL_CALL VCLXMenu::setAcceleratorKeyEvent(
715
    ::sal_Int16 nItemId,
716
    const css::awt::KeyEvent& aKeyEvent )
717
0
{
718
0
    SolarMutexGuard aSolarGuard;
719
0
    std::unique_lock aGuard( maMutex );
720
721
0
    if ( mpMenu && IsPopupMenu() && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) )
722
0
    {
723
0
        vcl::KeyCode aVCLKeyCode = lcl_AWTKey2VCLKey( aKeyEvent );
724
0
        mpMenu->SetAccelKey( nItemId, aVCLKeyCode );
725
0
    }
726
0
}
727
728
729
css::awt::KeyEvent SAL_CALL VCLXMenu::getAcceleratorKeyEvent(
730
    ::sal_Int16 nItemId )
731
0
{
732
0
    SolarMutexGuard aSolarGuard;
733
0
    std::unique_lock aGuard( maMutex );
734
735
0
    css::awt::KeyEvent aKeyEvent;
736
0
    if ( mpMenu && IsPopupMenu() && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) )
737
0
    {
738
0
        vcl::KeyCode nKeyCode = mpMenu->GetAccelKey( nItemId );
739
0
        aKeyEvent = lcl_VCLKey2AWTKey( nKeyCode );
740
0
    }
741
742
0
    return aKeyEvent;
743
0
}
744
745
746
void SAL_CALL VCLXMenu::setHelpText(
747
    ::sal_Int16 nItemId,
748
    const OUString& sHelpText )
749
0
{
750
0
    SolarMutexGuard aSolarGuard;
751
0
    std::unique_lock aGuard( maMutex );
752
753
0
    if ( mpMenu && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) )
754
0
    {
755
0
        mpMenu->SetHelpText( nItemId, sHelpText );
756
0
    }
757
0
}
758
759
760
OUString SAL_CALL VCLXMenu::getHelpText(
761
    ::sal_Int16 nItemId )
762
0
{
763
0
    SolarMutexGuard aSolarGuard;
764
0
    std::unique_lock aGuard( maMutex );
765
766
0
    OUString sHelpText;
767
0
    if ( mpMenu && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) )
768
0
    {
769
0
        sHelpText = mpMenu->GetHelpText( nItemId );
770
0
    }
771
772
0
    return sHelpText;
773
0
}
774
775
776
void SAL_CALL VCLXMenu::setTipHelpText(
777
    ::sal_Int16 nItemId,
778
    const OUString& sTipHelpText )
779
0
{
780
0
    SolarMutexGuard aSolarGuard;
781
0
    std::unique_lock aGuard( maMutex );
782
783
0
    if ( mpMenu && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) )
784
0
    {
785
0
        mpMenu->SetTipHelpText( nItemId, sTipHelpText );
786
0
    }
787
0
}
788
789
790
OUString SAL_CALL VCLXMenu::getTipHelpText(
791
    ::sal_Int16 nItemId )
792
0
{
793
0
    SolarMutexGuard aSolarGuard;
794
0
    std::unique_lock aGuard( maMutex );
795
796
0
    OUString sTipHelpText;
797
0
    if ( mpMenu && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) )
798
0
    {
799
0
        sTipHelpText = mpMenu->GetTipHelpText( nItemId );
800
0
    }
801
0
    return sTipHelpText;
802
0
}
803
804
805
void SAL_CALL VCLXMenu::setItemImage(
806
    ::sal_Int16 nItemId,
807
    const css::uno::Reference< css::graphic::XGraphic >& xGraphic,
808
    sal_Bool bScale )
809
0
{
810
0
    SolarMutexGuard aSolarGuard;
811
0
    std::unique_lock aGuard( maMutex );
812
813
0
    if ( mpMenu && IsPopupMenu() && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) )
814
0
    {
815
0
        Image aImage = lcl_XGraphic2VCLImage( xGraphic, bScale );
816
0
        mpMenu->SetItemImage( nItemId, aImage );
817
0
    }
818
0
}
819
820
821
css::uno::Reference< css::graphic::XGraphic > SAL_CALL
822
VCLXMenu::getItemImage(
823
    ::sal_Int16 nItemId )
824
0
{
825
0
    SolarMutexGuard aSolarGuard;
826
0
    std::unique_lock aGuard( maMutex );
827
828
0
    css::uno::Reference< css::graphic::XGraphic > rxGraphic;
829
830
0
    if ( mpMenu && IsPopupMenu() && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) )
831
0
    {
832
0
        Image aImage = mpMenu->GetItemImage( nItemId );
833
0
        if ( !!aImage )
834
0
            rxGraphic = Graphic(aImage.GetBitmap()).GetXGraphic();
835
0
    }
836
0
    return rxGraphic;
837
0
}
838
839
void VCLXMenu::setUserValue(sal_uInt16 nItemId, void* nUserValue, MenuUserDataReleaseFunction aFunc)
840
0
{
841
0
    SolarMutexGuard aSolarGuard;
842
0
    std::unique_lock aGuard(maMutex);
843
844
0
    mpMenu->SetUserValue(nItemId, nUserValue, aFunc);
845
0
}
846
847
void* VCLXMenu::getUserValue(sal_uInt16 nItemId)
848
0
{
849
0
    SolarMutexGuard aSolarGuard;
850
0
    std::unique_lock aGuard(maMutex);
851
852
0
    return mpMenu->GetUserValue(nItemId);
853
0
}
854
855
VCLXMenuBar::VCLXMenuBar()
856
0
{
857
0
    ImplCreateMenu( false );
858
0
}
859
860
0
VCLXMenuBar::VCLXMenuBar( MenuBar* pMenuBar ) : VCLXMenu( static_cast<Menu *>(pMenuBar) )
861
0
{
862
0
}
863
864
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
865
stardiv_Toolkit_VCLXMenuBar_get_implementation(
866
    css::uno::XComponentContext *,
867
    css::uno::Sequence<css::uno::Any> const &)
868
0
{
869
0
    return cppu::acquire(new VCLXMenuBar());
870
0
}
871
872
VCLXPopupMenu::VCLXPopupMenu()
873
0
{
874
0
    ImplCreateMenu( true );
875
0
}
876
877
0
VCLXPopupMenu::VCLXPopupMenu( PopupMenu* pPopMenu ) : VCLXMenu( static_cast<Menu *>(pPopMenu) )
878
0
{
879
0
    ImplAddListener();
880
0
}
881
882
VCLXPopupMenu::~VCLXPopupMenu() = default;
883
884
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
885
stardiv_Toolkit_VCLXPopupMenu_get_implementation(
886
    css::uno::XComponentContext *,
887
    css::uno::Sequence<css::uno::Any> const &)
888
0
{
889
0
    return cppu::acquire(new VCLXPopupMenu());
890
0
}
891
892
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */