moving code from QskInputPanel

This commit is contained in:
Uwe Rathmann 2018-06-02 17:10:41 +02:00
parent 11dd05ff49
commit 23eec85708
7 changed files with 308 additions and 369 deletions

View File

@ -265,11 +265,7 @@ int main( int argc, char* argv[] )
#endif
#if 0
/*
If no input panel has been assigned QskInputContext creates
default panel if none has been assigned
*/
QskInputContext::setInputPanel( new QskInputPanel() );
QskInputContext::setInputManager( ... );
#endif
auto box = new QskLinearBox( Qt::Horizontal );

View File

@ -790,4 +790,105 @@ void QskTextInput::setInputMethodHints(Qt::InputMethodHints hints )
}
}
void QskTextInput::setupFrom( const QQuickItem* item )
{
if ( item == nullptr )
return;
// finding attributes from the input hints of item
int maxCharacters = 32767;
QskTextInput::EchoMode echoMode = QskTextInput::Normal;
Qt::InputMethodQueries queries = Qt::ImQueryAll;
queries &= ~Qt::ImEnabled;
QInputMethodQueryEvent event( queries );
QCoreApplication::sendEvent( const_cast< QQuickItem* >( item ), &event );
if ( event.queries() & Qt::ImHints )
{
const auto hints = static_cast< Qt::InputMethodHints >(
event.value( Qt::ImHints ).toInt() );
if ( hints & Qt::ImhHiddenText )
echoMode = QskTextInput::NoEcho;
}
if ( event.queries() & Qt::ImMaximumTextLength )
{
// needs to be handled before Qt::ImCursorPosition !
const auto max = event.value( Qt::ImMaximumTextLength ).toInt();
maxCharacters = qBound( 0, max, maxCharacters );
}
setMaxLength( maxCharacters );
if ( event.queries() & Qt::ImSurroundingText )
{
const auto text = event.value( Qt::ImSurroundingText ).toString();
setText( text );
}
if ( event.queries() & Qt::ImCursorPosition )
{
const auto pos = event.value( Qt::ImCursorPosition ).toInt();
setCursorPosition( pos );
}
if ( event.queries() & Qt::ImCurrentSelection )
{
#if 0
const auto text = event.value( Qt::ImCurrentSelection ).toString();
if ( !text.isEmpty() )
{
}
#endif
}
int passwordMaskDelay = -1;
QString passwordCharacter;
if ( echoMode == QskTextInput::NoEcho )
{
/*
Qt::ImhHiddenText does not provide information
to decide between NoEcho/Password, or provides
more details about how to deal with hidden inputs.
So we try to find out more from trying some properties.
*/
QVariant value;
value = item->property( "passwordMaskDelay" );
if ( value.canConvert< int >() )
passwordMaskDelay = value.toInt();
value = item->property( "passwordCharacter" );
if ( value.canConvert< QString >() )
passwordCharacter = value.toString();
value = item->property( "echoMode" );
if ( value.canConvert< int >() )
{
const auto mode = value.toInt();
if ( mode == QskTextInput::Password )
echoMode = QskTextInput::Password;
}
}
if ( passwordMaskDelay >= 0 )
setPasswordMaskDelay( passwordMaskDelay );
else
resetPasswordMaskDelay();
if ( !passwordCharacter.isEmpty() )
setPasswordCharacter( passwordCharacter );
else
resetPasswordCharacter();
setEchoMode( echoMode );
}
#include "moc_QskTextInput.cpp"

View File

@ -31,6 +31,9 @@ class QSK_EXPORT QskTextInput : public QskControl
Q_PROPERTY( bool editing READ isEditing
WRITE setEditing NOTIFY editingChanged )
Q_PROPERTY( EchoMode echoMode READ echoMode
WRITE setEchoMode NOTIFY echoModeChanged )
Q_PROPERTY( QString passwordCharacter READ passwordCharacter
WRITE setPasswordCharacter RESET resetPasswordCharacter
NOTIFY passwordCharacterChanged )
@ -75,6 +78,8 @@ public:
virtual ~QskTextInput();
void setupFrom( const QQuickItem* );
QString text() const;
void setDescription( const QString& );

View File

@ -11,6 +11,12 @@
#include <QPointer>
#include <QTextCharFormat>
static inline QQuickItem* qskReceiverItem( const QskInputManager* manager )
{
auto item = manager->inputProxy();
return item ? item : manager->inputItem();
}
static inline void qskSendReplaceText( QQuickItem* receiver, const QString& text )
{
if ( receiver == nullptr )
@ -74,6 +80,7 @@ public:
QPointer< QskControl > panel;
QLocale predictorLocale;
Qt::InputMethodHints inputHints = 0;
};
QskInputManager::QskInputManager( QObject* parent ):
@ -98,14 +105,18 @@ void QskInputManager::attachInputItem( QQuickItem* item )
const auto locale = context->locale();
updateEngine( locale );
m_data->engine->reset();
panel->setEngine( m_data->engine );
panel->setLocale( locale );
panel->attachInputItem( item );
Qt::InputMethodQueries queries = Qt::ImQueryAll;
queries &= ~Qt::ImEnabled;
processInputMethodQueries( queries );
}
else
{
panel->setEngine( nullptr );
panel->attachInputItem( nullptr );
}
}
@ -113,8 +124,21 @@ void QskInputManager::attachInputItem( QQuickItem* item )
void QskInputManager::processInputMethodQueries(
Qt::InputMethodQueries queries )
{
if ( auto panel = qobject_cast< QskInputPanel* >( m_data->panel ) )
panel->processInputMethodQueries( queries );
if ( queries & Qt::ImHints )
{
m_data->inputHints = 0;
if ( auto item = inputItem() )
{
QInputMethodQueryEvent event( Qt::ImHints );
QCoreApplication::sendEvent( item, &event );
m_data->inputHints = static_cast< Qt::InputMethodHints >(
event.value( Qt::ImHints ).toInt() );
}
updatePanel();
}
}
QskControl* QskInputManager::panel( bool doCreate )
@ -134,7 +158,7 @@ Qt::Alignment QskInputManager::panelAlignment() const
{
if ( auto panel = qobject_cast< QskInputPanel* >( m_data->panel ) )
{
if ( panel->hasInputProxy() )
if ( panel->panelHints() & QskInputPanel::InputProxy )
{
/*
When the panel has an input proxy we don't need to see
@ -152,14 +176,11 @@ QskControl* QskInputManager::createPanel()
{
auto panel = new QskInputPanel();
connect( panel, &QskInputPanel::done,
this, &QskInputManager::applyInput, Qt::UniqueConnection );
connect( panel, &QskInputPanel::keySelected,
this, &QskInputManager::commitKey, Qt::UniqueConnection );
connect( panel, &QskInputPanel::textEntered,
this, &QskInputManager::applyText, Qt::UniqueConnection );
connect( panel, &QskInputPanel::keyEntered,
this, &QskInputManager::applyKey, Qt::UniqueConnection );
connect( panel, &QskInputPanel::predictiveTextSelected,
this, &QskInputManager::commitPredictiveText, Qt::UniqueConnection );
return panel;
}
@ -171,7 +192,7 @@ QskInputEngine* QskInputManager::createEngine()
void QskInputManager::updateEngine( const QLocale& locale )
{
auto context = QskInputContext::instance();
bool updatePredictor;
if ( m_data->engine == nullptr)
{
@ -179,18 +200,24 @@ void QskInputManager::updateEngine( const QLocale& locale )
if ( engine->parent() == nullptr )
engine->setParent( this );
m_data->predictorLocale = locale;
engine->setPredictor( context->textPredictor( locale ) );
connect( engine, &QskInputEngine::predictionChanged,
this, &QskInputManager::updatePrediction );
m_data->engine = engine;
updatePredictor = true;
}
else
{
if ( m_data->predictorLocale != locale )
updatePredictor = ( locale != m_data->predictorLocale );
}
if ( updatePredictor )
{
auto context = QskInputContext::instance();
m_data->predictorLocale = locale;
m_data->engine->setPredictor( context->textPredictor( locale ) );
}
updatePanel();
}
}
@ -206,6 +233,18 @@ void QskInputManager::updatePredictor()
}
}
void QskInputManager::updatePanel()
{
if ( auto panel = qobject_cast< QskInputPanel* >( m_data->panel ) )
{
const auto mask = Qt::ImhNoPredictiveText
| Qt::ImhExclusiveInputMask | Qt::ImhHiddenText;
panel->setPanelHint( QskInputPanel::Prediction,
m_data->engine->predictor() && !( m_data->inputHints & mask ) );
}
}
QQuickItem* QskInputManager::inputItem() const
{
if ( auto panel = qobject_cast< QskInputPanel* >( m_data->panel ) )
@ -218,7 +257,7 @@ QQuickItem* QskInputManager::inputProxy() const
{
if ( auto panel = qobject_cast< QskInputPanel* >( m_data->panel ) )
{
if ( panel->hasInputProxy() )
if ( panel->panelHints() & QskInputPanel::InputProxy )
return panel->inputProxy();
}
@ -246,22 +285,85 @@ void QskInputManager::applyInput( bool success )
void QskInputManager::applyText( const QString& text, bool isFinal )
{
auto item = inputProxy();
if ( item == nullptr )
item = inputItem();
qskSendText( item, text, isFinal );
qskSendText( qskReceiverItem( this ), text, isFinal );
}
void QskInputManager::applyKey( int key )
{
// control keys like left/right
qskSendKey( qskReceiverItem( this ), key );
}
auto item = inputProxy();
if ( item == nullptr )
item = inputItem();
void QskInputManager::commitPredictiveText( int index )
{
if ( auto panel = qobject_cast< QskInputPanel* >( m_data->panel ) )
{
panel->setPrediction( QStringList() );
qskSendKey( item, key );
const QString text = m_data->engine->predictiveText( index );
m_data->engine->reset();
applyText( text, true );
}
}
void QskInputManager::updatePrediction()
{
if ( auto panel = qobject_cast< QskInputPanel* >( m_data->panel ) )
panel->setPrediction( m_data->engine->prediction() );
}
void QskInputManager::commitKey( int key )
{
auto panel = qobject_cast< QskInputPanel* >( m_data->panel );
if ( panel == nullptr )
return;
int spaceLeft = -1;
if ( !( m_data->inputHints & Qt::ImhMultiLine ) )
{
QInputMethodQueryEvent event1( Qt::ImMaximumTextLength );
QCoreApplication::sendEvent( panel->attachedInputItem(), &event1 );
const int maxChars = event1.value( Qt::ImMaximumTextLength ).toInt();
if ( maxChars >= 0 )
{
QInputMethodQueryEvent event2( Qt::ImSurroundingText );
QCoreApplication::sendEvent( qskReceiverItem( this ), &event2 );
const auto text = event2.value( Qt::ImSurroundingText ).toString();
spaceLeft = maxChars - text.length();
}
}
const auto result = m_data->engine->processKey(
key, m_data->inputHints, spaceLeft );
if ( result.key )
{
switch( result.key )
{
case Qt::Key_Return:
{
applyInput( true );
break;
}
case Qt::Key_Escape:
{
applyInput( false );
break;
}
default:
{
applyKey( result.key );
}
}
}
else if ( !result.text.isEmpty() )
{
applyText( result.text, result.isFinal );
}
}
#include "moc_QskInputManager.cpp"

View File

@ -46,6 +46,12 @@ private:
void applyText( const QString&, bool isFinal );
void applyKey( int keyCode );
void commitKey( int keyCode );
void commitPredictiveText( int index );
void updatePrediction();
void updatePanel();
class PrivateData;
std::unique_ptr< PrivateData > m_data;
};

View File

@ -4,7 +4,6 @@
*****************************************************************************/
#include "QskInputPanel.h"
#include "QskInputEngine.h"
#include "QskVirtualKeyboard.h"
#include "QskInputPredictionBar.h"
#include "QskTextInput.h"
@ -28,39 +27,6 @@ namespace
setFocusPolicy( Qt::NoFocus );
}
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:
virtual void focusInEvent( QFocusEvent* ) override final
{
@ -77,20 +43,6 @@ QSK_SUBCONTROL( QskInputPanel, Panel )
class QskInputPanel::PrivateData
{
public:
PrivateData():
inputHints( 0 ),
maxChars( -1 ),
hasPrediction( true ),
hasInputProxy( true )
{
}
QQuickItem* receiverItem()
{
return hasInputProxy ? inputProxy : inputItem;
}
QPointer< QskInputEngine > engine;
QPointer< QQuickItem > inputItem;
QskLinearBox* layout;
@ -99,11 +51,9 @@ public:
QskInputPredictionBar* predictionBar;
QskVirtualKeyboard* keyboard;
Qt::InputMethodHints inputHints;
int maxChars;
int maxChars = -1;
bool hasPrediction : 1;
bool hasInputProxy : 1;
QskInputPanel::PanelHints panelHints = QskInputPanel::InputProxy;
};
QskInputPanel::QskInputPanel( QQuickItem* parent ):
@ -117,10 +67,12 @@ QskInputPanel::QskInputPanel( QQuickItem* parent ):
m_data->prompt->setVisible( false );
m_data->inputProxy = new TextInputProxy();
m_data->inputProxy->setVisible( m_data->hasInputProxy );
m_data->inputProxy->setVisible(
m_data->panelHints & QskInputPanel::InputProxy );
m_data->predictionBar = new QskInputPredictionBar();
m_data->predictionBar->setVisible( false );
m_data->predictionBar->setVisible(
m_data->panelHints & QskInputPanel::Prediction );
m_data->keyboard = new QskVirtualKeyboard();
@ -135,34 +87,45 @@ QskInputPanel::QskInputPanel( QQuickItem* parent ):
m_data->layout = layout;
connect( m_data->predictionBar, &QskInputPredictionBar::predictiveTextSelected,
this, &QskInputPanel::commitPredictiveText );
this, &QskInputPanel::predictiveTextSelected );
connect( m_data->keyboard, &QskVirtualKeyboard::keySelected,
this, &QskInputPanel::commitKey );
this, &QskInputPanel::keySelected );
}
QskInputPanel::~QskInputPanel()
{
}
void QskInputPanel::setEngine( QskInputEngine* engine )
void QskInputPanel::setPanelHint( PanelHint hint, bool on )
{
if ( engine == m_data->engine )
if ( on )
setPanelHints( m_data->panelHints | hint );
else
setPanelHints( m_data->panelHints & ~hint );
}
void QskInputPanel::setPanelHints( PanelHints hints )
{
if ( hints == m_data->panelHints )
return;
if ( m_data->engine )
m_data->engine->disconnect( this );
m_data->panelHints = hints;
m_data->engine = engine;
m_data->inputProxy->setVisible( hints & QskInputPanel::InputProxy );
m_data->predictionBar->setVisible( hints & QskInputPanel::Prediction );
if ( engine )
{
connect( engine, &QskInputEngine::predictionChanged,
this, &QskInputPanel::updatePrediction );
}
const bool showPrompt = ( hints & QskInputPanel::InputProxy )
&& !m_data->prompt->text().isEmpty();
m_data->predictionBar->setVisible(
m_data->hasPrediction && engine && engine->predictor() );
m_data->prompt->setVisible( showPrompt );
Q_EMIT panelHintsChanged();
}
QskInputPanel::PanelHints QskInputPanel::panelHints() const
{
return m_data->panelHints;
}
void QskInputPanel::attachInputItem( QQuickItem* item )
@ -172,29 +135,19 @@ void QskInputPanel::attachInputItem( QQuickItem* item )
m_data->inputItem = item;
if ( m_data->engine )
m_data->engine->reset();
if ( item )
{
Qt::InputMethodQueries queries = Qt::ImQueryAll;
queries &= ~Qt::ImEnabled;
processInputMethodQueries( queries );
if ( m_data->hasInputProxy )
if ( m_data->panelHints & QskInputPanel::InputProxy )
{
m_data->inputProxy->setupFrom( item );
m_data->inputProxy->setEditing( true );
// hiding the cursor in the real input item
// hiding the cursor in item
const QInputMethodEvent::Attribute attribute(
QInputMethodEvent::Cursor, 0, 0, QVariant() );
QInputMethodEvent event( QString(), { attribute } );
QCoreApplication::sendEvent( item, &event );
// not all information is available from the input method query
m_data->inputProxy->setup( item );
}
}
}
@ -209,17 +162,6 @@ QQuickItem* QskInputPanel::inputProxy() const
return m_data->inputProxy;
}
void QskInputPanel::updatePrediction()
{
m_data->predictionBar->setPrediction(
m_data->engine->prediction() );
}
QskInputEngine* QskInputPanel::engine()
{
return m_data->engine;
}
QskAspect::Subcontrol QskInputPanel::effectiveSubcontrol(
QskAspect::Subcontrol subControl ) const
{
@ -242,226 +184,16 @@ void QskInputPanel::setInputPrompt( const QString& text )
{
prompt->setText( text );
if ( m_data->hasInputProxy )
if ( m_data->panelHints & QskInputPanel::InputProxy )
prompt->setVisible( !text.isEmpty() );
Q_EMIT inputPromptChanged( text );
}
}
bool QskInputPanel::hasInputProxy() const
void QskInputPanel::setPrediction( const QStringList& prediction )
{
return m_data->hasInputProxy;
}
void QskInputPanel::setInputProxy( bool on )
{
if ( m_data->hasInputProxy == on )
return;
m_data->hasInputProxy = on;
m_data->inputProxy->setVisible( on );
auto prompt = m_data->prompt;
if ( on )
prompt->setVisible( !prompt->text().isEmpty() );
else
prompt->setVisible( false );
}
void QskInputPanel::commitPredictiveText( int index )
{
m_data->predictionBar->setPrediction( QStringList() );
if ( m_data->engine )
{
const QString text = m_data->engine->predictiveText( index );
m_data->engine->reset();
Q_EMIT textEntered( text, true );
}
}
void QskInputPanel::commitKey( int key )
{
if ( m_data->engine == nullptr || m_data->inputItem == nullptr )
return;
int spaceLeft = -1;
if ( !( m_data->inputHints & Qt::ImhMultiLine ) )
{
auto receiver = m_data->receiverItem();
if ( m_data->maxChars >= 0 )
{
QInputMethodQueryEvent event( Qt::ImSurroundingText );
QCoreApplication::sendEvent( receiver, &event );
const auto text = event.value( Qt::ImSurroundingText ).toString();
spaceLeft = m_data->maxChars - text.length();
}
}
processKey( key, m_data->inputHints, spaceLeft );
}
void QskInputPanel::processKey( int key,
Qt::InputMethodHints inputHints, int spaceLeft )
{
const auto result = m_data->engine->processKey( key, inputHints, spaceLeft );
auto inputItem = m_data->inputItem;
if ( result.key )
{
switch( result.key )
{
case Qt::Key_Return:
{
Q_EMIT done( true );
break;
}
case Qt::Key_Escape:
{
Q_EMIT done( false );
break;
}
default:
{
Q_EMIT keyEntered( result.key );
}
}
}
else if ( !result.text.isEmpty() )
{
Q_EMIT textEntered( result.text, result.isFinal );
}
}
void QskInputPanel::processInputMethodQueries( Qt::InputMethodQueries queries )
{
if ( m_data->inputItem == nullptr )
return;
QInputMethodQueryEvent event( queries );
QCoreApplication::sendEvent( m_data->inputItem, &event );
if ( event.queries() & Qt::ImHints )
{
bool hasPrediction = true;
QskTextInput::EchoMode echoMode = QskTextInput::Normal;
const auto hints = static_cast< Qt::InputMethodHints >(
event.value( Qt::ImHints ).toInt() );
if ( hints & Qt::ImhHiddenText )
{
echoMode = QskTextInput::NoEcho;
}
/*
- Qt::ImhSensitiveData
- Qt::ImhNoAutoUppercase
- Qt::ImhMultiLine
// we should start in a specific mode
- Qt::ImhPreferNumbers
- Qt::ImhPreferUppercase
- Qt::ImhPreferLowercase
- Qt::ImhPreferLatin
// we should lock all other modes
- Qt::ImhFormattedNumbersOnly
- Qt::ImhUppercaseOnly
- Qt::ImhDialableCharactersOnly
- Qt::ImhEmailCharactersOnly
- Qt::ImhUrlCharactersOnly
- Qt::ImhLatinOnly
// we should have specific input panels
- Qt::ImhDate
- Qt::ImhTime
- Qt::ImhDigitsOnly
- Qt::ImhFormattedNumbersOnly
*/
m_data->hasPrediction =
!( hints & ( Qt::ImhNoPredictiveText | Qt::ImhExclusiveInputMask ) );
m_data->predictionBar->setVisible(
hasPrediction && m_data->engine && m_data->engine->predictor() );
m_data->inputProxy->setEchoMode( echoMode );
m_data->inputHints = hints;
}
if ( event.queries() & Qt::ImPreferredLanguage )
{
// already handled by the input context
}
if ( event.queries() & Qt::ImMaximumTextLength )
{
// needs to be handled before Qt::ImCursorPosition !
m_data->maxChars = event.value( Qt::ImMaximumTextLength ).toInt();
#if 1
if ( m_data->maxChars >= 32767 )
m_data->maxChars = -1;
#endif
if ( m_data->hasInputProxy )
m_data->inputProxy->setMaxLength( m_data->maxChars );
}
if ( event.queries() & Qt::ImSurroundingText )
{
if ( m_data->hasInputProxy )
{
const auto text = event.value( Qt::ImSurroundingText ).toString();
m_data->inputProxy->setText( text );
}
}
if ( event.queries() & Qt::ImCursorPosition )
{
if ( m_data->hasInputProxy )
{
const auto pos = event.value( Qt::ImCursorPosition ).toInt();
m_data->inputProxy->setCursorPosition( pos );
}
}
if ( event.queries() & Qt::ImCurrentSelection )
{
#if 0
const auto text = event.value( Qt::ImCurrentSelection ).toString();
if ( !text.isEmpty() )
{
}
#endif
}
/*
Qt::ImMicroFocus
Qt::ImCursorRectangle
Qt::ImFont
Qt::ImAnchorPosition
Qt::ImAbsolutePosition
Qt::ImTextBeforeCursor
Qt::ImTextAfterCursor
Qt::ImPlatformData // hard to say...
Qt::ImEnterKeyType
Qt::ImAnchorRectangle
Qt::ImInputItemClipRectangle
*/
m_data->predictionBar->setPrediction( prediction );
}
void QskInputPanel::keyPressEvent( QKeyEvent* event )
@ -473,7 +205,7 @@ void QskInputPanel::keyPressEvent( QKeyEvent* event )
case Qt::Key_Return:
case Qt::Key_Escape:
{
commitKey( event->key() );
Q_EMIT keySelected( event->key() );
break;
}
@ -492,17 +224,13 @@ void QskInputPanel::keyPressEvent( QKeyEvent* event )
default:
{
const auto text = event->text();
if ( !text.isEmpty() )
commitKey( text[0].unicode() );
else
commitKey( event->key() );
}
}
}
void QskInputPanel::keyReleaseEvent( QKeyEvent* event )
{
return Inherited::keyReleaseEvent( event );
if ( !text.isEmpty() )
Q_EMIT keySelected( text[0].unicode() );
else
Q_EMIT keySelected( event->key() );
}
}
}
#include "moc_QskInputPanel.cpp"

View File

@ -20,8 +20,8 @@ class QSK_EXPORT QskInputPanel : public QskBox
using Inherited = QskBox;
Q_PROPERTY( bool inputProxy READ hasInputProxy
WRITE setInputProxy NOTIFY inputProxyChanged )
Q_PROPERTY( PanelHints panelHints READ panelHints
WRITE setPanelHints NOTIFY panelHintsChanged )
Q_PROPERTY( QString inputPrompt READ inputPrompt
WRITE setInputPrompt NOTIFY inputPromptChanged )
@ -29,16 +29,26 @@ class QSK_EXPORT QskInputPanel : public QskBox
public:
QSK_SUBCONTROLS( Panel )
enum PanelHint
{
InputProxy = 1 << 0,
Prediction = 1 << 1
};
Q_ENUM( PanelHint )
Q_DECLARE_FLAGS( PanelHints, PanelHint )
QskInputPanel( QQuickItem* parent = nullptr );
virtual ~QskInputPanel() override;
void attachInputItem( QQuickItem* );
QQuickItem* attachedInputItem() const;
void setEngine( QskInputEngine* );
QskInputEngine* engine();
void setPanelHint( PanelHint, bool on );
void setPanelHints( PanelHints );
PanelHints panelHints() const;
bool hasInputProxy() const;
QQuickItem* inputProxy() const;
QString inputPrompt() const;
@ -46,35 +56,26 @@ public:
virtual QskAspect::Subcontrol effectiveSubcontrol(
QskAspect::Subcontrol ) const override;
virtual void processInputMethodQueries( Qt::InputMethodQueries );
Q_SIGNALS:
void inputProxyChanged( bool );
void panelHintsChanged();
void inputPromptChanged( const QString& );
void textEntered( const QString&, bool isFinal );
void keyEntered( int keyCode );
void done( bool success );
void keySelected( int keyCode );
void predictiveTextSelected( int );
public Q_SLOTS:
void setInputPrompt( const QString& );
void setInputProxy( bool );
void setPrediction( const QStringList& );
protected:
virtual void keyPressEvent( QKeyEvent* ) override;
virtual void keyReleaseEvent( QKeyEvent* ) override;
virtual void processKey( int key,
Qt::InputMethodHints, int spaceLeft );
virtual void updatePrediction();
private:
void commitKey( int key );
void commitPredictiveText( int );
class PrivateData;
std::unique_ptr< PrivateData > m_data;
};
Q_DECLARE_OPERATORS_FOR_FLAGS( QskInputPanel::PanelHints )
Q_DECLARE_METATYPE( QskInputPanel::PanelHints )
#endif