nss: upgrade to release 3.73
[LibreOffice.git] / vcl / source / window / accmgr.cxx
blob003e09343bc3a4a0c917485bcbc86c370c972ce1
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->mnCurId = pEntry->mnId;
142 pAccel->mpDel = &bDel;
143 pAccel->Select();
145 // did the accelerator survive the call
146 if ( !bDel )
148 pAccel->mnCurId = 0;
149 pAccel->mpDel = nullptr;
152 return true;
154 else
156 // stop sequence as the accelerator was disabled
157 // transfer the key (to the system)
158 FlushAccel();
159 return false;
163 else
165 // wrong key => stop sequence
166 FlushAccel();
167 return false;
171 // step through the list of accelerators
172 for (Accelerator* i : *mpAccelList)
174 pAccel = i;
176 // is the entry contained ?
177 ImplAccelEntry* pEntry = pAccel->ImplGetAccelData( rKeyCode );
178 if ( pEntry )
180 Accelerator* pNextAccel = pEntry->mpAccel;
182 // is an accelerator assigned ?
183 if ( pNextAccel )
186 // create sequence list
187 mpSequenceList.reset( new std::vector< Accelerator* > );
188 mpSequenceList->insert( mpSequenceList->begin(), pAccel );
189 mpSequenceList->insert( mpSequenceList->begin(), pNextAccel );
191 // call activate-Handler of the new one
192 pNextAccel->Activate();
194 return true;
196 else
198 // already assigned !
199 if ( pEntry->mbEnabled )
201 // first call activate/deactivate-Handler
202 pAccel->Activate();
204 // define accelerator of the actual item
205 // and call the handler
206 bool bDel = false;
207 pAccel->mnCurId = pEntry->mnId;
208 pAccel->mpDel = &bDel;
209 pAccel->Select();
211 // if the accelerator did survive the call
212 if ( !bDel )
214 pAccel->mnCurId = 0;
215 pAccel->mpDel = nullptr;
218 return true;
220 else
221 return false;
226 return false;
229 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */