bump product version to 4.1.6.2
[LibreOffice.git] / vcl / source / window / accmgr.cxx
blobfd7ac8249a3c9658426f07b1a0a979dfc7a49036
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 .
21 #include <tools/debug.hxx>
23 #include <accel.h>
24 #include <vcl/accel.hxx>
25 #include <accmgr.hxx>
27 // =======================================================================
29 DBG_NAMEEX( Accelerator )
31 // =======================================================================
33 ImplAccelManager::~ImplAccelManager()
35 delete mpAccelList;
36 delete mpSequenceList;
39 // -----------------------------------------------------------------------
41 sal_Bool ImplAccelManager::InsertAccel( Accelerator* pAccel )
43 if ( !mpAccelList ) {
44 mpAccelList = new ImplAccelList;
45 } else {
46 for ( size_t i = 0, n = mpAccelList->size(); i < n; ++i ) {
47 if ( (*mpAccelList)[ i ] == pAccel ) {
48 return sal_False;
53 mpAccelList->insert( mpAccelList->begin(), pAccel );
54 return sal_True;
57 // -----------------------------------------------------------------------
59 void ImplAccelManager::RemoveAccel( Accelerator* pAccel )
61 // do we have a list ?
62 if ( !mpAccelList )
63 return;
65 //e.g. #i90599#. Someone starts typing a sequence in a dialog, but doesn't
66 //end it, and then closes the dialog, deleting the accelerators. So if
67 //we're removing an accelerator that a sub-accelerator which is in the
68 //sequence list, throw away the entire sequence
69 if ( mpSequenceList ) {
70 for (sal_uInt16 i = 0; i < pAccel->GetItemCount(); ++i) {
71 Accelerator* pSubAccel = pAccel->GetAccel( pAccel->GetItemId(i) );
72 for ( size_t j = 0, n = mpSequenceList->size(); j < n; ++j ) {
73 if ( (*mpSequenceList)[ j ] == pSubAccel ) {
74 EndSequence( true );
75 i = pAccel->GetItemCount();
76 break;
82 // throw it away
83 for ( ImplAccelList::iterator it = mpAccelList->begin();
84 it != mpAccelList->end();
85 ++it
86 ) {
87 if ( *it == pAccel ) {
88 mpAccelList->erase( it );
89 break;
94 // -----------------------------------------------------------------------
96 void ImplAccelManager::EndSequence( sal_Bool bCancel )
98 // are we in a list ?
99 if ( !mpSequenceList )
100 return;
102 // call all deactivate-handler of the accelerators in the list
103 for ( size_t i = 0, n = mpSequenceList->size(); i < n; ++i )
105 Accelerator* pTempAccel = (*mpSequenceList)[ i ];
106 sal_Bool bDel = sal_False;
107 pTempAccel->mbIsCancel = bCancel;
108 pTempAccel->mpDel = &bDel;
109 pTempAccel->Deactivate();
110 if ( !bDel )
112 pTempAccel->mbIsCancel = sal_False;
113 pTempAccel->mpDel = NULL;
117 // delete sequence-list
118 delete mpSequenceList;
119 mpSequenceList = NULL;
122 // -----------------------------------------------------------------------
124 sal_Bool ImplAccelManager::IsAccelKey( const KeyCode& rKeyCode, sal_uInt16 nRepeat )
126 Accelerator* pAccel;
128 // do we have accelerators ??
129 if ( !mpAccelList )
130 return sal_False;
131 if ( mpAccelList->empty() )
132 return sal_False;
134 // are we in a sequence ?
135 if ( mpSequenceList )
137 pAccel = mpSequenceList->empty() ? NULL : (*mpSequenceList)[ 0 ];
138 DBG_CHKOBJ( pAccel, Accelerator, NULL );
140 // not found ?
141 if ( !pAccel )
143 // abort sequence
144 FlushAccel();
145 return sal_False;
148 // can the entry be found ?
149 ImplAccelEntry* pEntry = pAccel->ImplGetAccelData( rKeyCode );
150 if ( pEntry )
152 Accelerator* pNextAccel = pEntry->mpAccel;
154 // is an accelerator coupled ?
155 if ( pNextAccel )
157 DBG_CHKOBJ( pNextAccel, Accelerator, NULL );
159 mpSequenceList->insert( mpSequenceList->begin(), pNextAccel );
161 // call Activate-Handler of the new one
162 pNextAccel->Activate();
163 return sal_True;
165 else
167 // it is there already !
168 if ( pEntry->mbEnabled )
170 // stop sequence (first call deactivate-handler)
171 EndSequence();
173 // set accelerator of the actuel item
174 // and call the handler
175 sal_Bool bDel = sal_False;
176 pAccel->maCurKeyCode = rKeyCode;
177 pAccel->mnCurId = pEntry->mnId;
178 pAccel->mnCurRepeat = nRepeat;
179 pAccel->mpDel = &bDel;
180 pAccel->Select();
182 // did the accelerator survive the call
183 if ( !bDel )
185 DBG_CHKOBJ( pAccel, Accelerator, NULL );
186 pAccel->maCurKeyCode = KeyCode();
187 pAccel->mnCurId = 0;
188 pAccel->mnCurRepeat = 0;
189 pAccel->mpDel = NULL;
192 return sal_True;
194 else
196 // stop sequence as the accelerator was disbled
197 // transfer the key (to the system)
198 FlushAccel();
199 return sal_False;
203 else
205 // wrong key => stop sequence
206 FlushAccel();
207 return sal_False;
211 // step through the list of accelerators
212 for ( size_t i = 0, n = mpAccelList->size(); i < n; ++i )
214 pAccel = (*mpAccelList)[ i ];
215 DBG_CHKOBJ( pAccel, Accelerator, NULL );
217 // is the entry contained ?
218 ImplAccelEntry* pEntry = pAccel->ImplGetAccelData( rKeyCode );
219 if ( pEntry )
221 Accelerator* pNextAccel = pEntry->mpAccel;
223 // is an accelerator assigned ?
224 if ( pNextAccel )
226 DBG_CHKOBJ( pNextAccel, Accelerator, NULL );
228 // create sequence list
229 mpSequenceList = new ImplAccelList;
230 mpSequenceList->insert( mpSequenceList->begin(), pAccel );
231 mpSequenceList->insert( mpSequenceList->begin(), pNextAccel );
233 // call activate-Handler of the new one
234 pNextAccel->Activate();
236 return sal_True;
238 else
240 // already assigned !
241 if ( pEntry->mbEnabled )
243 // first call activate/aeactivate-Handler
244 pAccel->Activate();
245 pAccel->Deactivate();
247 // define accelerator of the actual item
248 // and call the handler
249 sal_Bool bDel = sal_False;
250 pAccel->maCurKeyCode = rKeyCode;
251 pAccel->mnCurId = pEntry->mnId;
252 pAccel->mnCurRepeat = nRepeat;
253 pAccel->mpDel = &bDel;
254 pAccel->Select();
256 // if the accelerator did survive the call
257 if ( !bDel )
259 DBG_CHKOBJ( pAccel, Accelerator, NULL );
260 pAccel->maCurKeyCode = KeyCode();
261 pAccel->mnCurId = 0;
262 pAccel->mnCurRepeat = 0;
263 pAccel->mpDel = NULL;
266 return sal_True;
268 else
269 return sal_False;
274 return sal_False;
277 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */