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