Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/LibreOffice/vcl/source/window/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 9 kB image not shown  

Quelle  menuitemlist.cxx   Sprache: C

 
/* -*- 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 "menuitemlist.hxx"

#include <salframe.hxx>
#include <salinst.hxx>
#include <salmenu.hxx>
#include <svdata.hxx>

#include <vcl/i18nhelp.hxx>
#include <vcl/mnemonic.hxx>
#include <vcl/settings.hxx>
#include <vcl/vcllayout.hxx>
#include <vcl/window.hxx>

using namespace css;
using namespace vcl;

MenuItemData::~MenuItemData()
{
    if (aUserValueReleaseFunc)
        aUserValueReleaseFunc(nUserValue);
    pSalMenuItem.reset();
    pSubMenu.disposeAndClear();
}

SalLayoutGlyphs* MenuItemData::GetTextGlyphs(const OutputDevice* pOutputDevice)
{
    if (aTextGlyphs.IsValid())
        // Use pre-calculated result.
        return &aTextGlyphs;

    OUString aNonMnemonicString = removeMnemonicFromString(aText);
    std::unique_ptr<SalLayout> pLayout
        = pOutputDevice->ImplLayout(aNonMnemonicString, 0, aNonMnemonicString.getLength(),
                                    Point(0, 0), 0, {}, {}, SalLayoutFlags::GlyphItemsOnly);
    if (!pLayout)
        return nullptr;

    // Remember the calculation result.
    aTextGlyphs = pLayout->GetGlyphs();

    return &aTextGlyphs;
}

MenuItemList::~MenuItemList()
{
}

MenuItemData* MenuItemList::Insert(
    sal_uInt16 nId,
    MenuItemType eType,
    MenuItemBits nBits,
    const OUString& rStr,
    Menu* pMenu,
    size_t nPos,
    const OUString &rIdent
)
{
    MenuItemData* pData     = new MenuItemData( rStr );
    pData->nId              = nId;
    pData->sIdent           = rIdent;
    pData->eType            = eType;
    pData->nBits            = nBits;
    pData->pSubMenu         = nullptr;
    pData->nUserValue       = nullptr;
    pData->bChecked         = false;
    pData->bEnabled         = true;
    pData->bVisible         = true;
    pData->bIsTemporary     = false;

    SalItemParams aSalMIData;
    aSalMIData.nId = nId;
    aSalMIData.eType = eType;
    aSalMIData.nBits = nBits;
    aSalMIData.pMenu = pMenu;
    aSalMIData.aText = rStr;

    // Native-support: returns NULL if not supported
    pData->pSalMenuItem = ImplGetSVData()->mpDefInst->CreateMenuItem( aSalMIData );

    if( nPos < maItemList.size() ) {
        maItemList.insert( maItemList.begin() + nPos, std::unique_ptr<MenuItemData>(pData) );
    } else {
        maItemList.emplace_back( pData );
    }
    return pData;
}

void MenuItemList::InsertSeparator(const OUString &rIdent, size_t nPos)
{
    MenuItemData* pData     = new MenuItemData;
    pData->nId              = 0;
    pData->sIdent           = rIdent;
    pData->eType            = MenuItemType::SEPARATOR;
    pData->nBits            = MenuItemBits::NONE;
    pData->pSubMenu         = nullptr;
    pData->nUserValue       = nullptr;
    pData->bChecked         = false;
    pData->bEnabled         = true;
    pData->bVisible         = true;
    pData->bIsTemporary     = false;

    SalItemParams aSalMIData;
    aSalMIData.nId = 0;
    aSalMIData.eType = MenuItemType::SEPARATOR;
    aSalMIData.nBits = MenuItemBits::NONE;
    aSalMIData.pMenu = nullptr;
    aSalMIData.aText.clear();
    aSalMIData.aImage = Image();

    // Native-support: returns NULL if not supported
    pData->pSalMenuItem = ImplGetSVData()->mpDefInst->CreateMenuItem( aSalMIData );

    if( nPos < maItemList.size() ) {
        maItemList.insert( maItemList.begin() + nPos, std::unique_ptr<MenuItemData>(pData) );
    } else {
        maItemList.emplace_back( pData );
    }
}

void MenuItemList::Remove( size_t nPos )
{
    maItemList.erase( maItemList.begin() + nPos );
}

void MenuItemList::Clear()
{
    maItemList.clear();
}

MenuItemData* MenuItemList::GetData( sal_uInt16 nSVId, size_t& rPos ) const
{
    for( size_t i = 0, n = maItemList.size(); i < n; ++i )
    {
        if ( maItemList[ i ]->nId == nSVId )
        {
            rPos = i;
            return maItemList[ i ].get();
        }
    }
    return nullptr;
}

MenuItemData* MenuItemList::SearchItem(
    sal_Unicode cSelectChar,
    KeyCode aKeyCode,
    size_t& rPos,
    size_t& nDuplicates,
    size_t nCurrentPos
const
{
    const vcl::I18nHelper& rI18nHelper = Application::GetSettings().GetUILocaleI18nHelper();

    size_t nListCount = maItemList.size();

    // try character code first
    nDuplicates = GetItemCount( cSelectChar );  // return number of duplicates
    if( nDuplicates )
    {
        MenuItemData* pFirstMatch = nullptr;
        size_t nFirstPos(0);
        for ( rPos = 0; rPos < nListCount; rPos++)
        {
            MenuItemData* pData = maItemList[ rPos ].get();
            if ( pData->bEnabled && rI18nHelper.MatchMnemonic( pData->aText, cSelectChar ) )
            {
                if (nDuplicates == 1)
                    return pData;
                if (rPos > nCurrentPos)
                    return pData;   // select next entry with the same mnemonic
                if (!pFirstMatch)   // stash the first match for use if nothing follows nCurrentPos
                {
                    pFirstMatch = pData;
                    nFirstPos = rPos;
                }
            }
        }
        if (pFirstMatch)
        {
            rPos = nFirstPos;
            return pFirstMatch;
        }
    }

    // nothing found, try keycode instead
    nDuplicates = GetItemCount( aKeyCode ); // return number of duplicates

    if( nDuplicates )
    {
        char ascii = 0;
        if( aKeyCode.GetCode() >= KEY_A && aKeyCode.GetCode() <= KEY_Z )
            ascii = sal::static_int_cast<char>('A' + (aKeyCode.GetCode() - KEY_A));

        MenuItemData* pFirstMatch = nullptr;
        size_t nFirstPos(0);
        for ( rPos = 0; rPos < nListCount; rPos++)
        {
            MenuItemData* pData = maItemList[ rPos ].get();
            if ( pData->bEnabled )
            {
                sal_Int32 n = pData->aText.indexOf('~');
                if ( n != -1 )
                {
                    KeyCode nKeyCode;
                    sal_Unicode nUnicode = pData->aText[n+1];
                    vcl::Window* pDefWindow = ImplGetDefaultWindow();
                    if(  (  pDefWindow
                         && pDefWindow->ImplGetFrame()->MapUnicodeToKeyCode( nUnicode,
                             Application::GetSettings().GetUILanguageTag().getLanguageType(), nKeyCode )
                         && aKeyCode.GetCode() == nKeyCode.GetCode()
                         )
                      || (  ascii
                         && rI18nHelper.MatchMnemonic( pData->aText, ascii )
                         )
                      )
                    {
                        if (nDuplicates == 1)
                            return pData;
                        if (rPos > nCurrentPos)
                            return pData;   // select next entry with the same mnemonic
                        if (!pFirstMatch)   // stash the first match for use if nothing follows nCurrentPos
                        {
                            pFirstMatch = pData;
                            nFirstPos = rPos;
                        }
                    }
                }
            }
        }
        if (pFirstMatch)
        {
            rPos = nFirstPos;
            return pFirstMatch;
        }
    }

    return nullptr;
}

size_t MenuItemList::GetItemCount( sal_Unicode cSelectChar ) const
{
    // returns number of entries with same mnemonic
    const vcl::I18nHelper& rI18nHelper = Application::GetSettings().GetUILocaleI18nHelper();

    size_t nItems = 0;
    for ( size_t nPos = maItemList.size(); nPos; )
    {
        MenuItemData* pData = maItemList[ --nPos ].get();
        if ( pData->bEnabled && rI18nHelper.MatchMnemonic( pData->aText, cSelectChar ) )
            nItems++;
    }

    return nItems;
}

size_t MenuItemList::GetItemCount( KeyCode aKeyCode ) const
{
    // returns number of entries with same mnemonic
    // uses key codes instead of character codes
    const vcl::I18nHelper& rI18nHelper = Application::GetSettings().GetUILocaleI18nHelper();
    char ascii = 0;
    if( aKeyCode.GetCode() >= KEY_A && aKeyCode.GetCode() <= KEY_Z )
        ascii = sal::static_int_cast<char>('A' + (aKeyCode.GetCode() - KEY_A));

    size_t nItems = 0;
    for ( size_t nPos = maItemList.size(); nPos; )
    {
        MenuItemData* pData = maItemList[ --nPos ].get();
        if ( pData->bEnabled )
        {
            sal_Int32 n = pData->aText.indexOf('~');
            if (n != -1)
            {
                KeyCode nKeyCode;
                // if MapUnicodeToKeyCode fails or is unsupported we try the pure ascii mapping of the keycodes
                // so we have working shortcuts when ascii mnemonics are used
                vcl::Window* pDefWindow = ImplGetDefaultWindow();
                if(  (  pDefWindow
                     && pDefWindow->ImplGetFrame()->MapUnicodeToKeyCode( pData->aText[n+1],
                         Application::GetSettings().GetUILanguageTag().getLanguageType(), nKeyCode )
                     && aKeyCode.GetCode() == nKeyCode.GetCode()
                     )
                  || (  ascii
                     && rI18nHelper.MatchMnemonic( pData->aText, ascii )
                     )
                  )
                    nItems++;
            }
        }
    }

    return nItems;
}

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

Messung V0.5
C=91 H=89 G=89

¤ Dauer der Verarbeitung: 0.27 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.