key composition moved to QskInputContext
This commit is contained in:
parent
4ce1780f90
commit
dfe2b875fd
@ -10,8 +10,8 @@ public:
|
||||
QVector< QString > candidates;
|
||||
};
|
||||
|
||||
QskHunspellCompositionModel::QskHunspellCompositionModel( QskInputContext* context ):
|
||||
Inherited( Words, context ),
|
||||
QskHunspellCompositionModel::QskHunspellCompositionModel( QObject* object ):
|
||||
Inherited( Words, object ),
|
||||
m_data( new PrivateData() )
|
||||
{
|
||||
#if 1
|
||||
|
@ -14,7 +14,7 @@ class QskHunspellCompositionModel : public QskInputCompositionModel
|
||||
using Inherited = QskInputCompositionModel;
|
||||
|
||||
public:
|
||||
QskHunspellCompositionModel( QskInputContext* context );
|
||||
QskHunspellCompositionModel( QObject* );
|
||||
virtual ~QskHunspellCompositionModel() override;
|
||||
|
||||
virtual int candidateCount() const override;
|
||||
|
@ -4,13 +4,10 @@
|
||||
*****************************************************************************/
|
||||
|
||||
#include "QskInputCompositionModel.h"
|
||||
#include "QskInputContext.h"
|
||||
|
||||
#include <QInputMethodQueryEvent>
|
||||
|
||||
QskInputCompositionModel::QskInputCompositionModel(
|
||||
Attributes attributes, QskInputContext* context ):
|
||||
QObject( context ),
|
||||
Attributes attributes, QObject* parent ):
|
||||
QObject( parent ),
|
||||
m_attributes( attributes )
|
||||
{
|
||||
}
|
||||
@ -19,72 +16,9 @@ QskInputCompositionModel::~QskInputCompositionModel()
|
||||
{
|
||||
}
|
||||
|
||||
QskInputContext* QskInputCompositionModel::context() const
|
||||
QskInputCompositionModel::Attributes QskInputCompositionModel::attributes() const
|
||||
{
|
||||
return qobject_cast< QskInputContext* >( parent() );
|
||||
}
|
||||
|
||||
void QskInputCompositionModel::composeKey( const QString& text, int spaceLeft )
|
||||
{
|
||||
if ( candidateCount() > 0 )
|
||||
{
|
||||
m_preedit += text;
|
||||
|
||||
requestCandidates( m_preedit );
|
||||
context()->sendText( m_preedit, false );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
requestCandidates( m_preedit );
|
||||
|
||||
QString txt;
|
||||
if ( candidateCount() == 0 )
|
||||
{
|
||||
txt = m_preedit.left( spaceLeft );
|
||||
spaceLeft -= txt.length();
|
||||
}
|
||||
else
|
||||
{
|
||||
txt = candidate( 0 );
|
||||
--spaceLeft;
|
||||
}
|
||||
|
||||
context()->sendText( txt, true );
|
||||
m_preedit.clear();
|
||||
resetCandidates();
|
||||
|
||||
if ( spaceLeft )
|
||||
{
|
||||
m_preedit = text;
|
||||
requestCandidates( m_preedit );
|
||||
|
||||
if ( candidateCount() > 0 )
|
||||
{
|
||||
context()->sendText( m_preedit, false );
|
||||
}
|
||||
else
|
||||
{
|
||||
context()->sendText( m_preedit, true );
|
||||
m_preedit.clear();
|
||||
resetCandidates();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QskInputCompositionModel::setPreeditText( const QString& text )
|
||||
{
|
||||
if ( text != m_preedit )
|
||||
{
|
||||
m_preedit = text;
|
||||
requestCandidates( m_preedit );
|
||||
}
|
||||
}
|
||||
|
||||
void QskInputCompositionModel::reset()
|
||||
{
|
||||
m_preedit.clear();
|
||||
resetCandidates();
|
||||
return m_attributes;
|
||||
}
|
||||
|
||||
#include "moc_QskInputCompositionModel.cpp"
|
||||
|
@ -8,8 +8,6 @@
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class QskInputContext;
|
||||
|
||||
class QskInputCompositionModel : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -25,43 +23,22 @@ public:
|
||||
|
||||
virtual ~QskInputCompositionModel();
|
||||
|
||||
void composeKey( const QString& text, int spaceLeft );
|
||||
virtual void requestCandidates( const QString& preedit ) = 0;
|
||||
virtual void resetCandidates() = 0;
|
||||
|
||||
virtual int candidateCount() const = 0;
|
||||
virtual QString candidate( int ) const = 0;
|
||||
|
||||
void reset();
|
||||
|
||||
QString preeditText() const;
|
||||
void setPreeditText( const QString& );
|
||||
|
||||
Attributes attributes() const;
|
||||
|
||||
protected:
|
||||
QskInputCompositionModel( Attributes, QskInputContext* );
|
||||
|
||||
virtual void requestCandidates( const QString& preedit ) = 0;
|
||||
virtual void resetCandidates() = 0;
|
||||
|
||||
QskInputContext* context() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void candidatesChanged();
|
||||
|
||||
protected:
|
||||
QskInputCompositionModel( Attributes, QObject* );
|
||||
|
||||
private:
|
||||
QString m_preedit;
|
||||
const Attributes m_attributes;
|
||||
};
|
||||
|
||||
inline QString QskInputCompositionModel::preeditText() const
|
||||
{
|
||||
return m_preedit;
|
||||
}
|
||||
|
||||
inline QskInputCompositionModel::Attributes
|
||||
QskInputCompositionModel::attributes() const
|
||||
{
|
||||
return m_attributes;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -49,22 +49,6 @@ static inline QString qskKeyString( int keyCode )
|
||||
return QChar( keyCode );
|
||||
}
|
||||
|
||||
static inline bool qskIsControlKey( int keyCode )
|
||||
{
|
||||
switch ( keyCode )
|
||||
{
|
||||
case Qt::Key_Backspace:
|
||||
case Qt::Key_Muhenkan:
|
||||
case Qt::Key_Return:
|
||||
case Qt::Key_Left:
|
||||
case Qt::Key_Right:
|
||||
case Qt::Key_Escape:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void qskSetLocale( QQuickItem* inputPanel, const QLocale& locale )
|
||||
{
|
||||
if ( auto control = qobject_cast< QskControl* >( inputPanel ) )
|
||||
@ -145,6 +129,8 @@ public:
|
||||
|
||||
QHash< uint, QskInputCompositionModel* > compositionModels;
|
||||
|
||||
QString preedit;
|
||||
|
||||
// the input panel is embedded in a window
|
||||
bool ownsInputPanelWindow : 1;
|
||||
};
|
||||
@ -225,7 +211,7 @@ void QskInputContext::update( Qt::InputMethodQueries queries )
|
||||
ImhPreferNumbers = 0x8, // default to number keyboard
|
||||
ImhPreferUppercase = 0x10, // start with shift on
|
||||
ImhPreferLowercase = 0x20, // start with shift off
|
||||
ImhNoPredictiveText = 0x40, // ignored for now
|
||||
ImhNoPredictiveText = 0x40, // not use predictive text
|
||||
|
||||
ImhDate = 0x80, // ignored for now (no date keyboard)
|
||||
ImhTime = 0x100, // ignored for know (no time keyboard)
|
||||
@ -426,6 +412,12 @@ void QskInputContext::showInputPanel()
|
||||
}
|
||||
|
||||
update( Qt::ImQueryAll );
|
||||
|
||||
#if 1
|
||||
if ( auto panel = qobject_cast< QskInputPanel* >( m_data->inputPanel ) )
|
||||
panel->updateInputProxy( m_data->inputItem );
|
||||
#endif
|
||||
|
||||
inputPanel->setVisible( true );
|
||||
|
||||
#if 0
|
||||
@ -482,6 +474,10 @@ void QskInputContext::hideInputPanel()
|
||||
}
|
||||
|
||||
qGuiApp->removeEventFilter( this );
|
||||
|
||||
m_data->preedit.clear();
|
||||
if ( auto model = compositionModel() )
|
||||
model->resetCandidates();
|
||||
}
|
||||
|
||||
bool QskInputContext::isInputPanelVisible() const
|
||||
@ -612,7 +608,8 @@ void QskInputContext::invokeAction( QInputMethod::Action action, int value )
|
||||
|
||||
sendText( text, true );
|
||||
|
||||
model->reset();
|
||||
m_data->preedit.clear();
|
||||
model->resetCandidates();
|
||||
}
|
||||
|
||||
break;
|
||||
@ -664,6 +661,7 @@ void QskInputContext::processKey( int key )
|
||||
if ( !( hints & Qt::ImhHiddenText ) )
|
||||
model = compositionModel();
|
||||
|
||||
auto& preedit = m_data->preedit;
|
||||
/*
|
||||
First we have to handle the control keys
|
||||
*/
|
||||
@ -674,13 +672,12 @@ void QskInputContext::processKey( int key )
|
||||
{
|
||||
if ( model )
|
||||
{
|
||||
auto preeditText = model->preeditText();
|
||||
if ( !preeditText.isEmpty() )
|
||||
if ( !preedit.isEmpty() )
|
||||
{
|
||||
preeditText.chop( 1 );
|
||||
sendText( preeditText, false );
|
||||
preedit.chop( 1 );
|
||||
sendText( preedit, false );
|
||||
|
||||
model->setPreeditText( preeditText );
|
||||
model->requestCandidates( preedit );
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -692,13 +689,14 @@ void QskInputContext::processKey( int key )
|
||||
{
|
||||
if ( model )
|
||||
{
|
||||
const auto preeditText = model->preeditText();
|
||||
if ( !preeditText.isEmpty() )
|
||||
if ( !preedit.isEmpty() )
|
||||
{
|
||||
if ( spaceLeft )
|
||||
sendText( preeditText.left( spaceLeft ), true );
|
||||
sendText( preedit.left( spaceLeft ), true );
|
||||
|
||||
preedit.clear();
|
||||
model->resetCandidates();
|
||||
|
||||
model->reset();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -715,14 +713,14 @@ void QskInputContext::processKey( int key )
|
||||
{
|
||||
if ( model )
|
||||
{
|
||||
auto preeditText = model->preeditText();
|
||||
if ( !preeditText.isEmpty() && spaceLeft)
|
||||
if ( !preedit.isEmpty() && spaceLeft)
|
||||
{
|
||||
preeditText = preeditText.left( spaceLeft );
|
||||
sendText( preeditText, true );
|
||||
spaceLeft -= preeditText.length();
|
||||
preedit = preedit.left( spaceLeft );
|
||||
sendText( preedit, true );
|
||||
spaceLeft -= preedit.length();
|
||||
|
||||
model->reset();
|
||||
preedit.clear();
|
||||
model->resetCandidates();
|
||||
}
|
||||
}
|
||||
|
||||
@ -741,7 +739,19 @@ void QskInputContext::processKey( int key )
|
||||
|
||||
if ( model )
|
||||
{
|
||||
model->composeKey( text, spaceLeft );
|
||||
preedit += text;
|
||||
|
||||
model->requestCandidates( preedit );
|
||||
|
||||
if ( model->candidateCount() > 0 )
|
||||
{
|
||||
sendText( preedit, false );
|
||||
}
|
||||
else
|
||||
{
|
||||
sendText( preedit.left( spaceLeft ), true );
|
||||
preedit.clear();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -17,8 +17,8 @@ public:
|
||||
QStringList candidates;
|
||||
};
|
||||
|
||||
QskPinyinCompositionModel::QskPinyinCompositionModel( QskInputContext* context ):
|
||||
Inherited( Attributes(), context ),
|
||||
QskPinyinCompositionModel::QskPinyinCompositionModel( QObject* parent ):
|
||||
Inherited( Attributes(), parent ),
|
||||
m_data( new PrivateData )
|
||||
{
|
||||
#if 1
|
||||
|
@ -14,7 +14,7 @@ class QskPinyinCompositionModel : public QskInputCompositionModel
|
||||
using Inherited = QskInputCompositionModel;
|
||||
|
||||
public:
|
||||
QskPinyinCompositionModel( QskInputContext* );
|
||||
QskPinyinCompositionModel( QObject* );
|
||||
virtual ~QskPinyinCompositionModel() override;
|
||||
|
||||
virtual int candidateCount() const override;
|
||||
|
@ -125,7 +125,7 @@ public:
|
||||
|
||||
QskLinearBox* layout;
|
||||
QskTextLabel* prompt;
|
||||
TextInput* textInput;
|
||||
TextInput* inputProxy;
|
||||
QskInputSuggestionBar* suggestionBar;
|
||||
QskVirtualKeyboard* keyboard;
|
||||
|
||||
@ -142,8 +142,8 @@ QskInputPanel::QskInputPanel( QQuickItem* parent ):
|
||||
m_data->prompt = new QskTextLabel();
|
||||
m_data->prompt->setVisible( false );
|
||||
|
||||
m_data->textInput = new TextInput();
|
||||
m_data->textInput->setVisible( m_data->hasInputProxy );
|
||||
m_data->inputProxy = new TextInput();
|
||||
m_data->inputProxy->setVisible( m_data->hasInputProxy );
|
||||
|
||||
m_data->suggestionBar = new QskInputSuggestionBar();
|
||||
m_data->suggestionBar->setVisible( false );
|
||||
@ -153,7 +153,7 @@ QskInputPanel::QskInputPanel( QQuickItem* parent ):
|
||||
auto layout = new QskLinearBox( Qt::Vertical, this );
|
||||
|
||||
layout->addItem( m_data->prompt, Qt::AlignLeft | Qt::AlignHCenter );
|
||||
layout->addItem( m_data->textInput, Qt::AlignLeft | Qt::AlignHCenter );
|
||||
layout->addItem( m_data->inputProxy, Qt::AlignLeft | Qt::AlignHCenter );
|
||||
layout->addStretch( 10 );
|
||||
layout->addItem( m_data->suggestionBar );
|
||||
layout->addItem( m_data->keyboard );
|
||||
@ -199,7 +199,7 @@ qreal QskInputPanel::heightForWidth( qreal width ) const
|
||||
qreal height = m_data->keyboard->heightForWidth( width );
|
||||
|
||||
const QskControl* controls[] =
|
||||
{ m_data->prompt, m_data->textInput, m_data->suggestionBar };
|
||||
{ m_data->prompt, m_data->inputProxy, m_data->suggestionBar };
|
||||
|
||||
for ( auto control : controls )
|
||||
{
|
||||
@ -228,7 +228,7 @@ qreal QskInputPanel::widthForHeight( qreal height ) const
|
||||
height -= padding.top() + padding.bottom();
|
||||
|
||||
const QskControl* controls[] =
|
||||
{ m_data->prompt, m_data->textInput, m_data->suggestionBar };
|
||||
{ m_data->prompt, m_data->inputProxy, m_data->suggestionBar };
|
||||
|
||||
for ( auto control : controls )
|
||||
{
|
||||
@ -278,7 +278,7 @@ void QskInputPanel::setInputProxy( bool on )
|
||||
return;
|
||||
|
||||
m_data->hasInputProxy = on;
|
||||
m_data->textInput->setVisible( on );
|
||||
m_data->inputProxy->setVisible( on );
|
||||
|
||||
auto prompt = m_data->prompt;
|
||||
|
||||
@ -288,6 +288,56 @@ void QskInputPanel::setInputProxy( bool on )
|
||||
prompt->setVisible( false );
|
||||
}
|
||||
|
||||
void QskInputPanel::updateInputProxy( const QQuickItem* inputItem )
|
||||
{
|
||||
if ( inputItem == nullptr )
|
||||
return;
|
||||
|
||||
QInputMethodQueryEvent event( Qt::ImQueryAll );
|
||||
QCoreApplication::sendEvent( const_cast< QQuickItem* >( inputItem ), &event );
|
||||
|
||||
const auto proxy = m_data->inputProxy;
|
||||
|
||||
if ( event.queries() & Qt::ImHints )
|
||||
{
|
||||
const auto hints = static_cast< Qt::InputMethodHints >(
|
||||
event.value( Qt::ImHints ).toInt() );
|
||||
|
||||
const auto echoMode = ( hints & Qt::ImhHiddenText )
|
||||
? QskTextInput::PasswordEchoOnEdit : QskTextInput::Normal;
|
||||
|
||||
proxy->setEchoMode( echoMode );
|
||||
}
|
||||
|
||||
if ( event.queries() & Qt::ImSurroundingText )
|
||||
{
|
||||
const auto text = event.value( Qt::ImSurroundingText ).toString();
|
||||
proxy->setText( text );
|
||||
}
|
||||
|
||||
if ( event.queries() & Qt::ImCursorPosition )
|
||||
{
|
||||
const auto pos = event.value( Qt::ImCursorPosition ).toInt();
|
||||
proxy->setCursorPosition( pos );
|
||||
}
|
||||
|
||||
#if 0
|
||||
if ( event.queries() & Qt::ImCurrentSelection )
|
||||
{
|
||||
const auto text = event.value( Qt::ImCursorPosition ).toString();
|
||||
if ( !text.isEmpty() )
|
||||
{
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( event.queries() & Qt::ImMaximumTextLength )
|
||||
{
|
||||
const auto length = event.value( Qt::ImMaximumTextLength ).toInt();
|
||||
proxy->setMaxLength( length );
|
||||
}
|
||||
}
|
||||
|
||||
bool QskInputPanel::isCandidatesEnabled() const
|
||||
{
|
||||
return m_data->suggestionBar->isVisible();
|
||||
|
@ -52,6 +52,8 @@ public:
|
||||
virtual QskAspect::Subcontrol effectiveSubcontrol(
|
||||
QskAspect::Subcontrol ) const override;
|
||||
|
||||
void updateInputProxy( const QQuickItem* );
|
||||
|
||||
Q_SIGNALS:
|
||||
void inputProxyChanged( bool );
|
||||
void inputPromptChanged( const QString& );
|
||||
|
Loading…
x
Reference in New Issue
Block a user