kdecore Library: kaccelaction.cpp Source File (kdecore Library)

| # kdecore Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# kaccelaction.cpp

    00001 /*
    00002     Copyright (C) 1998 Mark Donohoe <donohoe@kde.org>
    00003     Copyright (C) 1997-2000 Nicolas Hadacek <hadacek@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 "kaccelaction.h"
    00024 #include "kaccelbase.h"   // for KAccelBase::slotRemoveAction() & emitSignal()
    00025
    00026 #include <qkeycode.h>
    00027
    00028 #include <kconfig.h>
    00029 #include "kckey.h"
    00030 #include <kdebug.h>
    00031 #include <kglobal.h>
    00032 #include <kkeynative.h>
    00033 #include <klocale.h>
    00034 #include <kshortcutlist.h>
    00035
    00036 //---------------------------------------------------------------------
    00037 // KAccelAction
    00038 //---------------------------------------------------------------------
    00039
    00040 class KAccelActionPrivate
    00041 {
    00042  public:
    00043     uint m_nConnections;
    00044 };
    00045
    00046 KAccelAction::KAccelAction()
    00047 {
    00048     //kdDebug(125) << "KAccelAction(): this = " << this << endl;
    00049     d = new KAccelActionPrivate;
    00050     m_pObjSlot = 0;
    00051     m_psMethodSlot = 0;
    00052     m_bConfigurable = true;
    00053     m_bEnabled = true;
    00054     m_nIDAccel = 0;
    00055     d->m_nConnections = 0;
    00056 }
    00057
    00058 KAccelAction::KAccelAction( const KAccelAction& action )
    00059 {
    00060     //kdDebug(125) << "KAccelAction( copy from \"" << action.m_sName << "\" ): this = " << this << endl;
    00061     d = new KAccelActionPrivate;
    00062     *this = action;
    00063 }
    00064
    00065 KAccelAction::KAccelAction( const QString& sName, const QString& sLabel, const QString& sWhatsThis,
    00066             const KShortcut& cutDef3, const KShortcut& cutDef4,
    00067             const QObject* pObjSlot, const char* psMethodSlot,
    00068             bool bConfigurable, bool bEnabled )
    00069 {
    00070     //kdDebug(125) << "KAccelAction( \"" << sName << "\" ): this = " << this << endl;
    00071     d = new KAccelActionPrivate;
    00072     init( sName, sLabel, sWhatsThis,
    00073         cutDef3, cutDef4,
    00074         pObjSlot, psMethodSlot,
    00075         bConfigurable, bEnabled );
    00076 }
    00077
    00078 KAccelAction::~KAccelAction()
    00079 {
    00080     //kdDebug(125) << "\t\t\tKAccelAction::~KAccelAction( \"" << m_sName << "\" ): this = " << this << endl;
    00081     delete d;
    00082 }
    00083
    00084 void KAccelAction::clear()
    00085 {
    00086     m_cut.clear();
    00087     m_pObjSlot = 0;
    00088     m_psMethodSlot = 0;
    00089     m_bConfigurable = true;
    00090     m_bEnabled = true;
    00091     m_nIDAccel = 0;
    00092     d->m_nConnections = 0;
    00093 }
    00094
    00095 bool KAccelAction::init( const QString& sName, const QString& sLabel, const QString& sWhatsThis,
    00096             const KShortcut& rgCutDefaults3, const KShortcut& rgCutDefaults4,
    00097             const QObject* pObjSlot, const char* psMethodSlot,
    00098             bool bConfigurable, bool bEnabled )
    00099 {
    00100     m_sName = sName;
    00101     m_sLabel = sLabel;
    00102     m_sWhatsThis = sWhatsThis;
    00103     m_cutDefault3 = rgCutDefaults3;
    00104     m_cutDefault4 = rgCutDefaults4;
    00105     m_pObjSlot = pObjSlot;
    00106     m_psMethodSlot = psMethodSlot;
    00107     m_bConfigurable = bConfigurable;
    00108     m_bEnabled = bEnabled;
    00109     m_nIDAccel = 0;
    00110     m_cut = shortcutDefault();
    00111     d->m_nConnections = 0;
    00112     if( !m_bEnabled )
    00113         kdDebug(125) << "KAccelAction::init( \"" << sName << "\" ): created with enabled = false" << endl;
    00114     return true;
    00115 }
    00116
    00117 KAccelAction& KAccelAction::operator =( const KAccelAction& action )
    00118 {
    00119     m_sName          = action.m_sName;
    00120     m_sLabel         = action.m_sLabel;
    00121     m_sWhatsThis     = action.m_sWhatsThis;
    00122     m_cutDefault3    = action.m_cutDefault3;
    00123     m_cutDefault4    = action.m_cutDefault4;
    00124     m_pObjSlot       = action.m_pObjSlot;
    00125     m_psMethodSlot   = action.m_psMethodSlot;
    00126     m_bConfigurable  = action.m_bConfigurable;
    00127     m_bEnabled       = action.m_bEnabled;
    00128     m_nIDAccel       = action.m_nIDAccel;
    00129     m_cut            = action.m_cut;
    00130     d->m_nConnections = action.d->m_nConnections;
    00131
    00132     return *this;
    00133 }
    00134
    00135 void KAccelAction::setName( const QString& s )
    00136     { m_sName = s; }
    00137 void KAccelAction::setLabel( const QString& s )
    00138     { m_sLabel = s; }
    00139 void KAccelAction::setWhatsThis( const QString& s )
    00140     { m_sWhatsThis = s; }
    00141
    00142 bool KAccelAction::setShortcut( const KShortcut& cut )
    00143 {
    00144     m_cut = cut;
    00145     return true;
    00146 }
    00147
    00148 void KAccelAction::setSlot( const QObject* pObjSlot, const char* psMethodSlot )
    00149 {
    00150     m_pObjSlot = pObjSlot;
    00151     m_psMethodSlot = psMethodSlot;
    00152 }
    00153
    00154 void KAccelAction::setConfigurable( bool b )
    00155     { m_bConfigurable = b; }
    00156 void KAccelAction::setEnabled( bool b )
    00157     { m_bEnabled = b; }
    00158
    00159 QString KAccelAction::toString() const
    00160     { return m_cut.toString(); }
    00161
    00162 QString KAccelAction::toStringInternal() const
    00163     { return m_cut.toStringInternal( &shortcutDefault() ); }
    00164
    00165 bool KAccelAction::setKeySequence( uint i, const KKeySequence& seq )
    00166 {
    00167     if( i < m_cut.count() ) {
    00168         m_cut.setSeq( i, seq );
    00169         return true;
    00170     } else if( i == m_cut.count() )
    00171         return m_cut.append( seq );
    00172     return false;
    00173 }
    00174
    00175 void KAccelAction::clearShortcut()
    00176 {
    00177     m_cut.clear();
    00178 }
    00179
    00180 bool KAccelAction::contains( const KKeySequence& seq )
    00181 {
    00182     return m_cut.contains( seq );
    00183     for( uint i = 0; i < m_cut.count(); i++ ) {
    00184         if( m_cut.seq(i) == seq )
    00185             return true;
    00186     }
    00187     return false;
    00188 }
    00189
    00190 const KShortcut& KAccelAction::shortcutDefault() const
    00191     { return (useFourModifierKeys()) ? m_cutDefault4 : m_cutDefault3; }
    00192 bool KAccelAction::isConnected() const
    00193     { return d->m_nConnections; }
    00194 void KAccelAction::incConnections()
    00195     { d->m_nConnections++; }
    00196 void KAccelAction::decConnections()
    00197     { if( d->m_nConnections > 0 ) d->m_nConnections--; }
    00198
    00199 // Indicate whether to default to the 3- or 4- modifier keyboard schemes
    00200 int KAccelAction::g_bUseFourModifierKeys = -1;
    00201
    00202 bool KAccelAction::useFourModifierKeys()
    00203 {
    00204     if( KAccelAction::g_bUseFourModifierKeys == -1 ) {
    00205         // Read in whether to use 4 modifier keys
    00206         KConfigGroupSaver cgs( KGlobal::config(), "Keyboard" );
    00207         bool b = KGlobal::config()->readBoolEntry( "Use Four Modifier Keys",  false );
    00208         KAccelAction::g_bUseFourModifierKeys = b && KKeyNative::keyboardHasWinKey();
    00209     }
    00210     return KAccelAction::g_bUseFourModifierKeys == 1;
    00211 }
    00212
    00213 void KAccelAction::useFourModifierKeys( bool b )
    00214 {
    00215     if( KAccelAction::g_bUseFourModifierKeys != (int)b ) {
    00216         KAccelAction::g_bUseFourModifierKeys = b && KKeyNative::keyboardHasWinKey();
    00217         // If we're 'turning off' the meta key or, if we're turning it on,
    00218         //  the keyboard must actually have a meta key.
    00219         if( b && !KKeyNative::keyboardHasWinKey() )
    00220             kdDebug(125) << "Tried to use four modifier keys on a keyboard layout without a Meta key.\n";
    00221     }
    00222     KConfigGroupSaver cgs( KGlobal::config(), "Keyboard" );
    00223     KGlobal::config()->writeEntry( "Use Four Modifier Keys", KAccelAction::g_bUseFourModifierKeys, true, true);
    00224
    00225     kdDebug(125) << "bUseFourModifierKeys = " << KAccelAction::g_bUseFourModifierKeys << endl;
    00226 }
    00227
    00228 //---------------------------------------------------------------------
    00229 // KAccelActions
    00230 //---------------------------------------------------------------------
    00231
    00232 class KAccelActionsPrivate
    00233 {
    00234  public:
    00235 };
    00236
    00237 KAccelActions::KAccelActions()
    00238 {
    00239     kdDebug(125) << "KAccelActions(): this = " << this << endl;
    00240     initPrivate( 0 );
    00241 }
    00242
    00243 KAccelActions::KAccelActions( const KAccelActions& actions )
    00244 {
    00245     kdDebug(125) << "KAccelActions( actions = " << &actions << " ): this = " << this << endl;
    00246     initPrivate( 0 );
    00247     init( actions );
    00248 }
    00249
    00250 KAccelActions::KAccelActions( KAccelBase* pKAccelBase )
    00251 {
    00252     kdDebug(125) << "KAccelActions( KAccelBase = " << pKAccelBase << " ): this = " << this << endl;
    00253     initPrivate( pKAccelBase );
    00254 }
    00255
    00256 KAccelActions::~KAccelActions()
    00257 {
    00258     //kdDebug(125) << "KAccelActions::~KAccelActions(): this = " << this << endl;
    00259     clear();
    00260     //delete d;
    00261 }
    00262
    00263 void KAccelActions::initPrivate( KAccelBase* pKAccelBase )
    00264 {
    00265     m_pKAccelBase = pKAccelBase;
    00266     m_nSizeAllocated = m_nSize = 0;
    00267     m_prgActions = 0;
    00268     //d = new KAccelActionsPrivate;
    00269 }
    00270
    00271 void KAccelActions::clear()
    00272 {
    00273     kdDebug(125) << "\tKAccelActions::clear()" << endl;
    00274     for( uint i = 0; i < m_nSize; i++ )
    00275         delete m_prgActions[i];
    00276     delete[] m_prgActions;
    00277
    00278     m_nSizeAllocated = m_nSize = 0;
    00279     m_prgActions = 0;
    00280 }
    00281
    00282 bool KAccelActions::init( const KAccelActions& actions )
    00283 {
    00284     clear();
    00285     resize( actions.count() );
    00286     for( uint i = 0; i < m_nSize; i++ ) {
    00287         KAccelAction* pAction = actions.m_prgActions[i];
    00288         if( pAction )
    00289             m_prgActions[i] = new KAccelAction( *pAction );
    00290         else
    00291             m_prgActions[i] = 0;
    00292     }
    00293
    00294     return true;
    00295 }
    00296
    00297 bool KAccelActions::init( KConfigBase& config, const QString& sGroup )
    00298 {
    00299     kdDebug(125) << "KAccelActions::init( " << sGroup << " )" << endl;
    00300     QMap<QString, QString> mapEntry = config.entryMap( sGroup );
    00301     resize( mapEntry.count() );
    00302
    00303     QMap<QString, QString>::Iterator it( mapEntry.begin() );
    00304     for( uint i = 0; it != mapEntry.end(); ++it, i++ ) {
    00305         QString sShortcuts = *it;
    00306         KShortcut cuts;
    00307
    00308         kdDebug(125) << it.key() << " = " << sShortcuts << endl;
    00309         if( !sShortcuts.isEmpty() && sShortcuts != "none" )
    00310             cuts.init( sShortcuts );
    00311
    00312         m_prgActions[i] = new KAccelAction( it.key(), it.key(), it.key(),
    00313             cuts, cuts,
    00314             0, 0,          // pObjSlot, psMethodSlot,
    00315             true, false ); // bConfigurable, bEnabled
    00316     }
    00317
    00318     return true;
    00319 }
    00320
    00321 void KAccelActions::resize( uint nSize )
    00322 {
    00323     if( nSize > m_nSizeAllocated ) {
    00324         uint nSizeAllocated = ((nSize/10) + 1) * 10;
    00325         KAccelAction** prgActions = new KAccelAction* [nSizeAllocated];
    00326
    00327         // Copy pointers over to new array
    00328         for( uint i = 0; i < m_nSizeAllocated; i++ )
    00329             prgActions[i] = m_prgActions[i];
    00330
    00331         // Null out new pointers
    00332         for( uint i = m_nSizeAllocated; i < nSizeAllocated; i++ )
    00333             prgActions[i] = 0;
    00334
    00335         delete[] m_prgActions;
    00336         m_prgActions = prgActions;
    00337         m_nSizeAllocated = nSizeAllocated;
    00338     }
    00339
    00340     m_nSize = nSize;
    00341 }
    00342
    00343 void KAccelActions::insertPtr( KAccelAction* pAction )
    00344 {
    00345     resize( m_nSize + 1 );
    00346     m_prgActions[m_nSize-1] = pAction;
    00347 }
    00348
    00349 void KAccelActions::updateShortcuts( KAccelActions& actions2 )
    00350 {
    00351     kdDebug(125) << "KAccelActions::updateShortcuts()" << endl;
    00352     bool bChanged = false;
    00353
    00354     for( uint i = 0; i < m_nSize; i++ ) {
    00355         KAccelAction* pAction = m_prgActions[i];
    00356         if( pAction && pAction->m_bConfigurable ) {
    00357             KAccelAction* pAction2 = actions2.actionPtr( pAction->m_sName );
    00358             if( pAction2 ) {
    00359                 QString sOld = pAction->m_cut.toStringInternal();
    00360                 pAction->m_cut = pAction2->m_cut;
    00361                 kdDebug(125) << "\t" << pAction->m_sName
    00362                     << " found: " << sOld
    00363                     << " => " << pAction2->m_cut.toStringInternal()
    00364                     << " = " << pAction->m_cut.toStringInternal() << endl;
    00365                 bChanged = true;
    00366             }
    00367         }
    00368     }
    00369
    00370     if( bChanged )
    00371         emitKeycodeChanged();
    00372 }
    00373
    00374 int KAccelActions::actionIndex( const QString& sAction ) const
    00375 {
    00376     for( uint i = 0; i < m_nSize; i++ ) {
    00377         if( m_prgActions[i] == 0 )
    00378             kdWarning(125) << "KAccelActions::actionPtr( " << sAction << " ): encountered null pointer at m_prgActions[" << i << "]" << endl;
    00379         else if( m_prgActions[i]->m_sName == sAction )
    00380             return (int) i;
    00381     }
    00382     return -1;
    00383 }
    00384
    00385 KAccelAction* KAccelActions::actionPtr( uint i )
    00386 {
    00387     return m_prgActions[i];
    00388 }
    00389
    00390 const KAccelAction* KAccelActions::actionPtr( uint i ) const
    00391 {
    00392     return m_prgActions[i];
    00393 }
    00394
    00395 KAccelAction* KAccelActions::actionPtr( const QString& sAction )
    00396 {
    00397     int i = actionIndex( sAction );
    00398     return (i >= 0) ? m_prgActions[i] : 0;
    00399 }
    00400
    00401 const KAccelAction* KAccelActions::actionPtr( const QString& sAction ) const
    00402 {
    00403     int i = actionIndex( sAction );
    00404     return (i >= 0) ? m_prgActions[i] : 0;
    00405 }
    00406
    00407 KAccelAction* KAccelActions::actionPtr( KKeySequence cut )
    00408 {
    00409     for( uint i = 0; i < m_nSize; i++ ) {
    00410         if( m_prgActions[i] == 0 )
    00411             kdWarning(125) << "KAccelActions::actionPtr( " << cut.toStringInternal() << " ): encountered null pointer at m_prgActions[" << i << "]" << endl;
    00412         else if( m_prgActions[i]->contains( cut ) )
    00413             return m_prgActions[i];
    00414     }
    00415     return 0;
    00416 }
    00417
    00418 KAccelAction& KAccelActions::operator []( uint i )
    00419 {
    00420     return *actionPtr( i );
    00421 }
    00422
    00423 const KAccelAction& KAccelActions::operator []( uint i ) const
    00424 {
    00425     return *actionPtr( i );
    00426 }
    00427
    00428 KAccelAction* KAccelActions::insert( const QString& sName, const QString& sLabel )
    00429 {
    00430     if( actionPtr( sName ) ) {
    00431         kdWarning(125) << "KAccelActions::insertLabel( " << sName << ", " << sLabel << " ): action with same name already present." << endl;
    00432         return 0;
    00433     }
    00434
    00435     KAccelAction* pAction = new KAccelAction;
    00436     pAction->m_sName = sName;
    00437     pAction->m_sLabel = sLabel;
    00438     pAction->m_bConfigurable = false;
    00439     pAction->m_bEnabled = false;
    00440
    00441     insertPtr( pAction );
    00442     return pAction;
    00443 }
    00444
    00445 KAccelAction* KAccelActions::insert( const QString& sAction, const QString& sLabel, const QString& sWhatsThis,
    00446             const KShortcut& rgCutDefaults3, const KShortcut& rgCutDefaults4,
    00447             const QObject* pObjSlot, const char* psMethodSlot,
    00448             bool bConfigurable, bool bEnabled )
    00449 {
    00450     //kdDebug(125) << "KAccelActions::insert()2 begin" << endl;
    00451     if( actionPtr( sAction ) ) {
    00452         kdWarning(125) << "KAccelActions::insert( " << sAction << " ): action with same name already present." << endl;
    00453         return 0;
    00454     }
    00455
    00456     KAccelAction* pAction = new KAccelAction(
    00457         sAction, sLabel, sWhatsThis,
    00458         rgCutDefaults3, rgCutDefaults4,
    00459         pObjSlot, psMethodSlot,
    00460         bConfigurable, bEnabled );
    00461     insertPtr( pAction );
    00462
    00463     //kdDebug(125) << "KAccelActions::insert()2 end" << endl;
    00464     return pAction;
    00465 }
    00466
    00467 bool KAccelActions::remove( const QString& sAction )
    00468 {
    00469     kdDebug(125) << "KAccelActions::remove( \"" << sAction << "\" ): this = " << this << " m_pKAccelBase = " << m_pKAccelBase << endl;
    00470
    00471     int iAction = actionIndex( sAction );
    00472     if( iAction < 0 )
    00473         return false;
    00474
    00475     if( m_pKAccelBase )
    00476         m_pKAccelBase->slotRemoveAction( m_prgActions[iAction] );
    00477     delete m_prgActions[iAction];
    00478
    00479     for( uint i = iAction; i < m_nSize - 1; i++ )
    00480         m_prgActions[i] = m_prgActions[i+1];
    00481     m_nSize--;
    00482
    00483     return true;
    00484 }
    00485
    00486 bool KAccelActions::readActions( const QString& sConfigGroup, KConfigBase* pConfig )
    00487 {
    00488     KAccelShortcutList accelList(*this, false);
    00489     return accelList.readSettings( sConfigGroup, pConfig );
    00490 }
    00491
    00492 /*
    00493     1) KAccelAction = "Something"
    00494         1) KKeySequence = "Meta+X,Asterisk"
    00495             1) KAccelSequence = "Meta+X"
    00496                 1) KKeySequence = Meta+X
    00497             2) KAccelSequence = "Asterisk"
    00498                 1) KKeySequence = Shift+8 (English layout)
    00499                 2) KKeySequence = Keypad_Asterisk
    00500         2) KKeySequence = "Alt+F2"
    00501             1) KAccelSequence = "Alt+F2"
    00502                 1) KKeySequence = Alt+F2
    00503     -> "Something=Meta+X,Asterisk;Alt+F2"
    00504 */
    00505 bool KAccelActions::writeActions( const QString &sGroup, KConfigBase* pConfig,
    00506             bool bWriteAll, bool bGlobal ) const
    00507 {
    00508     kdDebug(125) << "KAccelActions::writeActions( " << sGroup << ", " << pConfig << ", " << bWriteAll << ", " << bGlobal << " )" << endl;
    00509     if( !pConfig )
    00510         pConfig = KGlobal::config();
    00511     KConfigGroupSaver cs( pConfig, sGroup );
    00512
    00513     for( uint i = 0; i < m_nSize; i++ ) {
    00514         if( m_prgActions[i] == 0 ) {
    00515             kdWarning(125) << "KAccelActions::writeActions(): encountered null pointer at m_prgActions[" << i << "]" << endl;
    00516             continue;
    00517         }
    00518         const KAccelAction& action = *m_prgActions[i];
    00519
    00520         QString s;
    00521         bool bConfigHasAction = !pConfig->readEntry( action.m_sName ).isEmpty();
    00522         bool bSameAsDefault = true;
    00523         bool bWriteAction = false;
    00524
    00525         if( action.m_bConfigurable ) {
    00526             s = action.toStringInternal();
    00527             bSameAsDefault = (action.m_cut == action.shortcutDefault());
    00528
    00529             //if( bWriteAll && s.isEmpty() )
    00530             if( s.isEmpty() )
    00531                 s = "none";
    00532
    00533             // If we're using a global config or this setting
    00534             //  differs from the default, then we want to write.
    00535             if( bWriteAll || !bSameAsDefault )
    00536                 bWriteAction = true;
    00537
    00538             if( bWriteAction ) {
    00539                 kdDebug(125) << "\twriting " << action.m_sName << " = " << s << endl;
    00540                 // Is passing bGlobal irrelevant, since if it's true,
    00541                 //  then we're using the global config anyway? --ellis
    00542                 pConfig->writeEntry( action.m_sName, s, true, bGlobal );
    00543             }
    00544             // Otherwise, this key is the same as default
    00545             //  but exists in config file.  Remove it.
    00546             else if( bConfigHasAction ) {
    00547                 kdDebug(125) << "\tremoving " << action.m_sName << " because == default" << endl;
    00548                 pConfig->deleteEntry( action.m_sName, bGlobal );
    00549             }
    00550
    00551         }
    00552     }
    00553
    00554     pConfig->sync();
    00555     return true;
    00556 }
    00557
    00558 void KAccelActions::emitKeycodeChanged()
    00559 {
    00560     if( m_pKAccelBase )
    00561         m_pKAccelBase->emitSignal( KAccelBase::KEYCODE_CHANGED );
    00562 }
    00563
    00564 uint KAccelActions::count() const
    00565     { return m_nSize; }

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