Version 3.6.0.2, tag libreoffice-3.6.0.2
[LibreOffice.git] / vcl / source / window / accmgr.cxx
blobad127ace3b2ca99e8fa4722038ee9d69f4f5df1c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include <tools/debug.hxx>
32 #include <accel.h>
33 #include <vcl/accel.hxx>
34 #include <accmgr.hxx>
36 // =======================================================================
38 DBG_NAMEEX( Accelerator )
40 // =======================================================================
42 ImplAccelManager::~ImplAccelManager()
44 delete mpAccelList;
45 delete mpSequenceList;
48 // -----------------------------------------------------------------------
50 sal_Bool ImplAccelManager::InsertAccel( Accelerator* pAccel )
52 if ( !mpAccelList ) {
53 mpAccelList = new ImplAccelList;
54 } else {
55 for ( size_t i = 0, n = mpAccelList->size(); i < n; ++i ) {
56 if ( (*mpAccelList)[ i ] == pAccel ) {
57 return sal_False;
62 mpAccelList->insert( mpAccelList->begin(), pAccel );
63 return sal_True;
66 // -----------------------------------------------------------------------
68 void ImplAccelManager::RemoveAccel( Accelerator* pAccel )
70 // do we have a list ?
71 if ( !mpAccelList )
72 return;
74 //e.g. #i90599#. Someone starts typing a sequence in a dialog, but doesn't
75 //end it, and then closes the dialog, deleting the accelerators. So if
76 //we're removing an accelerator that a sub-accelerator which is in the
77 //sequence list, throw away the entire sequence
78 if ( mpSequenceList ) {
79 for (sal_uInt16 i = 0; i < pAccel->GetItemCount(); ++i) {
80 Accelerator* pSubAccel = pAccel->GetAccel( pAccel->GetItemId(i) );
81 for ( size_t j = 0, n = mpSequenceList->size(); j < n; ++j ) {
82 if ( (*mpSequenceList)[ j ] == pSubAccel ) {
83 EndSequence( true );
84 i = pAccel->GetItemCount();
85 break;
91 // throw it away
92 for ( ImplAccelList::iterator it = mpAccelList->begin();
93 it != mpAccelList->end();
94 ++it
95 ) {
96 if ( *it == pAccel ) {
97 mpAccelList->erase( it );
98 break;
103 // -----------------------------------------------------------------------
105 void ImplAccelManager::EndSequence( sal_Bool bCancel )
107 // are we in a list ?
108 if ( !mpSequenceList )
109 return;
111 // call all deactivate-handler of the accelerators in the list
112 for ( size_t i = 0, n = mpSequenceList->size(); i < n; ++i )
114 Accelerator* pTempAccel = (*mpSequenceList)[ i ];
115 sal_Bool bDel = sal_False;
116 pTempAccel->mbIsCancel = bCancel;
117 pTempAccel->mpDel = &bDel;
118 pTempAccel->Deactivate();
119 if ( !bDel )
121 pTempAccel->mbIsCancel = sal_False;
122 pTempAccel->mpDel = NULL;
126 // delete sequence-list
127 delete mpSequenceList;
128 mpSequenceList = NULL;
131 // -----------------------------------------------------------------------
133 sal_Bool ImplAccelManager::IsAccelKey( const KeyCode& rKeyCode, sal_uInt16 nRepeat )
135 Accelerator* pAccel;
137 // do we have accelerators ??
138 if ( !mpAccelList )
139 return sal_False;
140 if ( mpAccelList->empty() )
141 return sal_False;
143 // are we in a sequence ?
144 if ( mpSequenceList )
146 pAccel = mpSequenceList->empty() ? NULL : (*mpSequenceList)[ 0 ];
147 DBG_CHKOBJ( pAccel, Accelerator, NULL );
149 // not found ?
150 if ( !pAccel )
152 // abort sequence
153 FlushAccel();
154 return sal_False;
157 // can the entry be found ?
158 ImplAccelEntry* pEntry = pAccel->ImplGetAccelData( rKeyCode );
159 if ( pEntry )
161 Accelerator* pNextAccel = pEntry->mpAccel;
163 // is an accelerator coupled ?
164 if ( pNextAccel )
166 DBG_CHKOBJ( pNextAccel, Accelerator, NULL );
168 mpSequenceList->insert( mpSequenceList->begin(), pNextAccel );
170 // call Activate-Handler of the new one
171 pNextAccel->Activate();
172 return sal_True;
174 else
176 // it is there already !
177 if ( pEntry->mbEnabled )
179 // stop sequence (first call deactivate-handler)
180 EndSequence();
182 // set accelerator of the actuel item
183 // and call the handler
184 sal_Bool bDel = sal_False;
185 pAccel->maCurKeyCode = rKeyCode;
186 pAccel->mnCurId = pEntry->mnId;
187 pAccel->mnCurRepeat = nRepeat;
188 pAccel->mpDel = &bDel;
189 pAccel->Select();
191 // did the accelerator survive the call
192 if ( !bDel )
194 DBG_CHKOBJ( pAccel, Accelerator, NULL );
195 pAccel->maCurKeyCode = KeyCode();
196 pAccel->mnCurId = 0;
197 pAccel->mnCurRepeat = 0;
198 pAccel->mpDel = NULL;
201 return sal_True;
203 else
205 // stop sequence as the accelerator was disbled
206 // transfer the key (to the system)
207 FlushAccel();
208 return sal_False;
212 else
214 // wrong key => stop sequence
215 FlushAccel();
216 return sal_False;
220 // step through the list of accelerators
221 for ( size_t i = 0, n = mpAccelList->size(); i < n; ++i )
223 pAccel = (*mpAccelList)[ i ];
224 DBG_CHKOBJ( pAccel, Accelerator, NULL );
226 // is the entry contained ?
227 ImplAccelEntry* pEntry = pAccel->ImplGetAccelData( rKeyCode );
228 if ( pEntry )
230 Accelerator* pNextAccel = pEntry->mpAccel;
232 // is an accelerator assigned ?
233 if ( pNextAccel )
235 DBG_CHKOBJ( pNextAccel, Accelerator, NULL );
237 // create sequence list
238 mpSequenceList = new ImplAccelList;
239 mpSequenceList->insert( mpSequenceList->begin(), pAccel );
240 mpSequenceList->insert( mpSequenceList->begin(), pNextAccel );
242 // call activate-Handler of the new one
243 pNextAccel->Activate();
245 return sal_True;
247 else
249 // already assigned !
250 if ( pEntry->mbEnabled )
252 // first call activate/aeactivate-Handler
253 pAccel->Activate();
254 pAccel->Deactivate();
256 // define accelerator of the actual item
257 // and call the handler
258 sal_Bool bDel = sal_False;
259 pAccel->maCurKeyCode = rKeyCode;
260 pAccel->mnCurId = pEntry->mnId;
261 pAccel->mnCurRepeat = nRepeat;
262 pAccel->mpDel = &bDel;
263 pAccel->Select();
265 // if the accelerator did survive the call
266 if ( !bDel )
268 DBG_CHKOBJ( pAccel, Accelerator, NULL );
269 pAccel->maCurKeyCode = KeyCode();
270 pAccel->mnCurId = 0;
271 pAccel->mnCurRepeat = 0;
272 pAccel->mpDel = NULL;
275 return sal_True;
277 else
278 return sal_False;
283 return sal_False;
286 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */