kshortcut.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kshortcut.h"
00021 #include "kkeynative.h"
00022 #include "kkeyserver.h"
00023
00024 #include <qevent.h>
00025 #include <qstringlist.h>
00026
00027 #include <kdebug.h>
00028 #include <kglobal.h>
00029 #include <klocale.h>
00030 #include <ksimpleconfig.h>
00031
00032
00033
00034 static KKey* g_pspec = 0;
00035 static KKeySequence* g_pseq = 0;
00036 static KShortcut* g_pcut = 0;
00037
00038
00039
00040
00041
00042 KKey::KKey() { clear(); }
00043 KKey::KKey( uint key, uint modFlags ) { init( key, modFlags ); }
00044 KKey::KKey( int keyQt ) { init( keyQt ); }
00045 KKey::KKey( const QKeySequence& seq ) { init( seq ); }
00046 KKey::KKey( const QKeyEvent* pEvent ) { init( pEvent ); }
00047 KKey::KKey( const KKey& key ) { init( key ); }
00048 KKey::KKey( const QString& sKey ) { init( sKey ); }
00049
00050 KKey::~KKey()
00051 {
00052 }
00053
00054 void KKey::clear()
00055 {
00056 m_sym = 0;
00057 m_mod = 0;
00058 }
00059
00060 bool KKey::init( uint key, uint modFlags )
00061 {
00062 m_sym = key;
00063 m_mod = modFlags;
00064 return true;
00065 }
00066
00067 bool KKey::init( int keyQt )
00068 {
00069
00070
00071
00072 if( KKeyServer::keyQtToSym( keyQt, m_sym )
00073 && KKeyServer::keyQtToMod( keyQt, m_mod ) )
00074 return true;
00075 else {
00076 m_sym = 0;
00077 m_mod = 0;
00078 return false;
00079 }
00080 }
00081
00082 bool KKey::init( const QKeySequence& key )
00083 {
00084
00085 return init( (int) key );
00086 }
00087
00088 bool KKey::init( const QKeyEvent* pEvent )
00089 {
00090 int keyQt = pEvent->key();
00091 if( pEvent->state() & Qt::ShiftButton ) keyQt |= Qt::SHIFT;
00092 if( pEvent->state() & Qt::ControlButton ) keyQt |= Qt::CTRL;
00093 if( pEvent->state() & Qt::AltButton ) keyQt |= Qt::ALT;
00094 if( pEvent->state() & Qt::MetaButton ) keyQt |= Qt::META;
00095 return init( keyQt );
00096 }
00097
00098 bool KKey::init( const KKey& key )
00099 {
00100 m_sym = key.m_sym;
00101 m_mod = key.m_mod;
00102 return true;
00103 }
00104
00105 bool KKey::init( const QString& sSpec )
00106 {
00107 clear();
00108
00109 QString sKey = sSpec.stripWhiteSpace();
00110 if( sKey.startsWith( "default(" ) && sKey.endsWith( ")" ) )
00111 sKey = sKey.mid( 8, sKey.length() - 9 );
00112
00113 if( sKey.endsWith( "++" ) )
00114 sKey = sKey.left( sKey.length() - 1 ) + "plus";
00115 QStringList rgs = QStringList::split( '+', sKey, true );
00116
00117 uint i;
00118
00119 for( i = 0; i < rgs.size(); i++ ) {
00120 QString s = rgs[i].lower();
00121 if( s == "shift" ) m_mod |= KKey::SHIFT;
00122 else if( s == "ctrl" ) m_mod |= KKey::CTRL;
00123 else if( s == "alt" ) m_mod |= KKey::ALT;
00124 else if( s == "win" ) m_mod |= KKey::WIN;
00125 else if( s == "meta" ) m_mod |= KKey::WIN;
00126 else break;
00127 }
00128
00129 if( (i == rgs.size() - 1 && !rgs[i].isEmpty()) ) {
00130 KKeyServer::Sym sym( rgs[i] );
00131 m_sym = sym.m_sym;
00132 }
00133
00134 if( m_sym == 0 )
00135 m_mod = 0;
00136
00137 kdDebug(125) << "KKey::init( \"" << sSpec << "\" ):"
00138 << " m_sym = " << QString::number(m_sym, 16)
00139 << ", m_mod = " << QString::number(m_mod, 16) << endl;
00140
00141 return m_sym != 0;
00142 }
00143
00144 bool KKey::isNull() const { return m_sym == 0; }
00145 uint KKey::sym() const { return m_sym; }
00146 uint KKey::modFlags() const { return m_mod; }
00147
00148 int KKey::compare( const KKey& spec ) const
00149 {
00150 if( m_sym != spec.m_sym )
00151 return m_sym - spec.m_sym;
00152 if( m_mod != spec.m_mod )
00153 return m_mod - spec.m_mod;
00154 return 0;
00155 }
00156
00157 int KKey::keyCodeQt() const
00158 {
00159 return KKeyNative( *this ).keyCodeQt();
00160 }
00161
00162 QString KKey::toString() const
00163 {
00164 QString s;
00165
00166 s = KKeyServer::modToStringUser( m_mod );
00167 if( !s.isEmpty() )
00168 s += '+';
00169 s += KKeyServer::Sym(m_sym).toString();
00170
00171 return s;
00172 }
00173
00174 QString KKey::toStringInternal() const
00175 {
00176
00177
00178
00179 QString s;
00180
00181 s = KKeyServer::modToStringInternal( m_mod );
00182 if( !s.isEmpty() )
00183 s += '+';
00184 s += KKeyServer::Sym(m_sym).toStringInternal();
00185 return s;
00186 }
00187
00188 KKey& KKey::null()
00189 {
00190 if( !g_pspec )
00191 g_pspec = new KKey;
00192 if( !g_pspec->isNull() )
00193 g_pspec->clear();
00194 return *g_pspec;
00195 }
00196
00197 QString KKey::modFlagLabel( ModFlag modFlag )
00198 {
00199 return KKeyServer::modToStringUser( modFlag );
00200 }
00201
00202
00203
00204
00205
00206 KKeySequence::KKeySequence() { clear(); }
00207 KKeySequence::KKeySequence( const QKeySequence& seq ) { init( seq ); }
00208 KKeySequence::KKeySequence( const KKey& key ) { init( key ); }
00209 KKeySequence::KKeySequence( const KKeySequence& seq ) { init( seq ); }
00210 KKeySequence::KKeySequence( const QString& s ) { init( s ); }
00211
00212 KKeySequence::~KKeySequence()
00213 {
00214 }
00215
00216 void KKeySequence::clear()
00217 {
00218 m_nKeys = 0;
00219 m_bTriggerOnRelease = false;
00220 }
00221
00222 bool KKeySequence::init( const QKeySequence& seq )
00223 {
00224 clear();
00225 #if QT_VERSION >= 0x030100
00226 if( !seq.isEmpty() ) {
00227 for( uint i = 0; i < seq.count(); i++ ) {
00228 m_rgvar[i].init( seq[i] );
00229 if( m_rgvar[i].isNull() )
00230 return false;
00231 }
00232 m_nKeys = seq.count();
00233 m_bTriggerOnRelease = false;
00234 }
00235 #else // Qt 3.0.x
00236 if( seq ) {
00237 m_rgvar[ 0 ].init( seq );
00238 if( !m_rgvar[ 0 ].isNull() ) {
00239 m_nKeys = 1;
00240 m_bTriggerOnRelease = false;
00241 }
00242 }
00243 #endif
00244 return true;
00245 }
00246
00247 bool KKeySequence::init( const KKey& key )
00248 {
00249 if( !key.isNull() ) {
00250 m_nKeys = 1;
00251 m_rgvar[0].init( key );
00252 m_bTriggerOnRelease = false;
00253 } else
00254 clear();
00255 return true;
00256 }
00257
00258 bool KKeySequence::init( const KKeySequence& seq )
00259 {
00260 m_bTriggerOnRelease = false;
00261 m_nKeys = seq.m_nKeys;
00262 for( uint i = 0; i < m_nKeys; i++ ) {
00263 if( seq.m_rgvar[i].isNull() ) {
00264 kdDebug(125) << "KKeySequence::init( seq ): key[" << i << "] is null." << endl;
00265 m_nKeys = 0;
00266 return false;
00267 }
00268 m_rgvar[i] = seq.m_rgvar[i];
00269 }
00270 return true;
00271 }
00272
00273 bool KKeySequence::init( const QString& s )
00274 {
00275 m_bTriggerOnRelease = false;
00276
00277 QStringList rgs = QStringList::split( ',', s );
00278 if( s == "none" || rgs.size() == 0 ) {
00279 clear();
00280 return true;
00281 } else if( rgs.size() <= MAX_KEYS ) {
00282 m_nKeys = rgs.size();
00283 for( uint i = 0; i < m_nKeys; i++ ) {
00284 m_rgvar[i].init( KKey(rgs[i]) );
00285
00286 }
00287 return true;
00288 } else {
00289 clear();
00290 return false;
00291 }
00292 }
00293
00294 uint KKeySequence::count() const
00295 {
00296 return m_nKeys;
00297 }
00298
00299 const KKey& KKeySequence::key( uint i ) const
00300 {
00301 if( i < m_nKeys )
00302 return m_rgvar[i];
00303 else
00304 return KKey::null();
00305 }
00306
00307 bool KKeySequence::isTriggerOnRelease() const
00308 { return m_bTriggerOnRelease; }
00309
00310 bool KKeySequence::setKey( uint iKey, const KKey& key )
00311 {
00312 if( iKey <= m_nKeys && iKey < MAX_KEYS ) {
00313 m_rgvar[iKey].init( key );
00314 if( iKey == m_nKeys )
00315 m_nKeys++;
00316 return true;
00317 } else
00318 return false;
00319 }
00320
00321 bool KKeySequence::isNull() const
00322 {
00323 return m_nKeys == 0;
00324 }
00325
00326 bool KKeySequence::startsWith( const KKeySequence& seq ) const
00327 {
00328 if( m_nKeys < seq.m_nKeys )
00329 return false;
00330
00331 for( uint i = 0; i < seq.m_nKeys; i++ ) {
00332 if( m_rgvar[i] != seq.m_rgvar[i] )
00333 return false;
00334 }
00335
00336 return true;
00337 }
00338
00339 int KKeySequence::compare( const KKeySequence& seq ) const
00340 {
00341 for( uint i = 0; i < m_nKeys && i < seq.m_nKeys; i++ ) {
00342 int ret = m_rgvar[i].compare( seq.m_rgvar[i] );
00343 if( ret != 0 )
00344 return ret;
00345 }
00346 if( m_nKeys != seq.m_nKeys )
00347 return m_nKeys - seq.m_nKeys;
00348 else
00349 return 0;
00350 }
00351
00352 QKeySequence KKeySequence::qt() const
00353 {
00354 int k[4] = { 0, 0, 0, 0 };
00355
00356 for( uint i = 0; i < count(); i++ )
00357 k[i] = KKeyNative(key(i)).keyCodeQt();
00358 #if QT_VERSION >= 0x030100
00359 QKeySequence seq( k[0], k[1], k[2], k[3] );
00360 #else // Qt-3.0.x
00361 QKeySequence seq;
00362 if( count() == 1 )
00363 seq = KKeyNative( key( 0 ) ).keyCodeQt();
00364 #endif
00365 return seq;
00366 }
00367
00368 int KKeySequence::keyCodeQt() const
00369 {
00370 return (count() == 1) ? KKeyNative(key(0)).keyCodeQt() : 0;
00371 }
00372
00373 QString KKeySequence::toString() const
00374 {
00375 if( m_nKeys < 1 ) return QString::null;
00376
00377 QString s;
00378 s = m_rgvar[0].toString();
00379 for( uint i = 1; i < m_nKeys; i++ ) {
00380 s += ",";
00381 s += m_rgvar[i].toString();
00382 }
00383
00384 return s;
00385 }
00386
00387 QString KKeySequence::toStringInternal() const
00388 {
00389 if( m_nKeys < 1 ) return QString::null;
00390
00391 QString s;
00392 s = m_rgvar[0].toStringInternal();
00393 for( uint i = 1; i < m_nKeys; i++ ) {
00394 s += ",";
00395 s += m_rgvar[i].toStringInternal();
00396 }
00397
00398 return s;
00399 }
00400
00401 KKeySequence& KKeySequence::null()
00402 {
00403 if( !g_pseq )
00404 g_pseq = new KKeySequence;
00405 if( !g_pseq->isNull() )
00406 g_pseq->clear();
00407 return *g_pseq;
00408 }
00409
00410
00411
00412
00413
00414 KShortcut::KShortcut() { clear(); }
00415 KShortcut::KShortcut( int keyQt ) { init( keyQt ); }
00416 KShortcut::KShortcut( const QKeySequence& key ) { init( key ); }
00417 KShortcut::KShortcut( const KKey& key ) { init( key ); }
00418 KShortcut::KShortcut( const KKeySequence& seq ) { init( seq ); }
00419 KShortcut::KShortcut( const KShortcut& cut ) { init( cut ); }
00420 KShortcut::KShortcut( const char* ps ) { init( QString(ps) ); }
00421 KShortcut::KShortcut( const QString& s ) { init( s ); }
00422
00423 KShortcut::~KShortcut()
00424 {
00425 }
00426
00427 void KShortcut::clear()
00428 {
00429 m_nSeqs = 0;
00430 }
00431
00432 bool KShortcut::init( int keyQt )
00433 {
00434 if( keyQt ) {
00435 m_nSeqs = 1;
00436 m_rgseq[0].init( QKeySequence(keyQt) );
00437 } else
00438 clear();
00439 return true;
00440 }
00441
00442 bool KShortcut::init( const QKeySequence& key )
00443 {
00444 m_nSeqs = 1;
00445 m_rgseq[0].init( key );
00446 return true;
00447 }
00448
00449 bool KShortcut::init( const KKey& spec )
00450 {
00451 m_nSeqs = 1;
00452 m_rgseq[0].init( spec );
00453 return true;
00454 }
00455
00456 bool KShortcut::init( const KKeySequence& seq )
00457 {
00458 m_nSeqs = 1;
00459 m_rgseq[0] = seq;
00460 return true;
00461 }
00462
00463 bool KShortcut::init( const KShortcut& cut )
00464 {
00465 m_nSeqs = cut.m_nSeqs;
00466 for( uint i = 0; i < m_nSeqs; i++ )
00467 m_rgseq[i] = cut.m_rgseq[i];
00468 return true;
00469 }
00470
00471 bool KShortcut::init( const QString& s )
00472 {
00473 bool bRet = true;
00474 QStringList rgs = QStringList::split( ';', s );
00475
00476 if( s == "none" || rgs.size() == 0 )
00477 clear();
00478 else if( rgs.size() <= MAX_SEQUENCES ) {
00479 m_nSeqs = rgs.size();
00480 for( uint i = 0; i < m_nSeqs; i++ ) {
00481 QString& sSeq = rgs[i];
00482 if( sSeq.startsWith( "default(" ) )
00483 sSeq = sSeq.mid( 8, sSeq.length() - 9 );
00484 m_rgseq[i].init( sSeq );
00485
00486 }
00487 } else {
00488 clear();
00489 bRet = false;
00490 }
00491
00492 if( !s.isEmpty() ) {
00493 QString sDebug;
00494 QTextStream os( &sDebug, IO_WriteOnly );
00495 os << "KShortcut::init( \"" << s << "\" ): ";
00496 for( uint i = 0; i < m_nSeqs; i++ ) {
00497 os << " m_rgseq[" << i << "]: ";
00498 KKeyServer::Variations vars;
00499 vars.init( m_rgseq[i].key(0), true );
00500 for( uint j = 0; j < vars.count(); j++ )
00501 os << QString::number(vars.m_rgkey[j].keyCodeQt(),16) << ',';
00502 }
00503 kdDebug(125) << sDebug << endl;
00504 }
00505
00506 return bRet;
00507 }
00508
00509 uint KShortcut::count() const
00510 {
00511 return m_nSeqs;
00512 }
00513
00514 const KKeySequence& KShortcut::seq( uint i ) const
00515 {
00516 return (i < m_nSeqs) ? m_rgseq[i] : KKeySequence::null();
00517 }
00518
00519 int KShortcut::keyCodeQt() const
00520 {
00521 if( m_nSeqs >= 1 )
00522 return m_rgseq[0].keyCodeQt();
00523 return QKeySequence();
00524 }
00525
00526 bool KShortcut::isNull() const
00527 {
00528 return m_nSeqs == 0;
00529 }
00530
00531 int KShortcut::compare( const KShortcut& cut ) const
00532 {
00533 for( uint i = 0; i < m_nSeqs && i < cut.m_nSeqs; i++ ) {
00534 int ret = m_rgseq[i].compare( cut.m_rgseq[i] );
00535 if( ret != 0 )
00536 return ret;
00537 }
00538 return m_nSeqs - cut.m_nSeqs;
00539 }
00540
00541 bool KShortcut::contains( const KKey& key ) const
00542 {
00543 return contains( KKeySequence(key) );
00544 }
00545
00546 bool KShortcut::contains( const KKeyNative& keyNative ) const
00547 {
00548 KKey key = keyNative.key();
00549 key.simplify();
00550
00551 for( uint i = 0; i < count(); i++ ) {
00552 if( !m_rgseq[i].isNull()
00553 && m_rgseq[i].count() == 1
00554 && m_rgseq[i].key(0) == key )
00555 return true;
00556 }
00557 return false;
00558 }
00559
00560 bool KShortcut::contains( const KKeySequence& seq ) const
00561 {
00562 for( uint i = 0; i < count(); i++ ) {
00563 if( !m_rgseq[i].isNull() && m_rgseq[i] == seq )
00564 return true;
00565 }
00566 return false;
00567 }
00568
00569 bool KShortcut::setSeq( uint iSeq, const KKeySequence& seq )
00570 {
00571
00572 if( iSeq <= m_nSeqs && iSeq < MAX_SEQUENCES ) {
00573 m_rgseq[iSeq] = seq;
00574 if( iSeq == m_nSeqs )
00575 m_nSeqs++;
00576 return true;
00577 } else
00578 return false;
00579 }
00580
00581 void KShortcut::remove( const KKeySequence& seq )
00582 {
00583 if (seq.isNull()) return;
00584
00585 for( uint iSeq = 0; iSeq < m_nSeqs; iSeq++ )
00586 {
00587 if (m_rgseq[iSeq] == seq)
00588 {
00589 for( uint jSeq = iSeq + 1; jSeq < m_nSeqs; jSeq++)
00590 m_rgseq[jSeq-1] = m_rgseq[jSeq];
00591 m_nSeqs--;
00592 }
00593 }
00594 }
00595
00596 bool KShortcut::append( const KKeySequence& seq )
00597 {
00598 if( m_nSeqs < MAX_SEQUENCES ) {
00599 if( !seq.isNull() ) {
00600 m_rgseq[m_nSeqs] = seq;
00601 m_nSeqs++;
00602 }
00603 return true;
00604 } else
00605 return false;
00606 }
00607
00608 bool KShortcut::append( const KKey& spec )
00609 {
00610 if( m_nSeqs < MAX_SEQUENCES ) {
00611 m_rgseq[m_nSeqs].init( spec );
00612 m_nSeqs++;
00613 return true;
00614 } else
00615 return false;
00616 }
00617
00618 bool KShortcut::append( const KShortcut& cut )
00619 {
00620 uint seqs = m_nSeqs, co = cut.count();
00621 for( uint i=0; i<co; i++ ) {
00622 if (!contains(cut.seq(i))) seqs++;
00623 }
00624 if( seqs > MAX_SEQUENCES ) return false;
00625
00626 for( uint i=0; i<co; i++ ) {
00627 const KKeySequence& seq = cut.seq(i);
00628 if(!contains(seq)) {
00629 m_rgseq[m_nSeqs] = seq;
00630 m_nSeqs++;
00631 }
00632 }
00633 return true;
00634 }
00635
00636 KShortcut::operator QKeySequence () const
00637 {
00638 if( count() >= 1 )
00639 return m_rgseq[0].qt();
00640 else
00641 return QKeySequence();
00642 }
00643
00644 QString KShortcut::toString() const
00645 {
00646 QString s;
00647
00648 for( uint i = 0; i < count(); i++ ) {
00649 s += m_rgseq[i].toString();
00650 if( i < count() - 1 )
00651 s += ';';
00652 }
00653
00654 return s;
00655 }
00656
00657 QString KShortcut::toStringInternal( const KShortcut* pcutDefault ) const
00658 {
00659 QString s;
00660
00661 for( uint i = 0; i < count(); i++ ) {
00662 const KKeySequence& seq = m_rgseq[i];
00663 if( pcutDefault && i < pcutDefault->count() && seq == (*pcutDefault).seq(i) ) {
00664 s += "default(";
00665 s += seq.toStringInternal();
00666 s += ")";
00667 } else
00668 s += seq.toStringInternal();
00669 if( i < count() - 1 )
00670 s += ';';
00671 }
00672
00673 return s;
00674 }
00675
00676 KShortcut& KShortcut::null()
00677 {
00678 if( !g_pcut )
00679 g_pcut = new KShortcut;
00680 if( !g_pcut->isNull() )
00681 g_pcut->clear();
00682 return *g_pcut;
00683 }
This file is part of the documentation for kdecore Library Version 3.4.3.