Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  shutdowniconaqua.mm   Sprache: unbekannt

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */


#include <unotools/moduleoptions.hxx>
#include <unotools/dynamicmenuoptions.hxx>
#include <unotools/historyoptions.hxx>
#include <officecfg/Office/Common.hxx>
#include <rtl/ustring.hxx>
#include <tools/urlobj.hxx>
#include <osl/file.h>
#include <osl/diagnose.h>
#include <comphelper/sequenceashashmap.hxx>
#include <sfx2/app.hxx>
#include <sal/macros.h>
#include <sfx2/sfxresid.hxx>
#include <sfx2/strings.hrc>
#include <vcl/svapp.hxx>
#include <vcl/mnemonic.hxx>
#include <vcl/image.hxx>
#include <svtools/imagemgr.hxx>
#include <shutdownicon.hxx>

#include <com/sun/star/util/XStringWidth.hpp>

#include <cppuhelper/implbase.hxx>

#include <set>
#include <vector>

#include <premac.h>
#include <objc/objc-runtime.h>
#include <Cocoa/Cocoa.h>
#include <postmac.h>

#define MI_OPEN                    1
#define MI_WRITER                  2
#define MI_CALC                    3
#define MI_IMPRESS                 4
#define MI_DRAW                    5
#define MI_BASE                    6
#define MI_MATH                    7
#define MI_TEMPLATE                8
#define MI_STARTMODULE             9

#define UNO_TOGGLECURRENTMODULE_COMMAND ".uno:ToggleCurrentModule"

@interface QSMenuExecute : NSObject
{
}
-(void)executeMenuItem: (NSMenuItem*)pItem;
-(void)dockIconClicked: (NSObject*)pSender;
@end

@implementation QSMenuExecute
-(void)executeMenuItem: (NSMenuItem*)pItem
{
    SolarMutexGuard aGuard;

    switch( [pItem tag] )
    {
    case MI_OPEN:
        ShutdownIcon::FileOpen();
        break;
    case MI_WRITER:
        ShutdownIcon::OpenURL( WRITER_URL, "_default" );
        break;
    case MI_CALC:
        ShutdownIcon::OpenURL( CALC_URL, "_default" );
        break;
    case MI_IMPRESS:
        ShutdownIcon::OpenURL( IMPRESS_URL, "_default" );
        break;
    case MI_DRAW:
        ShutdownIcon::OpenURL( DRAW_URL, "_default" );
        break;
    case MI_BASE:
        ShutdownIcon::OpenURL( BASE_URL, "_default" );
        break;
    case MI_MATH:
        ShutdownIcon::OpenURL( MATH_URL, "_default" );
        break;
    case MI_TEMPLATE:
        ShutdownIcon::FromTemplate();
        break;
    case MI_STARTMODULE:
        ShutdownIcon::OpenURL( STARTMODULE_URL, "_default" );
        break;
    default:
        break;
    }
}

-(void)dockIconClicked: (NSObject*)pSender
{
    (void)pSender;

    SolarMutexGuard aGuard;

    // start module
    ShutdownIcon::OpenURL( STARTMODULE_URL, "_default" );
}

@end

bool ShutdownIcon::IsQuickstarterInstalled()
{
    return true;
}

static NSArray<NSMenuItem*>* pPreferredMenus = nil;
static NSMenuItem* pDefMenu = nil, *pDockSubMenu = nil;
static QSMenuExecute* pExecute = nil;

static std::set< OUString > aShortcuts;

static NSString* getAutoreleasedString( const OUString& rStr )
{
    return [[[NSString alloc] initWithCharacters: reinterpret_cast<unichar const *>(rStr.getStr()) length: rStr.getLength()] autorelease];
}

namespace {

struct RecentMenuEntry
{
    OUString aURL;
    OUString aFilter;
    OUString aTitle;
    OUString aPassword;
};

}

@interface QSCommandMenuItem : NSMenuItem
{
    OUString m_aCommand;
}
-(void)menuItemTriggered: (id)aSender;
-(void)setCommand: (OUString)aCommand;
@end

@implementation QSCommandMenuItem

-(void)menuItemTriggered: (id)aSender
{
    if ( m_aCommand.isEmpty() )
        return;

    SolarMutexGuard aGuard;

    if ( m_aCommand == "vnd.org.libreoffice.recentdocs:ClearRecentFileList" )
    {
        // Clearing the recent file list requires an extra step
        SvtHistoryOptions::Clear( EHistoryType::PickList, false );
    }
    else if ( m_aCommand == ".uno:Open" )
    {
        ShutdownIcon::FileOpen();
        return;
    }
    else if ( m_aCommand == ".uno:ConfigureDialog" )
    {
        // Selecting some menu items will cause a crash if there are
        // no visible windows
        ShutdownIcon::OpenURL( STARTMODULE_URL, "_default" );
    }
    else if ( m_aCommand == UNO_TOGGLECURRENTMODULE_COMMAND )
    {
        bool bIsExclusive = officecfg::Office::Common::History::ShowCurrentModuleOnly::get();
        std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
        officecfg::Office::Common::History::ShowCurrentModuleOnly::set(!bIsExclusive, batch);
        batch->commit();
        [self setState: bIsExclusive ? NSControlStateValueOff : NSControlStateValueOn];
        return;
    }

    // "private:" commands are used for menu items in the File > New menu
    if ( m_aCommand.startsWith( "private:" ) || m_aCommand == STARTMODULE_URL )
        ShutdownIcon::OpenURL( m_aCommand, "_default" );
    else
        ShutdownIcon::FromCommand( m_aCommand );
}

-(void)setCommand: (OUString)aCommand
{
    m_aCommand = aCommand;
}

@end

@interface RecentMenuDelegate : NSObject <NSMenuDelegate>
{
    std::vector< RecentMenuEntry >* m_pRecentFilesItems;
}
-(id)init;
-(void)dealloc;
-(void)menuNeedsUpdate:(NSMenu *)menu;
-(void)executeRecentEntry: (NSMenuItem*)item;
@end

@implementation RecentMenuDelegate
-(id)init
{
    if( (self = [super init]) )
    {
        m_pRecentFilesItems = new std::vector< RecentMenuEntry >();
    }
    return self;
}

-(void)dealloc
{
    delete m_pRecentFilesItems;
    [super dealloc];
}

-(void)menuNeedsUpdate:(NSMenu *)menu
{
    SolarMutexGuard aGuard;

    // clear menu
    int nItems = [menu numberOfItems];
    while( nItems -- )
        [menu removeItemAtIndex: 0];

    // update recent item list
    std::vector< SvtHistoryOptions::HistoryItem > aHistoryList( SvtHistoryOptions::GetList( EHistoryType::PickList ) );

    int nPickListMenuItems = ( aHistoryList.size() > 99 ) ? 99 : aHistoryList.size();

    m_pRecentFilesItems->clear();
    if( nPickListMenuItems > 0 )
    {
        for ( int i = 0; i < nPickListMenuItems; i++ )
        {
            const SvtHistoryOptions::HistoryItem & rPickListEntry = aHistoryList[i];
            RecentMenuEntry aRecentFile;
            aRecentFile.aURL = rPickListEntry.sURL;
            aRecentFile.aFilter = rPickListEntry.sFilter;
            aRecentFile.aTitle = rPickListEntry.sTitle;
            m_pRecentFilesItems->push_back( aRecentFile );
        }
    }

    // insert new recent items
    for ( std::vector<RecentMenuEntry>::size_type i = 0; i < m_pRecentFilesItems->size(); i++ )
    {
        OUStringBuffer aMenuShortCut;
        if ( i <= 9 )
        {
            if ( i == 9 )
                aMenuShortCut.append( "1~0. " );
            else
            {
                aMenuShortCut.append( "~N. " );
                aMenuShortCut[ 1 ] = sal_Unicode( i + '1' );
            }
        }
        else
        {
            aMenuShortCut.append( OUString::number(sal_Int32( i + 1 ) ) + ". " );
        }

        OUString   aMenuTitle;
        INetURLObject   aURL( (*m_pRecentFilesItems)[i].aURL );
        NSImage *pImage = nil;

        if ( aURL.GetProtocol() == INetProtocol::File )
        {
            // Do handle file URL differently: don't show the protocol,
            // just the file name
            aMenuTitle = aURL.GetLastName(INetURLObject::DecodeMechanism::WithCharset);

            if ( [NSApp respondsToSelector: @selector(createNSImage:)] )
            {
                BitmapEx aThumbnail(SvFileInformationManager::GetFileImageId(aURL));
                Size aBmpSize = aThumbnail.GetSizePixel();
                if ( aBmpSize.Width() > 0 && aBmpSize.Height() > 0 )
                {
                    Image aImage( aThumbnail );
                    NSValue *pImageValue = [NSValue valueWithPointer: &aImage];
                    pImage = [NSApp performSelector: @selector(createNSImage:) withObject: pImageValue];
                }
            }
        }
        else
        {
            // In all other URLs show the protocol name before the file name
            aMenuTitle   = INetURLObject::GetSchemeName(aURL.GetProtocol()) + ": " + aURL.getName();
        }

        aMenuShortCut.append( aMenuTitle );
        aMenuTitle = MnemonicGenerator::EraseAllMnemonicChars( aMenuShortCut.makeStringAndClear() );
        if ( aMenuTitle.isEmpty() )
            continue;

        if ( aMenuTitle.endsWith( "...", &aMenuTitle ) )
            aMenuTitle += u"\u2026";

        NSMenuItem* pNewItem = [[NSMenuItem alloc] initWithTitle: getAutoreleasedString( aMenuTitle )
                                                   action: @selector(executeRecentEntry:)
                                                   keyEquivalent: @""];
        [pNewItem setTag: i];
        [pNewItem setTarget: self];
        [pNewItem setEnabled: YES];
        if ( pImage )
        {
            [pNewItem setImage: pImage];
            [pImage release];
        }
        [menu addItem: pNewItem];
        [pNewItem autorelease];
    }

    if ( [menu numberOfItems] )
    {
        TranslateId aId( "STR_CLEAR_RECENT_FILES", "Clear List" );
        OUString aClearList = Translate::get( aId, Translate::Create("fwk") );
        if ( !aClearList.isEmpty() )
        {
            [menu addItem: [NSMenuItem separatorItem]];

            QSCommandMenuItem* pNewItem = [[QSCommandMenuItem alloc] initWithTitle: getAutoreleasedString( aClearList ) action: @selector(menuItemTriggered:) keyEquivalent: @""];
            [pNewItem setCommand: "vnd.org.libreoffice.recentdocs:ClearRecentFileList"];
            [pNewItem setTarget: pNewItem];
            [pNewItem setEnabled: YES];
            [menu addItem: pNewItem];
            [pNewItem autorelease];

            aId = TranslateId( "STR_TOGGLECURRENTMODULE", "Current Module Only" );
            OUString aToggleCurrentMode = Translate::get( aId, Translate::Create("fwk") );
            if ( !aToggleCurrentMode.isEmpty() )
            {
                pNewItem = [[QSCommandMenuItem alloc] initWithTitle: getAutoreleasedString( aToggleCurrentMode ) action: @selector(menuItemTriggered:) keyEquivalent: @""];
                [pNewItem setCommand: UNO_TOGGLECURRENTMODULE_COMMAND];
                [pNewItem setTarget: pNewItem];
                [pNewItem setState: officecfg::Office::Common::History::ShowCurrentModuleOnly::get() ? NSControlStateValueOn : NSControlStateValueOff];
                [pNewItem setEnabled: YES];
                [menu addItem: pNewItem];
                [pNewItem autorelease];
            }
        }
    }
    else
    {
        TranslateId aId( "STR_NODOCUMENT", "No Documents" );
        OUString aNoDocuments = Translate::get( aId, Translate::Create("fwk") );
        if ( !aNoDocuments.isEmpty() )
        {
            NSMenuItem* pNewItem = [[NSMenuItem alloc] initWithTitle: getAutoreleasedString( aNoDocuments ) action: nil keyEquivalent: @""];
            [pNewItem setEnabled: YES];
            [menu addItem: pNewItem];
            [pNewItem autorelease];
        }
    }
}

