summaryrefslogtreecommitdiffstats
path: root/tdecore/kaccelbase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tdecore/kaccelbase.cpp')
-rw-r--r--tdecore/kaccelbase.cpp616
1 files changed, 0 insertions, 616 deletions
diff --git a/tdecore/kaccelbase.cpp b/tdecore/kaccelbase.cpp
deleted file mode 100644
index 4ba4c9c3b..000000000
--- a/tdecore/kaccelbase.cpp
+++ /dev/null
@@ -1,616 +0,0 @@
-/*
- Copyright (C) 1997-2000 Nicolas Hadacek <hadacek@kde.org>
- Copyright (C) 1998 Mark Donohoe <donohoe@kde.org>
- Copyright (C) 1998 Matthias Ettrich <ettrich@kde.org>
- Copyright (c) 2001,2002 Ellis Whitehead <ellis@kde.org>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to
- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
-*/
-
-#include "kaccelbase.h"
-
-#include <tqkeycode.h>
-#include <tqlabel.h>
-#include <tqpopupmenu.h>
-
-#include <kconfig.h>
-#include "kckey.h"
-#include <kdebug.h>
-#include <kglobal.h>
-#include <kkeynative.h>
-#include "kkeyserver.h"
-#include <klocale.h>
-#include "kshortcutmenu.h"
-
-//---------------------------------------------------------------------
-// class KAccelBase::ActionInfo
-//---------------------------------------------------------------------
-
-//---------------------------------------------------------------------
-// class KAccelBase
-//---------------------------------------------------------------------
-
-KAccelBase::KAccelBase( int fInitCode )
-: m_rgActions( this )
-{
- kdDebug(125) << "KAccelBase(): this = " << this << endl;
- m_bNativeKeys = fInitCode & NATIVE_KEYS;
- m_bEnabled = true;
- m_sConfigGroup = "Shortcuts";
- m_bConfigIsGlobal = false;
- m_bAutoUpdate = false;
- mtemp_pActionRemoving = 0;
-}
-
-KAccelBase::~KAccelBase()
-{
- kdDebug(125) << "~KAccelBase(): this = " << this << endl;
-}
-
-uint KAccelBase::actionCount() const { return m_rgActions.count(); }
-KAccelActions& KAccelBase::actions() { return m_rgActions; }
-bool KAccelBase::isEnabled() const { return m_bEnabled; }
-// see KGlobalAccel::blockShortcuts() stuff - it's to temporarily block
-// all global shortcuts, so that the key grabs are released, but from the app's
-// point of view the KGlobalAccel is still enabled, so KGlobalAccel needs
-// to disable key grabbing even if enabled
-bool KAccelBase::isEnabledInternal() const { return isEnabled(); }
-
-KAccelAction* KAccelBase::actionPtr( const TQString& sAction )
- { return m_rgActions.actionPtr( sAction ); }
-
-const KAccelAction* KAccelBase::actionPtr( const TQString& sAction ) const
- { return m_rgActions.actionPtr( sAction ); }
-
-KAccelAction* KAccelBase::actionPtr( const KKeyServer::Key& key )
-{
- if( !m_mapKeyToAction.contains( key ) )
- return 0;
- // Note: If more than one action is connected to a single key, nil will be returned.
- return m_mapKeyToAction[key].pAction;
-}
-
-KAccelAction* KAccelBase::actionPtr( const KKey& key )
-{
- KKeyServer::Key k2;
- k2.init( key, !m_bNativeKeys );
- return actionPtr( k2 );
-}
-
-void KAccelBase::setConfigGroup( const TQString& sConfigGroup )
- { m_sConfigGroup = sConfigGroup; }
-
-void KAccelBase::setConfigGlobal( bool global )
- { m_bConfigIsGlobal = global; }
-
-bool KAccelBase::setActionEnabled( const TQString& sAction, bool bEnable )
-{
- KAccelAction* pAction = actionPtr( sAction );
- if( pAction ) {
- if( pAction->m_bEnabled != bEnable ) {
- kdDebug(125) << "KAccelBase::setActionEnabled( " << sAction << ", " << bEnable << " )" << endl;
- pAction->m_bEnabled = bEnable;
- if( m_bAutoUpdate ) {
- // FIXME: the action may already have it's connections inserted!
- if( bEnable )
- insertConnection( pAction );
- else if( pAction->isConnected() )
- removeConnection( pAction );
- }
- }
- return true;
- }
- return false;
-}
-
-bool KAccelBase::setAutoUpdate( bool bAuto )
-{
- kdDebug(125) << "KAccelBase::setAutoUpdate( " << bAuto << " ): m_bAutoUpdate on entrance = " << m_bAutoUpdate << endl;
- bool b = m_bAutoUpdate;
- if( !m_bAutoUpdate && bAuto )
- updateConnections();
- m_bAutoUpdate = bAuto;
- return b;
-}
-
-KAccelAction* KAccelBase::insert( const TQString& sAction, const TQString& sDesc, const TQString& sHelp,
- const KShortcut& rgCutDefaults3, const KShortcut& rgCutDefaults4,
- const TQObject* pObjSlot, const char* psMethodSlot,
- bool bConfigurable, bool bEnabled )
-{
- //kdDebug(125) << "KAccelBase::insert() begin" << endl;
- KAccelAction* pAction = m_rgActions.insert(
- sAction, sDesc, sHelp,
- rgCutDefaults3, rgCutDefaults4,
- pObjSlot, psMethodSlot,
- bConfigurable, bEnabled );
-
- if( pAction && m_bAutoUpdate )
- insertConnection( pAction );
-
- //kdDebug(125) << "KAccelBase::insert() end" << endl;
- return pAction;
-}
-
-KAccelAction* KAccelBase::insert( const TQString& sName, const TQString& sDesc )
- { return m_rgActions.insert( sName, sDesc ); }
-
-bool KAccelBase::remove( const TQString& sAction )
-{
- return m_rgActions.remove( sAction );
-}
-
-void KAccelBase::slotRemoveAction( KAccelAction* pAction )
-{
- removeConnection( pAction );
-}
-
-bool KAccelBase::setActionSlot( const TQString& sAction, const TQObject* pObjSlot, const char* psMethodSlot )
-{
- kdDebug(125) << "KAccelBase::setActionSlot( " << sAction << ", " << pObjSlot << ", " << psMethodSlot << " )\n";
- KAccelAction* pAction = m_rgActions.actionPtr( sAction );
- if( pAction ) {
- // If there was a previous connection, remove it.
- if( m_bAutoUpdate && pAction->isConnected() ) {
- kdDebug(125) << "\tm_pObjSlot = " << pAction->m_pObjSlot << " m_psMethodSlot = " << pAction->m_psMethodSlot << endl;
- removeConnection( pAction );
- }
-
- pAction->m_pObjSlot = pObjSlot;
- pAction->m_psMethodSlot = psMethodSlot;
-
- // If we're setting a connection,
- if( m_bAutoUpdate && pObjSlot && psMethodSlot )
- insertConnection( pAction );
-
- return true;
- } else
- return false;
-}
-
-/*
-KAccelBase
- Run Command=Meta+Enter;Alt+F2
- KAccelAction = "Run Command"
- 1) KAccelKeySeries = "Meta+Enter"
- 1a) Meta+Enter
- 1b) Meta+Keypad_Enter
- 2) KAccelKeySeries = "Alt+F2"
- 1a) Alt+F2
-
- Konqueror=Meta+I,I
- KAccelAction = "Konqueror"
- 1) KAccelKeySeries = "Meta+I,I"
- 1a) Meta+I
- 2a) I
-
- Something=Meta+Asterisk,X
- KAccelAction = "Something"
- 1) KAccelKeySeries = "Meta+Asterisk,X"
- 1a) Meta+Shift+8
- 1b) Meta+Keypad_8
- 2a) X
-
-read in a config entry
- split by ';'
- find key sequences to disconnect
- find new key sequences to connect
-check for conflicts with implicit keys
- disconnect conflicting implicit keys
-connect new key sequences
-*/
-/*
-{
- For {
- for( KAccelAction::iterator itAction = m_rgActions.begin(); itAction != m_rgActions.end(); ++itAction ) {
- KAccelAction& action = *itAction;
- for( KAccelSeries::iterator itSeries = action.m_rgSeries.begin(); itSeries != action.m_rgSeries.end(); ++itSeries ) {
- KAccelSeries& series = *itSeries;
- if(
- }
- }
- }
- Sort by: iVariation, iSequence, iSeries, iAction
-
- 1) KAccelAction = "Run Command"
- 1) KAccelKeySeries = "Meta+Enter"
- 1a) Meta+Enter
- 1b) Meta+Keypad_Enter
- 2) KAccelKeySeries = "Alt+F2"
- 1a) Alt+F2
-
- 2) KAccelAction = "Enter Calculation"
- 1) KAccelKeySeries = "Meta+Keypad_Enter"
- 1a) Meta+Keypad_Enter
-
- List =
- Meta+Enter -> 1, 1, 1a
- Meta+Keypad_Enter -> 2, 1, 1a
- Alt+F2 -> 1, 2, 1a
- [Meta+Keypad_Enter] -> [1, 1, 1b]
-
-}
-*/
-
-#ifdef Q_WS_X11
-struct KAccelBase::X
-{
- uint iAction, iSeq, iVari;
- KKeyServer::Key key;
-
- X() {}
- X( uint _iAction, uint _iSeq, uint _iVari, const KKeyServer::Key& _key )
- { iAction = _iAction; iSeq = _iSeq; iVari = _iVari; key = _key; }
-
- int compare( const X& x )
- {
- int n = key.compare( x.key );
- if( n != 0 ) return n;
- if( iVari != x.iVari ) return iVari - x.iVari;
- if( iSeq != x.iSeq ) return iSeq - x.iSeq;
- return 0;
- }
-
- bool operator <( const X& x ) { return compare( x ) < 0; }
- bool operator >( const X& x ) { return compare( x ) > 0; }
- bool operator <=( const X& x ) { return compare( x ) <= 0; }
-};
-#endif //Q_WS_X11
-
-/*
-#1 Ctrl+A
-#2 Ctrl+A
-#3 Ctrl+B
- ------
- Ctrl+A => Null
- Ctrl+B => #3
-
-#1 Ctrl+A
-#1 Ctrl+B;Ctrl+A
- ------
- Ctrl+A => #1
- Ctrl+B => #2
-
-#1 Ctrl+A
-#1 Ctrl+B,C
-#1 Ctrl+B,D
- ------
- Ctrl+A => #1
- Ctrl+B => Null
-
-#1 Ctrl+A
-#2 Ctrl+Plus(Ctrl+KP_Add)
- ------
- Ctrl+A => #1
- Ctrl+Plus => #2
- Ctrl+KP_Add => #2
-
-#1 Ctrl+Plus(Ctrl+KP_Add)
-#2 Ctrl+KP_Add
- ------
- Ctrl+Plus => #1
- Ctrl+KP_Add => #2
-
-#1 Ctrl+Plus(Ctrl+KP_Add)
-#2 Ctrl+A;Ctrl+KP_Add
- ------
- Ctrl+A => #2
- Ctrl+Plus => #1
- Ctrl+KP_Add => #2
-*/
-
-bool KAccelBase::updateConnections()
-{
-#ifdef Q_WS_X11
- kdDebug(125) << "KAccelBase::updateConnections() this = " << this << endl;
- // Retrieve the list of keys to be connected, sorted by priority.
- // (key, variation, seq)
- TQValueVector<X> rgKeys;
- createKeyList( rgKeys );
- m_rgActionsNonUnique.clear();
-
- KKeyToActionMap mapKeyToAction;
- for( uint i = 0; i < rgKeys.size(); i++ ) {
- X& x = rgKeys[i];
- KKeyServer::Key& key = x.key;
- ActionInfo info;
- bool bNonUnique = false;
-
- info.pAction = m_rgActions.actionPtr( x.iAction );
- info.iSeq = x.iSeq;
- info.iVariation = x.iVari;
-
- // If this is a multi-key shortcut,
- if( info.pAction->shortcut().seq(info.iSeq).count() > 1 )
- bNonUnique = true;
- // If this key is requested by more than one action,
- else if( i < rgKeys.size() - 1 && key == rgKeys[i+1].key ) {
- // If multiple actions requesting this key
- // have the same priority as the first one,
- if( info.iVariation == rgKeys[i+1].iVari && info.iSeq == rgKeys[i+1].iSeq )
- bNonUnique = true;
-
- kdDebug(125) << "key conflict = " << key.key().toStringInternal()
- << " action1 = " << info.pAction->name()
- << " action2 = " << m_rgActions.actionPtr( rgKeys[i+1].iAction )->name()
- << " non-unique = " << bNonUnique << endl;
-
- // Skip over the other records with this same key.
- while( i < rgKeys.size() - 1 && key == rgKeys[i+1].key )
- i++;
- }
-
- if( bNonUnique ) {
- // Remove connection to single action if there is one
- if( m_mapKeyToAction.contains( key ) ) {
- KAccelAction* pAction = m_mapKeyToAction[key].pAction;
- if( pAction ) {
- m_mapKeyToAction.remove( key );
- disconnectKey( *pAction, key );
- pAction->decConnections();
- m_rgActionsNonUnique.append( pAction );
- }
- }
- // Indicate that no single action is associated with this key.
- m_rgActionsNonUnique.append( info.pAction );
- info.pAction = 0;
- }
-
- //kdDebug(125) << "mapKeyToAction[" << key.toStringInternal() << "] = " << info.pAction << endl;
- mapKeyToAction[key] = info;
- }
-
- // Disconnect keys which no longer have bindings:
- for( KKeyToActionMap::iterator it = m_mapKeyToAction.begin(); it != m_mapKeyToAction.end(); ++it ) {
- const KKeyServer::Key& key = it.key();
- KAccelAction* pAction = (*it).pAction;
- // If this key is longer used or it points to a different action now,
- if( !mapKeyToAction.contains( key ) || mapKeyToAction[key].pAction != pAction ) {
- if( pAction ) {
- disconnectKey( *pAction, key );
- pAction->decConnections();
- } else
- disconnectKey( key );
- }
- }
-
- // Connect any unconnected keys:
- // In other words, connect any keys which are present in the
- // new action map, but which are _not_ present in the old one.
- for( KKeyToActionMap::iterator it = mapKeyToAction.begin(); it != mapKeyToAction.end(); ++it ) {
- const KKeyServer::Key& key = it.key();
- KAccelAction* pAction = (*it).pAction;
- if( !m_mapKeyToAction.contains( key ) || m_mapKeyToAction[key].pAction != pAction ) {
- // TODO: Decide what to do if connect fails.
- // Probably should remove this item from map.
- if( pAction ) {
- if( connectKey( *pAction, key ) )
- pAction->incConnections();
- } else
- connectKey( key );
- }
- }
-
- // Store new map.
- m_mapKeyToAction = mapKeyToAction;
-
-#ifndef NDEBUG
- for( KKeyToActionMap::iterator it = m_mapKeyToAction.begin(); it != m_mapKeyToAction.end(); ++it ) {
- kdDebug(125) << "Key: " << it.key().key().toStringInternal() << " => '"
- << (((*it).pAction) ? (*it).pAction->name() : TQString::null) << "'" << endl;
- }
-#endif
-#endif //Q_WS_X11
- return true;
-}
-
-#ifdef Q_WS_X11
-// Construct a list of keys to be connected, sorted highest priority first.
-void KAccelBase::createKeyList( TQValueVector<struct X>& rgKeys )
-{
- //kdDebug(125) << "KAccelBase::createKeyList()" << endl;
- if( !isEnabledInternal())
- return;
-
- // create the list
- // For each action
- for( uint iAction = 0; iAction < m_rgActions.count(); iAction++ ) {
- KAccelAction* pAction = m_rgActions.actionPtr( iAction );
- if( pAction && pAction->m_pObjSlot && pAction->m_psMethodSlot && pAction != mtemp_pActionRemoving ) {
- // For each key sequence associated with action
- for( uint iSeq = 0; iSeq < pAction->shortcut().count(); iSeq++ ) {
- const KKeySequence& seq = pAction->shortcut().seq(iSeq);
- if( seq.count() > 0 ) {
- KKeyServer::Variations vars;
- vars.init( seq.key(0), !m_bNativeKeys );
- for( uint iVari = 0; iVari < vars.count(); iVari++ ) {
- if( vars.key(iVari).code() && vars.key(iVari).sym() )
- rgKeys.push_back( X( iAction, iSeq, iVari, vars.key( iVari ) ) );
- //kdDebug(125) << "\t" << pAction->name() << ": " << vars.key(iVari).toStringInternal() << endl;
- }
- }
- //else
- // kdDebug(125) << "\t*" << pAction->name() << ":" << endl;
- }
- }
- }
-
- // sort by priority: iVariation[of first key], iSequence, iAction
- qHeapSort( rgKeys.begin(), rgKeys.end() );
-}
-#endif //Q_WS_X11
-
-bool KAccelBase::insertConnection( KAccelAction* pAction )
-{
- if( !pAction->m_pObjSlot || !pAction->m_psMethodSlot )
- return true;
-
- kdDebug(125) << "KAccelBase::insertConnection( " << pAction << "=\"" << pAction->m_sName << "\"; shortcut = " << pAction->shortcut().toStringInternal() << " ) this = " << this << endl;
-
- // For each sequence associated with the given action:
- for( uint iSeq = 0; iSeq < pAction->shortcut().count(); iSeq++ ) {
- // Get the first key of the sequence.
- KKeyServer::Variations vars;
- vars.init( pAction->shortcut().seq(iSeq).key(0), !m_bNativeKeys );
- for( uint iVari = 0; iVari < vars.count(); iVari++ ) {
- const KKeyServer::Key& key = vars.key( iVari );
-
- //if( !key.isNull() ) {
- if( key.sym() ) {
- if( !m_mapKeyToAction.contains( key ) ) {
- // If this is a single-key shortcut,
- if( pAction->shortcut().seq(iSeq).count() == 1 ) {
- m_mapKeyToAction[key] = ActionInfo( pAction, iSeq, iVari );
- if( connectKey( *pAction, key ) )
- pAction->incConnections();
- }
- // Else this is a multi-key shortcut,
- else {
- m_mapKeyToAction[key] = ActionInfo( 0, 0, 0 );
- // Insert into non-unique list if it's not already there.
- if( m_rgActionsNonUnique.findIndex( pAction ) == -1 )
- m_rgActionsNonUnique.append( pAction );
- if( connectKey( key ) )
- pAction->incConnections();
- }
- } else {
- // There is a key conflict. A full update
- // check is necessary.
- // TODO: make this more efficient where possible.
- if( m_mapKeyToAction[key].pAction != pAction
- && m_mapKeyToAction[key].pAction != 0 ) {
- kdDebug(125) << "Key conflict with action = " << m_mapKeyToAction[key].pAction->name()
- << " key = " << key.key().toStringInternal() << " : call updateConnections()" << endl;
- return updateConnections();
- }
- }
- }
- }
- }
-
- //kdDebug(125) << "\tActions = " << m_rgActions.size() << endl;
- //for( KAccelActions::const_iterator it = m_rgActions.begin(); it != m_rgActions.end(); ++it ) {
- // kdDebug(125) << "\t" << &(*it) << " '" << (*it).m_sName << "'" << endl;
- //}
-
- //kdDebug(125) << "\tKeys = " << m_mapKeyToAction.size() << endl;
- //for( KKeyToActionMap::iterator it = m_mapKeyToAction.begin(); it != m_mapKeyToAction.end(); ++it ) {
- // //kdDebug(125) << "\tKey: " << it.key().toString() << " => '" << (*it)->m_sName << "'" << endl;
- // kdDebug(125) << "\tKey: " << it.key().toString() << " => '" << *it << "'" << endl;
- // kdDebug(125) << "\t\t'" << (*it)->m_sName << "'" << endl;
- //}
-
- return true;
-}
-
-bool KAccelBase::removeConnection( KAccelAction* pAction )
-{
- kdDebug(125) << "KAccelBase::removeConnection( " << pAction << " = \"" << pAction->m_sName << "\"; shortcut = " << pAction->m_cut.toStringInternal() << " ): this = " << this << endl;
-
- //for( KKeyToActionMap::iterator it = m_mapKeyToAction.begin(); it != m_mapKeyToAction.end(); ++it )
- // kdDebug(125) << "\tKey: " << it.key().toString() << " => '" << (*it)->m_sName << "'" << " " << *it << endl;
-
- if( m_rgActionsNonUnique.findIndex( pAction ) >= 0 ) {
- mtemp_pActionRemoving = pAction;
- bool b = updateConnections();
- mtemp_pActionRemoving = 0;
- return b;
- }
-
- KKeyToActionMap::iterator it = m_mapKeyToAction.begin();
- while( it != m_mapKeyToAction.end() ) {
- KKeyServer::Key key = it.key();
- ActionInfo* pInfo = &(*it);
-
- // If the given action is connected to this key,
- if( pAction == pInfo->pAction ) {
- disconnectKey( *pAction, key );
- pAction->decConnections();
-
- KKeyToActionMap::iterator itRemove = it++;
- m_mapKeyToAction.remove( itRemove );
- } else
- ++it;
- }
- return true;
-}
-
-bool KAccelBase::setShortcut( const TQString& sAction, const KShortcut& cut )
-{
- KAccelAction* pAction = actionPtr( sAction );
- if( pAction ) {
- if( m_bAutoUpdate )
- removeConnection( pAction );
-
- pAction->setShortcut( cut );
-
- if( m_bAutoUpdate && !pAction->shortcut().isNull() )
- insertConnection( pAction );
- return true;
- } else
- return false;
-}
-
-void KAccelBase::readSettings( KConfigBase* pConfig )
-{
- m_rgActions.readActions( m_sConfigGroup, pConfig );
- if( m_bAutoUpdate )
- updateConnections();
-}
-
-void KAccelBase::writeSettings( KConfigBase* pConfig ) const
-{
- m_rgActions.writeActions( m_sConfigGroup, pConfig, m_bConfigIsGlobal, m_bConfigIsGlobal );
-}
-
-TQPopupMenu* KAccelBase::createPopupMenu( TQWidget* pParent, const KKeySequence& seq )
-{
- KShortcutMenu* pMenu = new KShortcutMenu( pParent, &actions(), seq );
-
- bool bActionInserted = false;
- bool bInsertSeparator = false;
- for( uint i = 0; i < actionCount(); i++ ) {
- const KAccelAction* pAction = actions().actionPtr( i );
-
- if( !pAction->isEnabled() )
- continue;
-
- // If an action has already been inserted into the menu
- // and we have a label instead of an action here,
- // then indicate that we should insert a separator before the next menu entry.
- if( bActionInserted && !pAction->isConfigurable() && pAction->name().contains( ':' ) )
- bInsertSeparator = true;
-
- for( uint iSeq = 0; iSeq < pAction->shortcut().count(); iSeq++ ) {
- const KKeySequence& seqAction = pAction->shortcut().seq(iSeq);
- if( seqAction.startsWith( seq ) ) {
- if( bInsertSeparator ) {
- pMenu->insertSeparator();
- bInsertSeparator = false;
- }
-
- pMenu->insertAction( i, seqAction );
-
- //kdDebug(125) << "sLabel = " << sLabel << ", seq = " << (TQString)seqMenu.qt() << ", i = " << i << endl;
- //kdDebug(125) << "pMenu->accel(" << i << ") = " << (TQString)pMenu->accel(i) << endl;
- bActionInserted = true;
- break;
- }
- }
- }
- pMenu->updateShortcuts();
- return pMenu;
-}