simplifying the inputcontext stuff

This commit is contained in:
Uwe Rathmann 2018-04-02 17:01:04 +02:00
parent d947fb3999
commit 0a0acb5e27
5 changed files with 94 additions and 101 deletions

View File

@ -10,9 +10,7 @@
#include <QTextCharFormat>
#include <QWindow>
#include <unordered_map>
static QString qskKeyString( int code )
static inline QString qskKeyString( int code )
{
// Special case entry codes here, else default to the symbol
switch ( code )
@ -38,6 +36,15 @@ static QString qskKeyString( int code )
return QChar( code );
}
static inline void qskSendKeyEvents( QObject* receiver, int key )
{
QKeyEvent keyPress( QEvent::KeyPress, key, Qt::NoModifier );
QCoreApplication::sendEvent( receiver, &keyPress );
QKeyEvent keyRelease( QEvent::KeyRelease, key, Qt::NoModifier );
QCoreApplication::sendEvent( receiver, &keyRelease );
}
class QskInputCompositionModel::PrivateData
{
public:
@ -55,14 +62,6 @@ public:
int groupIndex;
};
static inline void sendCompositionEvent( QInputMethodEvent* e )
{
if( auto focusObject = QGuiApplication::focusObject() )
{
QCoreApplication::sendEvent( focusObject, e );
}
}
QskInputCompositionModel::QskInputCompositionModel():
m_data( new PrivateData )
{
@ -148,20 +147,12 @@ void QskInputCompositionModel::composeKey( Qt::Key key )
{
commit( qskKeyString( key ) );
}
#if 0
else
{
auto focusWindow = QGuiApplication::focusWindow();
if( focusWindow )
{
QKeyEvent keyPress( QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier );
QKeyEvent keyRelease( QEvent::KeyRelease, Qt::Key_Return, Qt::NoModifier ); QCoreApplication::sendEvent( focusWindow, &keyPress );
QCoreApplication::sendEvent( focusWindow, &keyRelease );
if( auto focusWindow = QGuiApplication::focusWindow() )
qskSendKeyEvents( focusWindow, Qt::Key_Return );
}
}
#endif
return;
}
@ -218,8 +209,9 @@ void QskInputCompositionModel::composeKey( Qt::Key key )
}
m_data->preeditAttributes.first().length = displayPreedit.length();
QInputMethodEvent e( displayPreedit, m_data->preeditAttributes );
sendCompositionEvent( &e );
QInputMethodEvent event( displayPreedit, m_data->preeditAttributes );
sendCompositionEvent( &event );
}
void QskInputCompositionModel::clearPreedit()
@ -250,9 +242,10 @@ QString QskInputCompositionModel::polishPreedit( const QString& preedit )
void QskInputCompositionModel::commit( const QString& text )
{
QInputMethodEvent e( QString(), { } );
e.setCommitString( text );
sendCompositionEvent( &e );
QInputMethodEvent event( QString(), { } );
event.setCommitString( text );
sendCompositionEvent( &event );
m_data->preedit.clear();
polishPreedit( m_data->preedit );
}
@ -264,27 +257,24 @@ void QskInputCompositionModel::commitCandidate( int index )
void QskInputCompositionModel::backspace()
{
if ( !m_data->inputItem )
if ( m_data->inputItem == nullptr )
return;
if ( !m_data->preedit.isEmpty() )
{
m_data->preedit.chop( 1 );
const QString displayText = polishPreedit( m_data->preedit );
m_data->preeditAttributes.first().length = displayText.length();
QInputMethodEvent event( displayText, m_data->preeditAttributes );
sendCompositionEvent( &event );
}
else
{
// Backspace one character only if preedit was inactive
QKeyEvent keyPress( QEvent::KeyPress, Qt::Key_Backspace, Qt::NoModifier );
QKeyEvent keyRelease( QEvent::KeyRelease, Qt::Key_Backspace, Qt::NoModifier );
QCoreApplication::sendEvent( m_data->inputItem, &keyPress );
QCoreApplication::sendEvent( m_data->inputItem, &keyRelease );
return;
qskSendKeyEvents( m_data->inputItem, Qt::Key_Backspace );
}
const QString displayText = polishPreedit( m_data->preedit );
m_data->preeditAttributes.first().length = displayText.length();
QInputMethodEvent e( displayText, m_data->preeditAttributes );
sendCompositionEvent( &e );
}
void QskInputCompositionModel::moveCursor( Qt::Key key )
@ -339,8 +329,9 @@ void QskInputCompositionModel::setGroupIndex( int groupIndex )
m_data->groupIndex = groupIndex;
const QString displayText = polishPreedit( m_data->preedit );
m_data->preeditAttributes.first().length = displayText.length();
QInputMethodEvent e( displayText, m_data->preeditAttributes );
sendCompositionEvent( &e );
QInputMethodEvent event( displayText, m_data->preeditAttributes );
sendCompositionEvent( &event );
}
QVector< Qt::Key > QskInputCompositionModel::groups() const

View File

@ -23,7 +23,7 @@ public:
QPointer< QQuickItem > inputItem;
QPointer< QskVirtualKeyboard > inputPanel;
QskInputCompositionModel* compositionModel;
QHash< QLocale, QskInputCompositionModel* > inputModels;
QHash< QLocale, QskInputCompositionModel* > compositionModels;
};
QskInputContext::QskInputContext() :
@ -31,17 +31,17 @@ QskInputContext::QskInputContext() :
{
m_data->compositionModel = new QskInputCompositionModel();
connect( m_data->compositionModel, &QskInputCompositionModel::candidatesChanged,
this, &QskInputContext::handleCandidatesChanged );
connect( qskSetup, &QskSetup::inputPanelChanged,
this, &QskInputContext::setInputPanel );
#if 1
setCompositionModel( QLocale::Chinese, new QskPinyinCompositionModel() );
#endif
setInputPanel( qskSetup->inputPanel() );
QskPinyinCompositionModel* pinyinModel = new QskPinyinCompositionModel;
// see also: QskVirtualKeyboard::registerCompositionModelForLocale()
inputMethodRegistered( QLocale::Chinese, pinyinModel );
// We could connect candidatesChanged() here, but we don't emit
// the signal in the normal composition model anyhow
}
QskInputContext::~QskInputContext()
@ -49,7 +49,7 @@ QskInputContext::~QskInputContext()
if ( m_data->inputPanel )
delete m_data->inputPanel;
qDeleteAll( m_data->inputModels );
qDeleteAll( m_data->compositionModels );
}
bool QskInputContext::isValid() const
@ -249,18 +249,44 @@ void QskInputContext::setFocusObject( QObject* focusObject )
update( Qt::InputMethodQuery( Qt::ImQueryAll & ~Qt::ImEnabled ) );
}
void QskInputContext::inputMethodRegistered(
void QskInputContext::setCompositionModel(
const QLocale& locale, QskInputCompositionModel* model )
{
if ( auto oldModel = m_data->inputModels.value( locale, nullptr ) )
oldModel->deleteLater();
auto& models = m_data->compositionModels;
m_data->inputModels.insert( locale, model );
if ( model )
{
const auto it = models.find( locale );
if ( it != models.end() )
{
if ( it.value() == model )
return;
delete it.value();
*it = model;
}
else
{
models.insert( locale, model );
}
connect( model, &QskInputCompositionModel::candidatesChanged,
this, &QskInputContext::handleCandidatesChanged );
}
else
{
const auto it = models.find( locale );
if ( it != models.end() )
{
delete it.value();
models.erase( it );
}
}
}
QskInputCompositionModel* QskInputContext::compositionModel() const
{
return m_data->inputModels.value( locale(), m_data->compositionModel );
return m_data->compositionModels.value( locale(), m_data->compositionModel );
}
void QskInputContext::invokeAction( QInputMethod::Action action, int cursorPosition )
@ -282,6 +308,7 @@ void QskInputContext::invokeAction( QInputMethod::Action action, int cursorPosit
case QskVirtualKeyboard::SelectCandidate:
{
model->commitCandidate( cursorPosition );
if ( m_data->inputPanel )
m_data->inputPanel->setPreeditCandidates( QVector< QString >() );
@ -290,19 +317,19 @@ void QskInputContext::invokeAction( QInputMethod::Action action, int cursorPosit
}
}
void QskInputContext::emitAnimatingChanged()
{
QPlatformInputContext::emitAnimatingChanged();
}
void QskInputContext::handleCandidatesChanged()
{
const auto model = compositionModel();
if ( model == nullptr || m_data->inputPanel == nullptr )
return;
QVector< QString > candidates( model->candidateCount() );
const auto count = model->candidateCount();
for( int i = 0; i < candidates.length(); ++i )
candidates[i] = model->candidate( i );
QVector< QString > candidates;
candidates.reserve( count );
for( int i = 0; i < count; i++ )
candidates += model->candidate( i );
m_data->inputPanel->setPreeditCandidates( candidates );
}

View File

@ -38,11 +38,11 @@ public:
virtual QLocale locale() const override;
void setCompositionModel( const QLocale&, QskInputCompositionModel* );
private Q_SLOTS:
void emitAnimatingChanged();
void handleCandidatesChanged();
void setInputPanel( QskVirtualKeyboard* );
void inputMethodRegistered( const QLocale&, QskInputCompositionModel* );
private:
QskInputCompositionModel* compositionModel() const;

View File

@ -174,7 +174,6 @@ QSK_SUBCONTROL( QskVirtualKeyboard, Panel )
QSK_SUBCONTROL( QskVirtualKeyboardButton, Panel )
QSK_SUBCONTROL( QskVirtualKeyboardButton, Text )
QSK_SUBCONTROL( QskVirtualKeyboardButton, TextCancelButton )
QskVirtualKeyboardButton::QskVirtualKeyboardButton(
int keyIndex, QskVirtualKeyboard* inputPanel, QQuickItem* parent ) :
@ -214,7 +213,7 @@ QskAspect::Subcontrol QskVirtualKeyboardButton::effectiveSubcontrol(
return QskVirtualKeyboardButton::Panel;
if( subControl == QskPushButton::Text )
return isCancelButton() ? TextCancelButton : Text;
return QskVirtualKeyboardButton::Text;
return subControl;
}
@ -239,13 +238,6 @@ void QskVirtualKeyboardButton::updateText()
}
}
bool QskVirtualKeyboardButton::isCancelButton() const
{
auto keyData = m_inputPanel->keyDataAt( m_keyIndex );
bool isCancel = ( keyData.key == 0x2716 );
return isCancel;
}
class QskVirtualKeyboard::PrivateData
{
public:
@ -567,12 +559,6 @@ void QskVirtualKeyboard::setCandidateOffset( int candidateOffset )
}
}
void QskVirtualKeyboard::registerCompositionModelForLocale(
const QLocale& locale, QskInputCompositionModel* model )
{
Q_EMIT inputMethodRegistered( locale, model );
}
void QskVirtualKeyboard::geometryChanged(
const QRectF& newGeometry, const QRectF& oldGeometry )
{
@ -685,11 +671,6 @@ void QskVirtualKeyboard::handleKey( int keyIndex )
: SpecialCharacterMode ) );
return;
// This is (one of) the cancel symbol, not Qt::Key_Cancel:
case Qt::Key( 10006 ):
Q_EMIT cancelPressed();
return;
default:
break;
}

