• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

KDECore

kaccelaction.cpp

Go to the documentation of this file.
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., 51 Franklin Street, Fifth Floor,
00020     Boston, MA 02110-1301, 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; }

KDECore

Skip menu "KDECore"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • dcop
  • DNSSD
  • interfaces
  • Kate
  • kconf_update
  • KDECore
  • KDED
  • kdefx
  • KDEsu
  • kdeui
  • KDocTools
  • KHTML
  • KImgIO
  • KInit
  • kio
  • kioslave
  • KJS
  • KNewStuff
  • KParts
  • KUtils
Generated for API Reference by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal