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