You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
qt3/plugins/src/inputmethods/simple/qsimpleinputcontext.cpp

286 lines
7.6 KiB

/****************************************************************************
** $Id$
**
** Implementation of QSimpleInputContext class
**
** Copyright (C) 2004 immodule for Qt Project. All rights reserved.
**
** This file is written to contribute to Trolltech AS under their own
** licence. You may use this file under your Qt 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 Qt 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.QPL 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 Qt Enterprise Edition or Qt Professional Edition
** licenses may use this file in accordance with the Qt 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 Qt Commercial License Agreements.
** See http://www.trolltech.com/qpl/ for QPL 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.
**
**********************************************************************/
#include "qsimpleinputcontext.h"
#include <qnamespace.h>
#include <qevent.h>
#include <qglobal.h>
#include <algorithm>
static const int ignoreKeys[] = {
Qt::Key_Shift,
Qt::Key_Control,
Qt::Key_Meta,
Qt::Key_Alt,
Qt::Key_CapsLock,
Qt::Key_Super_L,
Qt::Key_Super_R,
Qt::Key_Hyper_L,
Qt::Key_Hyper_R,
Qt::Key_Mode_switch
};
static const int composingKeys[] = {
Qt::Key_Multi_key,
Qt::Key_Dead_Grave,
Qt::Key_Dead_Acute,
Qt::Key_Dead_Circumflex,
Qt::Key_Dead_Tilde,
Qt::Key_Dead_Macron,
Qt::Key_Dead_Breve,
Qt::Key_Dead_Abovedot,
Qt::Key_Dead_Diaeresis,
Qt::Key_Dead_Abovering,
Qt::Key_Dead_Doubleacute,
Qt::Key_Dead_Caron,
Qt::Key_Dead_Cedilla,
Qt::Key_Dead_Ogonek,
Qt::Key_Dead_Iota,
Qt::Key_Dead_Voiced_Sound,
Qt::Key_Dead_Semivoiced_Sound,
Qt::Key_Dead_Belowdot,
Qt::Key_Dead_Hook,
Qt::Key_Dead_Horn
};
class Cmp
{
public:
bool operator () (const QComposeTableElement &lhs, const QComposeTableElement &rhs) const {
for ( size_t i=0; i < QT_KEYSEQUENCE_MAX_LEN; i++ ) {
if ( lhs.keys[i] < rhs.keys[i] ) return TRUE;
else
if ( lhs.keys[i] > rhs.keys[i] ) return FALSE;
}
return FALSE;
}
bool operator () (const QComposeTableElement &lhs, const uint rhs[QT_KEYSEQUENCE_MAX_LEN]) const {
for ( size_t i=0; i < QT_KEYSEQUENCE_MAX_LEN; i++ ) {
if ( lhs.keys[i] < rhs[i] ) return TRUE;
else
if ( lhs.keys[i] > rhs[i] ) return FALSE;
}
return FALSE;
}
};
QSimpleInputContext::QSimpleInputContext()
: QInputContext()
{
clearComposeBuffer();
}
QSimpleInputContext::~QSimpleInputContext()
{
clearComposeBuffer();
}
bool QSimpleInputContext::filterEvent( const QEvent *event )
{
if ( event->type() != QEvent::KeyPress )
return FALSE;
QKeyEvent *keyevent = (QKeyEvent *)event;
int keyval = keyevent->key();
int val = 0;
if ( isIgnoreKeys( keyval ) )
return FALSE;
if ( isComposingKeys( keyval ) ) {
// If composing keys are pressed, use keyval directly
val = UNITIZE( keyval );
} else {
QString text = keyevent->text();
if ( text.isEmpty() )
return FALSE;
// If not composing keys are pressed, use the character's unicode value
// NOTE : The contents of QKeyEvent::text() is restricted to
// only one character. See description of
// QInputContext::filterEvent() about key compression.
val = text[0].unicode();
// qDebug( "str = %s", (const char*)keyevent->text().local8Bit() );
}
// Store value
int nCompose = 0;
while ( composeBuffer[nCompose] != 0 && nCompose < QT_KEYSEQUENCE_MAX_LEN )
nCompose++;
if ( nCompose == QT_KEYSEQUENCE_MAX_LEN ) {
clearComposeBuffer();
nCompose = 0;
}
composeBuffer[nCompose] = val;
// check sequence
if( checkComposeTable( composeBuffer, &defaultComposeTable ) )
return TRUE;
return FALSE;
}
void QSimpleInputContext::setFocus()
{
//qDebug( "QSimpleInputContext: %p->setFocus(), focusWidget()=%p",
//this, focusWidget() );
}
void QSimpleInputContext::unsetFocus()
{
//qDebug( "QSimpleInputContext: %p->unsetFocus(), focusWidget()=%p",
//this, focusWidget() );
reset();
}
void QSimpleInputContext::setMicroFocus( int x, int y, int w, int h, QFont *f )
{
}
void QSimpleInputContext::mouseHandler( int x, QEvent::Type type,
Qt::ButtonState button,
Qt::ButtonState state )
{
switch ( type ) {
case QEvent::MouseButtonPress:
case QEvent::MouseButtonRelease:
case QEvent::MouseButtonDblClick:
case QEvent::MouseMove:
// qDebug( "QSimpleInputContext::mouseHandler: "
// "x=%d, type=%d, button=%d, state=%d", x, type, button, state );
break;
default:
break;
}
}
void QSimpleInputContext::reset()
{
clearComposeBuffer();
QInputContext::reset();
}
QString QSimpleInputContext::identifierName()
{
return "simple";
}
QString QSimpleInputContext::language()
{
return ""; // FIXME
}
bool QSimpleInputContext::isIgnoreKeys( int keyval )
{
for ( uint i = 0; i < (sizeof(ignoreKeys)/sizeof(ignoreKeys[0])); i++ )
if ( keyval == ignoreKeys[i] )
return TRUE;
return FALSE;
}
bool QSimpleInputContext::isComposingKeys( int keyval )
{
for ( uint i = 0; i < (sizeof(composingKeys)/sizeof(composingKeys[0])); i++ )
if ( keyval == composingKeys[i] )
return TRUE;
return FALSE;
}
bool QSimpleInputContext::checkComposeTable( uint* composeBuffer, const QComposeTable *composeTable )
{
const QComposeTableElement *p = std::lower_bound( composeTable->data,
composeTable->data + composeTable->size,
composeBuffer,
Cmp() );
// no entries were found
if ( p == composeTable->data + composeTable->size ) {
// qDebug( "no match" );
clearComposeBuffer();
return FALSE;
}
// check if compose buffer is matched
for ( int i=0; i < QT_KEYSEQUENCE_MAX_LEN; i++ ) {
// check if partial match
if ( composeBuffer[i] == 0 && p->keys[i] ) {
// qDebug("partial match");
return TRUE;
}
if ( composeBuffer[i] != p->keys[i] ) {
// qDebug("different entry");
clearComposeBuffer();
return i!=0;
}
}
// qDebug("match exactly");
// match exactly
commitChar( p->value );
clearComposeBuffer();
return TRUE;
}
void QSimpleInputContext::commitChar( uint c )
{
sendIMEvent( QEvent::IMStart );
sendIMEvent( QEvent::IMEnd, QString(QChar(c)) );
}
void QSimpleInputContext::clearComposeBuffer(void)
{
for ( uint i=0; i < (sizeof(composeBuffer)/sizeof(int)); i++ )
composeBuffer[i] = 0;
}