-(void)executeRecentEntry: (NSMenuItem*)item
{
    sal_Int32 nIndex = [item tag];
    if( ( nIndex >= 0 ) && ( nIndex < static_cast<sal_Int32>( m_pRecentFilesItems->size() ) ) )
    {
        const RecentMenuEntry& rRecentFile = (*m_pRecentFilesItems)[ nIndex ];
        int NUM_OF_PICKLIST_ARGS = 3;
        css::uno::Sequence< css::beans::PropertyValue > aArgsList( NUM_OF_PICKLIST_ARGS );
        css::beans::PropertyValue* pArgsList = aArgsList.getArray();

        pArgsList[0].Name = "Referer";
        pArgsList[0].Value <<= OUString( "private:user" );

        // documents in the picklist will never be opened as templates
        pArgsList[1].Name = "AsTemplate";
        pArgsList[1].Value <<= false;

        OUString  aFilter( rRecentFile.aFilter );
        sal_Int32 nPos = aFilter.indexOf( '|' );
        if ( nPos >= 0 )
        {
            OUString aFilterOptions;

            if ( nPos < ( aFilter.getLength() - 1 ) )
                aFilterOptions = aFilter.copy( nPos+1 );

            pArgsList[2].Name = "FilterOptions";
            pArgsList[2].Value <<= aFilterOptions;

            aFilter = aFilter.copy( 0, nPos-1 );
            aArgsList.realloc( ++NUM_OF_PICKLIST_ARGS );
            pArgsList = aArgsList.getArray();
        }

        pArgsList[NUM_OF_PICKLIST_ARGS-1].Name = "FilterName";
        pArgsList[NUM_OF_PICKLIST_ARGS-1].Value <<= aFilter;

        ShutdownIcon::OpenURL( rRecentFile.aURL, "_default", aArgsList );
    }
}
@end

static RecentMenuDelegate* pRecentDelegate = nil;

static void appendMenuItem( NSMenu* i_pMenu, NSMenu* i_pDockMenu, const OUString& i_rTitle, int i_nTag, const OUString& i_rKeyEquiv )
{
    if( ! i_rTitle.getLength() )
        return;

    NSMenuItem* pItem = [[NSMenuItem alloc] initWithTitle: getAutoreleasedString( i_rTitle )
                                            action: @selector(executeMenuItem:)
                                            keyEquivalent: (i_rKeyEquiv.getLength() ? getAutoreleasedString( i_rKeyEquiv ) : @"")
                        ];
    [pItem setTag: i_nTag];
    [pItem setTarget: pExecute];
    [pItem setEnabled: YES];
    [i_pMenu addItem: pItem];
    [pItem autorelease];

    if( i_pDockMenu )
    {
        // create a similar entry in the dock menu
        pItem = [[NSMenuItem alloc] initWithTitle: getAutoreleasedString( i_rTitle )
                                    action: @selector(executeMenuItem:)
                                    keyEquivalent: @""
                            ];
        [pItem setTag: i_nTag];
        [pItem setTarget: pExecute];
        [pItem setEnabled: YES];
        [i_pDockMenu addItem: pItem];
        [pItem autorelease];
    }
}

static void appendRecentMenu( NSMenu* i_pMenu, const OUString& i_rTitle )
{
    if( ! pRecentDelegate )
        pRecentDelegate = [[RecentMenuDelegate alloc] init];

    NSMenuItem* pItem = [i_pMenu addItemWithTitle: getAutoreleasedString( i_rTitle )
                                                   action: @selector(executeMenuItem:)
                                                   keyEquivalent: @""
                        ];
    [pItem setEnabled: YES];
    NSMenu* pRecentMenu = [[NSMenu alloc] initWithTitle: getAutoreleasedString( i_rTitle ) ];

    [pRecentMenu setDelegate: pRecentDelegate];

    [pRecentMenu setAutoenablesItems: NO];
    [pItem setSubmenu: pRecentMenu];
}

