/**************************************************************************** ** $Id$ ** ** Implementation of TQMultiInputContext class ** ** Copyright (C) 2004 immodule for TQt Project. All rights reserved. ** ** This file is written to contribute to Trolltech AS under their own ** licence. You may use this file under your TQt license. Following ** description is copied from their original file headers. Contact ** immodule-qt@freedesktop.org if any conditions of this licensing are ** not clear to you. ** ** ** This file is part of the input method module of the TQt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.TQPL included in the packaging of this file. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** Licensees holding valid TQt Enterprise Edition or TQt Professional Edition ** licenses may use this file in accordance with the TQt Commercial License ** Agreement provided with the Software. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for ** information about TQt Commercial License Agreements. ** See http://www.trolltech.com/qpl/ for TQPL licensing information. ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #ifndef TQT_NO_IM #include "qmultiinputcontext.h" #include #include #include #ifndef TQT_NO_IM_EXTENSIONS #include #endif #include #define TQT_NO_IM_QMULTIINPUTCONTEXT_IMINDEX TQMultiInputContext::TQMultiInputContext() : TQInputContext(), _slave( 0 ), imIndex( 0 ), cachedFocus( FALSE ), cachedFocusWidget( 0 ), cachedHolderWidget( 0 ), beIndirectlyConnected( FALSE ), popup( NULL ), currentIMKey( TQString::null ) { keyDict.setAutoDelete( true ); keyDict.clear(); if ( getenv( "TQT_IM_MODULE" ) ) { currentIMKey = getenv( "TQT_IM_MODULE" ); } else { #ifndef TQT_NO_IM_EXTENSIONS TQSettings settings; currentIMKey = settings.readEntry( "/qt/DefaultInputMethod", "xim" ); #else currentIMKey = "xim"; #endif } } TQMultiInputContext::~TQMultiInputContext() { keyDict.clear(); } TQString TQMultiInputContext::identifierName() { return ( slave() ) ? slave()->identifierName() : ""; } TQString TQMultiInputContext::language() { return ( slave() ) ? slave()->language() : ""; } #if defined(Q_WS_X11) bool TQMultiInputContext::x11FilterEvent( TQWidget *keywidget, XEvent *event ) { return ( slave() ) ? slave()->x11FilterEvent( keywidget, event ) : FALSE; } #endif // Q_WS_X11 bool TQMultiInputContext::filterEvent( const TQEvent *event ) { #if !defined(TQT_NO_IM_QMULTIINPUTCONTEXT_IMINDEX) if ( event->type() == TQEvent::KeyPress ) { TQKeyEvent *keyevent = (TQKeyEvent *)event; // filter selection key // Control+Alt+Key_Down: change to next input method // Control+Alt+Key_Up: change to previous input method if ( ( keyevent->state() & TQt::ControlButton ) && ( keyevent->state() & TQt::AltButton ) ) { if ( keyevent->key() == TQt::Key_Up ) { changeInputMethod( --imIndex ); return TRUE; } else if ( keyevent->key() == TQt::Key_Down ) { changeInputMethod( ++imIndex ); return TRUE; } } } #endif return ( slave() ) ? slave()->filterEvent( event ) : FALSE; } void TQMultiInputContext::reset() { if ( slave() ) slave()->reset(); } void TQMultiInputContext::setFocus() { cachedFocus = TRUE; if ( slave() ) slave()->setFocus(); } void TQMultiInputContext::unsetFocus() { cachedFocus = FALSE; if ( slave() ) slave()->unsetFocus(); } void TQMultiInputContext::setMicroFocus( int x, int y, int w, int h, TQFont *f ) { if ( slave() ) slave()->setMicroFocus( x, y, w, h, f ); } void TQMultiInputContext::mouseHandler( int x, TQEvent::Type type, TQt::ButtonState button, TQt::ButtonState state ) { if ( slave() ) slave()->mouseHandler( x, type, button, state ); } TQFont TQMultiInputContext::font() const { return ( slave() ) ? slave()->font() : TQInputContext::font(); } void TQMultiInputContext::destroyInputContext() { if ( _slave ) { // _slave->reset() may not properly work in the case, so we // manually resets the composing state of text widget if ( _slave->focusWidget() ) { TQIMEvent *terminator = new TQIMEvent( TQEvent::IMEnd, TQString::null, -1 ); emit imEventGenerated( _slave->focusWidget(), terminator ); } _slave->deleteLater(); _slave = 0; } } /*! This function is a placeholder for future experiment or extension such as commit string snooping. set beIndirectlyConnected = TRUE to activate this virtual function. */ void TQMultiInputContext::postIMEvent( TQObject *receiver, TQIMEvent *event ) { emit imEventGenerated( receiver, event ); } #if defined(Q_WS_X11) TQWidget *TQMultiInputContext::focusWidget() const { return ( slave() ) ? slave()->focusWidget() : 0; } TQWidget *TQMultiInputContext::holderWidget() const { return ( slave() ) ? slave()->holderWidget() : 0; } void TQMultiInputContext::setFocusWidget( TQWidget *w ) { cachedFocusWidget = w; if ( slave() ) slave()->setFocusWidget( w ); } void TQMultiInputContext::setHolderWidget( TQWidget *w ) { cachedHolderWidget = w; if ( slave() ) slave()->setHolderWidget( w ); } void TQMultiInputContext::releaseComposingWidget( TQWidget *w ) { if ( slave() ) slave()->releaseComposingWidget( w ); } #endif bool TQMultiInputContext::isComposing() const { return ( slave() ) ? slave()->isComposing() : FALSE; } bool TQMultiInputContext::isPreeditRelocationEnabled() { return ( slave() ) ? slave()->isPreeditRelocationEnabled() : FALSE; } TQInputContext *TQMultiInputContext::slave() { if ( ! _slave ) { #if !defined(TQT_NO_IM_QMULTIINPUTCONTEXT_IMINDEX) changeInputMethod( imIndex ); #else changeInputMethod( currentIMKey ); #endif } return _slave; } const TQInputContext *TQMultiInputContext::slave() const { return _slave; } void TQMultiInputContext::changeInputMethod( int newIndex ) { #if !defined(TQT_NO_IM_QMULTIINPUTCONTEXT_IMINDEX) TQStringList keys = TQInputContextFactory::keys(); if ( keys.size() == 0 ) return; if ( newIndex >= (int)keys.size() ) { imIndex = 0; } else if ( newIndex < 0 ) { imIndex = keys.size() - 1; } else { imIndex = newIndex; } changeInputMethod( keys[imIndex] ); #endif } void TQMultiInputContext::changeInputMethod( TQString key ) { TQStringList keys = TQInputContextFactory::keys(); if ( keys.size() == 0 ) return; if ( key.isEmpty() ) key = keys[0]; if ( _slave ) { _slave->reset(); delete _slave; } _slave = TQInputContextFactory::create( key, cachedHolderWidget ); if ( _slave ) { insertChild( _slave ); const char *method; if ( beIndirectlyConnected ) { method = SLOT(imEventReceived(TQObject *,TQIMEvent *)); } else { method = SIGNAL(imEventGenerated(TQObject *,TQIMEvent *)); } connect( _slave, SIGNAL(imEventGenerated(TQObject *,TQIMEvent *)), this, method ); connect( _slave, SIGNAL(deletionRequested()), this, SLOT(destroyInputContext()) ); if ( cachedFocus ) { _slave->setFocus(); _slave->setFocusWidget( cachedFocusWidget ); } currentIMKey = key; //tqDebug( "TQMultiInputContext::changeInputMethod(): index=%d, slave=%s", // imIndex, (const char *)_slave->identifierName() ); } } TQPtrList *TQMultiInputContext::menus() { TQInputContextMenu *imSelMenu = new TQInputContextMenu; imSelMenu->title = tr( "Select Input &Method" ); imSelMenu->popup = createImSelPopup(); TQPtrList *result = new TQPtrList; result->append( imSelMenu ); TQPtrList *slaveMenus = ( slave() ) ? slave()->menus() : 0; if ( slaveMenus ) { for ( TQPtrList::Iterator it = slaveMenus->begin(); it != slaveMenus->end(); ++it ) { TQInputContextMenu *slaveMenu = *it; result->append( slaveMenu ); } delete slaveMenus; } return result; } TQPopupMenu *TQMultiInputContext::createImSelPopup() { if ( popup ) delete popup; popup = new TQPopupMenu(); keyDict.clear(); TQStringList keys = TQInputContextFactory::keys(); for ( uint i=0; i < keys.size(); i++ ) { TQString idName = keys[i]; bool isIMSwitcher = idName.startsWith( "imsw-" ); if ( ! isIMSwitcher ) { TQString dispName = TQInputContextFactory::displayName( idName ); if ( dispName.isEmpty() ) dispName = idName; int id = popup->insertItem( dispName ); keyDict.insert( (long)id, new TQString( idName ) ); if ( idName == currentIMKey ) popup->setItemChecked( id, true ); TQString descriptionStr = TQInputContextFactory::description( idName ); if ( ! descriptionStr.isEmpty() ) popup->setWhatsThis( id, descriptionStr ); } } TQObject::connect( popup, SIGNAL(activated(int)), this, SLOT(changeInputMethodWithMenuId(int)) ); return popup; } void TQMultiInputContext::changeInputMethodWithMenuId( int menuid ) { TQString *key = keyDict.find( (long)menuid ); changeInputMethod( (*key) ); } #endif