diff --git a/inputcontext/QskInputCompositionModel.cpp b/inputcontext/QskInputCompositionModel.cpp index 520e139c..96ddd22e 100644 --- a/inputcontext/QskInputCompositionModel.cpp +++ b/inputcontext/QskInputCompositionModel.cpp @@ -10,9 +10,7 @@ #include #include -#include - -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 diff --git a/inputcontext/QskInputContext.cpp b/inputcontext/QskInputContext.cpp index 13e0d9c9..82e4cf79 100644 --- a/inputcontext/QskInputContext.cpp +++ b/inputcontext/QskInputContext.cpp @@ -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 ); } diff --git a/inputcontext/QskInputContext.h b/inputcontext/QskInputContext.h index 17126a23..b5b6fcb1 100644 --- a/inputcontext/QskInputContext.h +++ b/inputcontext/QskInputContext.h @@ -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; diff --git a/src/controls/QskVirtualKeyboard.cpp b/src/controls/QskVirtualKeyboard.cpp index 288bcfc6..e5b4d6ee 100644 --- a/src/controls/QskVirtualKeyboard.cpp +++ b/src/controls/QskVirtualKeyboard.cpp @@ -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; } diff --git a/src/controls/QskVirtualKeyboard.h b/src/controls/QskVirtualKeyboard.h index afc2b98c..0061dd86 100644 --- a/src/controls/QskVirtualKeyboard.h +++ b/src/controls/QskVirtualKeyboard.h @@ -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; @@ -136,7 +134,7 @@ public: public Q_SLOTS: void setPreeditGroups( const QVector< Qt::Key >& ); - void setPreeditCandidates(const QVector< QString >& ); + void setPreeditCandidates( const QVector< QString >& ); protected: virtual void geometryChanged( const QRectF&, const QRectF& ) override; @@ -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;