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