build fix: no comphelper/profilezone.hxx in this branch
[LibreOffice.git] / vcl / source / window / accmgr.cxx
blob56a56345dd7dfe210fb6aee1245f2b9ee27a1122
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 .
20 #include <tools/debug.hxx>
22 #include <accel.h>
23 #include <vcl/accel.hxx>
24 #include <accmgr.hxx>
26 ImplAccelManager::~ImplAccelManager()
28 delete mpAccelList;
29 delete mpSequenceList;
32 bool ImplAccelManager::InsertAccel( Accelerator* pAccel )
34 if ( !mpAccelList ) {
35 mpAccelList = new ImplAccelList;
36 } else {
37 for (Accelerator* i : *mpAccelList) {
38 if ( i == pAccel ) {
39 return false;
44 mpAccelList->insert( mpAccelList->begin(), pAccel );
45 return true;
48 void ImplAccelManager::RemoveAccel( Accelerator* pAccel )
50 // do we have a list ?
51 if ( !mpAccelList )
52 return;
54 //e.g. #i90599#. Someone starts typing a sequence in a dialog, but doesn't
55 //end it, and then closes the dialog, deleting the accelerators. So if
56 //we're removing an accelerator that a sub-accelerator which is in the
57 //sequence list, throw away the entire sequence
58 if ( mpSequenceList ) {
59 for (sal_uInt16 i = 0; i < pAccel->GetItemCount(); ++i) {
60 Accelerator* pSubAccel = pAccel->GetAccel( pAccel->GetItemId(i) );
61 for (Accelerator* j : *mpSequenceList) {
62 if ( j == pSubAccel ) {
63 EndSequence();
64 i = pAccel->GetItemCount();
65 break;
71 // throw it away
72 for ( ImplAccelList::iterator it = mpAccelList->begin();
73 it != mpAccelList->end();
74 ++it
75 ) {
76 if ( *it == pAccel ) {
77 mpAccelList->erase( it );
78 break;
83 void ImplAccelManager::EndSequence()
85 // are we in a list ?
86 if ( !mpSequenceList )
87 return;
89 for (Accelerator* pTempAccel : *mpSequenceList)
91 pTempAccel->mpDel = nullptr;
94 // delete sequence-list
95 delete mpSequenceList;
96 mpSequenceList = nullptr;
99 bool ImplAccelManager::IsAccelKey( const vcl::KeyCode& rKeyCode, sal_uInt16 nRepeat )
101 Accelerator* pAccel;
103 // do we have accelerators ??
104 if ( !mpAccelList )
105 return false;
106 if ( mpAccelList->empty() )
107 return false;
109 // are we in a sequence ?
110 if ( mpSequenceList )
112 pAccel = mpSequenceList->empty() ? nullptr : (*mpSequenceList)[ 0 ];
114 // not found ?
115 if ( !pAccel )
117 // abort sequence
118 FlushAccel();
119 return false;
122 // can the entry be found ?
123 ImplAccelEntry* pEntry = pAccel->ImplGetAccelData( rKeyCode );
124 if ( pEntry )
126 Accelerator* pNextAccel = pEntry->mpAccel;
128 // is an accelerator coupled ?
129 if ( pNextAccel )
132 mpSequenceList->insert( mpSequenceList->begin(), pNextAccel );
134 // call Activate-Handler of the new one
135 pNextAccel->Activate();
136 return true;
138 else
140 // it is there already !
141 if ( pEntry->mbEnabled )
143 // stop sequence (first call deactivate-handler)
144 EndSequence();
146 // set accelerator of the actuel item
147 // and call the handler
148 bool bDel = false;
149 pAccel->maCurKeyCode = rKeyCode;
150 pAccel->mnCurId = pEntry->mnId;
151 pAccel->mnCurRepeat = nRepeat;
152 pAccel->mpDel = &bDel;
153 pAccel->Select();
155 // did the accelerator survive the call
156 if ( !bDel )
158 pAccel->maCurKeyCode = vcl::KeyCode();
159 pAccel->mnCurId = 0;
160 pAccel->mnCurRepeat = 0;
161 pAccel->mpDel = nullptr;
164 return true;
166 else
168 // stop sequence as the accelerator was disabled
169 // transfer the key (to the system)
170 FlushAccel();
171 return false;
175 else
177 // wrong key => stop sequence
178 FlushAccel();
179 return false;
183 // step through the list of accelerators
184 for (Accelerator* i : *mpAccelList)
186 pAccel = i;
188 // is the entry contained ?
189 ImplAccelEntry* pEntry = pAccel->ImplGetAccelData( rKeyCode );
190 if ( pEntry )
192 Accelerator* pNextAccel = pEntry->mpAccel;
194 // is an accelerator assigned ?
195 if ( pNextAccel )
198 // create sequence list
199 mpSequenceList = new ImplAccelList;
200 mpSequenceList->insert( mpSequenceList->begin(), pAccel );
201 mpSequenceList->insert( mpSequenceList->begin(), pNextAccel );
203 // call activate-Handler of the new one
204 pNextAccel->Activate();
206 return true;
208 else
210 // already assigned !
211 if ( pEntry->mbEnabled )
213 // first call activate/deactivate-Handler
214 pAccel->Activate();
216 // define accelerator of the actual item
217 // and call the handler
218 bool bDel = false;
219 pAccel->maCurKeyCode = rKeyCode;
220 pAccel->mnCurId = pEntry->mnId;
221 pAccel->mnCurRepeat = nRepeat;
222 pAccel->mpDel = &bDel;
223 pAccel->Select();
225 // if the accelerator did survive the call
226 if ( !bDel )
228 pAccel->maCurKeyCode = vcl::KeyCode();
229 pAccel->mnCurId = 0;
230 pAccel->mnCurRepeat = 0;
231 pAccel->mpDel = nullptr;
234 return true;
236 else
237 return false;
242 return false;
245 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */