kaccelaction.cpp Source File (kdecore Library)

| # kdecore Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | 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         return KAccelShortcutList(*this, false).readSettings( sConfigGroup, pConfig );
    00489 }
    00490
    00491 /*
    00492         1) KAccelAction = "Something"
    00493                 1) KKeySequence = "Meta+X,Asterisk"
    00494                         1) KAccelSequence = "Meta+X"
    00495                                 1) KKeySequence = Meta+X
    00496                         2) KAccelSequence = "Asterisk"
    00497                                 1) KKeySequence = Shift+8 (English layout)
    00498                                 2) KKeySequence = Keypad_Asterisk
    00499                 2) KKeySequence = "Alt+F2"
    00500                         1) KAccelSequence = "Alt+F2"
    00501                                 1) KKeySequence = Alt+F2
    00502         -> "Something=Meta+X,Asterisk;Alt+F2"
    00503 */
    00504 bool KAccelActions::writeActions( const QString &sGroup, KConfigBase* pConfig,
    00505                         bool bWriteAll, bool bGlobal ) const
    00506 {
    00507         kdDebug(125) << "KAccelActions::writeActions( " << sGroup << ", " << pConfig << ", " << bWriteAll << ", " << bGlobal << " )" << endl;
    00508         if( !pConfig )
    00509                 pConfig = KGlobal::config();
    00510         KConfigGroupSaver cs( pConfig, sGroup );
    00511
    00512         for( uint i = 0; i < m_nSize; i++ ) {
    00513                 if( m_prgActions[i] == 0 ) {
    00514                         kdWarning(125) << "KAccelActions::writeActions(): encountered null pointer at m_prgActions[" << i << "]" << endl;
    00515                         continue;
    00516                 }
    00517                 const KAccelAction& action = *m_prgActions[i];
    00518
    00519                 QString s;
    00520                 bool bConfigHasAction = !pConfig->readEntry( action.m_sName ).isEmpty();
    00521                 bool bSameAsDefault = true;
    00522                 bool bWriteAction = false;
    00523
    00524                 if( action.m_bConfigurable ) {
    00525                         s = action.toStringInternal();
    00526                         bSameAsDefault = (action.m_cut == action.shortcutDefault());
    00527
    00528                         //if( bWriteAll && s.isEmpty() )
    00529                         if( s.isEmpty() )
    00530                                 s = "none";
    00531
    00532                         // If we're using a global config or this setting
    00533                         //  differs from the default, then we want to write.
    00534                         if( bWriteAll || !bSameAsDefault )
    00535                                 bWriteAction = true;
    00536
    00537                         if( bWriteAction ) {
    00538                                 kdDebug(125) << "\twriting " << action.m_sName << " = " << s << endl;
    00539                                 // Is passing bGlobal irrelevant, since if it's true,
    00540                                 //  then we're using the global config anyway? --ellis
    00541                                 pConfig->writeEntry( action.m_sName, s, true, bGlobal );
    00542                         }
    00543                         // Otherwise, this key is the same as default
    00544                         //  but exists in config file.  Remove it.
    00545                         else if( bConfigHasAction ) {
    00546                                 kdDebug(125) << "\tremoving " << action.m_sName << " because == default" << endl;
    00547                                 pConfig->deleteEntry( action.m_sName, bGlobal );
    00548                         }
    00549
    00550                 }
    00551         }
    00552
    00553         pConfig->sync();
    00554         return true;
    00555 }
    00556
    00557 void KAccelActions::emitKeycodeChanged()
    00558 {
    00559         if( m_pKAccelBase )
    00560                 m_pKAccelBase->emitSignal( KAccelBase::KEYCODE_CHANGED );
    00561 }
    00562
    00563 uint KAccelActions::count() const
    00564         { return m_nSize; }

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