static void setKeyEquivalent( const vcl::KeyCode &rKeyCode, NSMenuItem *pNSMenuItem )
{
    if ( !pNSMenuItem )
        return;

    sal_uInt16 nKeyCode = rKeyCode.GetCode();
    if ( !nKeyCode )
        return;

    sal_Unicode nCommandKey = 0;
    if ((nKeyCode>=KEY_A) && (nKeyCode<=KEY_Z))           // letter A..Z
        nCommandKey = nKeyCode - KEY_A + 'a';
    else if ((nKeyCode>=KEY_0) && (nKeyCode<=KEY_9))      // numbers 0..9
        nCommandKey = nKeyCode - KEY_0 + '0';
    else if ((nKeyCode>=KEY_F1) && (nKeyCode<=KEY_F26))   // function keys F1..F26
        nCommandKey = nKeyCode - KEY_F1 + NSF1FunctionKey;

    if ( !nCommandKey )
        return;

    sal_uInt16 nModifier = rKeyCode.GetModifier();
    int nItemModifier = 0;

    if ( nModifier & KEY_SHIFT )
    {
        nItemModifier |= NSEventModifierFlagShift;   // actually useful only for function keys
        if ( nKeyCode >= KEY_A && nKeyCode <= KEY_Z )
            nCommandKey = nKeyCode - KEY_A + 'A';
    }

    if ( nModifier & KEY_MOD1 )
        nItemModifier |= NSEventModifierFlagCommand;

    if ( nModifier & KEY_MOD2 )
        nItemModifier |= NSEventModifierFlagOption;

    if ( nModifier & KEY_MOD3 )
        nItemModifier |= NSEventModifierFlagControl;

    // Don’t allow setting the ⌘N shortcut because it would conflict
    // with the “Startcenter” menu item which is added explicitly in
    // getNSMenuForVCLMenu
    if ( nCommandKey == 'n' && nItemModifier == NSEventModifierFlagCommand )
        return;

    OUString aCommandKey( &nCommandKey, 1 );
    NSString *pCommandKey = [NSString stringWithCharacters: reinterpret_cast< unichar const* >(aCommandKey.getStr()) length: aCommandKey.getLength()];
    [pNSMenuItem setKeyEquivalent: pCommandKey];
    [pNSMenuItem setKeyEquivalentModifierMask: nItemModifier];
}

static NSMenu *getNSMenuForVCLMenu( Menu *pMenu )
{
    NSMenu *pRet = nil;

    if ( !pMenu )
        return pRet;

    pMenu->Activate();

    sal_uInt16 nItemCount = pMenu->GetItemCount();
    if ( nItemCount )
    {
        pRet = [[[NSMenu alloc] initWithTitle: @""] autorelease];
        [pRet setAutoenablesItems: NO];
        for ( sal_uInt16 i = 0; i < nItemCount; i++ )
        {
            sal_uInt16 nId = pMenu->GetItemId( i );
            if ( nId && pMenu->IsItemEnabled( nId ) )
            {
                OUString aText = MnemonicGenerator::EraseAllMnemonicChars( pMenu->GetItemText( nId ) );
                if ( aText.isEmpty() )
                    continue;

                if ( aText.endsWith( "...", &aText ) )
                    aText += u"\u2026";

                // Use a custom menu in place of the Start Center's recent
                // documents menu so that the list can be dynamically updated
                OUString aCommand = pMenu->GetItemCommand( nId );
                if ( aCommand == ".uno:RecentFileList" )
                {
                    appendRecentMenu( pRet, aText );
                    continue;
                }

                NSString *pText = getAutoreleasedString( aText );
                // TODO: use the QSMenuExecute class to connect the command
                // string to one of the existing handler functions
                QSCommandMenuItem *pNSMenuItem = [[QSCommandMenuItem alloc] initWithTitle: pText action: @selector(menuItemTriggered:) keyEquivalent: @""];
                NSMenu *pNSSubmenu = getNSMenuForVCLMenu( pMenu->GetPopupMenu( nId ) );
                if ( pNSSubmenu && [pNSSubmenu numberOfItems] )
                {
                    [pNSSubmenu setTitle: pText];
                    [pNSMenuItem setSubmenu: pNSSubmenu];

                    if ( aCommand == ".uno:AddDirect" )
                    {
                        SvtModuleOptions aModuleOptions;
                        if ( aModuleOptions.IsModuleInstalled( SvtModuleOptions::EModule::STARTMODULE ) )
                        {
                            QSCommandMenuItem *pStartModuleMenuItem = [[QSCommandMenuItem alloc] initWithTitle: getAutoreleasedString( SfxResId( STR_QUICKSTART_STARTCENTER ) ) action: @selector(menuItemTriggered:) keyEquivalent: @"n"];
                            [pStartModuleMenuItem setTarget: pStartModuleMenuItem];
                            [pStartModuleMenuItem setCommand: STARTMODULE_URL];
                            [pNSSubmenu insertItem: pStartModuleMenuItem atIndex: 0];
                            [pStartModuleMenuItem autorelease];
                        }
                    }
                }
                else if ( !aCommand.isEmpty() )
                {
                    [pNSMenuItem setTarget: pNSMenuItem];
                    [pNSMenuItem setCommand: aCommand];

                    setKeyEquivalent( pMenu->GetAccelKey( nId ), pNSMenuItem );
                }

                [pRet addItem: pNSMenuItem];
                [pNSMenuItem autorelease];
            }
            else if ( pMenu->GetItemType( i ) == MenuItemType::SEPARATOR )
            {
                [pRet addItem: [NSMenuItem separatorItem]];
            }
        }
    }

    pMenu->Deactivate();

    return pRet;
}

