Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <tools/debug.hxx>
31 : :
32 : : #include <accel.h>
33 : : #include <vcl/accel.hxx>
34 : : #include <accmgr.hxx>
35 : :
36 : : // =======================================================================
37 : :
38 : : DBG_NAMEEX( Accelerator )
39 : :
40 : : // =======================================================================
41 : :
42 : 0 : ImplAccelManager::~ImplAccelManager()
43 : : {
44 [ # # ]: 0 : delete mpAccelList;
45 [ # # ]: 0 : delete mpSequenceList;
46 : 0 : }
47 : :
48 : : // -----------------------------------------------------------------------
49 : :
50 : 0 : sal_Bool ImplAccelManager::InsertAccel( Accelerator* pAccel )
51 : : {
52 [ # # ]: 0 : if ( !mpAccelList ) {
53 [ # # ]: 0 : mpAccelList = new ImplAccelList;
54 : : } else {
55 [ # # ]: 0 : for ( size_t i = 0, n = mpAccelList->size(); i < n; ++i ) {
56 [ # # ]: 0 : if ( (*mpAccelList)[ i ] == pAccel ) {
57 : 0 : return sal_False;
58 : : }
59 : : }
60 : : }
61 : :
62 : 0 : mpAccelList->insert( mpAccelList->begin(), pAccel );
63 : 0 : return sal_True;
64 : : }
65 : :
66 : : // -----------------------------------------------------------------------
67 : :
68 : 0 : void ImplAccelManager::RemoveAccel( Accelerator* pAccel )
69 : : {
70 : : // do we have a list ?
71 [ # # ]: 0 : if ( !mpAccelList )
72 : 0 : return;
73 : :
74 : : //e.g. #i90599#. Someone starts typing a sequence in a dialog, but doesn't
75 : : //end it, and then closes the dialog, deleting the accelerators. So if
76 : : //we're removing an accelerator that a sub-accelerator which is in the
77 : : //sequence list, throw away the entire sequence
78 [ # # ]: 0 : if ( mpSequenceList ) {
79 [ # # ]: 0 : for (sal_uInt16 i = 0; i < pAccel->GetItemCount(); ++i) {
80 : 0 : Accelerator* pSubAccel = pAccel->GetAccel( pAccel->GetItemId(i) );
81 [ # # ]: 0 : for ( size_t j = 0, n = mpSequenceList->size(); j < n; ++j ) {
82 [ # # ]: 0 : if ( (*mpSequenceList)[ j ] == pSubAccel ) {
83 : 0 : EndSequence( true );
84 : 0 : i = pAccel->GetItemCount();
85 : 0 : break;
86 : : }
87 : : }
88 : : }
89 : : }
90 : :
91 : : // throw it away
92 [ # # # # ]: 0 : for ( ImplAccelList::iterator it = mpAccelList->begin();
[ # # ]
93 : 0 : it != mpAccelList->end();
94 : : ++it
95 : : ) {
96 [ # # ][ # # ]: 0 : if ( *it == pAccel ) {
97 [ # # ]: 0 : mpAccelList->erase( it );
98 : 0 : break;
99 : : }
100 : : }
101 : : }
102 : :
103 : : // -----------------------------------------------------------------------
104 : :
105 : 0 : void ImplAccelManager::EndSequence( sal_Bool bCancel )
106 : : {
107 : : // are we in a list ?
108 [ # # ]: 0 : if ( !mpSequenceList )
109 : 0 : return;
110 : :
111 : : // call all deactivate-handler of the accelerators in the list
112 [ # # ]: 0 : for ( size_t i = 0, n = mpSequenceList->size(); i < n; ++i )
113 : : {
114 [ # # ]: 0 : Accelerator* pTempAccel = (*mpSequenceList)[ i ];
115 : 0 : sal_Bool bDel = sal_False;
116 : 0 : pTempAccel->mbIsCancel = bCancel;
117 : 0 : pTempAccel->mpDel = &bDel;
118 [ # # ]: 0 : pTempAccel->Deactivate();
119 [ # # ]: 0 : if ( !bDel )
120 : : {
121 : 0 : pTempAccel->mbIsCancel = sal_False;
122 : 0 : pTempAccel->mpDel = NULL;
123 : : }
124 : : }
125 : :
126 : : // delete sequence-list
127 [ # # ]: 0 : delete mpSequenceList;
128 : 0 : mpSequenceList = NULL;
129 : : }
130 : :
131 : : // -----------------------------------------------------------------------
132 : :
133 : 0 : sal_Bool ImplAccelManager::IsAccelKey( const KeyCode& rKeyCode, sal_uInt16 nRepeat )
134 : : {
135 : : Accelerator* pAccel;
136 : :
137 : : // do we have accelerators ??
138 [ # # ]: 0 : if ( !mpAccelList )
139 : 0 : return sal_False;
140 [ # # ]: 0 : if ( mpAccelList->empty() )
141 : 0 : return sal_False;
142 : :
143 : : // are we in a sequence ?
144 [ # # ]: 0 : if ( mpSequenceList )
145 : : {
146 [ # # ][ # # ]: 0 : pAccel = mpSequenceList->empty() ? NULL : (*mpSequenceList)[ 0 ];
147 : : DBG_CHKOBJ( pAccel, Accelerator, NULL );
148 : :
149 : : // not found ?
150 [ # # ]: 0 : if ( !pAccel )
151 : : {
152 : : // abort sequence
153 [ # # ]: 0 : FlushAccel();
154 : 0 : return sal_False;
155 : : }
156 : :
157 : : // can the entry be found ?
158 [ # # ]: 0 : ImplAccelEntry* pEntry = pAccel->ImplGetAccelData( rKeyCode );
159 [ # # ]: 0 : if ( pEntry )
160 : : {
161 : 0 : Accelerator* pNextAccel = pEntry->mpAccel;
162 : :
163 : : // is an accelerator coupled ?
164 [ # # ]: 0 : if ( pNextAccel )
165 : : {
166 : : DBG_CHKOBJ( pNextAccel, Accelerator, NULL );
167 : :
168 [ # # ]: 0 : mpSequenceList->insert( mpSequenceList->begin(), pNextAccel );
169 : :
170 : : // call Activate-Handler of the new one
171 [ # # ]: 0 : pNextAccel->Activate();
172 : 0 : return sal_True;
173 : : }
174 : : else
175 : : {
176 : : // it is there already !
177 [ # # ]: 0 : if ( pEntry->mbEnabled )
178 : : {
179 : : // stop sequence (first call deactivate-handler)
180 [ # # ]: 0 : EndSequence();
181 : :
182 : : // set accelerator of the actuel item
183 : : // and call the handler
184 : 0 : sal_Bool bDel = sal_False;
185 [ # # ]: 0 : pAccel->maCurKeyCode = rKeyCode;
186 : 0 : pAccel->mnCurId = pEntry->mnId;
187 : 0 : pAccel->mnCurRepeat = nRepeat;
188 : 0 : pAccel->mpDel = &bDel;
189 [ # # ]: 0 : pAccel->Select();
190 : :
191 : : // did the accelerator survive the call
192 [ # # ]: 0 : if ( !bDel )
193 : : {
194 : : DBG_CHKOBJ( pAccel, Accelerator, NULL );
195 [ # # ]: 0 : pAccel->maCurKeyCode = KeyCode();
196 : 0 : pAccel->mnCurId = 0;
197 : 0 : pAccel->mnCurRepeat = 0;
198 : 0 : pAccel->mpDel = NULL;
199 : : }
200 : :
201 : 0 : return sal_True;
202 : : }
203 : : else
204 : : {
205 : : // stop sequence as the accelerator was disbled
206 : : // transfer the key (to the system)
207 [ # # ]: 0 : FlushAccel();
208 : 0 : return sal_False;
209 : : }
210 : : }
211 : : }
212 : : else
213 : : {
214 : : // wrong key => stop sequence
215 [ # # ]: 0 : FlushAccel();
216 : 0 : return sal_False;
217 : : }
218 : : }
219 : :
220 : : // step through the list of accelerators
221 [ # # ]: 0 : for ( size_t i = 0, n = mpAccelList->size(); i < n; ++i )
222 : : {
223 [ # # ]: 0 : pAccel = (*mpAccelList)[ i ];
224 : : DBG_CHKOBJ( pAccel, Accelerator, NULL );
225 : :
226 : : // is the entry contained ?
227 [ # # ]: 0 : ImplAccelEntry* pEntry = pAccel->ImplGetAccelData( rKeyCode );
228 [ # # ]: 0 : if ( pEntry )
229 : : {
230 : 0 : Accelerator* pNextAccel = pEntry->mpAccel;
231 : :
232 : : // is an accelerator assigned ?
233 [ # # ]: 0 : if ( pNextAccel )
234 : : {
235 : : DBG_CHKOBJ( pNextAccel, Accelerator, NULL );
236 : :
237 : : // create sequence list
238 [ # # ][ # # ]: 0 : mpSequenceList = new ImplAccelList;
239 [ # # ]: 0 : mpSequenceList->insert( mpSequenceList->begin(), pAccel );
240 [ # # ]: 0 : mpSequenceList->insert( mpSequenceList->begin(), pNextAccel );
241 : :
242 : : // call activate-Handler of the new one
243 [ # # ]: 0 : pNextAccel->Activate();
244 : :
245 : 0 : return sal_True;
246 : : }
247 : : else
248 : : {
249 : : // already assigned !
250 [ # # ]: 0 : if ( pEntry->mbEnabled )
251 : : {
252 : : // first call activate/aeactivate-Handler
253 [ # # ]: 0 : pAccel->Activate();
254 [ # # ]: 0 : pAccel->Deactivate();
255 : :
256 : : // define accelerator of the actual item
257 : : // and call the handler
258 : 0 : sal_Bool bDel = sal_False;
259 [ # # ]: 0 : pAccel->maCurKeyCode = rKeyCode;
260 : 0 : pAccel->mnCurId = pEntry->mnId;
261 : 0 : pAccel->mnCurRepeat = nRepeat;
262 : 0 : pAccel->mpDel = &bDel;
263 [ # # ]: 0 : pAccel->Select();
264 : :
265 : : // if the accelerator did survive the call
266 [ # # ]: 0 : if ( !bDel )
267 : : {
268 : : DBG_CHKOBJ( pAccel, Accelerator, NULL );
269 [ # # ]: 0 : pAccel->maCurKeyCode = KeyCode();
270 : 0 : pAccel->mnCurId = 0;
271 : 0 : pAccel->mnCurRepeat = 0;
272 : 0 : pAccel->mpDel = NULL;
273 : : }
274 : :
275 : 0 : return sal_True;
276 : : }
277 : : else
278 : 0 : return sal_False;
279 : : }
280 : : }
281 : : }
282 : :
283 : 0 : return sal_False;
284 : : }
285 : :
286 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|