Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / vcl / source / window / accmgr.cxx
blobf7a3ea0545a16b1ab74699a7f85d98c313ffd21d
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 <accel.h>
22 #include <vcl/accel.hxx>
23 #include <accmgr.hxx>
25 #include <algorithm>
27 ImplAccelManager::~ImplAccelManager()
31 bool ImplAccelManager::InsertAccel( Accelerator* pAccel )
33 if ( !mpAccelList ) {
34 mpAccelList.reset( new std::vector< Accelerator* > );
35 } else {
36 for (Accelerator* i : *mpAccelList) {
37 if ( i == pAccel ) {
38 return false;
43 mpAccelList->insert( mpAccelList->begin(), pAccel );
44 return true;
47 void ImplAccelManager::RemoveAccel( Accelerator const * pAccel )
49 // do we have a list ?
50 if ( !mpAccelList )
51 return;
53 //e.g. #i90599#. Someone starts typing a sequence in a dialog, but doesn't
54 //end it, and then closes the dialog, deleting the accelerators. So if
55 //we're removing an accelerator that a sub-accelerator which is in the
56 //sequence list, throw away the entire sequence
57 if ( mpSequenceList ) {
58 for (sal_uInt16 i = 0; i < pAccel->GetItemCount(); ++i) {
59 Accelerator* pSubAccel = pAccel->GetAccel( pAccel->GetItemId(i) );
60 for (Accelerator* j : *mpSequenceList) {
61 if ( j == pSubAccel ) {
62 EndSequence();
63 i = pAccel->GetItemCount();
64 break;
70 // throw it away
71 auto it = std::find(mpAccelList->begin(), mpAccelList->end(), pAccel);
72 if (it != mpAccelList->end())
73 mpAccelList->erase( it );
76 void ImplAccelManager::EndSequence()
78 // are we in a list ?
79 if ( !mpSequenceList )
80 return;
82 for (Accelerator* pTempAccel : *mpSequenceList)
84 pTempAccel->mpDel = nullptr;
87 // delete sequence-list
88 mpSequenceList.reset();
91 bool ImplAccelManager::IsAccelKey( const vcl::KeyCode& rKeyCode )
93 Accelerator* pAccel;
95 // do we have accelerators ??
96 if ( !mpAccelList )
97 return false;
98 if ( mpAccelList->empty() )
99 return false;
101 // are we in a sequence ?
102 if ( mpSequenceList )
104 pAccel = mpSequenceList->empty() ? nullptr : (*mpSequenceList)[ 0 ];
106 // not found ?
107 if ( !pAccel )
109 // abort sequence
110 FlushAccel();
111 return false;
114 // can the entry be found ?
115 ImplAccelEntry* pEntry = pAccel->ImplGetAccelData( rKeyCode );
116 if ( pEntry )
118 Accelerator* pNextAccel = pEntry->mpAccel;
120 // is an accelerator coupled ?
121 if ( pNextAccel )
124 mpSequenceList->insert( mpSequenceList->begin(), pNextAccel );
126 // call Activate-Handler of the new one
127 pNextAccel->Activate();
128 return true;
130 else
132 // it is there already !
133 if ( pEntry->mbEnabled )
135 // stop sequence (first call deactivate-handler)
136 EndSequence();
138 // set accelerator of the actual item
139 // and call the handler
140 bool bDel = false;
141 pAccel->maCurKeyCode = rKeyCode;
142 pAccel->mnCurId = pEntry->mnId;
143 pAccel->mpDel = &bDel;
144 pAccel->Select();
146 // did the accelerator survive the call
147 if ( !bDel )
149 pAccel->maCurKeyCode = vcl::KeyCode();
150 pAccel->mnCurId = 0;
151 pAccel->mpDel = nullptr;
154 return true;
156 else
158 // stop sequence as the accelerator was disabled
159 // transfer the key (to the system)
160 FlushAccel();
161 return false;
165 else
167 // wrong key => stop sequence
168 FlushAccel();
169 return false;
173 // step through the list of accelerators
174 for (Accelerator* i : *mpAccelList)
176 pAccel = i;
178 // is the entry contained ?
179 ImplAccelEntry* pEntry = pAccel->ImplGetAccelData( rKeyCode );
180 if ( pEntry )
182 Accelerator* pNextAccel = pEntry->mpAccel;
184 // is an accelerator assigned ?
185 if ( pNextAccel )
188 // create sequence list
189 mpSequenceList.reset( new std::vector< Accelerator* > );
190 mpSequenceList->insert( mpSequenceList->begin(), pAccel );
191 mpSequenceList->insert( mpSequenceList->begin(), pNextAccel );
193 // call activate-Handler of the new one
194 pNextAccel->Activate();
196 return true;
198 else
200 // already assigned !
201 if ( pEntry->mbEnabled )
203 // first call activate/deactivate-Handler
204 pAccel->Activate();
206 // define accelerator of the actual item
207 // and call the handler
208 bool bDel = false;
209 pAccel->maCurKeyCode = rKeyCode;
210 pAccel->mnCurId = pEntry->mnId;
211 pAccel->mpDel = &bDel;
212 pAccel->Select();
214 // if the accelerator did survive the call
215 if ( !bDel )
217 pAccel->maCurKeyCode = vcl::KeyCode();
218 pAccel->mnCurId = 0;
219 pAccel->mpDel = nullptr;
222 return true;
224 else
225 return false;
230 return false;
233 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */