kaccelbase.cpp Source File (kdecore Library)

| # kdecore Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | 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_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 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 }

This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 12:46:18 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001