LibreOffice Module vcl (master)  1
accmgr.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 
21 #include <accel.h>
22 #include <vcl/accel.hxx>
23 #include <accmgr.hxx>
24 
25 #include <algorithm>
26 
28 {
29 }
30 
32 {
33  if ( !mpAccelList ) {
34  mpAccelList.reset( new std::vector< Accelerator* > );
35  } else {
36  for (Accelerator* i : *mpAccelList) {
37  if ( i == pAccel ) {
38  return false;
39  }
40  }
41  }
42 
43  mpAccelList->insert( mpAccelList->begin(), pAccel );
44  return true;
45 }
46 
48 {
49  // do we have a list ?
50  if ( !mpAccelList )
51  return;
52 
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;
65  }
66  }
67  }
68  }
69 
70  // throw it away
71  auto it = std::find(mpAccelList->begin(), mpAccelList->end(), pAccel);
72  if (it != mpAccelList->end())
73  mpAccelList->erase( it );
74 }
75 
77 {
78  // are we in a list ?
79  if ( !mpSequenceList )
80  return;
81 
82  for (Accelerator* pTempAccel : *mpSequenceList)
83  {
84  pTempAccel->mpDel = nullptr;
85  }
86 
87  // delete sequence-list
88  mpSequenceList.reset();
89 }
90 
92 {
93  Accelerator* pAccel;
94 
95  // do we have accelerators ??
96  if ( !mpAccelList )
97  return false;
98  if ( mpAccelList->empty() )
99  return false;
100 
101  // are we in a sequence ?
102  if ( mpSequenceList )
103  {
104  pAccel = mpSequenceList->empty() ? nullptr : (*mpSequenceList)[ 0 ];
105 
106  // not found ?
107  if ( !pAccel )
108  {
109  // abort sequence
110  FlushAccel();
111  return false;
112  }
113 
114  // can the entry be found ?
115  ImplAccelEntry* pEntry = pAccel->ImplGetAccelData( rKeyCode );
116  if ( pEntry )
117  {
118  Accelerator* pNextAccel = pEntry->mpAccel;
119 
120  // is an accelerator coupled ?
121  if ( pNextAccel )
122  {
123 
124  mpSequenceList->insert( mpSequenceList->begin(), pNextAccel );
125 
126  // call Activate-Handler of the new one
127  pNextAccel->Activate();
128  return true;
129  }
130  else
131  {
132  // it is there already !
133  if ( pEntry->mbEnabled )
134  {
135  // stop sequence (first call deactivate-handler)
136  EndSequence();
137 
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();
145 
146  // did the accelerator survive the call
147  if ( !bDel )
148  {
149  pAccel->maCurKeyCode = vcl::KeyCode();
150  pAccel->mnCurId = 0;
151  pAccel->mpDel = nullptr;
152  }
153 
154  return true;
155  }
156  else
157  {
158  // stop sequence as the accelerator was disabled
159  // transfer the key (to the system)
160  FlushAccel();
161  return false;
162  }
163  }
164  }
165  else
166  {
167  // wrong key => stop sequence
168  FlushAccel();
169  return false;
170  }
171  }
172 
173  // step through the list of accelerators
174  for (Accelerator* i : *mpAccelList)
175  {
176  pAccel = i;
177 
178  // is the entry contained ?
179  ImplAccelEntry* pEntry = pAccel->ImplGetAccelData( rKeyCode );
180  if ( pEntry )
181  {
182  Accelerator* pNextAccel = pEntry->mpAccel;
183 
184  // is an accelerator assigned ?
185  if ( pNextAccel )
186  {
187 
188  // create sequence list
189  mpSequenceList.reset( new std::vector< Accelerator* > );
190  mpSequenceList->insert( mpSequenceList->begin(), pAccel );
191  mpSequenceList->insert( mpSequenceList->begin(), pNextAccel );
192 
193  // call activate-Handler of the new one
194  pNextAccel->Activate();
195 
196  return true;
197  }
198  else
199  {
200  // already assigned !
201  if ( pEntry->mbEnabled )
202  {
203  // first call activate/deactivate-Handler
204  pAccel->Activate();
205 
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();
213 
214  // if the accelerator did survive the call
215  if ( !bDel )
216  {
217  pAccel->maCurKeyCode = vcl::KeyCode();
218  pAccel->mnCurId = 0;
219  pAccel->mpDel = nullptr;
220  }
221 
222  return true;
223  }
224  else
225  return false;
226  }
227  }
228  }
229 
230  return false;
231 }
232 
233 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::unique_ptr< std::vector< Accelerator * > > mpAccelList
Definition: accmgr.hxx:33
bool mbEnabled
Definition: accel.h:34
sal_uInt16 mnId
Definition: accel.h:30
void EndSequence()
Definition: accmgr.cxx:76
sal_uInt16 mnCurId
Definition: accel.hxx:43
void Select()
Definition: accel.cxx:245
std::unique_ptr< std::vector< Accelerator * > > mpSequenceList
Definition: accmgr.hxx:34
sal_uInt16 GetItemCount() const
Definition: accel.cxx:255
void RemoveAccel(Accelerator const *pAccel)
Definition: accmgr.cxx:47
bool IsAccelKey(const vcl::KeyCode &rKeyCode)
Definition: accmgr.cxx:91
int i
Accelerator * GetAccel(sal_uInt16 nItemId) const
Definition: accel.cxx:271
void FlushAccel()
Definition: accmgr.hxx:46
vcl::KeyCode maCurKeyCode
Definition: accel.hxx:42
Accelerator * mpAccel
Definition: accel.h:32
sal_uInt16 GetItemId(sal_uInt16 nPos) const
Definition: accel.cxx:261
SAL_DLLPRIVATE ImplAccelEntry * ImplGetAccelData(const vcl::KeyCode &rKeyCode) const
Definition: accel.cxx:126
bool * mpDel
Definition: accel.hxx:44
void Activate()
Definition: accel.cxx:240
bool InsertAccel(Accelerator *pAccel)
Definition: accmgr.cxx:31