View File

@ -44,11 +44,13 @@ class QSK_EXPORT QskVirtualKeyboardButton : public QskPushButton
using Inherited = QskPushButton;
public:
QSK_SUBCONTROLS( Panel, Text, TextCancelButton )
QSK_SUBCONTROLS( Panel, Text )
QskVirtualKeyboardButton( int keyIndex, QskVirtualKeyboard* inputPanel, QQuickItem* parent = nullptr );
QskVirtualKeyboardButton( int keyIndex,
QskVirtualKeyboard*, QQuickItem* parent = nullptr );
virtual QskAspect::Subcontrol effectiveSubcontrol( QskAspect::Subcontrol subControl ) const override;
virtual QskAspect::Subcontrol effectiveSubcontrol(
QskAspect::Subcontrol ) const override;
int keyIndex() const;
@ -56,8 +58,6 @@ public Q_SLOTS:
void updateText();
private:
bool isCancelButton() const;
const int m_keyIndex;
QskVirtualKeyboard* m_inputPanel;
};
@ -112,11 +112,12 @@ public:
QskVirtualKeyboard( QQuickItem* parent = nullptr );
virtual ~QskVirtualKeyboard() override;
virtual QskAspect::Subcontrol effectiveSubcontrol( QskAspect::Subcontrol subControl ) const override;
virtual QskAspect::Subcontrol effectiveSubcontrol(
QskAspect::Subcontrol ) const override;
void updateLocale( const QLocale& locale );
void updateLocale( const QLocale& );
void setMode( QskVirtualKeyboard::Mode index );
void setMode( QskVirtualKeyboard::Mode );
Mode mode() const;
const KeyDataSet& keyData( QskVirtualKeyboard::Mode = CurrentMode ) const;
@ -124,9 +125,6 @@ public:
QString textForKey( int ) const;
QString displayLanguageName() const;
// takes ownership:
void registerCompositionModelForLocale( const QLocale&, QskInputCompositionModel* );
void handleKey( int keyIndex );
KeyData& keyDataAt( int ) const;
QString currentTextForKeyIndex( int keyIndex ) const;
@ -156,11 +154,7 @@ private:
Q_SIGNALS:
void keyboardRectChanged();
void displayLanguageNameChanged();
void inputMethodRegistered( const QLocale& locale, QskInputCompositionModel* model );
void inputMethodEventReceived( QInputMethodEvent* inputMethodEvent );
void keyEventReceived( QKeyEvent* keyEvent );
void modeChanged( QskVirtualKeyboard::Mode mode );
void cancelPressed();
void modeChanged( QskVirtualKeyboard::Mode );
private:
class PrivateData;