# kdecore Library API Documentation

Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# 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.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 #ifdef Q_WS_X11
    00244 struct KAccelBase::X
    00245 {
    00246     uint iAction, iSeq, iVari;
    00247     KKeyServer::Key key;
    00248
    00249     X() {}
    00250     X( uint _iAction, uint _iSeq, uint _iVari, const KKeyServer::Key& _key )
    00251         { iAction = _iAction; iSeq = _iSeq; iVari = _iVari; key = _key; }
    00252
    00253     int compare( const X& x )
    00254     {
    00255         int n = key.compare( x.key );
    00256         if( n != 0 )           return n;
    00257         if( iVari != x.iVari ) return iVari - x.iVari;
    00258         if( iSeq != x.iSeq )   return iSeq - x.iSeq;
    00259         return 0;
    00260     }
    00261
    00262     bool operator <( const X& x )  { return compare( x ) < 0; }
    00263     bool operator >( const X& x )  { return compare( x ) > 0; }
    00264     bool operator <=( const X& x ) { return compare( x ) <= 0; }
    00265 };
    00266 #endif //Q_WS_X11
    00267
    00268 /*
    00269 #1 Ctrl+A
    00270 #2 Ctrl+A
    00271 #3 Ctrl+B
    00272    ------
    00273    Ctrl+A => Null
    00274    Ctrl+B => #3
    00275
    00276 #1 Ctrl+A
    00277 #1 Ctrl+B;Ctrl+A
    00278    ------
    00279    Ctrl+A => #1
    00280    Ctrl+B => #2
    00281
    00282 #1 Ctrl+A
    00283 #1 Ctrl+B,C
    00284 #1 Ctrl+B,D
    00285    ------
    00286    Ctrl+A => #1
    00287    Ctrl+B => Null
    00288
    00289 #1 Ctrl+A
    00290 #2 Ctrl+Plus(Ctrl+KP_Add)
    00291    ------
    00292    Ctrl+A => #1
    00293    Ctrl+Plus => #2
    00294    Ctrl+KP_Add => #2
    00295
    00296 #1 Ctrl+Plus(Ctrl+KP_Add)
    00297 #2 Ctrl+KP_Add
    00298    ------
    00299    Ctrl+Plus => #1
    00300    Ctrl+KP_Add => #2
    00301
    00302 #1 Ctrl+Plus(Ctrl+KP_Add)
    00303 #2 Ctrl+A;Ctrl+KP_Add
    00304    ------
    00305    Ctrl+A => #2
    00306    Ctrl+Plus => #1
    00307    Ctrl+KP_Add => #2
    00308 */
    00309
    00310 bool KAccelBase::updateConnections()
    00311 {
    00312 #ifdef Q_WS_X11
    00313     kdDebug(125) << "KAccelBase::updateConnections()  this = " << this << endl;
    00314     // Retrieve the list of keys to be connected, sorted by priority.
    00315     //  (key, variation, seq)
    00316     QValueVector<X> rgKeys;
    00317     createKeyList( rgKeys );
    00318     m_rgActionsNonUnique.clear();
    00319
    00320     KKeyToActionMap mapKeyToAction;
    00321     for( uint i = 0; i < rgKeys.size(); i++ ) {
    00322         X& x = rgKeys[i];
    00323         KKeyServer::Key& key = x.key;
    00324         ActionInfo info;
    00325         bool bNonUnique = false;
    00326
    00327         info.pAction = m_rgActions.actionPtr( x.iAction );
    00328         info.iSeq = x.iSeq;
    00329         info.iVariation = x.iVari;
    00330
    00331         // If this is a multi-key shortcut,
    00332         if( info.pAction->shortcut().seq(info.iSeq).count() > 1 )
    00333             bNonUnique = true;
    00334         // If this key is requested by more than one action,
    00335         else if( i < rgKeys.size() - 1 && key == rgKeys[i+1].key ) {
    00336             // If multiple actions requesting this key
    00337             //  have the same priority as the first one,
    00338             if( info.iVariation == rgKeys[i+1].iVari && info.iSeq == rgKeys[i+1].iSeq )
    00339                 bNonUnique = true;
    00340
    00341             kdDebug(125) << "key conflict = " << key.key().toStringInternal()
    00342                 << " action1 = " << info.pAction->name()
    00343                 << " action2 = " << m_rgActions.actionPtr( rgKeys[i+1].iAction )->name()
    00344                 << " non-unique = " << bNonUnique << endl;
    00345
    00346             // Skip over the other records with this same key.
    00347             while( i < rgKeys.size() - 1 && key == rgKeys[i+1].key )
    00348                 i++;
    00349         }
    00350
    00351         if( bNonUnique ) {
    00352             // Remove connection to single action if there is one
    00353             if( m_mapKeyToAction.contains( key ) ) {
    00354                 KAccelAction* pAction = m_mapKeyToAction[key].pAction;
    00355                 if( pAction ) {
    00356                     m_mapKeyToAction.remove( key );
    00357                     disconnectKey( *pAction, key );
    00358                     pAction->decConnections();
    00359                     m_rgActionsNonUnique.append( pAction );
    00360                 }
    00361             }
    00362             // Indicate that no single action is associated with this key.
    00363             m_rgActionsNonUnique.append( info.pAction );
    00364             info.pAction = 0;
    00365         }
    00366
    00367         //kdDebug(125) << "mapKeyToAction[" << key.toStringInternal() << "] = " << info.pAction << endl;
    00368         mapKeyToAction[key] = info;
    00369     }
    00370
    00371     // Disconnect keys which no longer have bindings:
    00372     for( KKeyToActionMap::iterator it = m_mapKeyToAction.begin(); it != m_mapKeyToAction.end(); ++it ) {
    00373         const KKeyServer::Key& key = it.key();
    00374         KAccelAction* pAction = (*it).pAction;
    00375         // If this key is longer used or it points to a different action now,
    00376         if( !mapKeyToAction.contains( key ) || mapKeyToAction[key].pAction != pAction ) {
    00377             if( pAction ) {
    00378                 disconnectKey( *pAction, key );
    00379                 pAction->decConnections();
    00380             } else
    00381                 disconnectKey( key );
    00382         }
    00383     }
    00384
    00385     // Connect any unconnected keys:
    00386     // In other words, connect any keys which are present in the
    00387     //  new action map, but which are _not_ present in the old one.
    00388     for( KKeyToActionMap::iterator it = mapKeyToAction.begin(); it != mapKeyToAction.end(); ++it ) {
    00389         const KKeyServer::Key& key = it.key();
    00390         KAccelAction* pAction = (*it).pAction;
    00391         if( !m_mapKeyToAction.contains( key ) || m_mapKeyToAction[key].pAction != pAction ) {
    00392             // TODO: Decide what to do if connect fails.
    00393             //  Probably should remove this item from map.
    00394             if( pAction ) {
    00395                 if( connectKey( *pAction, key ) )
    00396                     pAction->incConnections();
    00397             } else
    00398                 connectKey( key );
    00399         }
    00400     }
    00401
    00402     // Store new map.
    00403     m_mapKeyToAction = mapKeyToAction;
    00404
    00405 #ifndef NDEBUG
    00406     for( KKeyToActionMap::iterator it = m_mapKeyToAction.begin(); it != m_mapKeyToAction.end(); ++it ) {
    00407         kdDebug(125) << "Key: " << it.key().key().toStringInternal() << " => '"
    00408             << (((*it).pAction) ? (*it).pAction->name() : QString::null) << "'" << endl;
    00409     }
    00410 #endif
    00411 #endif //Q_WS_X11
    00412     return true;
    00413 }
    00414
    00415 #ifdef Q_WS_X11
    00416 // Construct a list of keys to be connected, sorted highest priority first.
    00417 void KAccelBase::createKeyList( QValueVector<struct X>& rgKeys )
    00418 {
    00419     //kdDebug(125) << "KAccelBase::createKeyList()" << endl;
    00420     if( !m_bEnabled )
    00421         return;
    00422
    00423     // create the list
    00424     // For each action
    00425     for( uint iAction = 0; iAction < m_rgActions.count(); iAction++ ) {
    00426         KAccelAction* pAction = m_rgActions.actionPtr( iAction );
    00427         if( pAction && pAction->m_pObjSlot && pAction->m_psMethodSlot && pAction != mtemp_pActionRemoving ) {
    00428             // For each key sequence associated with action
    00429             for( uint iSeq = 0; iSeq < pAction->shortcut().count(); iSeq++ ) {
    00430                 const KKeySequence& seq = pAction->shortcut().seq(iSeq);
    00431                 if( seq.count() > 0 ) {
    00432                     KKeyServer::Variations vars;
    00433                     vars.init( seq.key(0), !m_bNativeKeys );
    00434                     for( uint iVari = 0; iVari < vars.count(); iVari++ ) {
    00435                         if( vars.key(iVari).code() && vars.key(iVari).sym() )
    00436                             rgKeys.push_back( X( iAction, iSeq, iVari, vars.key( iVari ) ) );
    00437                         //kdDebug(125) << "\t" << pAction->name() << ": " << vars.key(iVari).toStringInternal() << endl;
    00438                     }
    00439                 }
    00440                 //else
    00441                 //  kdDebug(125) << "\t*" << pAction->name() << ":" << endl;
    00442             }
    00443         }
    00444     }
    00445
    00446     // sort by priority: iVariation[of first key], iSequence, iAction
    00447     qHeapSort( rgKeys.begin(), rgKeys.end() );
    00448 }
    00449 #endif //Q_WS_X11
    00450
    00451 bool KAccelBase::insertConnection( KAccelAction* pAction )
    00452 {
    00453     if( !pAction->m_pObjSlot || !pAction->m_psMethodSlot )
    00454         return true;
    00455
    00456     kdDebug(125) << "KAccelBase::insertConnection( " << pAction << "=\"" << pAction->m_sName << "\"; shortcut = " << pAction->shortcut().toStringInternal() << " )  this = " << this << endl;
    00457
    00458     // For each sequence associated with the given action:
    00459     for( uint iSeq = 0; iSeq < pAction->shortcut().count(); iSeq++ ) {
    00460         // Get the first key of the sequence.
    00461         KKeyServer::Variations vars;
    00462         vars.init( pAction->shortcut().seq(iSeq).key(0), !m_bNativeKeys );
    00463         for( uint iVari = 0; iVari < vars.count(); iVari++ ) {
    00464             const KKeyServer::Key& key = vars.key( iVari );
    00465
    00466             //if( !key.isNull() ) {
    00467             if( key.sym() ) {
    00468                 if( !m_mapKeyToAction.contains( key ) ) {
    00469                     // If this is a single-key shortcut,
    00470                     if( pAction->shortcut().seq(iSeq).count() == 1 ) {
    00471                         m_mapKeyToAction[key] = ActionInfo( pAction, iSeq, iVari );
    00472                         if( connectKey( *pAction, key ) )
    00473                             pAction->incConnections();
    00474                     }
    00475                     // Else this is a multi-key shortcut,
    00476                     else {
    00477                         m_mapKeyToAction[key] = ActionInfo( 0, 0, 0 );
    00478                         // Insert into non-unique list if it's not already there.
    00479                         if( m_rgActionsNonUnique.findIndex( pAction ) == -1 )
    00480                             m_rgActionsNonUnique.append( pAction );
    00481                         if( connectKey( key ) )
    00482                             pAction->incConnections();
    00483                     }
    00484                 } else {
    00485                     // There is a key conflict.  A full update
    00486                     //  check is necessary.
    00487                     // TODO: make this more efficient where possible.
    00488                     if( m_mapKeyToAction[key].pAction != pAction
    00489                         && m_mapKeyToAction[key].pAction != 0 ) {
    00490                         kdDebug(125) << "Key conflict with action = " << m_mapKeyToAction[key].pAction->name()
    00491                             << " key = " << key.key().toStringInternal() << " : call updateConnections()" << endl;
    00492                         return updateConnections();
    00493                     }
    00494                 }
    00495             }
    00496         }
    00497     }
    00498
    00499     //kdDebug(125) << "\tActions = " << m_rgActions.size() << endl;
    00500     //for( KAccelActions::const_iterator it = m_rgActions.begin(); it != m_rgActions.end(); ++it ) {
    00501     //  kdDebug(125) << "\t" << &(*it) << " '" << (*it).m_sName << "'" << endl;
    00502     //}
    00503
    00504     //kdDebug(125) << "\tKeys = " << m_mapKeyToAction.size() << endl;
    00505     //for( KKeyToActionMap::iterator it = m_mapKeyToAction.begin(); it != m_mapKeyToAction.end(); ++it ) {
    00506     //  //kdDebug(125) << "\tKey: " << it.key().toString() << " => '" << (*it)->m_sName << "'" << endl;
    00507     //  kdDebug(125) << "\tKey: " << it.key().toString() << " => '" << *it << "'" << endl;
    00508     //  kdDebug(125) << "\t\t'" << (*it)->m_sName << "'" << endl;
    00509     //}
    00510
    00511     return true;
    00512 }
    00513
    00514 bool KAccelBase::removeConnection( KAccelAction* pAction )
    00515 {
    00516     kdDebug(125) << "KAccelBase::removeConnection( " << pAction << " = \"" << pAction->m_sName << "\"; shortcut = " << pAction->m_cut.toStringInternal() << " ): this = " << this << endl;
    00517
    00518     //for( KKeyToActionMap::iterator it = m_mapKeyToAction.begin(); it != m_mapKeyToAction.end(); ++it )
    00519     //  kdDebug(125) << "\tKey: " << it.key().toString() << " => '" << (*it)->m_sName << "'" << " " << *it << endl;
    00520
    00521     if( m_rgActionsNonUnique.findIndex( pAction ) >= 0 ) {
    00522         mtemp_pActionRemoving = pAction;
    00523         bool b = updateConnections();
    00524         mtemp_pActionRemoving = 0;
    00525         return b;
    00526     }
    00527
    00528     KKeyToActionMap::iterator it = m_mapKeyToAction.begin();
    00529     while( it != m_mapKeyToAction.end() ) {
    00530         KKeyServer::Key key = it.key();
    00531         ActionInfo* pInfo = &(*it);
    00532
    00533         // If the given action is connected to this key,
    00534         if( pAction == pInfo->pAction ) {
    00535             disconnectKey( *pAction, key );
    00536             pAction->decConnections();
    00537
    00538             KKeyToActionMap::iterator itRemove = it++;
    00539             m_mapKeyToAction.remove( itRemove );
    00540         } else
    00541             ++it;
    00542     }
    00543     return true;
    00544 }
    00545
    00546 bool KAccelBase::setShortcut( const QString& sAction, const KShortcut& cut )
    00547 {
    00548     KAccelAction* pAction = actionPtr( sAction );
    00549     if( pAction ) {
    00550         if( m_bAutoUpdate )
    00551             removeConnection( pAction );
    00552
    00553         pAction->setShortcut( cut );
    00554
    00555         if( m_bAutoUpdate && !pAction->shortcut().isNull() )
    00556             insertConnection( pAction );
    00557         return true;
    00558     } else
    00559         return false;
    00560 }
    00561
    00562 void KAccelBase::readSettings( KConfigBase* pConfig )
    00563 {
    00564     m_rgActions.readActions( m_sConfigGroup, pConfig );
    00565     if( m_bAutoUpdate )
    00566         updateConnections();
    00567 }
    00568
    00569 void KAccelBase::writeSettings( KConfigBase* pConfig ) const
    00570 {
    00571     m_rgActions.writeActions( m_sConfigGroup, pConfig, m_bConfigIsGlobal, m_bConfigIsGlobal );
    00572 }
    00573
    00574 QPopupMenu* KAccelBase::createPopupMenu( QWidget* pParent, const KKeySequence& seq )
    00575 {
    00576     KShortcutMenu* pMenu = new KShortcutMenu( pParent, &actions(), seq );
    00577
    00578     bool bActionInserted = false;
    00579     bool bInsertSeparator = false;
    00580     for( uint i = 0; i < actionCount(); i++ ) {
    00581         const KAccelAction* pAction = actions().actionPtr( i );
    00582
    00583         if( !pAction->isEnabled() )
    00584             continue;
    00585
    00586         // If an action has already been inserted into the menu
    00587         //  and we have a label instead of an action here,
    00588         //  then indicate that we should insert a separator before the next menu entry.
    00589         if( bActionInserted && !pAction->isConfigurable() && pAction->name().contains( ':' ) )
    00590             bInsertSeparator = true;
    00591
    00592         for( uint iSeq = 0; iSeq < pAction->shortcut().count(); iSeq++ ) {
    00593             const KKeySequence& seqAction = pAction->shortcut().seq(iSeq);
    00594             if( seqAction.startsWith( seq ) ) {
    00595                 if( bInsertSeparator ) {
    00596                     pMenu->insertSeparator();
    00597                     bInsertSeparator = false;
    00598                 }
    00599
    00600                 pMenu->insertAction( i, seqAction );
    00601
    00602                 //kdDebug(125) << "sLabel = " << sLabel << ", seq = " << (QString)seqMenu.qt() << ", i = " << i << endl;
    00603                 //kdDebug(125) << "pMenu->accel(" << i << ") = " << (QString)pMenu->accel(i) << endl;
    00604                 bActionInserted = true;
    00605                 break;
    00606             }
    00607         }
    00608     }
    00609     pMenu->updateShortcuts();
    00610     return pMenu;
    00611 }

This file is part of the documentation for kdecore Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:18:00 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003