LibreOffice Module vcl (master) 1
accel.cxx
Go to the documentation of this file.
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 <sal/log.hxx>
21#include <osl/diagnose.h>
22#include <accel.hxx>
23
24#define ACCELENTRY_NOTFOUND (sal_uInt16(0xFFFF))
25
26static sal_uInt16 ImplAccelEntryGetIndex( const ImplAccelList* pList, sal_uInt16 nId,
27 sal_uInt16* pIndex = nullptr )
28{
29 size_t nLow;
30 size_t nHigh;
31 size_t nMid;
32 size_t nCount = pList->size();
33 sal_uInt16 nCompareId;
34
35 // check if first key is larger then the key to compare
36 if ( !nCount || (nId < (*pList)[ 0 ]->mnId) )
37 {
38 if ( pIndex )
39 *pIndex = 0;
41 }
42
43 // Binary search
44 nLow = 0;
45 nHigh = nCount-1;
46 do
47 {
48 nMid = (nLow + nHigh) / 2;
49 nCompareId = (*pList)[ nMid ]->mnId;
50 if ( nId < nCompareId )
51 nHigh = nMid-1;
52 else
53 {
54 if ( nId > nCompareId )
55 nLow = nMid + 1;
56 else
57 return static_cast<sal_uInt16>(nMid);
58 }
59 }
60 while ( nLow <= nHigh );
61
62 if ( pIndex )
63 {
64 if ( nId > nCompareId )
65 *pIndex = static_cast<sal_uInt16>(nMid+1);
66 else
67 *pIndex = static_cast<sal_uInt16>(nMid);
68 }
69
71}
72
73static void ImplAccelEntryInsert( ImplAccelList* pList, std::unique_ptr<ImplAccelEntry> pEntry )
74{
75 sal_uInt16 nInsIndex(0);
76 std::vector<ImplAccelEntry *>::size_type nIndex = ImplAccelEntryGetIndex( pList, pEntry->mnId, &nInsIndex );
77
79 {
80 do
81 {
82 nIndex++;
83 ImplAccelEntry* pTempEntry = nullptr;
84 if ( nIndex < pList->size() )
85 pTempEntry = (*pList)[ nIndex ].get();
86 if ( !pTempEntry || (pTempEntry->mnId != pEntry->mnId) )
87 break;
88 }
89 while ( nIndex < pList->size() );
90
91 if ( nIndex < pList->size() ) {
92 pList->insert( pList->begin() + nIndex, std::move(pEntry) );
93 } else {
94 pList->push_back( std::move(pEntry) );
95 }
96 }
97 else {
98 if ( nInsIndex < pList->size() ) {
99 pList->insert( pList->begin() + nInsIndex, std::move(pEntry) );
100 } else {
101 pList->push_back( std::move(pEntry) );
102 }
103 }
104}
105
107{
108 mnCurId = 0;
109 mpDel = nullptr;
110}
111
113{
114 auto it = maKeyMap.find( rKeyCode.GetFullCode() );
115 if( it != maKeyMap.end() )
116 return it->second;
117 else
118 return nullptr;
119}
120
121void Accelerator::ImplCopyData( const Accelerator& rAccelData )
122{
123 // copy table
124 for (const std::unique_ptr<ImplAccelEntry>& i : rAccelData.maIdList)
125 {
126 std::unique_ptr<ImplAccelEntry> pEntry(new ImplAccelEntry( *i ));
127
128 // sequence accelerator, then copy also
129 if ( pEntry->mpAccel )
130 {
131 pEntry->mpAccel = new Accelerator( *(pEntry->mpAccel) );
132 pEntry->mpAutoAccel = pEntry->mpAccel;
133 }
134 else
135 pEntry->mpAutoAccel = nullptr;
136
137 maKeyMap.insert( std::make_pair( pEntry->maKeyCode.GetFullCode(), pEntry.get() ) );
138 maIdList.push_back( std::move(pEntry) );
139 }
140}
141
143{
144 // delete accelerator-entries using the id-table
145 for (const std::unique_ptr<ImplAccelEntry>& pEntry : maIdList) {
146 delete pEntry->mpAutoAccel;
147 }
148 maIdList.clear();
149}
150
151void Accelerator::ImplInsertAccel( sal_uInt16 nItemId, const vcl::KeyCode& rKeyCode,
152 bool bEnable, Accelerator* pAutoAccel )
153{
154 SAL_WARN_IF( !nItemId, "vcl", "Accelerator::InsertItem(): ItemId == 0" );
155
156 if ( rKeyCode.IsFunction() )
157 {
158 sal_uInt16 nCode1;
159 sal_uInt16 nCode2;
160 sal_uInt16 nCode3;
161 sal_uInt16 nCode4;
162 ImplGetKeyCode( rKeyCode.GetFunction(), nCode1, nCode2, nCode3, nCode4 );
163 if ( nCode1 )
164 ImplInsertAccel( nItemId, vcl::KeyCode( nCode1, nCode1 ), bEnable, pAutoAccel );
165 if ( nCode2 )
166 {
167 if ( pAutoAccel )
168 pAutoAccel = new Accelerator( *pAutoAccel );
169 ImplInsertAccel( nItemId, vcl::KeyCode( nCode2, nCode2 ), bEnable, pAutoAccel );
170 if ( nCode3 )
171 {
172 if ( pAutoAccel )
173 pAutoAccel = new Accelerator( *pAutoAccel );
174 ImplInsertAccel( nItemId, vcl::KeyCode( nCode3, nCode3 ), bEnable, pAutoAccel );
175 }
176 }
177 return;
178 }
179
180 // fetch and fill new entries
181 std::unique_ptr<ImplAccelEntry> pEntry(new ImplAccelEntry);
182 pEntry->mnId = nItemId;
183 pEntry->maKeyCode = rKeyCode;
184 pEntry->mpAccel = pAutoAccel;
185 pEntry->mpAutoAccel = pAutoAccel;
186 pEntry->mbEnabled = bEnable;
187
188 // now into the tables
189 sal_uLong nCode = rKeyCode.GetFullCode();
190 if ( !nCode )
191 {
192 OSL_FAIL( "Accelerator::InsertItem(): KeyCode with KeyCode 0 not allowed" );
193 }
194 else if ( !maKeyMap.insert( std::make_pair( nCode, pEntry.get() ) ).second )
195 {
196 SAL_WARN( "vcl", "Accelerator::InsertItem(): KeyCode (Key: " << nCode << ") already exists" );
197 }
198 else
199 ImplAccelEntryInsert( &maIdList, std::move(pEntry) );
200}
201
203{
204 ImplInit();
205}
206
208{
209 ImplInit();
210 ImplCopyData(rAccel);
211}
212
214{
215
216 // inform AccelManager about deleting the Accelerator
217 if ( mpDel )
218 *mpDel = true;
219
221}
222
224{
225 maActivateHdl.Call( *this );
226}
227
229{
230 maSelectHdl.Call( *this );
231}
232
233void Accelerator::InsertItem( sal_uInt16 nItemId, const vcl::KeyCode& rKeyCode )
234{
235 ImplInsertAccel( nItemId, rKeyCode, true, nullptr );
236}
237
239{
240 return static_cast<sal_uInt16>(maIdList.size());
241}
242
243sal_uInt16 Accelerator::GetItemId( sal_uInt16 nPos ) const
244{
245
246 ImplAccelEntry* pEntry = ( nPos < maIdList.size() ) ? maIdList[ nPos ].get() : nullptr;
247 if ( pEntry )
248 return pEntry->mnId;
249 else
250 return 0;
251}
252
253Accelerator* Accelerator::GetAccel( sal_uInt16 nItemId ) const
254{
255
256 sal_uInt16 nIndex = ImplAccelEntryGetIndex( &maIdList, nItemId );
258 return maIdList[ nIndex ]->mpAccel;
259 else
260 return nullptr;
261}
262
264{
265 if(this == &rAccel)
266 return *this;
267
268 // assign new data
269 mnCurId = 0;
270
271 // delete and copy tables
273 maKeyMap.clear();
274 ImplCopyData(rAccel);
275
276 return *this;
277}
278
279/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static void ImplAccelEntryInsert(ImplAccelList *pList, std::unique_ptr< ImplAccelEntry > pEntry)
Definition: accel.cxx:73
#define ACCELENTRY_NOTFOUND
Definition: accel.cxx:24
static sal_uInt16 ImplAccelEntryGetIndex(const ImplAccelList *pList, sal_uInt16 nId, sal_uInt16 *pIndex=nullptr)
Definition: accel.cxx:26
::std::vector< std::unique_ptr< ImplAccelEntry > > ImplAccelList
Definition: accel.hxx:45
bool * mpDel
Definition: accel.hxx:60
sal_uInt16 mnCurId
Definition: accel.hxx:59
~Accelerator()
Definition: accel.cxx:213
Link< Accelerator &, void > maSelectHdl
Definition: accel.hxx:56
Accelerator * GetAccel(sal_uInt16 nItemId) const
Definition: accel.cxx:253
void ImplInit()
Definition: accel.cxx:106
sal_uInt16 GetItemCount() const
Definition: accel.cxx:238
void ImplDeleteData()
Definition: accel.cxx:142
void InsertItem(sal_uInt16 nItemId, const vcl::KeyCode &rKeyCode)
Definition: accel.cxx:233
void ImplCopyData(const Accelerator &rAccelData)
Definition: accel.cxx:121
Link< Accelerator &, void > maActivateHdl
Definition: accel.hxx:55
Accelerator()
Definition: accel.cxx:202
ImplAccelList maIdList
Definition: accel.hxx:54
ImplAccelEntry * ImplGetAccelData(const vcl::KeyCode &rKeyCode) const
Definition: accel.cxx:112
void Activate()
Definition: accel.cxx:223
sal_uInt16 GetItemId(sal_uInt16 nPos) const
Definition: accel.cxx:243
ImplAccelMap maKeyMap
Definition: accel.hxx:53
void ImplInsertAccel(sal_uInt16 nItemId, const vcl::KeyCode &rKeyCode, bool bEnable, Accelerator *pAutoAccel)
Definition: accel.cxx:151
void Select()
Definition: accel.cxx:228
Accelerator & operator=(const Accelerator &rAccel)
Definition: accel.cxx:263
sal_uInt16 mnId
Definition: accel.hxx:41
bool IsFunction() const
Definition: keycod.hxx:67
KeyFuncType GetFunction() const
Definition: keycod.cxx:72
sal_uInt16 GetFullCode() const
Definition: keycod.hxx:46
int nCount
sal_uInt16 mnId
sal_Int32 nIndex
bool ImplGetKeyCode(KeyFuncType eFunc, sal_uInt16 &rCode1, sal_uInt16 &rCode2, sal_uInt16 &rCode3, sal_uInt16 &rCode4)
Definition: keycod.cxx:40
sal_uInt16 nPos
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
size
int i
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
sal_Int16 nId
sal_uIntPtr sal_uLong