# kdecore Library API Documentation

Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Source Files

# kshortcut.cpp

    00001 /*  This file is part of the KDE libraries
    00002     Copyright (C) 2001,2002 Ellis Whitehead <ellis@kde.org>
    00003
    00004     This library is free software; you can redistribute it and/or
    00005     modify it under the terms of the GNU Library General Public
    00006     License as published by the Free Software Foundation; either
    00007     version 2 of the License, or (at your option) any later version.
    00008
    00009     This library is distributed in the hope that it will be useful,
    00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
    00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00012     Library General Public License for more details.
    00013
    00014     You should have received a copy of the GNU Library General Public License
    00015     along with this library; see the file COPYING.LIB.  If not, write to
    00016     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    00017     Boston, MA 02111-1307, USA.
    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 // KKey
    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         //KKeyServer::Sym sym;
    00072
    00073         //if( sym.initQt( keyQt )
    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         // TODO: if key.count() > 1, should we return failure?
    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         // i.e., "Ctrl++" = "Ctrl+Plus"
    00114         if( sKey.endsWith( "++" ) )
    00115                 sKey = sKey.left( sKey.length() - 1 ) + "plus";
    00116         QStringList rgs = QStringList::split( '+', sKey, true );
    00117
    00118         uint i;
    00119         // Check for modifier keys first.
    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         // If there is one non-blank key left:
    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         //kdDebug(125) << "KKey::toStringInternal(): this = " << this
    00178         //      << " mod = " << QString::number(m_mod, 16)
    00179         //      << " key = " << QString::number(m_sym, 16) << endl;
    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 // KKeySequence
    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         //kdDebug(125) << "KKeySequence::init( " << s << " )" << endl;
    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                         //kdDebug(125) << "\t'" << rgs[i] << "' => " << m_rgvar[i].toStringInternal() << endl;
    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 // KShortcut
    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                         //kdDebug(125) << "*\t'" << sSeq << "' => " << m_rgseq[i].toStringInternal() << endl;
    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         // TODO: check if seq is null, and act accordingly.
    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.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 12:46:52 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001