Line data Source code
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 "menuitemlist.hxx"
21 :
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>
29 :
30 : using namespace css;
31 : using namespace vcl;
32 :
33 1153808 : MenuItemData::~MenuItemData()
34 : {
35 576904 : if( pAutoSubMenu )
36 : {
37 8 : static_cast<PopupMenu*>(pAutoSubMenu)->pRefAutoSubMenu = NULL;
38 8 : delete pAutoSubMenu;
39 8 : pAutoSubMenu = NULL;
40 : }
41 576904 : if( pSalMenuItem )
42 0 : ImplGetSVData()->mpDefInst->DestroyMenuItem( pSalMenuItem );
43 576904 : }
44 :
45 279736 : MenuItemList::~MenuItemList()
46 : {
47 716650 : for( size_t i = 0, n = maItemList.size(); i < n; ++i )
48 576782 : delete maItemList[ i ];
49 139868 : }
50 :
51 490660 : MenuItemData* MenuItemList::Insert(
52 : sal_uInt16 nId,
53 : MenuItemType eType,
54 : MenuItemBits nBits,
55 : const OUString& rStr,
56 : const Image& rImage,
57 : Menu* pMenu,
58 : size_t nPos,
59 : const OString &rIdent
60 : )
61 : {
62 490660 : MenuItemData* pData = new MenuItemData( rStr, rImage );
63 490660 : pData->nId = nId;
64 490660 : pData->sIdent = rIdent;
65 490660 : pData->eType = eType;
66 490660 : pData->nBits = nBits;
67 490660 : pData->pSubMenu = NULL;
68 490660 : pData->pAutoSubMenu = NULL;
69 490660 : pData->nUserValue = 0;
70 490660 : pData->bChecked = false;
71 490660 : pData->bEnabled = true;
72 490660 : pData->bVisible = true;
73 490660 : pData->bIsTemporary = false;
74 490660 : pData->bMirrorMode = false;
75 490660 : pData->nItemImageAngle = 0;
76 :
77 490660 : SalItemParams aSalMIData;
78 490660 : aSalMIData.nId = nId;
79 490660 : aSalMIData.eType = eType;
80 490660 : aSalMIData.nBits = nBits;
81 490660 : aSalMIData.pMenu = pMenu;
82 490660 : aSalMIData.aText = rStr;
83 490660 : aSalMIData.aImage = rImage;
84 :
85 : // Native-support: returns NULL if not supported
86 490660 : pData->pSalMenuItem = ImplGetSVData()->mpDefInst->CreateMenuItem( &aSalMIData );
87 :
88 490660 : if( nPos < maItemList.size() ) {
89 2 : maItemList.insert( maItemList.begin() + nPos, pData );
90 : } else {
91 490658 : maItemList.push_back( pData );
92 : }
93 490660 : return pData;
94 : }
95 :
96 86272 : void MenuItemList::InsertSeparator(const OString &rIdent, size_t nPos)
97 : {
98 86272 : MenuItemData* pData = new MenuItemData;
99 86272 : pData->nId = 0;
100 86272 : pData->sIdent = rIdent;
101 86272 : pData->eType = MenuItemType::SEPARATOR;
102 86272 : pData->nBits = MenuItemBits::NONE;
103 86272 : pData->pSubMenu = NULL;
104 86272 : pData->pAutoSubMenu = NULL;
105 86272 : pData->nUserValue = 0;
106 86272 : pData->bChecked = false;
107 86272 : pData->bEnabled = true;
108 86272 : pData->bVisible = true;
109 86272 : pData->bIsTemporary = false;
110 86272 : pData->bMirrorMode = false;
111 86272 : pData->nItemImageAngle = 0;
112 :
113 86272 : SalItemParams aSalMIData;
114 86272 : aSalMIData.nId = 0;
115 86272 : aSalMIData.eType = MenuItemType::SEPARATOR;
116 86272 : aSalMIData.nBits = MenuItemBits::NONE;
117 86272 : aSalMIData.pMenu = NULL;
118 86272 : aSalMIData.aText = OUString();
119 86272 : aSalMIData.aImage = Image();
120 :
121 : // Native-support: returns NULL if not supported
122 86272 : pData->pSalMenuItem = ImplGetSVData()->mpDefInst->CreateMenuItem( &aSalMIData );
123 :
124 86272 : if( nPos < maItemList.size() ) {
125 0 : maItemList.insert( maItemList.begin() + nPos, pData );
126 : } else {
127 86272 : maItemList.push_back( pData );
128 86272 : }
129 86272 : }
130 :
131 122 : void MenuItemList::Remove( size_t nPos )
132 : {
133 122 : if( nPos < maItemList.size() )
134 : {
135 122 : delete maItemList[ nPos ];
136 122 : maItemList.erase( maItemList.begin() + nPos );
137 : }
138 122 : }
139 :
140 2413218 : MenuItemData* MenuItemList::GetData( sal_uInt16 nSVId, size_t& rPos ) const
141 : {
142 19491191 : for( size_t i = 0, n = maItemList.size(); i < n; ++i )
143 : {
144 19469403 : if ( maItemList[ i ]->nId == nSVId )
145 : {
146 2391430 : rPos = i;
147 2391430 : return maItemList[ i ];
148 : }
149 : }
150 21788 : return NULL;
151 : }
152 :
153 0 : MenuItemData* MenuItemList::SearchItem(
154 : sal_Unicode cSelectChar,
155 : KeyCode aKeyCode,
156 : sal_uInt16& rPos,
157 : sal_uInt16& nDuplicates,
158 : sal_uInt16 nCurrentPos
159 : ) const
160 : {
161 0 : const vcl::I18nHelper& rI18nHelper = Application::GetSettings().GetUILocaleI18nHelper();
162 :
163 0 : size_t nListCount = maItemList.size();
164 :
165 : // try character code first
166 0 : nDuplicates = GetItemCount( cSelectChar ); // return number of duplicates
167 0 : if( nDuplicates )
168 : {
169 0 : for ( rPos = 0; rPos < nListCount; rPos++)
170 : {
171 0 : MenuItemData* pData = maItemList[ rPos ];
172 0 : if ( pData->bEnabled && rI18nHelper.MatchMnemonic( pData->aText, cSelectChar ) )
173 : {
174 0 : if( nDuplicates > 1 && rPos == nCurrentPos )
175 0 : continue; // select next entry with the same mnemonic
176 : else
177 0 : return pData;
178 : }
179 : }
180 : }
181 :
182 : // nothing found, try keycode instead
183 0 : nDuplicates = GetItemCount( aKeyCode ); // return number of duplicates
184 :
185 0 : if( nDuplicates )
186 : {
187 0 : char ascii = 0;
188 0 : if( aKeyCode.GetCode() >= KEY_A && aKeyCode.GetCode() <= KEY_Z )
189 0 : ascii = sal::static_int_cast<char>('A' + (aKeyCode.GetCode() - KEY_A));
190 :
191 0 : for ( rPos = 0; rPos < nListCount; rPos++)
192 : {
193 0 : MenuItemData* pData = maItemList[ rPos ];
194 0 : if ( pData->bEnabled )
195 : {
196 0 : sal_Int32 n = pData->aText.indexOf('~');
197 0 : if ( n != -1 )
198 : {
199 0 : KeyCode mnKeyCode;
200 0 : sal_Unicode mnUnicode = pData->aText[n+1];
201 0 : vcl::Window* pDefWindow = ImplGetDefaultWindow();
202 0 : if( ( pDefWindow
203 0 : && pDefWindow->ImplGetFrame()->MapUnicodeToKeyCode( mnUnicode,
204 0 : Application::GetSettings().GetUILanguageTag().getLanguageType(), mnKeyCode )
205 0 : && aKeyCode.GetCode() == mnKeyCode.GetCode()
206 : )
207 0 : || ( ascii
208 0 : && rI18nHelper.MatchMnemonic( pData->aText, ascii )
209 : )
210 : )
211 : {
212 0 : if( nDuplicates > 1 && rPos == nCurrentPos )
213 0 : continue; // select next entry with the same mnemonic
214 : else
215 0 : return pData;
216 : }
217 : }
218 : }
219 : }
220 : }
221 :
222 0 : return NULL;
223 : }
224 :
225 0 : size_t MenuItemList::GetItemCount( sal_Unicode cSelectChar ) const
226 : {
227 : // returns number of entries with same mnemonic
228 0 : const vcl::I18nHelper& rI18nHelper = Application::GetSettings().GetUILocaleI18nHelper();
229 :
230 0 : size_t nItems = 0;
231 0 : for ( size_t nPos = maItemList.size(); nPos; )
232 : {
233 0 : MenuItemData* pData = maItemList[ --nPos ];
234 0 : if ( pData->bEnabled && rI18nHelper.MatchMnemonic( pData->aText, cSelectChar ) )
235 0 : nItems++;
236 : }
237 :
238 0 : return nItems;
239 : }
240 :
241 0 : size_t MenuItemList::GetItemCount( KeyCode aKeyCode ) const
242 : {
243 : // returns number of entries with same mnemonic
244 : // uses key codes instead of character codes
245 0 : const vcl::I18nHelper& rI18nHelper = Application::GetSettings().GetUILocaleI18nHelper();
246 0 : char ascii = 0;
247 0 : if( aKeyCode.GetCode() >= KEY_A && aKeyCode.GetCode() <= KEY_Z )
248 0 : ascii = sal::static_int_cast<char>('A' + (aKeyCode.GetCode() - KEY_A));
249 :
250 0 : size_t nItems = 0;
251 0 : for ( size_t nPos = maItemList.size(); nPos; )
252 : {
253 0 : MenuItemData* pData = maItemList[ --nPos ];
254 0 : if ( pData->bEnabled )
255 : {
256 0 : sal_Int32 n = pData->aText.indexOf('~');
257 0 : if (n != -1)
258 : {
259 0 : KeyCode mnKeyCode;
260 : // if MapUnicodeToKeyCode fails or is unsupported we try the pure ascii mapping of the keycodes
261 : // so we have working shortcuts when ascii mnemonics are used
262 0 : vcl::Window* pDefWindow = ImplGetDefaultWindow();
263 0 : if( ( pDefWindow
264 0 : && pDefWindow->ImplGetFrame()->MapUnicodeToKeyCode( pData->aText[n+1],
265 0 : Application::GetSettings().GetUILanguageTag().getLanguageType(), mnKeyCode )
266 0 : && aKeyCode.GetCode() == mnKeyCode.GetCode()
267 : )
268 0 : || ( ascii
269 0 : && rI18nHelper.MatchMnemonic( pData->aText, ascii )
270 : )
271 : )
272 0 : nItems++;
273 : }
274 : }
275 : }
276 :
277 0 : return nItems;
278 1233 : }
279 :
280 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|