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 .
21 #include <tools/debug.hxx>
24 #include <vcl/accel.hxx>
27 // =======================================================================
29 DBG_NAMEEX( Accelerator
)
31 // =======================================================================
33 ImplAccelManager::~ImplAccelManager()
36 delete mpSequenceList
;
39 // -----------------------------------------------------------------------
41 sal_Bool
ImplAccelManager::InsertAccel( Accelerator
* pAccel
)
44 mpAccelList
= new ImplAccelList
;
46 for ( size_t i
= 0, n
= mpAccelList
->size(); i
< n
; ++i
) {
47 if ( (*mpAccelList
)[ i
] == pAccel
) {
53 mpAccelList
->insert( mpAccelList
->begin(), pAccel
);
57 // -----------------------------------------------------------------------
59 void ImplAccelManager::RemoveAccel( Accelerator
* pAccel
)
61 // do we have a list ?
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
) {
75 i
= pAccel
->GetItemCount();
83 for ( ImplAccelList::iterator it
= mpAccelList
->begin();
84 it
!= mpAccelList
->end();
87 if ( *it
== pAccel
) {
88 mpAccelList
->erase( it
);
94 // -----------------------------------------------------------------------
96 void ImplAccelManager::EndSequence( sal_Bool bCancel
)
99 if ( !mpSequenceList
)
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();
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
)
128 // do we have accelerators ??
131 if ( mpAccelList
->empty() )
134 // are we in a sequence ?
135 if ( mpSequenceList
)
137 pAccel
= mpSequenceList
->empty() ? NULL
: (*mpSequenceList
)[ 0 ];
138 DBG_CHKOBJ( pAccel
, Accelerator
, NULL
);
148 // can the entry be found ?
149 ImplAccelEntry
* pEntry
= pAccel
->ImplGetAccelData( rKeyCode
);
152 Accelerator
* pNextAccel
= pEntry
->mpAccel
;
154 // is an accelerator coupled ?
157 DBG_CHKOBJ( pNextAccel
, Accelerator
, NULL
);
159 mpSequenceList
->insert( mpSequenceList
->begin(), pNextAccel
);
161 // call Activate-Handler of the new one
162 pNextAccel
->Activate();
167 // it is there already !
168 if ( pEntry
->mbEnabled
)
170 // stop sequence (first call deactivate-handler)
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
;
182 // did the accelerator survive the call
185 DBG_CHKOBJ( pAccel
, Accelerator
, NULL
);
186 pAccel
->maCurKeyCode
= KeyCode();
188 pAccel
->mnCurRepeat
= 0;
189 pAccel
->mpDel
= NULL
;
196 // stop sequence as the accelerator was disbled
197 // transfer the key (to the system)
205 // wrong key => stop sequence
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
);
221 Accelerator
* pNextAccel
= pEntry
->mpAccel
;
223 // is an accelerator assigned ?
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();
240 // already assigned !
241 if ( pEntry
->mbEnabled
)
243 // first call activate/aeactivate-Handler
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
;
256 // if the accelerator did survive the call
259 DBG_CHKOBJ( pAccel
, Accelerator
, NULL
);
260 pAccel
->maCurKeyCode
= KeyCode();
262 pAccel
->mnCurRepeat
= 0;
263 pAccel
->mpDel
= NULL
;
277 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */