kaccel.cpp

00001 /*
00002     Copyright (c) 2001,2002 Ellis Whitehead <ellis@kde.org>
00003 
00004     This library is free software; you can redistribute it and/or
00005     modify it under the terms of the GNU Library General Public
00006     License as published by the Free Software Foundation; either
00007     version 2 of the License, or (at your option) any later version.
00008 
00009     This library is distributed in the hope that it will be useful,
00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012     Library General Public License for more details.
00013 
00014     You should have received a copy of the GNU Library General Public License
00015     along with this library; see the file COPYING.LIB.  If not, write to
00016     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017     Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #include "kaccel.h"
00021 
00022 #include <qaccel.h>
00023 #include <qguardedptr.h>
00024 #include <qpopupmenu.h>
00025 #include <qregexp.h>
00026 #include <qstring.h>
00027 #include <qtimer.h>
00028 
00029 #include "kaccelbase.h"
00030 #include <kapplication.h>
00031 #include <kdebug.h>
00032 #include <klocale.h>
00033 #include <kshortcut.h>
00034 
00035 #include "kaccelprivate.h"
00036 
00037 #ifdef Q_WS_X11
00038 #   include <X11/Xlib.h>
00039 #   ifdef KeyPress // needed for --enable-final
00040         // defined by X11 headers
00041         const int XKeyPress = KeyPress;
00042 #       undef KeyPress
00043 #   endif
00044 #endif
00045 
00046 // TODO: Put in kaccelbase.cpp
00047 //---------------------------------------------------------------------
00048 // KAccelEventHandler
00049 //---------------------------------------------------------------------
00050 //
00051 // In KAccelEventHandler::x11Event we do our own X11 keyboard event handling
00052 // This allows us to map the Win key to Qt::MetaButton, Qt does not know about
00053 // the Win key.
00054 //
00055 // KAccelEventHandler::x11Event will generate an AccelOverride event. The
00056 // AccelOverride event is abused a bit to ensure that KAccelPrivate::eventFilter
00057 // (as an event filter on the toplevel widget) will get the key event first
00058 // (in the form of AccelOverride) before any of the intermediate widgets are
00059 // able to process it.
00060 //
00061 // Qt normally sends an AccelOverride, Accel and then a KeyPress event.
00062 // A widget can accept the AccelOverride event in which case the Accel event will be
00063 // skipped and the KeyPress is followed immediately.
00064 // If the Accel event is accepted, no KeyPress event will follow.
00065 //
00066 // KAccelEventHandler::x11Event converts a X11 keyboard event into an AccelOverride
00067 // event, there are now two possibilities:
00068 //
00069 // 1) If KAccel intercepts the AccelOverride we are done and can consider the X11
00070 // keyboard event as handled.
00071 // 2) If another widget accepts the AccelOverride, it will expect to get a normal
00072 // Qt generated KeyPress event afterwards. So we let Qt handle the X11 keyboard event
00073 // again. However, this will first generate an AccelOverride event, and we already
00074 // had send that one. To compnesate for this, the global event filter in KApplication
00075 // is instructed to eat the next AccelOveride event. Qt will then send a normal KeyPress
00076 // event and from then on everything is normal again.
00077 //
00078 // kde_g_bKillAccelOverride is used to tell KApplication::notify to eat the next
00079 // AccelOverride event.
00080 
00081 bool kde_g_bKillAccelOverride = false;
00082 
00083 class KAccelEventHandler : public QWidget
00084 {
00085  public:
00086     static KAccelEventHandler* self()
00087     {
00088         if( !g_pSelf )
00089             g_pSelf = new KAccelEventHandler;
00090         return g_pSelf;
00091     }
00092 
00093     static void accelActivated( bool b ) { g_bAccelActivated = b; }
00094 
00095  private:
00096     KAccelEventHandler();
00097 
00098 #   ifdef Q_WS_X11
00099     bool x11Event( XEvent* pEvent );
00100 #   endif
00101 
00102     static KAccelEventHandler* g_pSelf;
00103     static bool g_bAccelActivated;
00104 };
00105 
00106 KAccelEventHandler* KAccelEventHandler::g_pSelf = 0;
00107 bool KAccelEventHandler::g_bAccelActivated = false;
00108 
00109 KAccelEventHandler::KAccelEventHandler()
00110     : QWidget( 0, "KAccelEventHandler" )
00111 {
00112 #   ifdef Q_WS_X11
00113     if ( kapp )
00114         kapp->installX11EventFilter( this );
00115 #   endif
00116 }
00117 
00118 #ifdef Q_WS_X11
00119 bool    qt_try_modal( QWidget *, XEvent * );
00120 
00121 bool KAccelEventHandler::x11Event( XEvent* pEvent )
00122 {
00123     if( QWidget::keyboardGrabber() || !kapp->focusWidget() )
00124         return false;
00125 
00126     if ( !qt_try_modal(kapp->focusWidget(), pEvent) )
00127             return false;
00128 
00129     if( pEvent->type == XKeyPress ) {
00130         unsigned int tmp = pEvent->xkey.state;
00131         pEvent->xkey.state &= ~0x2000;
00132         KKeyNative keyNative( pEvent );
00133         pEvent->xkey.state = tmp;
00134         KKey key( keyNative );
00135         key.simplify();
00136         int keyCodeQt = key.keyCodeQt();
00137         int state = 0;
00138         if( key.modFlags() & KKey::SHIFT ) state |= Qt::ShiftButton;
00139         if( key.modFlags() & KKey::CTRL )  state |= Qt::ControlButton;
00140         if( key.modFlags() & KKey::ALT )   state |= Qt::AltButton;
00141         if( key.modFlags() & KKey::WIN )   state |= Qt::MetaButton;
00142 
00143         QKeyEvent ke( QEvent::AccelOverride, keyCodeQt, 0,  state );
00144         ke.ignore();
00145 
00146         g_bAccelActivated = false;
00147         kapp->sendEvent( kapp->focusWidget(), &ke );
00148 
00149         // If the Override event was accepted from a non-KAccel widget,
00150         //  then kill the next AccelOverride in KApplication::notify.
00151         if( ke.isAccepted() && !g_bAccelActivated )
00152             kde_g_bKillAccelOverride = true;
00153 
00154         // Stop event processing if a KDE accelerator was activated.
00155         return g_bAccelActivated;
00156     }
00157 
00158     return false;
00159 }
00160 #endif // Q_WS_X11
00161 
00162 //---------------------------------------------------------------------
00163 // KAccelPrivate
00164 //---------------------------------------------------------------------
00165 
00166 KAccelPrivate::KAccelPrivate( KAccel* pParent, QWidget* pWatch )
00167 : KAccelBase( KAccelBase::QT_KEYS )
00168 {
00169     //kdDebug(125) << "KAccelPrivate::KAccelPrivate( pParent = " << pParent << " ): this = " << this << endl;
00170     m_pAccel = pParent;
00171     m_pWatch = pWatch;
00172     m_bAutoUpdate = true;
00173     connect( (QAccel*)m_pAccel, SIGNAL(activated(int)), this, SLOT(slotKeyPressed(int)) );
00174 
00175 #ifdef Q_WS_X11 //only makes sense if KAccelEventHandler is working
00176     if( m_pWatch )
00177         m_pWatch->installEventFilter( this );
00178 #endif
00179     KAccelEventHandler::self();
00180 }
00181 
00182 void KAccelPrivate::setEnabled( bool bEnabled )
00183 {
00184     m_bEnabled = bEnabled;
00185     ((QAccel*)m_pAccel)->setEnabled( bEnabled );
00186 }
00187 
00188 bool KAccelPrivate::setEnabled( const QString& sAction, bool bEnable )
00189 {
00190     kdDebug(125) << "KAccelPrivate::setEnabled( \"" << sAction << "\", " << bEnable << " ): this = " << this << endl;
00191     KAccelAction* pAction = actionPtr( sAction );
00192     if( !pAction )
00193         return false;
00194     if( pAction->isEnabled() == bEnable )
00195         return true;
00196 
00197     pAction->setEnabled( bEnable );
00198 
00199     QMap<int, KAccelAction*>::const_iterator it = m_mapIDToAction.begin();
00200     for( ; it != m_mapIDToAction.end(); ++it ) {
00201         if( *it == pAction )
00202             ((QAccel*)m_pAccel)->setItemEnabled( it.key(), bEnable );
00203     }
00204     return true;
00205 }
00206 
00207 bool KAccelPrivate::removeAction( const QString& sAction )
00208 {
00209     // FIXME: getID() doesn't contains any useful
00210     //  information!  Use mapIDToAction. --ellis, 2/May/2002
00211     //  Or maybe KAccelBase::remove() takes care of QAccel indirectly...
00212     KAccelAction* pAction = actions().actionPtr( sAction );
00213     if( pAction ) {
00214         int nID = pAction->getID();
00215         //bool b = actions().removeAction( sAction );
00216         bool b = KAccelBase::remove( sAction );
00217         ((QAccel*)m_pAccel)->removeItem( nID );
00218         return b;
00219     } else
00220         return false;
00221 }
00222 
00223 bool KAccelPrivate::emitSignal( KAccelBase::Signal signal )
00224 {
00225     if( signal == KAccelBase::KEYCODE_CHANGED ) {
00226         m_pAccel->emitKeycodeChanged();
00227         return true;
00228     }
00229     return false;
00230 }
00231 
00232 bool KAccelPrivate::connectKey( KAccelAction& action, const KKeyServer::Key& key )
00233 {
00234     uint keyQt = key.keyCodeQt();
00235     int nID = ((QAccel*)m_pAccel)->insertItem( keyQt );
00236     m_mapIDToAction[nID] = &action;
00237     m_mapIDToKey[nID] = keyQt;
00238 
00239     if( action.objSlotPtr() && action.methodSlotPtr() ) {
00240 #ifdef Q_WS_WIN 
00241         ((QAccel*)m_pAccel)->connectItem( nID, action.objSlotPtr(), action.methodSlotPtr() );
00242 #else
00243         ((QAccel*)m_pAccel)->connectItem( nID, this, SLOT(slotKeyPressed(int)));
00244 #endif
00245         if( !action.isEnabled() )
00246             ((QAccel*)m_pAccel)->setItemEnabled( nID, false );
00247     }
00248 
00249     kdDebug(125) << "KAccelPrivate::connectKey( \"" << action.name() << "\", " << key.key().toStringInternal() << " = 0x" << QString::number(keyQt,16) << " ): id = " << nID << " m_pObjSlot = " << action.objSlotPtr() << endl;
00250     //kdDebug(125) << "m_pAccel = " << m_pAccel << endl;
00251     return nID != 0;
00252 }
00253 
00254 bool KAccelPrivate::connectKey( const KKeyServer::Key& key )
00255 {
00256     uint keyQt = key.keyCodeQt();
00257     int nID = ((QAccel*)m_pAccel)->insertItem( keyQt );
00258 
00259     m_mapIDToKey[nID] = keyQt;
00260 
00261     kdDebug(125) << "KAccelPrivate::connectKey( " << key.key().toStringInternal() << " = 0x" << QString::number(keyQt,16) << " ): id = " << nID << endl;
00262     return nID != 0;
00263 }
00264 
00265 bool KAccelPrivate::disconnectKey( KAccelAction& action, const KKeyServer::Key& key )
00266 {
00267     int keyQt = key.keyCodeQt();
00268     QMap<int, int>::iterator it = m_mapIDToKey.begin();
00269     for( ; it != m_mapIDToKey.end(); ++it ) {
00270         //kdDebug(125) << "m_mapIDToKey[" << it.key() << "] = " << QString::number(*it,16) << " == " << QString::number(keyQt,16) << endl;
00271         if( *it == keyQt ) {
00272             int nID = it.key();
00273             kdDebug(125) << "KAccelPrivate::disconnectKey( \"" << action.name() << "\", 0x" << QString::number(keyQt,16) << " ) : id = " << nID << " m_pObjSlot = " << action.objSlotPtr() << endl;
00274             ((QAccel*)m_pAccel)->removeItem( nID );
00275             m_mapIDToAction.remove( nID );
00276             m_mapIDToKey.remove( it );
00277             return true;
00278         }
00279     }
00280     //kdWarning(125) << kdBacktrace() << endl;
00281     kdWarning(125) << "Didn't find key in m_mapIDToKey." << endl;
00282     return false;
00283 }
00284 
00285 bool KAccelPrivate::disconnectKey( const KKeyServer::Key& key )
00286 {
00287     int keyQt = key.keyCodeQt();
00288     kdDebug(125) << "KAccelPrivate::disconnectKey( 0x" << QString::number(keyQt,16) << " )" << endl;
00289     QMap<int, int>::iterator it = m_mapIDToKey.begin();
00290     for( ; it != m_mapIDToKey.end(); ++it ) {
00291         if( *it == keyQt ) {
00292             ((QAccel*)m_pAccel)->removeItem( it.key() );
00293             m_mapIDToKey.remove( it );
00294             return true;
00295         }
00296     }
00297     //kdWarning(125) << kdBacktrace() << endl;
00298     kdWarning(125) << "Didn't find key in m_mapIDTokey." << endl;
00299     return false;
00300 }
00301 
00302 void KAccelPrivate::slotKeyPressed( int id )
00303 {
00304     kdDebug(125) << "KAccelPrivate::slotKeyPressed( " << id << " )" << endl;
00305 
00306     if( m_mapIDToKey.contains( id ) ) {
00307         KKey key = m_mapIDToKey[id];
00308         KKeySequence seq( key );
00309         QPopupMenu* pMenu = createPopupMenu( m_pWatch, seq );
00310 
00311         // If there was only one action mapped to this key,
00312         //  and that action is not a multi-key shortcut,
00313         //  then activated it without popping up the menu.
00314         // This is needed for when there are multiple actions
00315         //  with the same shortcut where all but one is disabled.
00316         // pMenu->count() also counts the menu title, so one shortcut will give count = 2.
00317         if( pMenu->count() == 2 && pMenu->accel(1).isEmpty() ) {
00318             int iAction = pMenu->idAt(1);
00319             slotMenuActivated( iAction );
00320         } else {
00321             connect( pMenu, SIGNAL(activated(int)), this, SLOT(slotMenuActivated(int)) );
00322             pMenu->exec( m_pWatch->mapToGlobal( QPoint( 0, 0 ) ) );
00323             disconnect( pMenu, SIGNAL(activated(int)), this, SLOT(slotMenuActivated(int)) );
00324         }
00325         delete pMenu;
00326     }
00327 }
00328 
00329 void KAccelPrivate::slotShowMenu()
00330 {
00331 }
00332 
00333 void KAccelPrivate::slotMenuActivated( int iAction )
00334 {
00335     kdDebug(125) << "KAccelPrivate::slotMenuActivated( " << iAction << " )" << endl;
00336     KAccelAction* pAction = actions().actionPtr( iAction );
00337 #ifdef Q_WS_WIN 
00338     if( pAction ) {
00339         connect( this, SIGNAL(menuItemActivated()), pAction->objSlotPtr(), pAction->methodSlotPtr() );
00340         emit menuItemActivated();
00341         disconnect( this, SIGNAL(menuItemActivated()), pAction->objSlotPtr(), pAction->methodSlotPtr() );
00342     }
00343 #else
00344     emitActivatedSignal( pAction );
00345 #endif
00346 }
00347 
00348 bool KAccelPrivate::eventFilter( QObject* /*pWatched*/, QEvent* pEvent )
00349 {
00350     if( pEvent->type() == QEvent::AccelOverride && m_bEnabled ) {
00351         QKeyEvent* pKeyEvent = (QKeyEvent*) pEvent;
00352         KKey key( pKeyEvent );
00353         kdDebug(125) << "KAccelPrivate::eventFilter( AccelOverride ): this = " << this << ", key = " << key.toStringInternal() << endl;
00354         int keyCodeQt = key.keyCodeQt();
00355         QMap<int, int>::iterator it = m_mapIDToKey.begin();
00356         for( ; it != m_mapIDToKey.end(); ++it ) {
00357             if( (*it) == keyCodeQt ) {
00358                 int nID = it.key();
00359                 kdDebug(125) << "shortcut found!" << endl;
00360                 if( m_mapIDToAction.contains( nID ) ) {
00361                     // TODO: reduce duplication between here and slotMenuActivated
00362                     KAccelAction* pAction = m_mapIDToAction[nID];
00363                     if( !pAction->isEnabled() )
00364                         continue;
00365 #ifdef Q_WS_WIN 
00366                     QGuardedPtr<KAccelPrivate> me = this;
00367                     connect( this, SIGNAL(menuItemActivated()), pAction->objSlotPtr(), pAction->methodSlotPtr() );
00368                     emit menuItemActivated();
00369                     if (me) {
00370                         disconnect( me, SIGNAL(menuItemActivated()), pAction->objSlotPtr(), pAction->methodSlotPtr() );
00371                     }
00372 #else
00373                     emitActivatedSignal( pAction );
00374 #endif
00375                 } else
00376                     slotKeyPressed( nID );
00377 
00378                 pKeyEvent->accept();
00379                 KAccelEventHandler::accelActivated( true );
00380                 return true;
00381             }
00382         }
00383     }
00384     return false;
00385 }
00386 
00387 #ifndef Q_WS_WIN 
00388 void KAccelPrivate::emitActivatedSignal( KAccelAction* pAction )
00389 {
00390     if( pAction ) {
00391         QGuardedPtr<KAccelPrivate> me = this;
00392         QRegExp reg( "([ ]*KAccelAction.*)" );
00393         if( reg.search( pAction->methodSlotPtr()) >= 0 ) {
00394             connect( this, SIGNAL(menuItemActivated(KAccelAction*)),
00395                 pAction->objSlotPtr(), pAction->methodSlotPtr() );
00396             emit menuItemActivated( pAction );
00397             if (me)
00398                 disconnect( me, SIGNAL(menuItemActivated(KAccelAction*)),
00399                     pAction->objSlotPtr(), pAction->methodSlotPtr() );
00400         } else {
00401             connect( this, SIGNAL(menuItemActivated()),
00402                 pAction->objSlotPtr(), pAction->methodSlotPtr() );
00403             emit menuItemActivated();
00404             if (me)
00405                 disconnect( me, SIGNAL(menuItemActivated()),
00406                     pAction->objSlotPtr(), pAction->methodSlotPtr() );
00407 
00408         }
00409     }
00410 }
00411 #endif
00412 
00413 //---------------------------------------------------------------------
00414 // KAccel
00415 //---------------------------------------------------------------------
00416 
00417 KAccel::KAccel( QWidget* pParent, const char* psName )
00418 : QAccel( pParent, (psName) ? psName : "KAccel-QAccel" )
00419 {
00420     kdDebug(125) << "KAccel( pParent = " << pParent << ", psName = " << psName << " ): this = " << this << endl;
00421     d = new KAccelPrivate( this, pParent );
00422 }
00423 
00424 KAccel::KAccel( QWidget* watch, QObject* pParent, const char* psName )
00425 : QAccel( watch, pParent, (psName) ? psName : "KAccel-QAccel" )
00426 {
00427     kdDebug(125) << "KAccel( watch = " << watch << ", pParent = " << pParent << ", psName = " << psName << " ): this = " << this << endl;
00428     if( !watch )
00429         kdDebug(125) << kdBacktrace() << endl;
00430     d = new KAccelPrivate( this, watch );
00431 }
00432 
00433 KAccel::~KAccel()
00434 {
00435     kdDebug(125) << "~KAccel(): this = " << this << endl;
00436     delete d;
00437 }
00438 
00439 KAccelActions& KAccel::actions()             { return d->actions(); }
00440 const KAccelActions& KAccel::actions() const { return d->actions(); }
00441 bool KAccel::isEnabled()                     { return d->isEnabled(); }
00442 void KAccel::setEnabled( bool bEnabled )     { d->setEnabled( bEnabled ); }
00443 bool KAccel::setAutoUpdate( bool bAuto )     { return d->setAutoUpdate( bAuto ); }
00444 
00445 KAccelAction* KAccel::insert( const QString& sAction, const QString& sLabel, const QString& sWhatsThis,
00446         const KShortcut& cutDef,
00447         const QObject* pObjSlot, const char* psMethodSlot,
00448         bool bConfigurable, bool bEnabled )
00449 {
00450     return d->insert( sAction, sLabel, sWhatsThis,
00451         cutDef, cutDef,
00452         pObjSlot, psMethodSlot,
00453         bConfigurable, bEnabled );
00454 }
00455 
00456 KAccelAction* KAccel::insert( const QString& sAction, const QString& sLabel, const QString& sWhatsThis,
00457         const KShortcut& cutDef3, const KShortcut& cutDef4,
00458         const QObject* pObjSlot, const char* psMethodSlot,
00459         bool bConfigurable, bool bEnabled )
00460 {
00461     return d->insert( sAction, sLabel, sWhatsThis,
00462         cutDef3, cutDef4,
00463         pObjSlot, psMethodSlot,
00464         bConfigurable, bEnabled );
00465 }
00466 
00467 KAccelAction* KAccel::insert( const char* psAction, const KShortcut& cutDef,
00468         const QObject* pObjSlot, const char* psMethodSlot,
00469         bool bConfigurable, bool bEnabled )
00470 {
00471     return d->insert( psAction, i18n(psAction), QString::null,
00472         cutDef, cutDef,
00473         pObjSlot, psMethodSlot,
00474         bConfigurable, bEnabled );
00475 }
00476 
00477 KAccelAction* KAccel::insert( KStdAccel::StdAccel id,
00478         const QObject* pObjSlot, const char* psMethodSlot,
00479         bool bConfigurable, bool bEnabled )
00480 {
00481     QString sAction = KStdAccel::name( id );
00482     if( sAction.isEmpty() )
00483         return 0;
00484 
00485     KAccelAction* pAction = d->insert( sAction, KStdAccel::label( id ), KStdAccel::whatsThis( id ),
00486         KStdAccel::shortcutDefault3( id ), KStdAccel::shortcutDefault4( id ),
00487         pObjSlot, psMethodSlot,
00488         bConfigurable, bEnabled );
00489     if( pAction )
00490         pAction->setShortcut( KStdAccel::shortcut( id ) );
00491 
00492     return pAction;
00493 }
00494 
00495 bool KAccel::remove( const QString& sAction )
00496     { return d->removeAction( sAction ); }
00497 bool KAccel::updateConnections()
00498     { return d->updateConnections(); }
00499 
00500 const KShortcut& KAccel::shortcut( const QString& sAction ) const
00501 {
00502     const KAccelAction* pAction = actions().actionPtr( sAction );
00503     return (pAction) ? pAction->shortcut() : KShortcut::null();
00504 }
00505 
00506 bool KAccel::setSlot( const QString& sAction, const QObject* pObjSlot, const char* psMethodSlot )
00507     { return d->setActionSlot( sAction, pObjSlot, psMethodSlot ); }
00508 
00509 bool KAccel::setEnabled( const QString& sAction, bool bEnable )
00510     { return d->setEnabled( sAction, bEnable ); }
00511 
00512 bool KAccel::setShortcut( const QString& sAction, const KShortcut& cut )
00513 {
00514     kdDebug(125) << "KAccel::setShortcut( \"" << sAction << "\", " << cut.toStringInternal() << " )" << endl;
00515     KAccelAction* pAction = actions().actionPtr( sAction );
00516     if( pAction ) {
00517         if( pAction->shortcut() != cut )
00518             return d->setShortcut( sAction, cut );
00519         return true;
00520     }
00521     return false;
00522 }
00523 
00524 const QString& KAccel::configGroup() const
00525     { return d->configGroup(); }
00526 // for kdegames/ksirtet
00527 void KAccel::setConfigGroup( const QString& s )
00528     { d->setConfigGroup( s ); }
00529 
00530 bool KAccel::readSettings( KConfigBase* pConfig )
00531 {
00532     d->readSettings( pConfig );
00533     return true;
00534 }
00535 
00536 bool KAccel::writeSettings( KConfigBase* pConfig ) const
00537     { d->writeSettings( pConfig ); return true; }
00538 
00539 void KAccel::emitKeycodeChanged()
00540 {
00541     kdDebug(125) << "KAccel::emitKeycodeChanged()" << endl;
00542     emit keycodeChanged();
00543 }
00544 
00545 #ifndef KDE_NO_COMPAT
00546 //------------------------------------------------------------
00547 // Obsolete methods -- for backward compatibility
00548 //------------------------------------------------------------
00549 
00550 bool KAccel::insertItem( const QString& sLabel, const QString& sAction,
00551         const char* cutsDef,
00552         int /*nIDMenu*/, QPopupMenu *, bool bConfigurable )
00553 {
00554     KShortcut cut( cutsDef );
00555     bool b = d->insert( sAction, sLabel, QString::null,
00556         cut, cut,
00557         0, 0,
00558         bConfigurable ) != 0;
00559     return b;
00560 }
00561 
00562 bool KAccel::insertItem( const QString& sLabel, const QString& sAction,
00563         int key,
00564         int /*nIDMenu*/, QPopupMenu*, bool bConfigurable )
00565 {
00566     KShortcut cut;
00567     cut.init( QKeySequence(key) );
00568     KAccelAction* pAction = d->insert( sAction, sLabel, QString::null,
00569         cut, cut,
00570         0, 0,
00571         bConfigurable );
00572     return pAction != 0;
00573 }
00574 
00575 // Used in kdeutils/kjots
00576 bool KAccel::insertStdItem( KStdAccel::StdAccel id, const QString& sLabel )
00577 {
00578     KAccelAction* pAction = d->insert( KStdAccel::name( id ), sLabel, QString::null,
00579         KStdAccel::shortcutDefault3( id ), KStdAccel::shortcutDefault4( id ),
00580         0, 0 );
00581     if( pAction )
00582         pAction->setShortcut( KStdAccel::shortcut( id ) );
00583 
00584     return true;
00585 }
00586 
00587 bool KAccel::connectItem( const QString& sAction, const QObject* pObjSlot, const char* psMethodSlot, bool bActivate )
00588 {
00589     kdDebug(125) << "KAccel::connectItem( " << sAction << ", " << pObjSlot << ", " << psMethodSlot << " )" << endl;
00590     if( bActivate == false )
00591         d->setActionEnabled( sAction, false );
00592     bool b = setSlot( sAction, pObjSlot, psMethodSlot );
00593     if( bActivate == true )
00594         d->setActionEnabled( sAction, true );
00595     return b;
00596 }
00597 
00598 bool KAccel::removeItem( const QString& sAction )
00599     { return d->removeAction( sAction ); }
00600 
00601 bool KAccel::setItemEnabled( const QString& sAction, bool bEnable )
00602     { return setEnabled( sAction, bEnable ); }
00603 
00604 void KAccel::changeMenuAccel( QPopupMenu *menu, int id, const QString& action )
00605 {
00606     KAccelAction* pAction = actions().actionPtr( action );
00607     QString s = menu->text( id );
00608     if( !pAction || s.isEmpty() )
00609         return;
00610 
00611     int i = s.find( '\t' );
00612 
00613     QString k = pAction->shortcut().seq(0).toString();
00614     if( k.isEmpty() )
00615         return;
00616 
00617     if ( i >= 0 )
00618         s.replace( i+1, s.length()-i, k );
00619     else {
00620         s += '\t';
00621         s += k;
00622     }
00623 
00624     QPixmap *pp = menu->pixmap(id);
00625     if( pp && !pp->isNull() )
00626         menu->changeItem( *pp, s, id );
00627     else
00628         menu->changeItem( s, id );
00629 }
00630 
00631 void KAccel::changeMenuAccel( QPopupMenu *menu, int id, KStdAccel::StdAccel accel )
00632 {
00633     changeMenuAccel( menu, id, KStdAccel::name( accel ) );
00634 }
00635 
00636 int KAccel::stringToKey( const QString& sKey )
00637 {
00638     return KKey( sKey ).keyCodeQt();
00639 }
00640 
00641 int KAccel::currentKey( const QString& sAction ) const
00642 {
00643     KAccelAction* pAction = d->actionPtr( sAction );
00644     if( pAction )
00645         return pAction->shortcut().keyCodeQt();
00646     return 0;
00647 }
00648 
00649 QString KAccel::findKey( int key ) const
00650 {
00651     KAccelAction* pAction = d->actionPtr( KKey(key) );
00652     if( pAction )
00653         return pAction->name();
00654     else
00655         return QString::null;
00656 }
00657 #endif // !KDE_NO_COMPAT
00658 
00659 void KAccel::virtual_hook( int, void* )
00660 { /*BASE::virtual_hook( id, data );*/ }
00661 
00662 #include "kaccel.moc"
00663 #include "kaccelprivate.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys