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.hxx>
22 #include <accmgr.hxx>
23 
24 #include <algorithm>
25 
27 {
28 }
29 
31 {
32  if ( !mxAccelList ) {
33  mxAccelList.emplace();
34  } else {
35  for (Accelerator* i : *mxAccelList) {
36  if ( i == pAccel ) {
37  return false;
38  }
39  }
40  }
41 
42  mxAccelList->insert( mxAccelList->begin(), pAccel );
43  return true;
44 }
45 
47 {
48  // do we have a list ?
49  if ( !mxAccelList )
50  return;
51 
52  //e.g. #i90599#. Someone starts typing a sequence in a dialog, but doesn't
53  //end it, and then closes the dialog, deleting the accelerators. So if
54  //we're removing an accelerator that a sub-accelerator which is in the
55  //sequence list, throw away the entire sequence
56  if ( mxSequenceList ) {
57  for (sal_uInt16 i = 0; i < pAccel->GetItemCount(); ++i) {
58  Accelerator* pSubAccel = pAccel->GetAccel( pAccel->GetItemId(i) );
59  for (Accelerator* j : *mxSequenceList) {
60  if ( j == pSubAccel ) {
61  EndSequence();
62  i = pAccel->GetItemCount();
63  break;
64  }
65  }
66  }
67  }
68 
69  // throw it away
70  auto it = std::find(mxAccelList->begin(), mxAccelList->end(), pAccel);
71  if (it != mxAccelList->end())
72  mxAccelList->erase( it );
73 }
74 
76 {
77  // are we in a list ?
78  if ( !mxSequenceList )
79  return;
80 
81  for (Accelerator* pTempAccel : *mxSequenceList)
82  {
83  pTempAccel->mpDel = nullptr;
84  }
85 
86  // delete sequence-list
87  mxSequenceList.reset();
88 }
89 
91 {
92  Accelerator* pAccel;
93 
94  // do we have accelerators ??
95  if ( !mxAccelList )
96  return false;
97  if ( mxAccelList->empty() )
98  return false;
99 
100  // are we in a sequence ?
101  if ( mxSequenceList )
102  {
103  pAccel = mxSequenceList->empty() ? nullptr : (*mxSequenceList)[ 0 ];
104 
105  // not found ?
106  if ( !pAccel )
107  {
108  // abort sequence
109  FlushAccel();
110  return false;
111  }
112 
113  // can the entry be found ?
114  ImplAccelEntry* pEntry = pAccel->ImplGetAccelData( rKeyCode );
115  if ( pEntry )
116  {
117  Accelerator* pNextAccel = pEntry->mpAccel;
118 
119  // is an accelerator coupled ?
120  if ( pNextAccel )
121  {
122 
123  mxSequenceList->insert( mxSequenceList->begin(), pNextAccel );
124 
125  // call Activate-Handler of the new one
126  pNextAccel->Activate();
127  return true;
128  }
129  else
130  {
131  // it is there already !
132  if ( pEntry->mbEnabled )
133  {
134  // stop sequence (first call deactivate-handler)
135  EndSequence();
136 
137  // set accelerator of the actual item
138  // and call the handler
139  bool bDel = false;
140  pAccel->mnCurId = pEntry->mnId;
141  pAccel->mpDel = &bDel;
142  pAccel->Select();
143 
144  // did the accelerator survive the call
145  if ( !bDel )
146  {
147  pAccel->mnCurId = 0;
148  pAccel->mpDel = nullptr;
149  }
150 
151  return true;
152  }
153  else
154  {
155  // stop sequence as the accelerator was disabled
156  // transfer the key (to the system)
157  FlushAccel();
158  return false;
159  }
160  }
161  }
162  else
163  {
164  // wrong key => stop sequence
165  FlushAccel();
166  return false;
167  }
168  }
169 
170  // step through the list of accelerators
171  for (Accelerator* i : *mxAccelList)
172  {
173  pAccel = i;
174 
175  // is the entry contained ?
176  ImplAccelEntry* pEntry = pAccel->ImplGetAccelData( rKeyCode );
177  if ( pEntry )
178  {
179  Accelerator* pNextAccel = pEntry->mpAccel;
180 
181  // is an accelerator assigned ?
182  if ( pNextAccel )
183  {
184 
185  // create sequence list
186  mxSequenceList.emplace();
187  mxSequenceList->insert( mxSequenceList->begin(), pAccel );
188  mxSequenceList->insert( mxSequenceList->begin(), pNextAccel );
189 
190  // call activate-Handler of the new one
191  pNextAccel->Activate();
192 
193  return true;
194  }
195  else
196  {
197  // already assigned !
198  if ( pEntry->mbEnabled )
199  {
200  // first call activate/deactivate-Handler
201  pAccel->Activate();
202 
203  // define accelerator of the actual item
204  // and call the handler
205  bool bDel = false;
206  pAccel->mnCurId = pEntry->mnId;
207  pAccel->mpDel = &bDel;
208  pAccel->Select();
209 
210  // if the accelerator did survive the call
211  if ( !bDel )
212  {
213  pAccel->mnCurId = 0;
214  pAccel->mpDel = nullptr;
215  }
216 
217  return true;
218  }
219  else
220  return false;
221  }
222  }
223  }
224 
225  return false;
226 }
227 
228 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool mbEnabled
Definition: accel.hxx:42
sal_uInt16 mnId
Definition: accel.hxx:41
void EndSequence()
Definition: accmgr.cxx:75
sal_uInt16 mnCurId
Definition: accel.hxx:59
void Select()
Definition: accel.cxx:228
std::optional< std::vector< Accelerator * > > mxSequenceList
Definition: accmgr.hxx:34
sal_uInt16 GetItemCount() const
Definition: accel.cxx:238
void RemoveAccel(Accelerator const *pAccel)
Definition: accmgr.cxx:46
int i
bool IsAccelKey(const vcl::KeyCode &rKeyCode)
Definition: accmgr.cxx:90
Accelerator * GetAccel(sal_uInt16 nItemId) const
Definition: accel.cxx:253
void FlushAccel()
Definition: accmgr.hxx:46
Accelerator * mpAccel
Definition: accel.hxx:38
sal_uInt16 GetItemId(sal_uInt16 nPos) const
Definition: accel.cxx:243
ImplAccelEntry * ImplGetAccelData(const vcl::KeyCode &rKeyCode) const
Definition: accel.cxx:112
std::optional< std::vector< Accelerator * > > mxAccelList
Definition: accmgr.hxx:33
bool * mpDel
Definition: accel.hxx:60
void Activate()
Definition: accel.cxx:223
bool InsertAccel(Accelerator *pAccel)
Definition: accmgr.cxx:30