code moved to QskInputManager
This commit is contained in:
parent
186b18587b
commit
11dd05ff49
@ -7,7 +7,65 @@
|
||||
#include "QskInputPanel.h"
|
||||
#include "QskInputEngine.h"
|
||||
#include "QskInputContext.h"
|
||||
|
||||
#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
|
||||
{
|
||||
@ -92,7 +150,18 @@ Qt::Alignment QskInputManager::panelAlignment() const
|
||||
|
||||
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()
|
||||
@ -136,3 +205,63 @@ void QskInputManager::updatePredictor()
|
||||
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 );
|
||||
virtual Qt::Alignment panelAlignment() const;
|
||||
|
||||
virtual QQuickItem* inputProxy() const;
|
||||
virtual QQuickItem* inputItem() const;
|
||||
|
||||
protected:
|
||||
virtual QskControl* createPanel();
|
||||
virtual QskInputEngine* createEngine();
|
||||
@ -39,6 +42,10 @@ protected:
|
||||
void updateEngine( const QLocale& );
|
||||
|
||||
private:
|
||||
void applyInput( bool success );
|
||||
void applyText( const QString&, bool isFinal );
|
||||
void applyKey( int keyCode );
|
||||
|
||||
class PrivateData;
|
||||
std::unique_ptr< PrivateData > m_data;
|
||||
};
|
||||
|
@ -13,100 +13,8 @@
|
||||
|
||||
#include <QString>
|
||||
#include <QLocale>
|
||||
#include <QGuiApplication>
|
||||
#include <QPointer>
|
||||
#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
|
||||
{
|
||||
@ -117,9 +25,40 @@ namespace
|
||||
QskTextInput( parentItem )
|
||||
{
|
||||
setObjectName( "InputPanelInputProxy" );
|
||||
#if 1
|
||||
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:
|
||||
@ -255,7 +194,7 @@ void QskInputPanel::attachInputItem( QQuickItem* item )
|
||||
QCoreApplication::sendEvent( item, &event );
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
QQuickItem* QskInputPanel::inputProxy() const
|
||||
{
|
||||
return m_data->inputProxy;
|
||||
}
|
||||
|
||||
void QskInputPanel::updatePrediction()
|
||||
{
|
||||
m_data->predictionBar->setPrediction(
|
||||
@ -335,7 +279,7 @@ void QskInputPanel::commitPredictiveText( int index )
|
||||
const QString text = m_data->engine->predictiveText( index );
|
||||
|
||||
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:
|
||||
{
|
||||
done( true );
|
||||
Q_EMIT done( true );
|
||||
break;
|
||||
}
|
||||
case Qt::Key_Escape:
|
||||
{
|
||||
done( false );
|
||||
Q_EMIT done( false );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
qskSendKey( m_data->receiverItem(), result.key );
|
||||
Q_EMIT keyEntered( result.key );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( !result.text.isEmpty() )
|
||||
{
|
||||
// changing the current text
|
||||
qskSendText( m_data->receiverItem(), result.text, result.isFinal );
|
||||
Q_EMIT textEntered( 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 )
|
||||
{
|
||||
if ( m_data->inputItem == nullptr )
|
||||
|
@ -39,6 +39,8 @@ public:
|
||||
QskInputEngine* engine();
|
||||
|
||||
bool hasInputProxy() const;
|
||||
QQuickItem* inputProxy() const;
|
||||
|
||||
QString inputPrompt() const;
|
||||
|
||||
virtual QskAspect::Subcontrol effectiveSubcontrol(
|
||||
@ -50,6 +52,10 @@ Q_SIGNALS:
|
||||
void inputProxyChanged( bool );
|
||||
void inputPromptChanged( const QString& );
|
||||
|
||||
void textEntered( const QString&, bool isFinal );
|
||||
void keyEntered( int keyCode );
|
||||
void done( bool success );
|
||||
|
||||
public Q_SLOTS:
|
||||
void setInputPrompt( const QString& );
|
||||
void setInputProxy( bool );
|
||||
@ -62,7 +68,6 @@ protected:
|
||||
Qt::InputMethodHints, int spaceLeft );
|
||||
|
||||
virtual void updatePrediction();
|
||||
virtual void done( bool success );
|
||||
|
||||
private:
|
||||
void commitKey( int key );
|
||||
|
@ -300,6 +300,7 @@ SOURCES += \
|
||||
SOURCES += \
|
||||
inputpanel/QskTextPredictor.cpp \
|
||||
inputpanel/QskInputContext.cpp \
|
||||
inputpanel/QskInputManager.cpp \
|
||||
inputpanel/QskInputEngine.cpp \
|
||||
inputpanel/QskInputPanel.cpp \
|
||||
inputpanel/QskInputPredictionBar.cpp \
|
||||
@ -308,6 +309,7 @@ SOURCES += \
|
||||
HEADERS += \
|
||||
inputpanel/QskTextPredictor.h \
|
||||
inputpanel/QskInputContext.h \
|
||||
inputpanel/QskInputManager.h \
|
||||
inputpanel/QskInputEngine.h \
|
||||
inputpanel/QskInputPanel.h \
|
||||
inputpanel/QskInputPredictionBar.h \
|
||||
|
Loading…
x
Reference in New Issue
Block a user