kdecore Library API Documentation

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; }
KDE Logo
This file is part of the documentation for kdecore Library Version 3.2.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Aug 20 09:48:24 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003