code moved to QskInputManager
This commit is contained in:
parent
186b18587b
commit
11dd05ff49
@ -7,7 +7,65 @@
|
|||||||
#include "QskInputPanel.h"
|
#include "QskInputPanel.h"
|
||||||
#include "QskInputEngine.h"
|
#include "QskInputEngine.h"
|
||||||
#include "QskInputContext.h"
|
#include "QskInputContext.h"
|
||||||
|
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
|
#include <QTextCharFormat>
|
||||||
|
|
||||||
|
static inline void qskSendReplaceText( QQuickItem* receiver, const QString& text )
|
||||||
|
{
|
||||||
|
if ( receiver == nullptr )
|
||||||
|
return;
|
||||||
|
|
||||||
|
QInputMethodEvent::Attribute attribute(
|
||||||
|
QInputMethodEvent::Selection, 0, 32767, QVariant() );
|
||||||
|
|
||||||
|
QInputMethodEvent event1( QString(), { attribute } );
|
||||||
|
QCoreApplication::sendEvent( receiver, &event1 );
|
||||||
|
|
||||||
|
QInputMethodEvent event2;
|
||||||
|
event2.setCommitString( text );
|
||||||
|
|
||||||
|
QCoreApplication::sendEvent( receiver, &event2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void qskSendText( QQuickItem* receiver,
|
||||||
|
const QString& text, bool isFinal )
|
||||||
|
{
|
||||||
|
if ( receiver == nullptr )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( isFinal )
|
||||||
|
{
|
||||||
|
QInputMethodEvent event;
|
||||||
|
event.setCommitString( text );
|
||||||
|
|
||||||
|
QCoreApplication::sendEvent( receiver, &event );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QTextCharFormat format;
|
||||||
|
format.setFontUnderline( true );
|
||||||
|
|
||||||
|
const QInputMethodEvent::Attribute attribute(
|
||||||
|
QInputMethodEvent::TextFormat, 0, text.length(), format );
|
||||||
|
|
||||||
|
QInputMethodEvent event( text, { attribute } );
|
||||||
|
|
||||||
|
QCoreApplication::sendEvent( receiver, &event );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void qskSendKey( QQuickItem* receiver, int key )
|
||||||
|
{
|
||||||
|
if ( receiver == nullptr )
|
||||||
|
return;
|
||||||
|
|
||||||
|
QKeyEvent keyPress( QEvent::KeyPress, key, Qt::NoModifier );
|
||||||
|
QCoreApplication::sendEvent( receiver, &keyPress );
|
||||||
|
|
||||||
|
QKeyEvent keyRelease( QEvent::KeyRelease, key, Qt::NoModifier );
|
||||||
|
QCoreApplication::sendEvent( receiver, &keyRelease );
|
||||||
|
}
|
||||||
|
|
||||||
class QskInputManager::PrivateData
|
class QskInputManager::PrivateData
|
||||||
{
|
{
|
||||||
@ -92,7 +150,18 @@ Qt::Alignment QskInputManager::panelAlignment() const
|
|||||||
|
|
||||||
QskControl* QskInputManager::createPanel()
|
QskControl* QskInputManager::createPanel()
|
||||||
{
|
{
|
||||||
return new QskInputPanel();
|
auto panel = new QskInputPanel();
|
||||||
|
|
||||||
|
connect( panel, &QskInputPanel::done,
|
||||||
|
this, &QskInputManager::applyInput, Qt::UniqueConnection );
|
||||||
|
|
||||||
|
connect( panel, &QskInputPanel::textEntered,
|
||||||
|
this, &QskInputManager::applyText, Qt::UniqueConnection );
|
||||||
|
|
||||||
|
connect( panel, &QskInputPanel::keyEntered,
|
||||||
|
this, &QskInputManager::applyKey, Qt::UniqueConnection );
|
||||||
|
|
||||||
|
return panel;
|
||||||
}
|
}
|
||||||
|
|
||||||
QskInputEngine* QskInputManager::createEngine()
|
QskInputEngine* QskInputManager::createEngine()
|
||||||
@ -136,3 +205,63 @@ void QskInputManager::updatePredictor()
|
|||||||
m_data->engine->setPredictor( context->textPredictor( locale ) );
|
m_data->engine->setPredictor( context->textPredictor( locale ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QQuickItem* QskInputManager::inputItem() const
|
||||||
|
{
|
||||||
|
if ( auto panel = qobject_cast< QskInputPanel* >( m_data->panel ) )
|
||||||
|
return panel->attachedInputItem();
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
QQuickItem* QskInputManager::inputProxy() const
|
||||||
|
{
|
||||||
|
if ( auto panel = qobject_cast< QskInputPanel* >( m_data->panel ) )
|
||||||
|
{
|
||||||
|
if ( panel->hasInputProxy() )
|
||||||
|
return panel->inputProxy();
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskInputManager::applyInput( bool success )
|
||||||
|
{
|
||||||
|
auto item = inputItem();
|
||||||
|
if ( item == nullptr )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( success )
|
||||||
|
{
|
||||||
|
if ( auto proxy = inputProxy() )
|
||||||
|
{
|
||||||
|
const auto value = proxy->property( "text" );
|
||||||
|
if ( value.canConvert<QString>() )
|
||||||
|
qskSendReplaceText( item, value.toString() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qskSendKey( item, success ? Qt::Key_Return : Qt::Key_Escape );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskInputManager::applyText( const QString& text, bool isFinal )
|
||||||
|
{
|
||||||
|
auto item = inputProxy();
|
||||||
|
if ( item == nullptr )
|
||||||
|
item = inputItem();
|
||||||
|
|
||||||
|
qskSendText( item, text, isFinal );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskInputManager::applyKey( int key )
|
||||||
|
{
|
||||||
|
// control keys like left/right
|
||||||
|
|
||||||
|
auto item = inputProxy();
|
||||||
|
if ( item == nullptr )
|
||||||
|
item = inputItem();
|
||||||
|
|
||||||
|
qskSendKey( item, key );
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "moc_QskInputManager.cpp"
|
||||||
|
@ -31,6 +31,9 @@ public:
|
|||||||
QskControl* panel( bool doCreate );
|
QskControl* panel( bool doCreate );
|
||||||
virtual Qt::Alignment panelAlignment() const;
|
virtual Qt::Alignment panelAlignment() const;
|
||||||
|
|
||||||
|
virtual QQuickItem* inputProxy() const;
|
||||||
|
virtual QQuickItem* inputItem() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual QskControl* createPanel();
|
virtual QskControl* createPanel();
|
||||||
virtual QskInputEngine* createEngine();
|
virtual QskInputEngine* createEngine();
|
||||||
@ -39,6 +42,10 @@ protected:
|
|||||||
void updateEngine( const QLocale& );
|
void updateEngine( const QLocale& );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void applyInput( bool success );
|
||||||
|
void applyText( const QString&, bool isFinal );
|
||||||
|
void applyKey( int keyCode );
|
||||||
|
|
||||||
class PrivateData;
|
class PrivateData;
|
||||||
std::unique_ptr< PrivateData > m_data;
|
std::unique_ptr< PrivateData > m_data;
|
||||||
};
|
};
|
||||||
|
@ -13,100 +13,8 @@
|
|||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QLocale>
|
#include <QLocale>
|
||||||
#include <QGuiApplication>
|
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
#include <QInputMethodQueryEvent>
|
#include <QInputMethodQueryEvent>
|
||||||
#include <QTextCharFormat>
|
|
||||||
|
|
||||||
static inline void qskSendReplaceText( QQuickItem* receiver, const QString& text )
|
|
||||||
{
|
|
||||||
if ( receiver == nullptr )
|
|
||||||
return;
|
|
||||||
|
|
||||||
QInputMethodEvent::Attribute attribute(
|
|
||||||
QInputMethodEvent::Selection, 0, 32767, QVariant() );
|
|
||||||
|
|
||||||
QInputMethodEvent event1( QString(), { attribute } );
|
|
||||||
QCoreApplication::sendEvent( receiver, &event1 );
|
|
||||||
|
|
||||||
QInputMethodEvent event2;
|
|
||||||
event2.setCommitString( text );
|
|
||||||
|
|
||||||
QCoreApplication::sendEvent( receiver, &event2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void qskSendText( QQuickItem* receiver,
|
|
||||||
const QString& text, bool isFinal )
|
|
||||||
{
|
|
||||||
if ( receiver == nullptr )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if ( isFinal )
|
|
||||||
{
|
|
||||||
QInputMethodEvent event;
|
|
||||||
event.setCommitString( text );
|
|
||||||
|
|
||||||
QCoreApplication::sendEvent( receiver, &event );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
QTextCharFormat format;
|
|
||||||
format.setFontUnderline( true );
|
|
||||||
|
|
||||||
const QInputMethodEvent::Attribute attribute(
|
|
||||||
QInputMethodEvent::TextFormat, 0, text.length(), format );
|
|
||||||
|
|
||||||
QInputMethodEvent event( text, { attribute } );
|
|
||||||
|
|
||||||
QCoreApplication::sendEvent( receiver, &event );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void qskSendKey( QQuickItem* receiver, int key )
|
|
||||||
{
|
|
||||||
if ( receiver == nullptr )
|
|
||||||
return;
|
|
||||||
|
|
||||||
QKeyEvent keyPress( QEvent::KeyPress, key, Qt::NoModifier );
|
|
||||||
QCoreApplication::sendEvent( receiver, &keyPress );
|
|
||||||
|
|
||||||
QKeyEvent keyRelease( QEvent::KeyRelease, key, Qt::NoModifier );
|
|
||||||
QCoreApplication::sendEvent( receiver, &keyRelease );
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void qskSyncInputProxy(
|
|
||||||
QQuickItem* inputItem, QskTextInput* inputProxy )
|
|
||||||
{
|
|
||||||
int passwordMaskDelay = -1;
|
|
||||||
QString passwordCharacter;
|
|
||||||
|
|
||||||
if ( auto textInput = qobject_cast< QskTextInput* >( inputItem ) )
|
|
||||||
{
|
|
||||||
passwordMaskDelay = textInput->passwordMaskDelay();
|
|
||||||
passwordCharacter = textInput->passwordCharacter();
|
|
||||||
|
|
||||||
if ( inputProxy->echoMode() == QskTextInput::NoEcho )
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Qt::ImhHiddenText does not provide information
|
|
||||||
to decide between NoEcho/Password
|
|
||||||
*/
|
|
||||||
auto mode = textInput->echoMode();
|
|
||||||
if ( mode == QskTextInput::Password )
|
|
||||||
inputProxy->setEchoMode( mode );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( passwordMaskDelay >= 0 )
|
|
||||||
inputProxy->setPasswordMaskDelay( passwordMaskDelay );
|
|
||||||
else
|
|
||||||
inputProxy->resetPasswordMaskDelay();
|
|
||||||
|
|
||||||
if ( !passwordCharacter.isEmpty() )
|
|
||||||
inputProxy->setPasswordCharacter( passwordCharacter );
|
|
||||||
else
|
|
||||||
inputProxy->resetPasswordCharacter();
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@ -117,9 +25,40 @@ namespace
|
|||||||
QskTextInput( parentItem )
|
QskTextInput( parentItem )
|
||||||
{
|
{
|
||||||
setObjectName( "InputPanelInputProxy" );
|
setObjectName( "InputPanelInputProxy" );
|
||||||
#if 1
|
|
||||||
setFocusPolicy( Qt::NoFocus );
|
setFocusPolicy( Qt::NoFocus );
|
||||||
#endif
|
}
|
||||||
|
|
||||||
|
void setup( QQuickItem* inputItem )
|
||||||
|
{
|
||||||
|
int passwordMaskDelay = -1;
|
||||||
|
QString passwordCharacter;
|
||||||
|
|
||||||
|
if ( auto textInput = qobject_cast< QskTextInput* >( inputItem ) )
|
||||||
|
{
|
||||||
|
passwordMaskDelay = textInput->passwordMaskDelay();
|
||||||
|
passwordCharacter = textInput->passwordCharacter();
|
||||||
|
|
||||||
|
if ( echoMode() == QskTextInput::NoEcho )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Qt::ImhHiddenText does not provide information
|
||||||
|
to decide between NoEcho/Password
|
||||||
|
*/
|
||||||
|
auto mode = textInput->echoMode();
|
||||||
|
if ( mode == QskTextInput::Password )
|
||||||
|
setEchoMode( mode );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( passwordMaskDelay >= 0 )
|
||||||
|
setPasswordMaskDelay( passwordMaskDelay );
|
||||||
|
else
|
||||||
|
resetPasswordMaskDelay();
|
||||||
|
|
||||||
|
if ( !passwordCharacter.isEmpty() )
|
||||||
|
setPasswordCharacter( passwordCharacter );
|
||||||
|
else
|
||||||
|
resetPasswordCharacter();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -255,7 +194,7 @@ void QskInputPanel::attachInputItem( QQuickItem* item )
|
|||||||
QCoreApplication::sendEvent( item, &event );
|
QCoreApplication::sendEvent( item, &event );
|
||||||
|
|
||||||
// not all information is available from the input method query
|
// not all information is available from the input method query
|
||||||
qskSyncInputProxy( item, m_data->inputProxy );
|
m_data->inputProxy->setup( item );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -265,6 +204,11 @@ QQuickItem* QskInputPanel::attachedInputItem() const
|
|||||||
return m_data->inputItem;
|
return m_data->inputItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QQuickItem* QskInputPanel::inputProxy() const
|
||||||
|
{
|
||||||
|
return m_data->inputProxy;
|
||||||
|
}
|
||||||
|
|
||||||
void QskInputPanel::updatePrediction()
|
void QskInputPanel::updatePrediction()
|
||||||
{
|
{
|
||||||
m_data->predictionBar->setPrediction(
|
m_data->predictionBar->setPrediction(
|
||||||
@ -335,7 +279,7 @@ void QskInputPanel::commitPredictiveText( int index )
|
|||||||
const QString text = m_data->engine->predictiveText( index );
|
const QString text = m_data->engine->predictiveText( index );
|
||||||
|
|
||||||
m_data->engine->reset();
|
m_data->engine->reset();
|
||||||
qskSendText( m_data->receiverItem(), text, true );
|
Q_EMIT textEntered( text, true );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,39 +320,26 @@ void QskInputPanel::processKey( int key,
|
|||||||
{
|
{
|
||||||
case Qt::Key_Return:
|
case Qt::Key_Return:
|
||||||
{
|
{
|
||||||
done( true );
|
Q_EMIT done( true );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Qt::Key_Escape:
|
case Qt::Key_Escape:
|
||||||
{
|
{
|
||||||
done( false );
|
Q_EMIT done( false );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
qskSendKey( m_data->receiverItem(), result.key );
|
Q_EMIT keyEntered( result.key );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( !result.text.isEmpty() )
|
else if ( !result.text.isEmpty() )
|
||||||
{
|
{
|
||||||
// changing the current text
|
Q_EMIT textEntered( result.text, result.isFinal );
|
||||||
qskSendText( m_data->receiverItem(), result.text, result.isFinal );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskInputPanel::done( bool success )
|
|
||||||
{
|
|
||||||
if ( success )
|
|
||||||
{
|
|
||||||
if ( m_data->hasInputProxy )
|
|
||||||
qskSendReplaceText( m_data->inputItem, m_data->inputProxy->text() );
|
|
||||||
}
|
|
||||||
|
|
||||||
qskSendKey( m_data->inputItem,
|
|
||||||
success ? Qt::Key_Return : Qt::Key_Escape );
|
|
||||||
}
|
|
||||||
|
|
||||||
void QskInputPanel::processInputMethodQueries( Qt::InputMethodQueries queries )
|
void QskInputPanel::processInputMethodQueries( Qt::InputMethodQueries queries )
|
||||||
{
|
{
|
||||||
if ( m_data->inputItem == nullptr )
|
if ( m_data->inputItem == nullptr )
|
||||||
|
@ -39,6 +39,8 @@ public:
|
|||||||
QskInputEngine* engine();
|
QskInputEngine* engine();
|
||||||
|
|
||||||
bool hasInputProxy() const;
|
bool hasInputProxy() const;
|
||||||
|
QQuickItem* inputProxy() const;
|
||||||
|
|
||||||
QString inputPrompt() const;
|
QString inputPrompt() const;
|
||||||
|
|
||||||
virtual QskAspect::Subcontrol effectiveSubcontrol(
|
virtual QskAspect::Subcontrol effectiveSubcontrol(
|
||||||
@ -50,6 +52,10 @@ Q_SIGNALS:
|
|||||||
void inputProxyChanged( bool );
|
void inputProxyChanged( bool );
|
||||||
void inputPromptChanged( const QString& );
|
void inputPromptChanged( const QString& );
|
||||||
|
|
||||||
|
void textEntered( const QString&, bool isFinal );
|
||||||
|
void keyEntered( int keyCode );
|
||||||
|
void done( bool success );
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void setInputPrompt( const QString& );
|
void setInputPrompt( const QString& );
|
||||||
void setInputProxy( bool );
|
void setInputProxy( bool );
|
||||||
@ -62,7 +68,6 @@ protected:
|
|||||||
Qt::InputMethodHints, int spaceLeft );
|
Qt::InputMethodHints, int spaceLeft );
|
||||||
|
|
||||||
virtual void updatePrediction();
|
virtual void updatePrediction();
|
||||||
virtual void done( bool success );
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void commitKey( int key );
|
void commitKey( int key );
|
||||||
|
@ -300,6 +300,7 @@ SOURCES += \
|
|||||||
SOURCES += \
|
SOURCES += \
|
||||||
inputpanel/QskTextPredictor.cpp \
|
inputpanel/QskTextPredictor.cpp \
|
||||||
inputpanel/QskInputContext.cpp \
|
inputpanel/QskInputContext.cpp \
|
||||||
|
inputpanel/QskInputManager.cpp \
|
||||||
inputpanel/QskInputEngine.cpp \
|
inputpanel/QskInputEngine.cpp \
|
||||||
inputpanel/QskInputPanel.cpp \
|
inputpanel/QskInputPanel.cpp \
|
||||||
inputpanel/QskInputPredictionBar.cpp \
|
inputpanel/QskInputPredictionBar.cpp \
|
||||||
@ -308,6 +309,7 @@ SOURCES += \
|
|||||||
HEADERS += \
|
HEADERS += \
|
||||||
inputpanel/QskTextPredictor.h \
|
inputpanel/QskTextPredictor.h \
|
||||||
inputpanel/QskInputContext.h \
|
inputpanel/QskInputContext.h \
|
||||||
|
inputpanel/QskInputManager.h \
|
||||||
inputpanel/QskInputEngine.h \
|
inputpanel/QskInputEngine.h \
|
||||||
inputpanel/QskInputPanel.h \
|
inputpanel/QskInputPanel.h \
|
||||||
inputpanel/QskInputPredictionBar.h \
|
inputpanel/QskInputPredictionBar.h \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user