1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
26 #include <vcl/i18nhelp.hxx>
27 #include <vcl/settings.hxx>
28 #include <vcl/window.hxx>
33 MenuItemData::~MenuItemData()
35 if (aUserValueReleaseFunc
)
36 aUserValueReleaseFunc(nUserValue
);
39 static_cast<PopupMenu
*>(pAutoSubMenu
.get())->pRefAutoSubMenu
= nullptr;
40 pAutoSubMenu
.disposeAndClear();
43 ImplGetSVData()->mpDefInst
->DestroyMenuItem( pSalMenuItem
);
44 pSubMenu
.disposeAndClear();
47 MenuItemList::~MenuItemList()
49 for(MenuItemData
* i
: maItemList
)
53 MenuItemData
* MenuItemList::Insert(
64 MenuItemData
* pData
= new MenuItemData( rStr
, rImage
);
66 pData
->sIdent
= rIdent
;
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
;
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
);
91 maItemList
.push_back( pData
);
96 void MenuItemList::InsertSeparator(const OString
&rIdent
, size_t nPos
)
98 MenuItemData
* pData
= new MenuItemData
;
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
;
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
);
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
)
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
)
152 return maItemList
[ i
];
158 MenuItemData
* MenuItemList::SearchItem(
159 sal_Unicode cSelectChar
,
162 sal_uInt16
& nDuplicates
,
163 sal_uInt16 nCurrentPos
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
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
187 // nothing found, try keycode instead
188 nDuplicates
= GetItemCount( aKeyCode
); // return number of duplicates
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('~');
205 sal_Unicode nUnicode
= pData
->aText
[n
+1];
206 vcl::Window
* pDefWindow
= ImplGetDefaultWindow();
208 && pDefWindow
->ImplGetFrame()->MapUnicodeToKeyCode( nUnicode
,
209 Application::GetSettings().GetUILanguageTag().getLanguageType(), nKeyCode
)
210 && aKeyCode
.GetCode() == nKeyCode
.GetCode()
213 && rI18nHelper
.MatchMnemonic( pData
->aText
, ascii
)
217 if( nDuplicates
> 1 && rPos
== nCurrentPos
)
218 continue; // select next entry with the same mnemonic
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();
236 for ( size_t nPos
= maItemList
.size(); nPos
; )
238 MenuItemData
* pData
= maItemList
[ --nPos
];
239 if ( pData
->bEnabled
&& rI18nHelper
.MatchMnemonic( pData
->aText
, cSelectChar
) )
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();
252 if( aKeyCode
.GetCode() >= KEY_A
&& aKeyCode
.GetCode() <= KEY_Z
)
253 ascii
= sal::static_int_cast
<char>('A' + (aKeyCode
.GetCode() - KEY_A
));
256 for ( size_t nPos
= maItemList
.size(); nPos
; )
258 MenuItemData
* pData
= maItemList
[ --nPos
];
259 if ( pData
->bEnabled
)
261 sal_Int32 n
= pData
->aText
.indexOf('~');
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();
269 && pDefWindow
->ImplGetFrame()->MapUnicodeToKeyCode( pData
->aText
[n
+1],
270 Application::GetSettings().GetUILanguageTag().getLanguageType(), nKeyCode
)
271 && aKeyCode
.GetCode() == nKeyCode
.GetCode()
274 && rI18nHelper
.MatchMnemonic( pData
->aText
, ascii
)
285 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */