build fix: no comphelper/profilezone.hxx in this branch
[LibreOffice.git] / vcl / source / window / menuitemlist.cxx
blob30bd874d976334bcafa0cfd1548261ead7b6c5af
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "menuitemlist.hxx"
22 #include <salframe.hxx>
23 #include <salinst.hxx>
24 #include <salmenu.hxx>
25 #include <svdata.hxx>
26 #include <vcl/i18nhelp.hxx>
27 #include <vcl/settings.hxx>
28 #include <vcl/window.hxx>
30 using namespace css;
31 using namespace vcl;
33 MenuItemData::~MenuItemData()
35 if (aUserValueReleaseFunc)
36 aUserValueReleaseFunc(nUserValue);
37 if( pAutoSubMenu )
39 static_cast<PopupMenu*>(pAutoSubMenu.get())->pRefAutoSubMenu = nullptr;
40 pAutoSubMenu.disposeAndClear();
42 if( pSalMenuItem )
43 ImplGetSVData()->mpDefInst->DestroyMenuItem( pSalMenuItem );
44 pSubMenu.disposeAndClear();
47 MenuItemList::~MenuItemList()
49 for(MenuItemData* i : maItemList)
50 delete i;
53 MenuItemData* MenuItemList::Insert(
54 sal_uInt16 nId,
55 MenuItemType eType,
56 MenuItemBits nBits,
57 const OUString& rStr,
58 const Image& rImage,
59 Menu* pMenu,
60 size_t nPos,
61 const OString &rIdent
64 MenuItemData* pData = new MenuItemData( rStr, rImage );
65 pData->nId = nId;
66 pData->sIdent = rIdent;
67 pData->eType = eType;
68 pData->nBits = nBits;
69 pData->pSubMenu = nullptr;
70 pData->pAutoSubMenu = nullptr;
71 pData->nUserValue = 0;
72 pData->bChecked = false;
73 pData->bEnabled = true;
74 pData->bVisible = true;
75 pData->bIsTemporary = false;
77 SalItemParams aSalMIData;
78 aSalMIData.nId = nId;
79 aSalMIData.eType = eType;
80 aSalMIData.nBits = nBits;
81 aSalMIData.pMenu = pMenu;
82 aSalMIData.aText = rStr;
83 aSalMIData.aImage = rImage;
85 // Native-support: returns NULL if not supported
86 pData->pSalMenuItem = ImplGetSVData()->mpDefInst->CreateMenuItem( &aSalMIData );
88 if( nPos < maItemList.size() ) {
89 maItemList.insert( maItemList.begin() + nPos, pData );
90 } else {
91 maItemList.push_back( pData );
93 return pData;
96 void MenuItemList::InsertSeparator(const OString &rIdent, size_t nPos)
98 MenuItemData* pData = new MenuItemData;
99 pData->nId = 0;
100 pData->sIdent = rIdent;
101 pData->eType = MenuItemType::SEPARATOR;
102 pData->nBits = MenuItemBits::NONE;
103 pData->pSubMenu = nullptr;
104 pData->pAutoSubMenu = nullptr;
105 pData->nUserValue = 0;
106 pData->bChecked = false;
107 pData->bEnabled = true;
108 pData->bVisible = true;
109 pData->bIsTemporary = false;
111 SalItemParams aSalMIData;
112 aSalMIData.nId = 0;
113 aSalMIData.eType = MenuItemType::SEPARATOR;
114 aSalMIData.nBits = MenuItemBits::NONE;
115 aSalMIData.pMenu = nullptr;
116 aSalMIData.aText.clear();
117 aSalMIData.aImage = Image();
119 // Native-support: returns NULL if not supported
120 pData->pSalMenuItem = ImplGetSVData()->mpDefInst->CreateMenuItem( &aSalMIData );
122 if( nPos < maItemList.size() ) {
123 maItemList.insert( maItemList.begin() + nPos, pData );
124 } else {
125 maItemList.push_back( pData );
129 void MenuItemList::Remove( size_t nPos )
131 if( nPos < maItemList.size() )
133 delete maItemList[ nPos ];
134 maItemList.erase( maItemList.begin() + nPos );
138 void MenuItemList::Clear()
140 for (MenuItemData* i : maItemList)
141 delete i;
142 maItemList.resize(0);
145 MenuItemData* MenuItemList::GetData( sal_uInt16 nSVId, size_t& rPos ) const
147 for( size_t i = 0, n = maItemList.size(); i < n; ++i )
149 if ( maItemList[ i ]->nId == nSVId )
151 rPos = i;
152 return maItemList[ i ];
155 return nullptr;
158 MenuItemData* MenuItemList::SearchItem(
159 sal_Unicode cSelectChar,
160 KeyCode aKeyCode,
161 sal_uInt16& rPos,
162 sal_uInt16& nDuplicates,
163 sal_uInt16 nCurrentPos
164 ) const
166 const vcl::I18nHelper& rI18nHelper = Application::GetSettings().GetUILocaleI18nHelper();
168 size_t nListCount = maItemList.size();
170 // try character code first
171 nDuplicates = GetItemCount( cSelectChar ); // return number of duplicates
172 if( nDuplicates )
174 for ( rPos = 0; rPos < nListCount; rPos++)
176 MenuItemData* pData = maItemList[ rPos ];
177 if ( pData->bEnabled && rI18nHelper.MatchMnemonic( pData->aText, cSelectChar ) )
179 if( nDuplicates > 1 && rPos == nCurrentPos )
180 continue; // select next entry with the same mnemonic
181 else
182 return pData;
187 // nothing found, try keycode instead
188 nDuplicates = GetItemCount( aKeyCode ); // return number of duplicates
190 if( nDuplicates )
192 char ascii = 0;
193 if( aKeyCode.GetCode() >= KEY_A && aKeyCode.GetCode() <= KEY_Z )
194 ascii = sal::static_int_cast<char>('A' + (aKeyCode.GetCode() - KEY_A));
196 for ( rPos = 0; rPos < nListCount; rPos++)
198 MenuItemData* pData = maItemList[ rPos ];
199 if ( pData->bEnabled )
201 sal_Int32 n = pData->aText.indexOf('~');
202 if ( n != -1 )
204 KeyCode nKeyCode;
205 sal_Unicode nUnicode = pData->aText[n+1];
206 vcl::Window* pDefWindow = ImplGetDefaultWindow();
207 if( ( pDefWindow
208 && pDefWindow->ImplGetFrame()->MapUnicodeToKeyCode( nUnicode,
209 Application::GetSettings().GetUILanguageTag().getLanguageType(), nKeyCode )
210 && aKeyCode.GetCode() == nKeyCode.GetCode()
212 || ( ascii
213 && rI18nHelper.MatchMnemonic( pData->aText, ascii )
217 if( nDuplicates > 1 && rPos == nCurrentPos )
218 continue; // select next entry with the same mnemonic
219 else
220 return pData;
227 return nullptr;
230 size_t MenuItemList::GetItemCount( sal_Unicode cSelectChar ) const
232 // returns number of entries with same mnemonic
233 const vcl::I18nHelper& rI18nHelper = Application::GetSettings().GetUILocaleI18nHelper();
235 size_t nItems = 0;
236 for ( size_t nPos = maItemList.size(); nPos; )
238 MenuItemData* pData = maItemList[ --nPos ];
239 if ( pData->bEnabled && rI18nHelper.MatchMnemonic( pData->aText, cSelectChar ) )
240 nItems++;
243 return nItems;
246 size_t MenuItemList::GetItemCount( KeyCode aKeyCode ) const
248 // returns number of entries with same mnemonic
249 // uses key codes instead of character codes
250 const vcl::I18nHelper& rI18nHelper = Application::GetSettings().GetUILocaleI18nHelper();
251 char ascii = 0;
252 if( aKeyCode.GetCode() >= KEY_A && aKeyCode.GetCode() <= KEY_Z )
253 ascii = sal::static_int_cast<char>('A' + (aKeyCode.GetCode() - KEY_A));
255 size_t nItems = 0;
256 for ( size_t nPos = maItemList.size(); nPos; )
258 MenuItemData* pData = maItemList[ --nPos ];
259 if ( pData->bEnabled )
261 sal_Int32 n = pData->aText.indexOf('~');
262 if (n != -1)
264 KeyCode nKeyCode;
265 // if MapUnicodeToKeyCode fails or is unsupported we try the pure ascii mapping of the keycodes
266 // so we have working shortcuts when ascii mnemonics are used
267 vcl::Window* pDefWindow = ImplGetDefaultWindow();
268 if( ( pDefWindow
269 && pDefWindow->ImplGetFrame()->MapUnicodeToKeyCode( pData->aText[n+1],
270 Application::GetSettings().GetUILanguageTag().getLanguageType(), nKeyCode )
271 && aKeyCode.GetCode() == nKeyCode.GetCode()
273 || ( ascii
274 && rI18nHelper.MatchMnemonic( pData->aText, ascii )
277 nItems++;
282 return nItems;
285 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */