• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

KDECore

kaccelbase.cpp

Go to the documentation of this file.
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., 51 Franklin Street, Fifth Floor,
00020     Boston, MA 02110-1301, 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.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 // see KGlobalAccel::blockShortcuts() stuff - it's to temporarily block
00067 // all global shortcuts, so that the key grabs are released, but from the app's
00068 // point of view the KGlobalAccel is still enabled, so KGlobalAccel needs
00069 // to disable key grabbing even if enabled
00070 bool KAccelBase::isEnabledInternal() const { return isEnabled(); }
00071 
00072 KAccelAction* KAccelBase::actionPtr( const QString& sAction )
00073     { return m_rgActions.actionPtr( sAction ); }
00074 
00075 const KAccelAction* KAccelBase::actionPtr( const QString& sAction ) const
00076     { return m_rgActions.actionPtr( sAction ); }
00077 
00078 KAccelAction* KAccelBase::actionPtr( const KKeyServer::Key& key )
00079 {
00080     if( !m_mapKeyToAction.contains( key ) )
00081         return 0;
00082     // Note: If more than one action is connected to a single key, nil will be returned.
00083     return m_mapKeyToAction[key].pAction;
00084 }
00085 
00086 KAccelAction* KAccelBase::actionPtr( const KKey& key )
00087 {
00088     KKeyServer::Key k2;
00089     k2.init( key, !m_bNativeKeys );
00090     return actionPtr( k2 );
00091 }
00092 
00093 void KAccelBase::setConfigGroup( const QString& sConfigGroup )
00094     { m_sConfigGroup = sConfigGroup; }
00095 
00096 void KAccelBase::setConfigGlobal( bool global )
00097     { m_bConfigIsGlobal = global; }
00098 
00099 bool KAccelBase::setActionEnabled( const QString& sAction, bool bEnable )
00100 {
00101     KAccelAction* pAction = actionPtr( sAction );
00102     if( pAction ) {
00103         if( pAction->m_bEnabled != bEnable ) {
00104             kdDebug(125) << "KAccelBase::setActionEnabled( " << sAction << ", " << bEnable << " )" << endl;
00105             pAction->m_bEnabled = bEnable;
00106             if( m_bAutoUpdate ) {
00107                 // FIXME: the action may already have it's connections inserted!
00108                 if( bEnable )
00109                     insertConnection( pAction );
00110                 else if( pAction->isConnected() )
00111                     removeConnection( pAction );
00112             }
00113         }
00114         return true;
00115     }
00116     return false;
00117 }
00118 
00119 bool KAccelBase::setAutoUpdate( bool bAuto )
00120 {
00121     kdDebug(125) << "KAccelBase::setAutoUpdate( " << bAuto << " ): m_bAutoUpdate on entrance = " << m_bAutoUpdate << endl;
00122     bool b = m_bAutoUpdate;
00123     if( !m_bAutoUpdate && bAuto )
00124         updateConnections();
00125     m_bAutoUpdate = bAuto;
00126     return b;
00127 }
00128 
00129 KAccelAction* KAccelBase::insert( const QString& sAction, const QString& sDesc, const QString& sHelp,
00130             const KShortcut& rgCutDefaults3, const KShortcut& rgCutDefaults4,
00131             const QObject* pObjSlot, const char* psMethodSlot,
00132             bool bConfigurable, bool bEnabled )
00133 {
00134     //kdDebug(125) << "KAccelBase::insert() begin" << endl;
00135     KAccelAction* pAction = m_rgActions.insert(
00136         sAction, sDesc, sHelp,
00137         rgCutDefaults3, rgCutDefaults4,
00138         pObjSlot, psMethodSlot,
00139         bConfigurable, bEnabled );
00140 
00141     if( pAction && m_bAutoUpdate )
00142         insertConnection( pAction );
00143 
00144     //kdDebug(125) << "KAccelBase::insert() end" << endl;
00145     return pAction;
00146 }
00147 
00148 KAccelAction* KAccelBase::insert( const QString& sName, const QString& sDesc )
00149     { return m_rgActions.insert( sName, sDesc ); }
00150 
00151 bool KAccelBase::remove( const QString& sAction )
00152 {
00153     return m_rgActions.remove( sAction );
00154 }
00155 
00156 void KAccelBase::slotRemoveAction( KAccelAction* pAction )
00157 {
00158     removeConnection( pAction );
00159 }
00160 
00161 bool KAccelBase::setActionSlot( const QString& sAction, const QObject* pObjSlot, const char* psMethodSlot )
00162 {
00163     kdDebug(125) << "KAccelBase::setActionSlot( " << sAction << ", " << pObjSlot << ", " << psMethodSlot << " )\n";
00164     KAccelAction* pAction = m_rgActions.actionPtr( sAction );
00165     if( pAction ) {
00166         // If there was a previous connection, remove it.
00167         if( m_bAutoUpdate && pAction->isConnected() ) {
00168             kdDebug(125) << "\tm_pObjSlot = " << pAction->m_pObjSlot << " m_psMethodSlot = " << pAction->m_psMethodSlot << endl;
00169             removeConnection( pAction );
00170         }
00171 
00172         pAction->m_pObjSlot = pObjSlot;
00173         pAction->m_psMethodSlot = psMethodSlot;
00174 
00175         // If we're setting a connection,
00176         if( m_bAutoUpdate && pObjSlot && psMethodSlot )
00177             insertConnection( pAction );
00178 
00179         return true;
00180     } else
00181         return false;
00182 }
00183 
00184 /*
00185 KAccelBase
00186     Run Command=Meta+Enter;Alt+F2
00187     KAccelAction = "Run Command"
00188         1) KAccelKeySeries = "Meta+Enter"
00189             1a) Meta+Enter
00190             1b) Meta+Keypad_Enter
00191         2) KAccelKeySeries = "Alt+F2"
00192             1a) Alt+F2
00193 
00194     Konqueror=Meta+I,I
00195     KAccelAction = "Konqueror"
00196         1) KAccelKeySeries = "Meta+I,I"
00197             1a) Meta+I
00198             2a) I
00199 
00200     Something=Meta+Asterisk,X
00201     KAccelAction = "Something"
00202         1) KAccelKeySeries = "Meta+Asterisk,X"
00203             1a) Meta+Shift+8
00204             1b) Meta+Keypad_8
00205             2a) X
00206 
00207 read in a config entry
00208     split by ';'
00209     find key sequences to disconnect
00210     find new key sequences to connect
00211 check for conflicts with implicit keys
00212     disconnect conflicting implicit keys
00213 connect new key sequences
00214 */
00215 /*
00216 {
00217     For {
00218         for( KAccelAction::iterator itAction = m_rgActions.begin(); itAction != m_rgActions.end(); ++itAction ) {
00219             KAccelAction& action = *itAction;
00220             for( KAccelSeries::iterator itSeries = action.m_rgSeries.begin(); itSeries != action.m_rgSeries.end(); ++itSeries ) {
00221                 KAccelSeries& series = *itSeries;
00222                 if(
00223             }
00224         }
00225     }
00226     Sort by: iVariation, iSequence, iSeries, iAction
00227 
00228     1) KAccelAction = "Run Command"
00229         1) KAccelKeySeries = "Meta+Enter"
00230             1a) Meta+Enter
00231             1b) Meta+Keypad_Enter
00232         2) KAccelKeySeries = "Alt+F2"
00233             1a) Alt+F2
00234 
00235     2) KAccelAction = "Enter Calculation"
00236         1) KAccelKeySeries = "Meta+Keypad_Enter"
00237             1a) Meta+Keypad_Enter
00238 
00239     List =
00240         Meta+Enter      -> 1, 1, 1a
00241         Meta+Keypad_Enter   -> 2, 1, 1a
00242         Alt+F2          -> 1, 2, 1a
00243         [Meta+Keypad_Enter] -> [1, 1, 1b]
00244 
00245 }
00246 */
00247 
00248 #ifdef Q_WS_X11
00249 struct KAccelBase::X
00250 {
00251     uint iAction, iSeq, iVari;
00252     KKeyServer::Key key;
00253 
00254     X() {}
00255     X( uint _iAction, uint _iSeq, uint _iVari, const KKeyServer::Key& _key )
00256         { iAction = _iAction; iSeq = _iSeq; iVari = _iVari; key = _key; }
00257 
00258     int compare( const X& x )
00259     {
00260         int n = key.compare( x.key );
00261         if( n != 0 )           return n;
00262         if( iVari != x.iVari ) return iVari - x.iVari;
00263         if( iSeq != x.iSeq )   return iSeq - x.iSeq;
00264         return 0;
00265     }
00266 
00267     bool operator <( const X& x )  { return compare( x ) < 0; }
00268     bool operator >( const X& x )  { return compare( x ) > 0; }
00269     bool operator <=( const X& x ) { return compare( x ) <= 0; }
00270 };
00271 #endif //Q_WS_X11
00272 
00273 /*
00274 #1 Ctrl+A
00275 #2 Ctrl+A
00276 #3 Ctrl+B
00277    ------
00278    Ctrl+A => Null
00279    Ctrl+B => #3
00280 
00281 #1 Ctrl+A
00282 #1 Ctrl+B;Ctrl+A
00283    ------
00284    Ctrl+A => #1
00285    Ctrl+B => #2
00286 
00287 #1 Ctrl+A
00288 #1 Ctrl+B,C
00289 #1 Ctrl+B,D
00290    ------
00291    Ctrl+A => #1
00292    Ctrl+B => Null
00293 
00294 #1 Ctrl+A
00295 #2 Ctrl+Plus(Ctrl+KP_Add)
00296    ------
00297    Ctrl+A => #1
00298    Ctrl+Plus => #2
00299    Ctrl+KP_Add => #2
00300 
00301 #1 Ctrl+Plus(Ctrl+KP_Add)
00302 #2 Ctrl+KP_Add
00303    ------
00304    Ctrl+Plus => #1
00305    Ctrl+KP_Add => #2
00306 
00307 #1 Ctrl+Plus(Ctrl+KP_Add)
00308 #2 Ctrl+A;Ctrl+KP_Add
00309    ------
00310    Ctrl+A => #2
00311    Ctrl+Plus => #1
00312    Ctrl+KP_Add => #2
00313 */
00314 
00315 bool KAccelBase::updateConnections()
00316 {
00317 #ifdef Q_WS_X11
00318     kdDebug(125) << "KAccelBase::updateConnections()  this = " << this << endl;
00319     // Retrieve the list of keys to be connected, sorted by priority.
00320     //  (key, variation, seq)
00321     QValueVector<X> rgKeys;
00322     createKeyList( rgKeys );
00323     m_rgActionsNonUnique.clear();
00324 
00325     KKeyToActionMap mapKeyToAction;
00326     for( uint i = 0; i < rgKeys.size(); i++ ) {
00327         X& x = rgKeys[i];
00328         KKeyServer::Key& key = x.key;
00329         ActionInfo info;
00330         bool bNonUnique = false;
00331 
00332         info.pAction = m_rgActions.actionPtr( x.iAction );
00333         info.iSeq = x.iSeq;
00334         info.iVariation = x.iVari;
00335 
00336         // If this is a multi-key shortcut,
00337         if( info.pAction->shortcut().seq(info.iSeq).count() > 1 )
00338             bNonUnique = true;
00339         // If this key is requested by more than one action,
00340         else if( i < rgKeys.size() - 1 && key == rgKeys[i+1].key ) {
00341             // If multiple actions requesting this key
00342             //  have the same priority as the first one,
00343             if( info.iVariation == rgKeys[i+1].iVari && info.iSeq == rgKeys[i+1].iSeq )
00344                 bNonUnique = true;
00345 
00346             kdDebug(125) << "key conflict = " << key.key().toStringInternal()
00347                 << " action1 = " << info.pAction->name()
00348                 << " action2 = " << m_rgActions.actionPtr( rgKeys[i+1].iAction )->name()
00349                 << " non-unique = " << bNonUnique << endl;
00350 
00351             // Skip over the other records with this same key.
00352             while( i < rgKeys.size() - 1 && key == rgKeys[i+1].key )
00353                 i++;
00354         }
00355 
00356         if( bNonUnique ) {
00357             // Remove connection to single action if there is one
00358             if( m_mapKeyToAction.contains( key ) ) {
00359                 KAccelAction* pAction = m_mapKeyToAction[key].pAction;
00360                 if( pAction ) {
00361                     m_mapKeyToAction.remove( key );
00362                     disconnectKey( *pAction, key );
00363                     pAction->decConnections();
00364                     m_rgActionsNonUnique.append( pAction );
00365                 }
00366             }
00367             // Indicate that no single action is associated with this key.
00368             m_rgActionsNonUnique.append( info.pAction );
00369             info.pAction = 0;
00370         }
00371 
00372         //kdDebug(125) << "mapKeyToAction[" << key.toStringInternal() << "] = " << info.pAction << endl;
00373         mapKeyToAction[key] = info;
00374     }
00375 
00376     // Disconnect keys which no longer have bindings:
00377     for( KKeyToActionMap::iterator it = m_mapKeyToAction.begin(); it != m_mapKeyToAction.end(); ++it ) {
00378         const KKeyServer::Key& key = it.key();
00379         KAccelAction* pAction = (*it).pAction;
00380         // If this key is longer used or it points to a different action now,
00381         if( !mapKeyToAction.contains( key ) || mapKeyToAction[key].pAction != pAction ) {
00382             if( pAction ) {
00383                 disconnectKey( *pAction, key );
00384                 pAction->decConnections();
00385             } else
00386                 disconnectKey( key );
00387         }
00388     }
00389 
00390     // Connect any unconnected keys:
00391     // In other words, connect any keys which are present in the
00392     //  new action map, but which are _not_ present in the old one.
00393     for( KKeyToActionMap::iterator it = mapKeyToAction.begin(); it != mapKeyToAction.end(); ++it ) {
00394         const KKeyServer::Key& key = it.key();
00395         KAccelAction* pAction = (*it).pAction;
00396         if( !m_mapKeyToAction.contains( key ) || m_mapKeyToAction[key].pAction != pAction ) {
00397             // TODO: Decide what to do if connect fails.
00398             //  Probably should remove this item from map.
00399             if( pAction ) {
00400                 if( connectKey( *pAction, key ) )
00401                     pAction->incConnections();
00402             } else
00403                 connectKey( key );
00404         }
00405     }
00406 
00407     // Store new map.
00408     m_mapKeyToAction = mapKeyToAction;
00409 
00410 #ifndef NDEBUG
00411     for( KKeyToActionMap::iterator it = m_mapKeyToAction.begin(); it != m_mapKeyToAction.end(); ++it ) {
00412         kdDebug(125) << "Key: " << it.key().key().toStringInternal() << " => '"
00413             << (((*it).pAction) ? (*it).pAction->name() : QString::null) << "'" << endl;
00414     }
00415 #endif
00416 #endif //Q_WS_X11
00417     return true;
00418 }
00419 
00420 #ifdef Q_WS_X11
00421 // Construct a list of keys to be connected, sorted highest priority first.
00422 void KAccelBase::createKeyList( QValueVector<struct X>& rgKeys )
00423 {
00424     //kdDebug(125) << "KAccelBase::createKeyList()" << endl;
00425     if( !isEnabledInternal())
00426         return;
00427 
00428     // create the list
00429     // For each action
00430     for( uint iAction = 0; iAction < m_rgActions.count(); iAction++ ) {
00431         KAccelAction* pAction = m_rgActions.actionPtr( iAction );
00432         if( pAction && pAction->m_pObjSlot && pAction->m_psMethodSlot && pAction != mtemp_pActionRemoving ) {
00433             // For each key sequence associated with action
00434             for( uint iSeq = 0; iSeq < pAction->shortcut().count(); iSeq++ ) {
00435                 const KKeySequence& seq = pAction->shortcut().seq(iSeq);
00436                 if( seq.count() > 0 ) {
00437                     KKeyServer::Variations vars;
00438                     vars.init( seq.key(0), !m_bNativeKeys );
00439                     for( uint iVari = 0; iVari < vars.count(); iVari++ ) {
00440                         if( vars.key(iVari).code() && vars.key(iVari).sym() )
00441                             rgKeys.push_back( X( iAction, iSeq, iVari, vars.key( iVari ) ) );
00442                         //kdDebug(125) << "\t" << pAction->name() << ": " << vars.key(iVari).toStringInternal() << endl;
00443                     }
00444                 }
00445                 //else
00446                 //  kdDebug(125) << "\t*" << pAction->name() << ":" << endl;
00447             }
00448         }
00449     }
00450 
00451     // sort by priority: iVariation[of first key], iSequence, iAction
00452     qHeapSort( rgKeys.begin(), rgKeys.end() );
00453 }
00454 #endif //Q_WS_X11
00455 
00456 bool KAccelBase::insertConnection( KAccelAction* pAction )
00457 {
00458     if( !pAction->m_pObjSlot || !pAction->m_psMethodSlot )
00459         return true;
00460 
00461     kdDebug(125) << "KAccelBase::insertConnection( " << pAction << "=\"" << pAction->m_sName << "\"; shortcut = " << pAction->shortcut().toStringInternal() << " )  this = " << this << endl;
00462 
00463     // For each sequence associated with the given action:
00464     for( uint iSeq = 0; iSeq < pAction->shortcut().count(); iSeq++ ) {
00465         // Get the first key of the sequence.
00466         KKeyServer::Variations vars;
00467         vars.init( pAction->shortcut().seq(iSeq).key(0), !m_bNativeKeys );
00468         for( uint iVari = 0; iVari < vars.count(); iVari++ ) {
00469             const KKeyServer::Key& key = vars.key( iVari );
00470 
00471             //if( !key.isNull() ) {
00472             if( key.sym() ) {
00473                 if( !m_mapKeyToAction.contains( key ) ) {
00474                     // If this is a single-key shortcut,
00475                     if( pAction->shortcut().seq(iSeq).count() == 1 ) {
00476                         m_mapKeyToAction[key] = ActionInfo( pAction, iSeq, iVari );
00477                         if( connectKey( *pAction, key ) )
00478                             pAction->incConnections();
00479                     }
00480                     // Else this is a multi-key shortcut,
00481                     else {
00482                         m_mapKeyToAction[key] = ActionInfo( 0, 0, 0 );
00483                         // Insert into non-unique list if it's not already there.
00484                         if( m_rgActionsNonUnique.findIndex( pAction ) == -1 )
00485                             m_rgActionsNonUnique.append( pAction );
00486                         if( connectKey( key ) )
00487                             pAction->incConnections();
00488                     }
00489                 } else {
00490                     // There is a key conflict.  A full update
00491                     //  check is necessary.
00492                     // TODO: make this more efficient where possible.
00493                     if( m_mapKeyToAction[key].pAction != pAction
00494                         && m_mapKeyToAction[key].pAction != 0 ) {
00495                         kdDebug(125) << "Key conflict with action = " << m_mapKeyToAction[key].pAction->name() 
00496                             << " key = " << key.key().toStringInternal() << " : call updateConnections()" << endl;
00497                         return updateConnections();
00498                     }
00499                 }
00500             }
00501         }
00502     }
00503 
00504     //kdDebug(125) << "\tActions = " << m_rgActions.size() << endl;
00505     //for( KAccelActions::const_iterator it = m_rgActions.begin(); it != m_rgActions.end(); ++it ) {
00506     //  kdDebug(125) << "\t" << &(*it) << " '" << (*it).m_sName << "'" << endl;
00507     //}
00508 
00509     //kdDebug(125) << "\tKeys = " << m_mapKeyToAction.size() << endl;
00510     //for( KKeyToActionMap::iterator it = m_mapKeyToAction.begin(); it != m_mapKeyToAction.end(); ++it ) {
00511     //  //kdDebug(125) << "\tKey: " << it.key().toString() << " => '" << (*it)->m_sName << "'" << endl;
00512     //  kdDebug(125) << "\tKey: " << it.key().toString() << " => '" << *it << "'" << endl;
00513     //  kdDebug(125) << "\t\t'" << (*it)->m_sName << "'" << endl;
00514     //}
00515 
00516     return true;
00517 }
00518 
00519 bool KAccelBase::removeConnection( KAccelAction* pAction )
00520 {
00521     kdDebug(125) << "KAccelBase::removeConnection( " << pAction << " = \"" << pAction->m_sName << "\"; shortcut = " << pAction->m_cut.toStringInternal() << " ): this = " << this << endl;
00522 
00523     //for( KKeyToActionMap::iterator it = m_mapKeyToAction.begin(); it != m_mapKeyToAction.end(); ++it )
00524     //  kdDebug(125) << "\tKey: " << it.key().toString() << " => '" << (*it)->m_sName << "'" << " " << *it << endl;
00525 
00526     if( m_rgActionsNonUnique.findIndex( pAction ) >= 0 ) {
00527         mtemp_pActionRemoving = pAction;
00528         bool b = updateConnections();
00529         mtemp_pActionRemoving = 0;
00530         return b;
00531     }
00532 
00533     KKeyToActionMap::iterator it = m_mapKeyToAction.begin();
00534     while( it != m_mapKeyToAction.end() ) {
00535         KKeyServer::Key key = it.key();
00536         ActionInfo* pInfo = &(*it);
00537 
00538         // If the given action is connected to this key,
00539         if( pAction == pInfo->pAction ) {
00540             disconnectKey( *pAction, key );
00541             pAction->decConnections();
00542 
00543             KKeyToActionMap::iterator itRemove = it++;
00544             m_mapKeyToAction.remove( itRemove );
00545         } else
00546             ++it;
00547     }
00548     return true;
00549 }
00550 
00551 bool KAccelBase::setShortcut( const QString& sAction, const KShortcut& cut )
00552 {
00553     KAccelAction* pAction = actionPtr( sAction );
00554     if( pAction ) {
00555         if( m_bAutoUpdate )
00556             removeConnection( pAction );
00557 
00558         pAction->setShortcut( cut );
00559 
00560         if( m_bAutoUpdate && !pAction->shortcut().isNull() )
00561             insertConnection( pAction );
00562         return true;
00563     } else
00564         return false;
00565 }
00566 
00567 void KAccelBase::readSettings( KConfigBase* pConfig )
00568 {
00569     m_rgActions.readActions( m_sConfigGroup, pConfig );
00570     if( m_bAutoUpdate )
00571         updateConnections();
00572 }
00573 
00574 void KAccelBase::writeSettings( KConfigBase* pConfig ) const
00575 {
00576     m_rgActions.writeActions( m_sConfigGroup, pConfig, m_bConfigIsGlobal, m_bConfigIsGlobal );
00577 }
00578 
00579 QPopupMenu* KAccelBase::createPopupMenu( QWidget* pParent, const KKeySequence& seq )
00580 {
00581     KShortcutMenu* pMenu = new KShortcutMenu( pParent, &actions(), seq );
00582 
00583     bool bActionInserted = false;
00584     bool bInsertSeparator = false;
00585     for( uint i = 0; i < actionCount(); i++ ) {
00586         const KAccelAction* pAction = actions().actionPtr( i );
00587 
00588         if( !pAction->isEnabled() )
00589             continue;
00590 
00591         // If an action has already been inserted into the menu
00592         //  and we have a label instead of an action here,
00593         //  then indicate that we should insert a separator before the next menu entry.
00594         if( bActionInserted && !pAction->isConfigurable() && pAction->name().contains( ':' ) )
00595             bInsertSeparator = true;
00596 
00597         for( uint iSeq = 0; iSeq < pAction->shortcut().count(); iSeq++ ) {
00598             const KKeySequence& seqAction = pAction->shortcut().seq(iSeq);
00599             if( seqAction.startsWith( seq ) ) {
00600                 if( bInsertSeparator ) {
00601                     pMenu->insertSeparator();
00602                     bInsertSeparator = false;
00603                 }
00604 
00605                 pMenu->insertAction( i, seqAction );
00606 
00607                 //kdDebug(125) << "sLabel = " << sLabel << ", seq = " << (QString)seqMenu.qt() << ", i = " << i << endl;
00608                 //kdDebug(125) << "pMenu->accel(" << i << ") = " << (QString)pMenu->accel(i) << endl;
00609                 bActionInserted = true;
00610                 break;
00611             }
00612         }
00613     }
00614     pMenu->updateShortcuts();
00615     return pMenu;
00616 }

KDECore

Skip menu "KDECore"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • dcop
  • DNSSD
  • interfaces
  • Kate
  • kconf_update
  • KDECore
  • KDED
  • kdefx
  • KDEsu
  • kdeui
  • KDocTools
  • KHTML
  • KImgIO
  • KInit
  • kio
  • kioslave
  • KJS
  • KNewStuff
  • KParts
  • KUtils
Generated for API Reference by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal