/*
    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 "kaccel.h"

#include <tqaccel.h>
#include <tqguardedptr.h>
#include <tqpopupmenu.h>
#include <tqregexp.h>
#include <tqstring.h>
#include <tqtimer.h>

#include "kaccelbase.h"
#include <kapplication.h>
#include <kdebug.h>
#include <klocale.h>
#include <kshortcut.h>

#include "kaccelprivate.h"

#ifdef Q_WS_X11
#	include <X11/Xlib.h>
#	ifdef KeyPress // needed for --enable-final
		// defined by X11 headers
		const int XKeyPress = KeyPress;
#		undef KeyPress
#	endif
#endif

// TODO: Put in kaccelbase.cpp
//---------------------------------------------------------------------
// KAccelEventHandler
//---------------------------------------------------------------------
//
// In KAccelEventHandler::x11Event we do our own X11 keyboard event handling
// This allows us to map the Win key to Qt::MetaButton, Qt does not know about
// the Win key.
//
// KAccelEventHandler::x11Event will generate an AccelOverride event. The
// AccelOverride event is abused a bit to ensure that KAccelPrivate::eventFilter
// (as an event filter on the toplevel widget) will get the key event first
// (in the form of AccelOverride) before any of the intermediate widgets are
// able to process it.
//
// Qt normally sends an AccelOverride, Accel and then a KeyPress event.
// A widget can accept the AccelOverride event in which case the Accel event will be
// skipped and the KeyPress is followed immediately.
// If the Accel event is accepted, no KeyPress event will follow.
//
// KAccelEventHandler::x11Event converts a X11 keyboard event into an AccelOverride
// event, there are now two possibilities:
//
// 1) If KAccel intercepts the AccelOverride we are done and can consider the X11
// keyboard event as handled.
// 2) If another widget accepts the AccelOverride, it will expect to get a normal
// Qt generated KeyPress event afterwards. So we let Qt handle the X11 keyboard event
// again. However, this will first generate an AccelOverride event, and we already
// had send that one. To compnesate for this, the global event filter in KApplication
// is instructed to eat the next AccelOveride event. Qt will then send a normal KeyPress
// event and from then on everything is normal again.
//
// kde_g_bKillAccelOverride is used to tell KApplication::notify to eat the next
// AccelOverride event.

bool kde_g_bKillAccelOverride = false;

class KAccelEventHandler : public TQWidget
{
 public:
	static KAccelEventHandler* self()
	{
		if( !g_pSelf )
			g_pSelf = new KAccelEventHandler;
		return g_pSelf;
	}

	static void accelActivated( bool b ) { g_bAccelActivated = b; }

 private:
	KAccelEventHandler();

#	ifdef Q_WS_X11
	bool x11Event( XEvent* pEvent );
#	endif

	static KAccelEventHandler* g_pSelf;
	static bool g_bAccelActivated;
};

KAccelEventHandler* KAccelEventHandler::g_pSelf = 0;
bool KAccelEventHandler::g_bAccelActivated = false;

KAccelEventHandler::KAccelEventHandler()
    : TQWidget( 0, "KAccelEventHandler" )
{
#	ifdef Q_WS_X11
	if ( kapp )
		kapp->installX11EventFilter( TQT_TQWIDGET(this) );
#	endif
}

#ifdef Q_WS_X11
bool	tqt_try_modal( TQWidget *, XEvent * );

bool KAccelEventHandler::x11Event( XEvent* pEvent )
{
	if( TQWidget::keyboardGrabber() || !kapp->focusWidget() )
		return false;

	if ( !tqt_try_modal(kapp->focusWidget(), pEvent) )
	        return false;

	if( pEvent->type == XKeyPress ) {
		unsigned int tmp = pEvent->xkey.state;
		pEvent->xkey.state &= ~0x2000;
		KKeyNative keyNative( pEvent );
		pEvent->xkey.state = tmp;
		KKey key( keyNative );
		key.simplify();
		int keyCodeQt = key.keyCodeQt();
		int state = 0;
		if( key.modFlags() & KKey::SHIFT ) state |= TQt::ShiftButton;
		if( key.modFlags() & KKey::CTRL )  state |= TQt::ControlButton;
		if( key.modFlags() & KKey::ALT )   state |= TQt::AltButton;
		if( key.modFlags() & KKey::WIN )   state |= TQt::MetaButton;

		TQKeyEvent ke( TQEvent::AccelOverride, keyCodeQt, 0,  state );
		ke.ignore();

		g_bAccelActivated = false;
		kapp->sendEvent( kapp->focusWidget(), &ke );

		// If the Override event was accepted from a non-KAccel widget,
		//  then kill the next AccelOverride in KApplication::notify.
		if( ke.isAccepted() && !g_bAccelActivated )
			kde_g_bKillAccelOverride = true;

		// Stop event processing if a KDE accelerator was activated.
		return g_bAccelActivated;
	}

	return false;
}
#endif // Q_WS_X11

//---------------------------------------------------------------------
// KAccelPrivate
//---------------------------------------------------------------------

KAccelPrivate::KAccelPrivate( KAccel* pParent, TQWidget* pWatch )
: KAccelBase( KAccelBase::QT_KEYS )
{
	//kdDebug(125) << "KAccelPrivate::KAccelPrivate( pParent = " << pParent << " ): this = " << this << endl;
	m_pAccel = pParent;
	m_pWatch = pWatch;
	m_bAutoUpdate = true;
	connect( (TQAccel*)m_pAccel, TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotKeyPressed(int)) );

#ifdef Q_WS_X11 //only makes sense if KAccelEventHandler is working
	if( m_pWatch )
		m_pWatch->installEventFilter( this );
#endif
	KAccelEventHandler::self();
}

void KAccelPrivate::setEnabled( bool bEnabled )
{
	m_bEnabled = bEnabled;
	((TQAccel*)m_pAccel)->setEnabled( bEnabled );
}

bool KAccelPrivate::setEnabled( const TQString& sAction, bool bEnable )
{
	kdDebug(125) << "KAccelPrivate::setEnabled( \"" << sAction << "\", " << bEnable << " ): this = " << this << endl;
	KAccelAction* pAction = actionPtr( sAction );
	if( !pAction )
		return false;
	if( pAction->isEnabled() == bEnable )
		return true;

	pAction->setEnabled( bEnable );

	TQMap<int, KAccelAction*>::const_iterator it = m_mapIDToAction.begin();
	for( ; it != m_mapIDToAction.end(); ++it ) {
		if( *it == pAction )
			((TQAccel*)m_pAccel)->setItemEnabled( it.key(), bEnable );
	}
	return true;
}

bool KAccelPrivate::removeAction( const TQString& sAction )
{
	// FIXME: getID() doesn't contains any useful
	//  information!  Use mapIDToAction. --ellis, 2/May/2002
	//  Or maybe KAccelBase::remove() takes care of TQAccel indirectly...
	KAccelAction* pAction = actions().actionPtr( sAction );
	if( pAction ) {
		int nID = pAction->getID();
		//bool b = actions().removeAction( sAction );
		bool b = KAccelBase::remove( sAction );
		((TQAccel*)m_pAccel)->removeItem( nID );
		return b;
	} else
		return false;
}

bool KAccelPrivate::emitSignal( KAccelBase::Signal signal )
{
	if( signal == KAccelBase::KEYCODE_CHANGED ) {
		m_pAccel->emitKeycodeChanged();
		return true;
	}
	return false;
}

bool KAccelPrivate::connectKey( KAccelAction& action, const KKeyServer::Key& key )
{
	uint keyQt = key.keyCodeQt();
	int nID = ((TQAccel*)m_pAccel)->insertItem( keyQt );
	m_mapIDToAction[nID] = &action;
	m_mapIDToKey[nID] = keyQt;

	if( action.objSlotPtr() && action.methodSlotPtr() ) {
#ifdef Q_WS_WIN /** @todo TEMP: new implementation (commit #424926) didn't work */
		((TQAccel*)m_pAccel)->connectItem( nID, action.objSlotPtr(), action.methodSlotPtr() );
#else
		((TQAccel*)m_pAccel)->connectItem( nID, this, TQT_SLOT(slotKeyPressed(int)));
#endif
		if( !action.isEnabled() )
			((TQAccel*)m_pAccel)->setItemEnabled( nID, false );
	}

	kdDebug(125) << "KAccelPrivate::connectKey( \"" << action.name() << "\", " << key.key().toStringInternal() << " = 0x" << TQString::number(keyQt,16) << " ): id = " << nID << " m_pObjSlot = " << action.objSlotPtr() << endl;
	//kdDebug(125) << "m_pAccel = " << m_pAccel << endl;
	return nID != 0;
}

bool KAccelPrivate::connectKey( const KKeyServer::Key& key )
{
	uint keyQt = key.keyCodeQt();
	int nID = ((TQAccel*)m_pAccel)->insertItem( keyQt );

	m_mapIDToKey[nID] = keyQt;

	kdDebug(125) << "KAccelPrivate::connectKey( " << key.key().toStringInternal() << " = 0x" << TQString::number(keyQt,16) << " ): id = " << nID << endl;
	return nID != 0;
}

bool KAccelPrivate::disconnectKey( KAccelAction& action, const KKeyServer::Key& key )
{
	int keyQt = key.keyCodeQt();
	TQMap<int, int>::iterator it = m_mapIDToKey.begin();
	for( ; it != m_mapIDToKey.end(); ++it ) {
		//kdDebug(125) << "m_mapIDToKey[" << it.key() << "] = " << TQString::number(*it,16) << " == " << TQString::number(keyQt,16) << endl;
		if( *it == keyQt ) {
			int nID = it.key();
			kdDebug(125) << "KAccelPrivate::disconnectKey( \"" << action.name() << "\", 0x" << TQString::number(keyQt,16) << " ) : id = " << nID << " m_pObjSlot = " << action.objSlotPtr() << endl;
			((TQAccel*)m_pAccel)->removeItem( nID );
			m_mapIDToAction.remove( nID );
			m_mapIDToKey.remove( it );
			return true;
		}
	}
	//kdWarning(125) << kdBacktrace() << endl;
	kdWarning(125) << "Didn't find key in m_mapIDToKey." << endl;
	return false;
}

bool KAccelPrivate::disconnectKey( const KKeyServer::Key& key )
{
	int keyQt = key.keyCodeQt();
	kdDebug(125) << "KAccelPrivate::disconnectKey( 0x" << TQString::number(keyQt,16) << " )" << endl;
	TQMap<int, int>::iterator it = m_mapIDToKey.begin();
	for( ; it != m_mapIDToKey.end(); ++it ) {
		if( *it == keyQt ) {
			((TQAccel*)m_pAccel)->removeItem( it.key() );
			m_mapIDToKey.remove( it );
			return true;
		}
	}
	//kdWarning(125) << kdBacktrace() << endl;
	kdWarning(125) << "Didn't find key in m_mapIDTokey." << endl;
	return false;
}

void KAccelPrivate::slotKeyPressed( int id )
{
	kdDebug(125) << "KAccelPrivate::slotKeyPressed( " << id << " )" << endl;

	if( m_mapIDToKey.contains( id ) ) {
		KKey key = m_mapIDToKey[id];
		KKeySequence seq( key );
		TQPopupMenu* pMenu = createPopupMenu( m_pWatch, seq );

		// If there was only one action mapped to this key,
		//  and that action is not a multi-key shortcut,
		//  then activated it without popping up the menu.
		// This is needed for when there are multiple actions
		//  with the same shortcut where all but one is disabled.
		// pMenu->count() also counts the menu title, so one shortcut will give count = 2.
		if( pMenu->count() == 2 && pMenu->accel(1).isEmpty() ) {
			int iAction = pMenu->idAt(1);
			slotMenuActivated( iAction );
		} else {
			connect( pMenu, TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotMenuActivated(int)) );
			pMenu->exec( m_pWatch->mapToGlobal( TQPoint( 0, 0 ) ) );
			disconnect( pMenu, TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotMenuActivated(int)) );
		}
		delete pMenu;
	}
}

void KAccelPrivate::slotShowMenu()
{
}

void KAccelPrivate::slotMenuActivated( int iAction )
{
	kdDebug(125) << "KAccelPrivate::slotMenuActivated( " << iAction << " )" << endl;
	KAccelAction* pAction = actions().actionPtr( iAction );
#ifdef Q_WS_WIN /** @todo TEMP: new implementation (commit #424926) didn't work */
	if( pAction ) {
		connect( this, TQT_SIGNAL(menuItemActivated()), pAction->objSlotPtr(), pAction->methodSlotPtr() );
		emit menuItemActivated();
		disconnect( this, TQT_SIGNAL(menuItemActivated()), pAction->objSlotPtr(), pAction->methodSlotPtr() );
	}
#else
	emitActivatedSignal( pAction );
#endif
}

bool KAccelPrivate::eventFilter( TQObject* /*pWatched*/, TQEvent* pEvent )
{
	if( pEvent->type() == TQEvent::AccelOverride && m_bEnabled ) {
		TQKeyEvent* pKeyEvent = (TQKeyEvent*) pEvent;
		KKey key( pKeyEvent );
		kdDebug(125) << "KAccelPrivate::eventFilter( AccelOverride ): this = " << this << ", key = " << key.toStringInternal() << endl;
		int keyCodeQt = key.keyCodeQt();
		TQMap<int, int>::iterator it = m_mapIDToKey.begin();
		for( ; it != m_mapIDToKey.end(); ++it ) {
			if( (*it) == keyCodeQt ) {
				int nID = it.key();
				kdDebug(125) << "shortcut found!" << endl;
				if( m_mapIDToAction.contains( nID ) ) {
					// TODO: reduce duplication between here and slotMenuActivated
					KAccelAction* pAction = m_mapIDToAction[nID];
					if( !pAction->isEnabled() )
						continue;
#ifdef Q_WS_WIN /** @todo TEMP: new implementation (commit #424926) didn't work */
					TQGuardedPtr<KAccelPrivate> me = this;
					connect( this, TQT_SIGNAL(menuItemActivated()), pAction->objSlotPtr(), pAction->methodSlotPtr() );
					emit menuItemActivated();
					if (me) {
						disconnect( me, TQT_SIGNAL(menuItemActivated()), pAction->objSlotPtr(), pAction->methodSlotPtr() );
					}
#else
					emitActivatedSignal( pAction );
#endif
				} else
					slotKeyPressed( nID );

				pKeyEvent->accept();
				KAccelEventHandler::accelActivated( true );
				return true;
			}
		}
	}
	return false;
}

#ifndef Q_WS_WIN /** @todo TEMP: new implementation (commit #424926) didn't work */
void KAccelPrivate::emitActivatedSignal( KAccelAction* pAction )
{
	if( pAction ) {
		TQGuardedPtr<KAccelPrivate> me = this;
		TQRegExp reg( "([ ]*KAccelAction.*)" );
		if( reg.search( pAction->methodSlotPtr()) >= 0 ) {
			connect( this, TQT_SIGNAL(menuItemActivated(KAccelAction*)),
				pAction->objSlotPtr(), pAction->methodSlotPtr() );
			emit menuItemActivated( pAction );
			if (me)
				disconnect( me, TQT_SIGNAL(menuItemActivated(KAccelAction*)),
					pAction->objSlotPtr(), pAction->methodSlotPtr() );
		} else {
			connect( this, TQT_SIGNAL(menuItemActivated()),
				pAction->objSlotPtr(), pAction->methodSlotPtr() );
			emit menuItemActivated();
			if (me)
				disconnect( me, TQT_SIGNAL(menuItemActivated()),
					pAction->objSlotPtr(), pAction->methodSlotPtr() );

		}
	}
}
#endif

//---------------------------------------------------------------------
// KAccel
//---------------------------------------------------------------------

KAccel::KAccel( TQWidget* pParent, const char* psName )
: TQAccel( pParent, (psName) ? psName : "KAccel-TQAccel" )
{
	kdDebug(125) << "KAccel( pParent = " << pParent << ", psName = " << psName << " ): this = " << this << endl;
	d = new KAccelPrivate( this, pParent );
}

KAccel::KAccel( TQWidget* watch, TQObject* pParent, const char* psName )
: TQAccel( watch, pParent, (psName) ? psName : "KAccel-TQAccel" )
{
	kdDebug(125) << "KAccel( watch = " << watch << ", pParent = " << pParent << ", psName = " << psName << " ): this = " << this << endl;
	if( !watch )
		kdDebug(125) << kdBacktrace() << endl;
	d = new KAccelPrivate( this, watch );
}

KAccel::~KAccel()
{
	kdDebug(125) << "~KAccel(): this = " << this << endl;
	delete d;
}

KAccelActions& KAccel::actions()             { return d->actions(); }
const KAccelActions& KAccel::actions() const { return d->actions(); }
bool KAccel::isEnabled()                     { return d->isEnabled(); }
void KAccel::setEnabled( bool bEnabled )     { d->setEnabled( bEnabled ); }
bool KAccel::setAutoUpdate( bool bAuto )     { return d->setAutoUpdate( bAuto ); }

KAccelAction* KAccel::insert( const TQString& sAction, const TQString& sLabel, const TQString& sWhatsThis,
		const KShortcut& cutDef,
		const TQObject* pObjSlot, const char* psMethodSlot,
		bool bConfigurable, bool bEnabled )
{
	return d->insert( sAction, sLabel, sWhatsThis,
		cutDef, cutDef,
		pObjSlot, psMethodSlot,
		bConfigurable, bEnabled );
}

KAccelAction* KAccel::insert( const TQString& sAction, const TQString& sLabel, const TQString& sWhatsThis,
		const KShortcut& cutDef3, const KShortcut& cutDef4,
		const TQObject* pObjSlot, const char* psMethodSlot,
		bool bConfigurable, bool bEnabled )
{
	return d->insert( sAction, sLabel, sWhatsThis,
		cutDef3, cutDef4,
		pObjSlot, psMethodSlot,
		bConfigurable, bEnabled );
}

KAccelAction* KAccel::insert( const char* psAction, const KShortcut& cutDef,
		const TQObject* pObjSlot, const char* psMethodSlot,
		bool bConfigurable, bool bEnabled )
{
	return d->insert( psAction, i18n(psAction), TQString::null,
		cutDef, cutDef,
		pObjSlot, psMethodSlot,
		bConfigurable, bEnabled );
}

KAccelAction* KAccel::insert( KStdAccel::StdAccel id,
		const TQObject* pObjSlot, const char* psMethodSlot,
		bool bConfigurable, bool bEnabled )
{
	TQString sAction = KStdAccel::name( id );
	if( sAction.isEmpty() )
		return 0;

	KAccelAction* pAction = d->insert( sAction, KStdAccel::label( id ), KStdAccel::whatsThis( id ),
		KStdAccel::shortcutDefault3( id ), KStdAccel::shortcutDefault4( id ),
		pObjSlot, psMethodSlot,
		bConfigurable, bEnabled );
	if( pAction )
		pAction->setShortcut( KStdAccel::shortcut( id ) );

	return pAction;
}

bool KAccel::remove( const TQString& sAction )
	{ return d->removeAction( sAction ); }
bool KAccel::updateConnections()
	{ return d->updateConnections(); }

const KShortcut& KAccel::shortcut( const TQString& sAction ) const
{
	const KAccelAction* pAction = actions().actionPtr( sAction );
	return (pAction) ? pAction->shortcut() : KShortcut::null();
}

bool KAccel::setSlot( const TQString& sAction, const TQObject* pObjSlot, const char* psMethodSlot )
	{ return d->setActionSlot( sAction, pObjSlot, psMethodSlot ); }

bool KAccel::setEnabled( const TQString& sAction, bool bEnable )
	{ return d->setEnabled( sAction, bEnable ); }

bool KAccel::setShortcut( const TQString& sAction, const KShortcut& cut )
{
	kdDebug(125) << "KAccel::setShortcut( \"" << sAction << "\", " << cut.toStringInternal() << " )" << endl;
	KAccelAction* pAction = actions().actionPtr( sAction );
	if( pAction ) {
		if( pAction->shortcut() != cut )
			return d->setShortcut( sAction, cut );
		return true;
	}
	return false;
}

const TQString& KAccel::configGroup() const
	{ return d->configGroup(); }
// for tdegames/ksirtet
void KAccel::setConfigGroup( const TQString& s )
	{ d->setConfigGroup( s ); }

bool KAccel::readSettings( KConfigBase* pConfig )
{
	d->readSettings( pConfig );
	return true;
}

bool KAccel::writeSettings( KConfigBase* pConfig ) const
	{ d->writeSettings( pConfig ); return true; }

void KAccel::emitKeycodeChanged()
{
	kdDebug(125) << "KAccel::emitKeycodeChanged()" << endl;
	emit keycodeChanged();
}

#ifndef KDE_NO_COMPAT
//------------------------------------------------------------
// Obsolete methods -- for backward compatibility
//------------------------------------------------------------

bool KAccel::insertItem( const TQString& sLabel, const TQString& sAction,
		const char* cutsDef,
		int /*nIDMenu*/, TQPopupMenu *, bool bConfigurable )
{
	KShortcut cut( cutsDef );
	bool b = d->insert( sAction, sLabel, TQString::null,
		cut, cut,
		0, 0,
		bConfigurable ) != 0;
	return b;
}

bool KAccel::insertItem( const TQString& sLabel, const TQString& sAction,
		int key,
		int /*nIDMenu*/, TQPopupMenu*, bool bConfigurable )
{
	KShortcut cut;
	cut.init( TQKeySequence(key) );
	KAccelAction* pAction = d->insert( sAction, sLabel, TQString::null,
		cut, cut,
		0, 0,
		bConfigurable );
	return pAction != 0;
}

// Used in tdeutils/kjots
bool KAccel::insertStdItem( KStdAccel::StdAccel id, const TQString& sLabel )
{
	KAccelAction* pAction = d->insert( KStdAccel::name( id ), sLabel, TQString::null,
		KStdAccel::shortcutDefault3( id ), KStdAccel::shortcutDefault4( id ),
		0, 0 );
	if( pAction )
		pAction->setShortcut( KStdAccel::shortcut( id ) );

	return true;
}

bool KAccel::connectItem( const TQString& sAction, const TQObject* pObjSlot, const char* psMethodSlot, bool bActivate )
{
	kdDebug(125) << "KAccel::connectItem( " << sAction << ", " << pObjSlot << ", " << psMethodSlot << " )" << endl;
	if( bActivate == false )
		d->setActionEnabled( sAction, false );
	bool b = setSlot( sAction, pObjSlot, psMethodSlot );
	if( bActivate == true )
		d->setActionEnabled( sAction, true );
	return b;
}

bool KAccel::removeItem( const TQString& sAction )
	{ return d->removeAction( sAction ); }

bool KAccel::setItemEnabled( const TQString& sAction, bool bEnable )
	{ return setEnabled( sAction, bEnable ); }

void KAccel::changeMenuAccel( TQPopupMenu *menu, int id, const TQString& action )
{
	KAccelAction* pAction = actions().actionPtr( action );
	TQString s = menu->text( id );
	if( !pAction || s.isEmpty() )
		return;

	int i = s.find( '\t' );

	TQString k = pAction->shortcut().seq(0).toString();
	if( k.isEmpty() )
		return;

	if ( i >= 0 )
		s.replace( i+1, s.length()-i, k );
	else {
		s += '\t';
		s += k;
	}

	TQPixmap *pp = menu->pixmap(id);
	if( pp && !pp->isNull() )
		menu->changeItem( *pp, s, id );
	else
		menu->changeItem( s, id );
}

void KAccel::changeMenuAccel( TQPopupMenu *menu, int id, KStdAccel::StdAccel accel )
{
	changeMenuAccel( menu, id, KStdAccel::name( accel ) );
}

int KAccel::stringToKey( const TQString& sKey )
{
	return KKey( sKey ).keyCodeQt();
}

int KAccel::currentKey( const TQString& sAction ) const
{
	KAccelAction* pAction = d->actionPtr( sAction );
	if( pAction )
		return pAction->shortcut().keyCodeQt();
	return 0;
}

TQString KAccel::findKey( int key ) const
{
	KAccelAction* pAction = d->actionPtr( KKey(key) );
	if( pAction )
		return pAction->name();
	else
		return TQString::null;
}
#endif // !KDE_NO_COMPAT

void KAccel::virtual_hook( int, void* )
{ /*BASE::virtual_hook( id, data );*/ }

#include "kaccel.moc"
#include "kaccelprivate.moc"
