kdecore Library API Documentation

kaccelbase.cpp

00001 /* 00002 Copyright (C) 1997-2000 Nicolas Hadacek <hadacek@kde.org> 00003 Copyright (C) 1998 Mark Donohoe <donohoe@kde.org> 00004 Copyright (C) 1998 Matthias Ettrich <ettrich@kde.org> 00005 Copyright (c) 2001,2002 Ellis Whitehead <ellis@kde.org> 00006 00007 This library is free software; you can redistribute it and/or 00008 modify it under the terms of the GNU Library General Public 00009 License as published by the Free Software Foundation; either 00010 version 2 of the License, or (at your option) any later version. 00011 00012 This library is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 Library General Public License for more details. 00016 00017 You should have received a copy of the GNU Library General Public License 00018 along with this library; see the file COPYING.LIB. If not, write to 00019 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00020 Boston, MA 02111-1307, USA. 00021 */ 00022 00023 #include "kaccelbase.h" 00024 00025 #include <qkeycode.h> 00026 #include <qlabel.h> 00027 #include <qpopupmenu.h> 00028 00029 #include <kconfig.h> 00030 #include "kckey.h" 00031 #include <kdebug.h> 00032 #include <kglobal.h> 00033 #include <kkeynative.h> 00034 #include "kkeyserver_x11.h" 00035 #include <klocale.h> 00036 #include "kshortcutmenu.h" 00037 00038 //--------------------------------------------------------------------- 00039 // class KAccelBase::ActionInfo 00040 //--------------------------------------------------------------------- 00041 00042 //--------------------------------------------------------------------- 00043 // class KAccelBase 00044 //--------------------------------------------------------------------- 00045 00046 KAccelBase::KAccelBase( int fInitCode ) 00047 : m_rgActions( this ) 00048 { 00049 kdDebug(125) << "KAccelBase(): this = " << this << endl; 00050 m_bNativeKeys = fInitCode & NATIVE_KEYS; 00051 m_bEnabled = true; 00052 m_sConfigGroup = "Shortcuts"; 00053 m_bConfigIsGlobal = false; 00054 m_bAutoUpdate = false; 00055 mtemp_pActionRemoving = 0; 00056 } 00057 00058 KAccelBase::~KAccelBase() 00059 { 00060 kdDebug(125) << "~KAccelBase(): this = " << this << endl; 00061 } 00062 00063 uint KAccelBase::actionCount() const { return m_rgActions.count(); } 00064 KAccelActions& KAccelBase::actions() { return m_rgActions; } 00065 bool KAccelBase::isEnabled() const { return m_bEnabled; } 00066 00067 KAccelAction* KAccelBase::actionPtr( const QString& sAction ) 00068 { return m_rgActions.actionPtr( sAction ); } 00069 00070 const KAccelAction* KAccelBase::actionPtr( const QString& sAction ) const 00071 { return m_rgActions.actionPtr( sAction ); } 00072 00073 KAccelAction* KAccelBase::actionPtr( const KKeyServer::Key& key ) 00074 { 00075 if( !m_mapKeyToAction.contains( key ) ) 00076 return 0; 00077 // Note: If more than one action is connected to a single key, nil will be returned. 00078 return m_mapKeyToAction[key].pAction; 00079 } 00080 00081 KAccelAction* KAccelBase::actionPtr( const KKey& key ) 00082 { 00083 KKeyServer::Key k2; 00084 k2.init( key, !m_bNativeKeys ); 00085 return actionPtr( k2 ); 00086 } 00087 00088 void KAccelBase::setConfigGroup( const QString& sConfigGroup ) 00089 { m_sConfigGroup = sConfigGroup; } 00090 00091 void KAccelBase::setConfigGlobal( bool global ) 00092 { m_bConfigIsGlobal = global; } 00093 00094 bool KAccelBase::setActionEnabled( const QString& sAction, bool bEnable ) 00095 { 00096 KAccelAction* pAction = actionPtr( sAction ); 00097 if( pAction ) { 00098 if( pAction->m_bEnabled != bEnable ) { 00099 kdDebug(125) << "KAccelBase::setActionEnabled( " << sAction << ", " << bEnable << " )" << endl; 00100 pAction->m_bEnabled = bEnable; 00101 if( m_bAutoUpdate ) { 00102 // FIXME: the action may already have it's connections inserted! 00103 if( bEnable ) 00104 insertConnection( pAction ); 00105 else if( pAction->isConnected() ) 00106 removeConnection( pAction ); 00107 } 00108 } 00109 return true; 00110 } 00111 return false; 00112 } 00113 00114 bool KAccelBase::setAutoUpdate( bool bAuto ) 00115 { 00116 kdDebug(125) << "KAccelBase::setAutoUpdate( " << bAuto << " ): m_bAutoUpdate on entrance = " << m_bAutoUpdate << endl; 00117 bool b = m_bAutoUpdate; 00118 if( !m_bAutoUpdate && bAuto ) 00119 updateConnections(); 00120 m_bAutoUpdate = bAuto; 00121 return b; 00122 } 00123 00124 KAccelAction* KAccelBase::insert( const QString& sAction, const QString& sDesc, const QString& sHelp, 00125 const KShortcut& rgCutDefaults3, const KShortcut& rgCutDefaults4, 00126 const QObject* pObjSlot, const char* psMethodSlot, 00127 bool bConfigurable, bool bEnabled ) 00128 { 00129 //kdDebug(125) << "KAccelBase::insert() begin" << endl; 00130 KAccelAction* pAction = m_rgActions.insert( 00131 sAction, sDesc, sHelp, 00132 rgCutDefaults3, rgCutDefaults4, 00133 pObjSlot, psMethodSlot, 00134 bConfigurable, bEnabled ); 00135 00136 if( pAction && m_bAutoUpdate ) 00137 insertConnection( pAction ); 00138 00139 //kdDebug(125) << "KAccelBase::insert() end" << endl; 00140 return pAction; 00141 } 00142 00143 KAccelAction* KAccelBase::insert( const QString& sName, const QString& sDesc ) 00144 { return m_rgActions.insert( sName, sDesc ); } 00145 00146 bool KAccelBase::remove( const QString& sAction ) 00147 { 00148 return m_rgActions.remove( sAction ); 00149 } 00150 00151 void KAccelBase::slotRemoveAction( KAccelAction* pAction ) 00152 { 00153 removeConnection( pAction ); 00154 } 00155 00156 bool KAccelBase::setActionSlot( const QString& sAction, const QObject* pObjSlot, const char* psMethodSlot ) 00157 { 00158 kdDebug(125) << "KAccelBase::setActionSlot( " << sAction << ", " << pObjSlot << ", " << psMethodSlot << " )\n"; 00159 KAccelAction* pAction = m_rgActions.actionPtr( sAction ); 00160 if( pAction ) { 00161 // If there was a previous connection, remove it. 00162 if( m_bAutoUpdate && pAction->isConnected() ) { 00163 kdDebug(125) << "\tm_pObjSlot = " << pAction->m_pObjSlot << " m_psMethodSlot = " << pAction->m_psMethodSlot << endl; 00164 removeConnection( pAction ); 00165 } 00166 00167 pAction->m_pObjSlot = pObjSlot; 00168 pAction->m_psMethodSlot = psMethodSlot; 00169 00170 // If we're setting a connection, 00171 if( m_bAutoUpdate && pObjSlot && psMethodSlot ) 00172 insertConnection( pAction ); 00173 00174 return true; 00175 } else 00176 return false; 00177 } 00178 00179 /* 00180 KAccelBase 00181 Run Command=Meta+Enter;Alt+F2 00182 KAccelAction = "Run Command" 00183 1) KAccelKeySeries = "Meta+Enter" 00184 1a) Meta+Enter 00185 1b) Meta+Keypad_Enter 00186 2) KAccelKeySeries = "Alt+F2" 00187 1a) Alt+F2 00188 00189 Konqueror=Meta+I,I 00190 KAccelAction = "Konqueror" 00191 1) KAccelKeySeries = "Meta+I,I" 00192 1a) Meta+I 00193 2a) I 00194 00195 Something=Meta+Asterisk,X 00196 KAccelAction = "Something" 00197 1) KAccelKeySeries = "Meta+Asterisk,X" 00198 1a) Meta+Shift+8 00199 1b) Meta+Keypad_8 00200 2a) X 00201 00202 read in a config entry 00203 split by ';' 00204 find key sequences to disconnect 00205 find new key sequences to connect 00206 check for conflicts with implicit keys 00207 disconnect conflicting implicit keys 00208 connect new key sequences 00209 */ 00210 /* 00211 { 00212 For { 00213 for( KAccelAction::iterator itAction = m_rgActions.begin(); itAction != m_rgActions.end(); ++itAction ) { 00214 KAccelAction& action = *itAction; 00215 for( KAccelSeries::iterator itSeries = action.m_rgSeries.begin(); itSeries != action.m_rgSeries.end(); ++itSeries ) { 00216 KAccelSeries& series = *itSeries; 00217 if( 00218 } 00219 } 00220 } 00221 Sort by: iVariation, iSequence, iSeries, iAction 00222 00223 1) KAccelAction = "Run Command" 00224 1) KAccelKeySeries = "Meta+Enter" 00225 1a) Meta+Enter 00226 1b) Meta+Keypad_Enter 00227 2) KAccelKeySeries = "Alt+F2" 00228 1a) Alt+F2 00229 00230 2) KAccelAction = "Enter Calculation" 00231 1) KAccelKeySeries = "Meta+Keypad_Enter" 00232 1a) Meta+Keypad_Enter 00233 00234 List = 00235 Meta+Enter -> 1, 1, 1a 00236 Meta+Keypad_Enter -> 2, 1, 1a 00237 Alt+F2 -> 1, 2, 1a 00238 [Meta+Keypad_Enter] -> [1, 1, 1b] 00239 00240 } 00241 */ 00242 00243 struct KAccelBase::X 00244 { 00245 uint iAction, iSeq, iVari; 00246 KKeyServer::Key key; 00247 00248 X() {} 00249 X( uint _iAction, uint _iSeq, uint _iVari, const KKeyServer::Key& _key ) 00250 { iAction = _iAction; iSeq = _iSeq; iVari = _iVari; key = _key; } 00251 00252 int compare( const X& x ) 00253 { 00254 int n = key.compare( x.key ); 00255 if( n != 0 ) return n; 00256 if( iVari != x.iVari ) return iVari - x.iVari; 00257 if( iSeq != x.iSeq ) return iSeq - x.iSeq; 00258 return 0; 00259 } 00260 00261 bool operator <( const X& x ) { return compare( x ) < 0; } 00262 bool operator >( const X& x ) { return compare( x ) > 0; } 00263 bool operator <=( const X& x ) { return compare( x ) <= 0; } 00264 }; 00265 00266 /* 00267 #1 Ctrl+A 00268 #2 Ctrl+A 00269 #3 Ctrl+B 00270 ------ 00271 Ctrl+A => Null 00272 Ctrl+B => #3 00273 00274 #1 Ctrl+A 00275 #1 Ctrl+B;Ctrl+A 00276 ------ 00277 Ctrl+A => #1 00278 Ctrl+B => #2 00279 00280 #1 Ctrl+A 00281 #1 Ctrl+B,C 00282 #1 Ctrl+B,D 00283 ------ 00284 Ctrl+A => #1 00285 Ctrl+B => Null 00286 00287 #1 Ctrl+A 00288 #2 Ctrl+Plus(Ctrl+KP_Add) 00289 ------ 00290 Ctrl+A => #1 00291 Ctrl+Plus => #2 00292 Ctrl+KP_Add => #2 00293 00294 #1 Ctrl+Plus(Ctrl+KP_Add) 00295 #2 Ctrl+KP_Add 00296 ------ 00297 Ctrl+Plus => #1 00298 Ctrl+KP_Add => #2 00299 00300 #1 Ctrl+Plus(Ctrl+KP_Add) 00301 #2 Ctrl+A;Ctrl+KP_Add 00302 ------ 00303 Ctrl+A => #2 00304 Ctrl+Plus => #1 00305 Ctrl+KP_Add => #2 00306 */ 00307 00308 bool KAccelBase::updateConnections() 00309 { 00310 kdDebug(125) << "KAccelBase::updateConnections() this = " << this << endl; 00311 // Retrieve the list of keys to be connected, sorted by priority. 00312 // (key, variation, seq) 00313 QValueVector<X> rgKeys; 00314 createKeyList( rgKeys ); 00315 m_rgActionsNonUnique.clear(); 00316 00317 KKeyToActionMap mapKeyToAction; 00318 for( uint i = 0; i < rgKeys.size(); i++ ) { 00319 X& x = rgKeys[i]; 00320 KKeyServer::Key& key = x.key; 00321 ActionInfo info; 00322 bool bNonUnique = false; 00323 00324 info.pAction = m_rgActions.actionPtr( x.iAction ); 00325 info.iSeq = x.iSeq; 00326 info.iVariation = x.iVari; 00327 00328 // If this is a multi-key shortcut, 00329 if( info.pAction->shortcut().seq(info.iSeq).count() > 1 ) 00330 bNonUnique = true; 00331 // If this key is requested by more than one action, 00332 else if( i < rgKeys.size() - 1 && key == rgKeys[i+1].key ) { 00333 // If multiple actions requesting this key 00334 // have the same priority as the first one, 00335 if( info.iVariation == rgKeys[i+1].iVari && info.iSeq == rgKeys[i+1].iSeq ) 00336 bNonUnique = true; 00337 00338 kdDebug(125) << "key conflict = " << key.key().toStringInternal() 00339 << " action1 = " << info.pAction->name() 00340 << " action2 = " << m_rgActions.actionPtr( rgKeys[i+1].iAction )->name() 00341 << " non-unique = " << bNonUnique << endl; 00342 00343 // Skip over the other records with this same key. 00344 while( i < rgKeys.size() - 1 && key == rgKeys[i+1].key ) 00345 i++; 00346 } 00347 00348 if( bNonUnique ) { 00349 // Remove connection to single action if there is one 00350 if( m_mapKeyToAction.contains( key ) ) { 00351 KAccelAction* pAction = m_mapKeyToAction[key].pAction; 00352 if( pAction ) { 00353 m_mapKeyToAction.remove( key ); 00354 disconnectKey( *pAction, key ); 00355 pAction->decConnections(); 00356 m_rgActionsNonUnique.append( pAction ); 00357 } 00358 } 00359 // Indicate that no single action is associated with this key. 00360 m_rgActionsNonUnique.append( info.pAction ); 00361 info.pAction = 0; 00362 } 00363 00364 //kdDebug(125) << "mapKeyToAction[" << key.toStringInternal() << "] = " << info.pAction << endl; 00365 mapKeyToAction[key] = info; 00366 } 00367 00368 // Disconnect keys which no longer have bindings: 00369 for( KKeyToActionMap::iterator it = m_mapKeyToAction.begin(); it != m_mapKeyToAction.end(); ++it ) { 00370 const KKeyServer::Key& key = it.key(); 00371 KAccelAction* pAction = (*it).pAction; 00372 // If this key is longer used or it points to a different action now, 00373 if( !mapKeyToAction.contains( key ) || mapKeyToAction[key].pAction != pAction ) { 00374 if( pAction ) { 00375 disconnectKey( *pAction, key ); 00376 pAction->decConnections(); 00377 } else 00378 disconnectKey( key ); 00379 } 00380 } 00381 00382 // Connect any unconnected keys: 00383 // In other words, connect any keys which are present in the 00384 // new action map, but which are _not_ present in the old one. 00385 for( KKeyToActionMap::iterator it = mapKeyToAction.begin(); it != mapKeyToAction.end(); ++it ) { 00386 const KKeyServer::Key& key = it.key(); 00387 KAccelAction* pAction = (*it).pAction; 00388 if( !m_mapKeyToAction.contains( key ) || m_mapKeyToAction[key].pAction != pAction ) { 00389 // TODO: Decide what to do if connect fails. 00390 // Probably should remove this item from map. 00391 if( pAction ) { 00392 if( connectKey( *pAction, key ) ) 00393 pAction->incConnections(); 00394 } else 00395 connectKey( key ); 00396 } 00397 } 00398 00399 // Store new map. 00400 m_mapKeyToAction = mapKeyToAction; 00401 00402 #ifndef NDEBUG 00403 for( KKeyToActionMap::iterator it = m_mapKeyToAction.begin(); it != m_mapKeyToAction.end(); ++it ) { 00404 kdDebug(125) << "Key: " << it.key().key().toStringInternal() << " => '" 00405 << (((*it).pAction) ? (*it).pAction->name() : QString::null) << "'" << endl; 00406 } 00407 #endif 00408 return true; 00409 } 00410 00411 // Construct a list of keys to be connected, sorted highest priority first. 00412 void KAccelBase::createKeyList( QValueVector<struct X>& rgKeys ) 00413 { 00414 //kdDebug(125) << "KAccelBase::createKeyList()" << endl; 00415 if( !m_bEnabled ) 00416 return; 00417 00418 // create the list 00419 // For each action 00420 for( uint iAction = 0; iAction < m_rgActions.count(); iAction++ ) { 00421 KAccelAction* pAction = m_rgActions.actionPtr( iAction ); 00422 if( pAction && pAction->m_pObjSlot && pAction->m_psMethodSlot && pAction != mtemp_pActionRemoving ) { 00423 // For each key sequence associated with action 00424 for( uint iSeq = 0; iSeq < pAction->shortcut().count(); iSeq++ ) { 00425 const KKeySequence& seq = pAction->shortcut().seq(iSeq); 00426 if( seq.count() > 0 ) { 00427 KKeyServer::Variations vars; 00428 vars.init( seq.key(0), !m_bNativeKeys ); 00429 for( uint iVari = 0; iVari < vars.count(); iVari++ ) { 00430 if( vars.key(iVari).code() && vars.key(iVari).sym() ) 00431 rgKeys.push_back( X( iAction, iSeq, iVari, vars.key( iVari ) ) ); 00432 //kdDebug(125) << "\t" << pAction->name() << ": " << vars.key(iVari).toStringInternal() << endl; 00433 } 00434 } 00435 //else 00436 // kdDebug(125) << "\t*" << pAction->name() << ":" << endl; 00437 } 00438 } 00439 } 00440 00441 // sort by priority: iVariation[of first key], iSequence, iAction 00442 qHeapSort( rgKeys.begin(), rgKeys.end() ); 00443 } 00444 00445 bool KAccelBase::insertConnection( KAccelAction* pAction ) 00446 { 00447 if( !pAction->m_pObjSlot || !pAction->m_psMethodSlot ) 00448 return true; 00449 00450 kdDebug(125) << "KAccelBase::insertConnection( " << pAction << "=\"" << pAction->m_sName << "\"; shortcut = " << pAction->shortcut().toStringInternal() << " ) this = " << this << endl; 00451 00452 // For each sequence associated with the given action: 00453 for( uint iSeq = 0; iSeq < pAction->shortcut().count(); iSeq++ ) { 00454 // Get the first key of the sequence. 00455 KKeyServer::Variations vars; 00456 vars.init( pAction->shortcut().seq(iSeq).key(0), !m_bNativeKeys ); 00457 for( uint iVari = 0; iVari < vars.count(); iVari++ ) { 00458 const KKeyServer::Key& key = vars.key( iVari ); 00459 00460 //if( !key.isNull() ) { 00461 if( key.sym() ) { 00462 if( !m_mapKeyToAction.contains( key ) ) { 00463 // If this is a single-key shortcut, 00464 if( pAction->shortcut().seq(iSeq).count() == 1 ) { 00465 m_mapKeyToAction[key] = ActionInfo( pAction, iSeq, iVari ); 00466 if( connectKey( *pAction, key ) ) 00467 pAction->incConnections(); 00468 } 00469 // Else this is a multi-key shortcut, 00470 else { 00471 m_mapKeyToAction[key] = ActionInfo( 0, 0, 0 ); 00472 // Insert into non-unique list if it's not already there. 00473 if( m_rgActionsNonUnique.findIndex( pAction ) == -1 ) 00474 m_rgActionsNonUnique.append( pAction ); 00475 if( connectKey( key ) ) 00476 pAction->incConnections(); 00477 } 00478 } else { 00479 // There is a key conflict. A full update 00480 // check is necessary. 00481 // TODO: make this more efficient where possible. 00482 if( m_mapKeyToAction[key].pAction != pAction 00483 && m_mapKeyToAction[key].pAction != 0 ) { 00484 kdDebug(125) << "Key conflict: call updateConnections():" 00485 << " key = " << key.key().toStringInternal() << endl; 00486 return updateConnections(); 00487 } 00488 } 00489 } 00490 } 00491 } 00492 00493 //kdDebug(125) << "\tActions = " << m_rgActions.size() << endl; 00494 //for( KAccelActions::const_iterator it = m_rgActions.begin(); it != m_rgActions.end(); ++it ) { 00495 // kdDebug(125) << "\t" << &(*it) << " '" << (*it).m_sName << "'" << endl; 00496 //} 00497 00498 //kdDebug(125) << "\tKeys = " << m_mapKeyToAction.size() << endl; 00499 //for( KKeyToActionMap::iterator it = m_mapKeyToAction.begin(); it != m_mapKeyToAction.end(); ++it ) { 00500 // //kdDebug(125) << "\tKey: " << it.key().toString() << " => '" << (*it)->m_sName << "'" << endl; 00501 // kdDebug(125) << "\tKey: " << it.key().toString() << " => '" << *it << "'" << endl; 00502 // kdDebug(125) << "\t\t'" << (*it)->m_sName << "'" << endl; 00503 //} 00504 00505 return true; 00506 } 00507 00508 bool KAccelBase::removeConnection( KAccelAction* pAction ) 00509 { 00510 kdDebug(125) << "KAccelBase::removeConnection( " << pAction << " = \"" << pAction->m_sName << "\"; shortcut = " << pAction->m_cut.toStringInternal() << " ): this = " << this << endl; 00511 00512 //for( KKeyToActionMap::iterator it = m_mapKeyToAction.begin(); it != m_mapKeyToAction.end(); ++it ) 00513 // kdDebug(125) << "\tKey: " << it.key().toString() << " => '" << (*it)->m_sName << "'" << " " << *it << endl; 00514 00515 if( m_rgActionsNonUnique.findIndex( pAction ) >= 0 ) { 00516 mtemp_pActionRemoving = pAction; 00517 bool b = updateConnections(); 00518 mtemp_pActionRemoving = 0; 00519 return b; 00520 } 00521 00522 KKeyToActionMap::iterator it = m_mapKeyToAction.begin(); 00523 while( it != m_mapKeyToAction.end() ) { 00524 KKeyServer::Key key = it.key(); 00525 ActionInfo* pInfo = &(*it); 00526 00527 // If the given action is connected to this key, 00528 if( pAction == pInfo->pAction ) { 00529 disconnectKey( *pAction, key ); 00530 pAction->decConnections(); 00531 00532 KKeyToActionMap::iterator itRemove = it++; 00533 m_mapKeyToAction.remove( itRemove ); 00534 } else 00535 ++it; 00536 } 00537 return true; 00538 } 00539 00540 bool KAccelBase::setShortcut( const QString& sAction, const KShortcut& cut ) 00541 { 00542 KAccelAction* pAction = actionPtr( sAction ); 00543 if( pAction ) { 00544 if( m_bAutoUpdate ) 00545 removeConnection( pAction ); 00546 00547 pAction->setShortcut( cut ); 00548 00549 if( m_bAutoUpdate && !pAction->shortcut().isNull() ) 00550 insertConnection( pAction ); 00551 return true; 00552 } else 00553 return false; 00554 } 00555 00556 void KAccelBase::readSettings( KConfigBase* pConfig ) 00557 { 00558 m_rgActions.readActions( m_sConfigGroup, pConfig ); 00559 if( m_bAutoUpdate ) 00560 updateConnections(); 00561 } 00562 00563 void KAccelBase::writeSettings( KConfigBase* pConfig ) const 00564 { 00565 m_rgActions.writeActions( m_sConfigGroup, pConfig, m_bConfigIsGlobal, m_bConfigIsGlobal ); 00566 } 00567 00568 QPopupMenu* KAccelBase::createPopupMenu( QWidget* pParent, const KKeySequence& seq ) 00569 { 00570 KShortcutMenu* pMenu = new KShortcutMenu( pParent, &actions(), seq ); 00571 00572 bool bActionInserted = false; 00573 bool bInsertSeparator = false; 00574 for( uint i = 0; i < actionCount(); i++ ) { 00575 const KAccelAction* pAction = actions().actionPtr( i ); 00576 00577 if( !pAction->isEnabled() ) 00578 continue; 00579 00580 // If an action has already been inserted into the menu 00581 // and we have a label instead of an action here, 00582 // then indicate that we should insert a separator before the next menu entry. 00583 if( bActionInserted && !pAction->isConfigurable() && pAction->name().contains( ':' ) ) 00584 bInsertSeparator = true; 00585 00586 for( uint iSeq = 0; iSeq < pAction->shortcut().count(); iSeq++ ) { 00587 const KKeySequence& seqAction = pAction->shortcut().seq(iSeq); 00588 if( seqAction.startsWith( seq ) ) { 00589 if( bInsertSeparator ) { 00590 pMenu->insertSeparator(); 00591 bInsertSeparator = false; 00592 } 00593 00594 pMenu->insertAction( i, seqAction ); 00595 00596 //kdDebug(125) << "sLabel = " << sLabel << ", seq = " << (QString)seqMenu.qt() << ", i = " << i << endl; 00597 //kdDebug(125) << "pMenu->accel(" << i << ") = " << (QString)pMenu->accel(i) << endl; 00598 bActionInserted = true; 00599 break; 00600 } 00601 } 00602 } 00603 pMenu->updateShortcuts(); 00604 return pMenu; 00605 }
KDE Logo
This file is part of the documentation for kdecore Library Version 3.2.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Aug 20 09:48:24 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003