static void clearDefaultMenuBar()
{
    if( ![NSApp respondsToSelector: @selector(removeFallbackMenuItem:)] )
        return;

    // Remove previous default menu
    if ( pDefMenu )
        [NSApp performSelector:@selector(removeFallbackMenuItem:) withObject: pDefMenu];

    // Remove previous preferred menu
    if ( pPreferredMenus && [pPreferredMenus count] )
    {
        for ( NSMenuItem *pNSMenuItem in pPreferredMenus )
            [NSApp performSelector:@selector(removeFallbackMenuItem:) withObject: pNSMenuItem];
    }
}

static void resetMenuBar()
{
    if( ![NSApp respondsToSelector: @selector(addFallbackMenuItem:)] )
        return;

    clearDefaultMenuBar();

    if ( pPreferredMenus && [pPreferredMenus count] )
    {
        for ( NSMenuItem *pNSMenuItem in pPreferredMenus )
            [NSApp performSelector:@selector(addFallbackMenuItem:) withObject: pNSMenuItem];
    }
    else if ( pDefMenu )
    {
        [NSApp performSelector:@selector(addFallbackMenuItem:) withObject: pDefMenu];
    }
}

void ShutdownIcon::SetDefaultMenuBar( MenuBar *pMenuBar )
{
    if ( !pMenuBar )
        return;

    SolarMutexGuard aGuard;

    clearDefaultMenuBar();
    if ( pPreferredMenus )
    {
        [pPreferredMenus release];
        pPreferredMenus = nil;
    }

    NSMenu *pNSMenu = getNSMenuForVCLMenu( pMenuBar );
    if ( pNSMenu && [pNSMenu numberOfItems] )
    {
        pPreferredMenus = [NSMutableArray arrayWithArray: [pNSMenu itemArray]];
        [pNSMenu removeAllItems];
        [pPreferredMenus retain];
    }

    resetMenuBar();
}


