1*9f62ea84SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*9f62ea84SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*9f62ea84SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*9f62ea84SAndrew Rist * distributed with this work for additional information 6*9f62ea84SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*9f62ea84SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*9f62ea84SAndrew Rist * "License"); you may not use this file except in compliance 9*9f62ea84SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*9f62ea84SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*9f62ea84SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*9f62ea84SAndrew Rist * software distributed under the License is distributed on an 15*9f62ea84SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*9f62ea84SAndrew Rist * KIND, either express or implied. See the License for the 17*9f62ea84SAndrew Rist * specific language governing permissions and limitations 18*9f62ea84SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*9f62ea84SAndrew Rist *************************************************************/ 21*9f62ea84SAndrew Rist 22*9f62ea84SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_vcl.hxx" 26cdf0e10cSrcweir #include <tools/list.hxx> 27cdf0e10cSrcweir #include <tools/debug.hxx> 28cdf0e10cSrcweir 29cdf0e10cSrcweir #include <accel.h> 30cdf0e10cSrcweir #include <vcl/accel.hxx> 31cdf0e10cSrcweir #include <accmgr.hxx> 32cdf0e10cSrcweir 33cdf0e10cSrcweir 34cdf0e10cSrcweir 35cdf0e10cSrcweir // ======================================================================= 36cdf0e10cSrcweir 37cdf0e10cSrcweir DECLARE_LIST( ImplAccelList, Accelerator* ) 38cdf0e10cSrcweir 39cdf0e10cSrcweir // ======================================================================= 40cdf0e10cSrcweir 41cdf0e10cSrcweir DBG_NAMEEX( Accelerator ) 42cdf0e10cSrcweir 43cdf0e10cSrcweir // ======================================================================= 44cdf0e10cSrcweir 45cdf0e10cSrcweir ImplAccelManager::~ImplAccelManager() 46cdf0e10cSrcweir { 47cdf0e10cSrcweir if ( mpAccelList ) 48cdf0e10cSrcweir delete mpAccelList; 49cdf0e10cSrcweir if ( mpSequenceList ) 50cdf0e10cSrcweir delete mpSequenceList; 51cdf0e10cSrcweir } 52cdf0e10cSrcweir 53cdf0e10cSrcweir // ----------------------------------------------------------------------- 54cdf0e10cSrcweir 55cdf0e10cSrcweir sal_Bool ImplAccelManager::InsertAccel( Accelerator* pAccel ) 56cdf0e10cSrcweir { 57cdf0e10cSrcweir if ( !mpAccelList ) 58cdf0e10cSrcweir mpAccelList = new ImplAccelList; 59cdf0e10cSrcweir else 60cdf0e10cSrcweir { 61cdf0e10cSrcweir // Gibts den schon ? 62cdf0e10cSrcweir if ( mpAccelList->GetPos( pAccel ) != LIST_ENTRY_NOTFOUND ) 63cdf0e10cSrcweir return sal_False; 64cdf0e10cSrcweir } 65cdf0e10cSrcweir 66cdf0e10cSrcweir // Am Anfang der Liste einfuegen 67cdf0e10cSrcweir mpAccelList->Insert( pAccel, (sal_uLong)0 ); 68cdf0e10cSrcweir 69cdf0e10cSrcweir return sal_True; 70cdf0e10cSrcweir } 71cdf0e10cSrcweir 72cdf0e10cSrcweir // ----------------------------------------------------------------------- 73cdf0e10cSrcweir 74cdf0e10cSrcweir void ImplAccelManager::RemoveAccel( Accelerator* pAccel ) 75cdf0e10cSrcweir { 76cdf0e10cSrcweir // Haben wir ueberhaupt eine Liste ? 77cdf0e10cSrcweir if ( !mpAccelList ) 78cdf0e10cSrcweir return; 79cdf0e10cSrcweir 80cdf0e10cSrcweir //e.g. #i90599#. Someone starts typing a sequence in a dialog, but doesn't 81cdf0e10cSrcweir //end it, and then closes the dialog, deleting the accelerators. So if 82cdf0e10cSrcweir //we're removing an accelerator that a sub-accelerator which is in the 83cdf0e10cSrcweir //sequence list, throw away the entire sequence 84cdf0e10cSrcweir if ( mpSequenceList ) 85cdf0e10cSrcweir { 86cdf0e10cSrcweir for (sal_uInt16 i = 0; i < pAccel->GetItemCount(); ++i) 87cdf0e10cSrcweir { 88cdf0e10cSrcweir Accelerator* pSubAccel = pAccel->GetAccel(pAccel->GetItemId(i)); 89cdf0e10cSrcweir if ( mpSequenceList->GetPos( pSubAccel ) != LIST_ENTRY_NOTFOUND ) 90cdf0e10cSrcweir { 91cdf0e10cSrcweir EndSequence( true ); 92cdf0e10cSrcweir break; 93cdf0e10cSrcweir } 94cdf0e10cSrcweir } 95cdf0e10cSrcweir } 96cdf0e10cSrcweir 97cdf0e10cSrcweir // Raus damit 98cdf0e10cSrcweir mpAccelList->Remove( pAccel ); 99cdf0e10cSrcweir } 100cdf0e10cSrcweir 101cdf0e10cSrcweir // ----------------------------------------------------------------------- 102cdf0e10cSrcweir 103cdf0e10cSrcweir void ImplAccelManager::EndSequence( sal_Bool bCancel ) 104cdf0e10cSrcweir { 105cdf0e10cSrcweir // Sind wir ueberhaupt in einer Sequenz ? 106cdf0e10cSrcweir if ( !mpSequenceList ) 107cdf0e10cSrcweir return; 108cdf0e10cSrcweir 109cdf0e10cSrcweir // Alle Deactivate-Handler der Acceleratoren in der Sequenz rufen 110cdf0e10cSrcweir Accelerator* pTempAccel = mpSequenceList->First(); 111cdf0e10cSrcweir while( pTempAccel ) 112cdf0e10cSrcweir { 113cdf0e10cSrcweir sal_Bool bDel = sal_False; 114cdf0e10cSrcweir pTempAccel->mbIsCancel = bCancel; 115cdf0e10cSrcweir pTempAccel->mpDel = &bDel; 116cdf0e10cSrcweir pTempAccel->Deactivate(); 117cdf0e10cSrcweir if ( !bDel ) 118cdf0e10cSrcweir { 119cdf0e10cSrcweir pTempAccel->mbIsCancel = sal_False; 120cdf0e10cSrcweir pTempAccel->mpDel = NULL; 121cdf0e10cSrcweir } 122cdf0e10cSrcweir 123cdf0e10cSrcweir pTempAccel = mpSequenceList->Next(); 124cdf0e10cSrcweir } 125cdf0e10cSrcweir 126cdf0e10cSrcweir // Sequenz-Liste loeschen 127cdf0e10cSrcweir delete mpSequenceList; 128cdf0e10cSrcweir mpSequenceList = NULL; 129cdf0e10cSrcweir } 130cdf0e10cSrcweir 131cdf0e10cSrcweir // ----------------------------------------------------------------------- 132cdf0e10cSrcweir 133cdf0e10cSrcweir sal_Bool ImplAccelManager::IsAccelKey( const KeyCode& rKeyCode, sal_uInt16 nRepeat ) 134cdf0e10cSrcweir { 135cdf0e10cSrcweir Accelerator* pAccel; 136cdf0e10cSrcweir 137cdf0e10cSrcweir // Haben wir ueberhaupt Acceleratoren ?? 138cdf0e10cSrcweir if ( !mpAccelList ) 139cdf0e10cSrcweir return sal_False; 140cdf0e10cSrcweir if ( !mpAccelList->Count() ) 141cdf0e10cSrcweir return sal_False; 142cdf0e10cSrcweir 143cdf0e10cSrcweir // Sind wir in einer Sequenz ? 144cdf0e10cSrcweir if ( mpSequenceList ) 145cdf0e10cSrcweir { 146cdf0e10cSrcweir pAccel = mpSequenceList->GetObject( 0 ); 147cdf0e10cSrcweir DBG_CHKOBJ( pAccel, Accelerator, NULL ); 148cdf0e10cSrcweir 149cdf0e10cSrcweir // Nicht Gefunden ? 150cdf0e10cSrcweir if ( !pAccel ) 151cdf0e10cSrcweir { 152cdf0e10cSrcweir // Sequenz abbrechen 153cdf0e10cSrcweir FlushAccel(); 154cdf0e10cSrcweir return sal_False; 155cdf0e10cSrcweir } 156cdf0e10cSrcweir 157cdf0e10cSrcweir // Ist der Eintrag da drin ? 158cdf0e10cSrcweir ImplAccelEntry* pEntry = pAccel->ImplGetAccelData( rKeyCode ); 159cdf0e10cSrcweir if ( pEntry ) 160cdf0e10cSrcweir { 161cdf0e10cSrcweir Accelerator* pNextAccel = pEntry->mpAccel; 162cdf0e10cSrcweir 163cdf0e10cSrcweir // Ist da ein Accelerator hinter ? 164cdf0e10cSrcweir if ( pNextAccel ) 165cdf0e10cSrcweir { 166cdf0e10cSrcweir DBG_CHKOBJ( pNextAccel, Accelerator, NULL ); 167cdf0e10cSrcweir 168cdf0e10cSrcweir mpSequenceList->Insert( pNextAccel, (sal_uLong)0 ); 169cdf0e10cSrcweir 170cdf0e10cSrcweir // Activate-Handler vom Neuen rufen 171cdf0e10cSrcweir pNextAccel->Activate(); 172cdf0e10cSrcweir return sal_True; 173cdf0e10cSrcweir } 174cdf0e10cSrcweir else 175cdf0e10cSrcweir { 176cdf0e10cSrcweir // Hat ihn schon ! 177cdf0e10cSrcweir if ( pEntry->mbEnabled ) 178cdf0e10cSrcweir { 179cdf0e10cSrcweir // Sequence beenden (Deactivate-Handler vorher rufen) 180cdf0e10cSrcweir EndSequence(); 181cdf0e10cSrcweir 182cdf0e10cSrcweir // Dem Accelerator das aktuelle Item setzen 183cdf0e10cSrcweir // und Handler rufen 184cdf0e10cSrcweir sal_Bool bDel = sal_False; 185cdf0e10cSrcweir pAccel->maCurKeyCode = rKeyCode; 186cdf0e10cSrcweir pAccel->mnCurId = pEntry->mnId; 187cdf0e10cSrcweir pAccel->mnCurRepeat = nRepeat; 188cdf0e10cSrcweir pAccel->mpDel = &bDel; 189cdf0e10cSrcweir pAccel->Select(); 190cdf0e10cSrcweir 191cdf0e10cSrcweir // Hat Accel den Aufruf ueberlebt 192cdf0e10cSrcweir if ( !bDel ) 193cdf0e10cSrcweir { 194cdf0e10cSrcweir DBG_CHKOBJ( pAccel, Accelerator, NULL ); 195cdf0e10cSrcweir pAccel->maCurKeyCode = KeyCode(); 196cdf0e10cSrcweir pAccel->mnCurId = 0; 197cdf0e10cSrcweir pAccel->mnCurRepeat = 0; 198cdf0e10cSrcweir pAccel->mpDel = NULL; 199cdf0e10cSrcweir } 200cdf0e10cSrcweir 201cdf0e10cSrcweir return sal_True; 202cdf0e10cSrcweir } 203cdf0e10cSrcweir else 204cdf0e10cSrcweir { 205cdf0e10cSrcweir // Sequenz abbrechen, weil Acceleraor disabled 206cdf0e10cSrcweir // Taste wird weitergeleitet (ans System) 207cdf0e10cSrcweir FlushAccel(); 208cdf0e10cSrcweir return sal_False; 209cdf0e10cSrcweir } 210cdf0e10cSrcweir } 211cdf0e10cSrcweir } 212cdf0e10cSrcweir else 213cdf0e10cSrcweir { 214cdf0e10cSrcweir // Sequenz abbrechen wegen falscher Taste 215cdf0e10cSrcweir FlushAccel(); 216cdf0e10cSrcweir return sal_False; 217cdf0e10cSrcweir } 218cdf0e10cSrcweir } 219cdf0e10cSrcweir 220cdf0e10cSrcweir // Durch die Liste der Acceleratoren wuehlen 221cdf0e10cSrcweir pAccel = mpAccelList->First(); 222cdf0e10cSrcweir while ( pAccel ) 223cdf0e10cSrcweir { 224cdf0e10cSrcweir DBG_CHKOBJ( pAccel, Accelerator, NULL ); 225cdf0e10cSrcweir 226cdf0e10cSrcweir // Ist der Eintrag da drin ? 227cdf0e10cSrcweir ImplAccelEntry* pEntry = pAccel->ImplGetAccelData( rKeyCode ); 228cdf0e10cSrcweir if ( pEntry ) 229cdf0e10cSrcweir { 230cdf0e10cSrcweir Accelerator* pNextAccel = pEntry->mpAccel; 231cdf0e10cSrcweir 232cdf0e10cSrcweir // Ist da ein Accelerator hinter ? 233cdf0e10cSrcweir if ( pNextAccel ) 234cdf0e10cSrcweir { 235cdf0e10cSrcweir DBG_CHKOBJ( pNextAccel, Accelerator, NULL ); 236cdf0e10cSrcweir 237cdf0e10cSrcweir // Sequenz-Liste erzeugen 238cdf0e10cSrcweir mpSequenceList = new ImplAccelList; 239cdf0e10cSrcweir mpSequenceList->Insert( pAccel, (sal_uLong)0 ); 240cdf0e10cSrcweir mpSequenceList->Insert( pNextAccel, (sal_uLong)0 ); 241cdf0e10cSrcweir 242cdf0e10cSrcweir // Activate-Handler vom Neuen rufen 243cdf0e10cSrcweir pNextAccel->Activate(); 244cdf0e10cSrcweir 245cdf0e10cSrcweir return sal_True; 246cdf0e10cSrcweir } 247cdf0e10cSrcweir else 248cdf0e10cSrcweir { 249cdf0e10cSrcweir // Hat ihn schon ! 250cdf0e10cSrcweir if ( pEntry->mbEnabled ) 251cdf0e10cSrcweir { 252cdf0e10cSrcweir // Activate/Deactivate-Handler vorher rufen 253cdf0e10cSrcweir pAccel->Activate(); 254cdf0e10cSrcweir pAccel->Deactivate(); 255cdf0e10cSrcweir 256cdf0e10cSrcweir // Dem Accelerator das aktuelle Item setzen 257cdf0e10cSrcweir // und Handler rufen 258cdf0e10cSrcweir sal_Bool bDel = sal_False; 259cdf0e10cSrcweir pAccel->maCurKeyCode = rKeyCode; 260cdf0e10cSrcweir pAccel->mnCurId = pEntry->mnId; 261cdf0e10cSrcweir pAccel->mnCurRepeat = nRepeat; 262cdf0e10cSrcweir pAccel->mpDel = &bDel; 263cdf0e10cSrcweir pAccel->Select(); 264cdf0e10cSrcweir 265cdf0e10cSrcweir // Hat Accel den Aufruf ueberlebt 266cdf0e10cSrcweir if ( !bDel ) 267cdf0e10cSrcweir { 268cdf0e10cSrcweir DBG_CHKOBJ( pAccel, Accelerator, NULL ); 269cdf0e10cSrcweir pAccel->maCurKeyCode = KeyCode(); 270cdf0e10cSrcweir pAccel->mnCurId = 0; 271cdf0e10cSrcweir pAccel->mnCurRepeat = 0; 272cdf0e10cSrcweir pAccel->mpDel = NULL; 273cdf0e10cSrcweir } 274cdf0e10cSrcweir 275cdf0e10cSrcweir return sal_True; 276cdf0e10cSrcweir } 277cdf0e10cSrcweir else 278cdf0e10cSrcweir return sal_False; 279cdf0e10cSrcweir } 280cdf0e10cSrcweir } 281cdf0e10cSrcweir 282cdf0e10cSrcweir // Nicht gefunden, vielleicht im naechsten Accelerator 283cdf0e10cSrcweir pAccel = mpAccelList->Next(); 284cdf0e10cSrcweir } 285cdf0e10cSrcweir 286cdf0e10cSrcweir return sal_False; 287cdf0e10cSrcweir } 288