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