extern "C"
{

void aqua_init_systray()
{
    SolarMutexGuard aGuard;

    ShutdownIcon *pShutdownIcon = ShutdownIcon::getInstance();
    if( ! pShutdownIcon )
        return;

    // disable shutdown
    pShutdownIcon->SetVeto( true );
    ShutdownIcon::addTerminateListener();

    if( ! pDefMenu )
    {
        if( [NSApp respondsToSelector: @selector(addFallbackMenuItem:)] )
        {
            aShortcuts.clear();

            pExecute = [[QSMenuExecute alloc] init];
            pDefMenu = [[NSMenuItem alloc] initWithTitle: getAutoreleasedString( SfxResId(STR_QUICKSTART_FILE) ) action: nullptr keyEquivalent: @""];
            pDockSubMenu = [[NSMenuItem alloc] initWithTitle: getAutoreleasedString( SfxResId(STR_QUICKSTART_FILE) ) action: nullptr keyEquivalent: @""];
            NSMenu* pMenu = [[NSMenu alloc] initWithTitle: getAutoreleasedString( SfxResId(STR_QUICKSTART_FILE) )];
            [pMenu setAutoenablesItems: NO];
            NSMenu* pDockMenu = [[NSMenu alloc] initWithTitle: getAutoreleasedString( SfxResId(STR_QUICKSTART_FILE) )];
            [pDockMenu setAutoenablesItems: NO];

            // collect the URLs of the entries in the File/New menu
            SvtModuleOptions    aModuleOptions;
            std::set< OUString > aFileNewAppsAvailable;
            std::vector < SvtDynMenuEntry > const aNewMenu = SvtDynamicMenuOptions::GetMenu( EDynamicMenuType::NewMenu );

            for ( SvtDynMenuEntry const & newMenuProp : aNewMenu )
            {
                if ( !newMenuProp.sURL.isEmpty() )
                    aFileNewAppsAvailable.insert( newMenuProp.sURL );
            }

            // describe the menu entries for launching the applications
            struct MenuEntryDescriptor
            {
                SvtModuleOptions::EModule   eModuleIdentifier;
                int                         nMenuTag;
                OUString                    sURLDescription;
            } static constexpr aMenuItems[] =
            {
                { SvtModuleOptions::EModule::WRITER,    MI_WRITER,  WRITER_URL },
                { SvtModuleOptions::EModule::CALC,      MI_CALC,    CALC_URL },
                { SvtModuleOptions::EModule::IMPRESS,   MI_IMPRESS, IMPRESS_WIZARD_URL },
                { SvtModuleOptions::EModule::DRAW,      MI_DRAW,    DRAW_URL },
                { SvtModuleOptions::EModule::DATABASE,  MI_BASE,    BASE_URL },
                { SvtModuleOptions::EModule::MATH,      MI_MATH,    MATH_URL }
            };

            // insert entry for startcenter
            if( aModuleOptions.IsModuleInstalled( SvtModuleOptions::EModule::STARTMODULE ) )
            {
                appendMenuItem( pMenu, nil, SfxResId(STR_QUICKSTART_STARTCENTER), MI_STARTMODULE, "n" );
                if( [NSApp respondsToSelector: @selector(setDockIconClickHandler:)] )
                    [NSApp performSelector:@selector(setDockIconClickHandler:) withObject: pExecute];
                else
                    OSL_FAIL( "setDockIconClickHandler selector failed on NSApp" );

            }

            // insert the menu entries for launching the applications
            for ( size_t i = 0; i < SAL_N_ELEMENTS( aMenuItems ); ++i )
            {
                if ( !aModuleOptions.IsModuleInstalled( aMenuItems[i].eModuleIdentifier ) )
                    // the complete application is not even installed
                    continue;

                const OUString& sURL( aMenuItems[i].sURLDescription );

                if ( aFileNewAppsAvailable.find( sURL ) == aFileNewAppsAvailable.end() )
                    // the application is installed, but the entry has been configured to *not* appear in the File/New
                    // menu => also let not appear it in the quickstarter
                    continue;

                appendMenuItem( pMenu, pDockMenu, ShutdownIcon::GetUrlDescription( sURL ), aMenuItems[i].nMenuTag, "" );
            }

            // insert the remaining menu entries

            // add recent menu
            appendRecentMenu( pMenu, SfxResId(STR_QUICKSTART_RECENTDOC) );

            OUString aTitle( SfxResId(STR_QUICKSTART_FROMTEMPLATE) );
            appendMenuItem( pMenu, pDockMenu, aTitle, MI_TEMPLATE, "" );
            aTitle = SfxResId(STR_QUICKSTART_FILEOPEN);
            appendMenuItem( pMenu, pDockMenu, aTitle, MI_OPEN, "" );

            [pDefMenu setSubmenu: pMenu];
            resetMenuBar();

            if( [NSApp respondsToSelector: @selector(addDockMenuItem:)] )
            {
                [pDockSubMenu setSubmenu: pDockMenu];
                // add the submenu
                [NSApp performSelector:@selector(addDockMenuItem:) withObject: pDockSubMenu];
            }
            else
                OSL_FAIL( "addDockMenuItem selector failed on NSApp" );

            [pMenu autorelease];
            [pDockMenu autorelease];
        }
        else
            OSL_FAIL( "addFallbackMenuItem selector failed on NSApp" );
    }
}

void SAL_DLLPUBLIC_EXPORT aqua_shutdown_systray()
{
}

}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

[ Dauer der Verarbeitung: 0.3 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge