input panel stuff

This commit is contained in:
Uwe Rathmann 2018-04-01 12:47:44 +02:00
parent 897f6c520b
commit d947fb3999
7 changed files with 251 additions and 283 deletions

View File

@ -146,7 +146,7 @@ void QskInputCompositionModel::composeKey( Qt::Key key )
}
else if( hints & Qt::ImhMultiLine )
{
commit( qskKeyString( key ) );
commit( qskKeyString( key ) );
}
#if 0
else
@ -348,7 +348,7 @@ QVector< Qt::Key > QskInputCompositionModel::groups() const
return QVector< Qt::Key >();
}
void QskInputCompositionModel::setInputItem( QObject *inputItem )
void QskInputCompositionModel::setInputItem( QObject* inputItem )
{
m_data->inputItem = inputItem;
}

View File

@ -14,17 +14,30 @@
#include <QskSetup.h>
#include <QGuiApplication>
#include <QHash>
#include <QPointer>
QskInputContext::QskInputContext():
Inherited(),
m_defaultInputCompositionModel( new QskInputCompositionModel )
class QskInputContext::PrivateData
{
public:
QPointer< QQuickItem > inputItem;
QPointer< QskVirtualKeyboard > inputPanel;
QskInputCompositionModel* compositionModel;
QHash< QLocale, QskInputCompositionModel* > inputModels;
};
QskInputContext::QskInputContext() :
m_data( new PrivateData() )
{
m_data->compositionModel = new QskInputCompositionModel();
connect( qskSetup, &QskSetup::inputPanelChanged,
this, &QskInputContext::setInputPanel );
setInputPanel( qskSetup->inputPanel() );
QskPinyinCompositionModel* pinyinModel = new QskPinyinCompositionModel;
// For input methods outside skinny, call QskInputPanel::registerCompositionModelForLocale()
// see also: QskVirtualKeyboard::registerCompositionModelForLocale()
inputMethodRegistered( QLocale::Chinese, pinyinModel );
// We could connect candidatesChanged() here, but we don't emit
@ -33,13 +46,10 @@ QskInputContext::QskInputContext():
QskInputContext::~QskInputContext()
{
if ( m_inputPanel )
delete m_inputPanel;
if ( m_data->inputPanel )
delete m_data->inputPanel;
for( int a = 0; a < m_inputModels.values().count(); a++ )
{
delete m_inputModels.values()[a];
}
qDeleteAll( m_data->inputModels );
}
bool QskInputContext::isValid() const
@ -49,11 +59,11 @@ bool QskInputContext::isValid() const
void QskInputContext::update( Qt::InputMethodQueries queries )
{
if ( !m_inputItem )
if ( !m_data->inputItem )
return;
QInputMethodQueryEvent queryEvent( queries );
if ( !QCoreApplication::sendEvent( m_inputItem, &queryEvent ) )
if ( !QCoreApplication::sendEvent( m_data->inputItem, &queryEvent ) )
return;
// Qt::ImCursorRectangle
@ -98,26 +108,24 @@ void QskInputContext::update( Qt::InputMethodQueries queries )
{
const auto locale = queryEvent.value( Qt::ImPreferredLanguage ).toLocale();
auto oldModel = currentInputCompositionModel();
auto oldModel = compositionModel();
if( m_inputPanel )
m_inputPanel->setLocale( locale );
if( m_data->inputPanel )
m_data->inputPanel->setLocale( locale );
auto newModel = currentInputCompositionModel();
auto newModel = compositionModel();
bool modelChanged = ( oldModel != newModel );
if( modelChanged )
if( oldModel != newModel )
{
if( m_inputPanel )
if( m_data->inputPanel )
{
m_inputPanel->setCandidateBarVisible( newModel->supportsSuggestions() );
m_inputPanel->disconnect( oldModel );
QObject::connect(
newModel, &QskInputCompositionModel::groupsChanged,
m_inputPanel.data(), &QskVirtualKeyboard::setPreeditGroups );
QObject::connect(
newModel, &QskInputCompositionModel::candidatesChanged,
m_data->inputPanel->setCandidateBarVisible( newModel->supportsSuggestions() );
m_data->inputPanel->disconnect( oldModel );
connect( newModel, &QskInputCompositionModel::groupsChanged,
m_data->inputPanel.data(), &QskVirtualKeyboard::setPreeditGroups );
connect( newModel, &QskInputCompositionModel::candidatesChanged,
this, &QskInputContext::handleCandidatesChanged );
}
}
@ -131,10 +139,10 @@ void QskInputContext::update( Qt::InputMethodQueries queries )
QRectF QskInputContext::keyboardRect() const
{
if ( m_inputPanel
if ( m_data->inputPanel
&& QskDialog::instance()->policy() != QskDialog::TopLevelWindow )
{
return m_inputPanel->geometry();
return m_data->inputPanel->geometry();
}
return Inherited::keyboardRect();
@ -147,16 +155,16 @@ bool QskInputContext::isAnimating() const
void QskInputContext::showInputPanel()
{
if ( !m_inputPanel )
if ( !m_data->inputPanel )
{
setInputPanel( new QskVirtualKeyboard );
setInputPanel( new QskVirtualKeyboard() );
if ( QskDialog::instance()->policy() == QskDialog::TopLevelWindow )
{
auto window = new QskWindow;
window->setFlags( Qt::Tool | Qt::WindowDoesNotAcceptFocus );
window->resize( 800, 240 ); // ### what size?
m_inputPanel->setParentItem( window->contentItem() );
m_data->inputPanel->setParentItem( window->contentItem() );
connect( window, &QskWindow::visibleChanged,
this, &QskInputContext::emitInputPanelVisibleChanged );
}
@ -165,62 +173,62 @@ void QskInputContext::showInputPanel()
auto window = qobject_cast< QQuickWindow* >( QGuiApplication::focusWindow() );
if ( window )
{
m_inputPanel->setParentItem( window->contentItem() );
m_inputPanel->setSize( window->size() );
m_data->inputPanel->setParentItem( window->contentItem() );
m_data->inputPanel->setSize( window->size() );
}
}
}
auto window = m_inputPanel->window();
auto window = m_data->inputPanel->window();
if ( window && window != QGuiApplication::focusWindow() )
window->show();
else
m_inputPanel->setVisible( true );
m_data->inputPanel->setVisible( true );
}
void QskInputContext::hideInputPanel()
{
if ( !m_inputPanel )
if ( !m_data->inputPanel )
return;
auto window = m_inputPanel->window();
auto window = m_data->inputPanel->window();
if ( window && window != QGuiApplication::focusWindow() )
window->hide();
else
m_inputPanel->setVisible( false );
m_data->inputPanel->setVisible( false );
}
bool QskInputContext::isInputPanelVisible() const
{
return m_inputPanel && m_inputPanel->isVisible()
&& m_inputPanel->window() && m_inputPanel->window()->isVisible();
auto panel = m_data->inputPanel;
return panel && panel->isVisible()
&& panel->window() && panel->window()->isVisible();
}
QLocale QskInputContext::locale() const
{
return m_inputPanel ? m_inputPanel->locale() : QLocale();
return m_data->inputPanel ? m_data->inputPanel->locale() : QLocale();
}
void QskInputContext::setFocusObject( QObject* focusObject )
{
m_focusObject = focusObject;
if ( !m_focusObject )
if ( focusObject == nullptr )
{
m_inputItem = nullptr;
currentInputCompositionModel()->setInputItem( nullptr );
m_data->inputItem = nullptr;
compositionModel()->setInputItem( nullptr );
return;
}
bool inputItemChanged = false;
auto focusQuickItem = qobject_cast< QQuickItem* >( focusObject );
if( focusQuickItem )
auto focusItem = qobject_cast< QQuickItem* >( focusObject );
if( focusItem )
{
// Do not change the input item when panel buttons get the focus:
if( qskNearestFocusScope( focusQuickItem ) != m_inputPanel )
if( qskNearestFocusScope( focusItem ) != m_data->inputPanel )
{
m_inputItem = focusQuickItem;
currentInputCompositionModel()->setInputItem( m_inputItem ); // ### use a signal/slot connection
m_data->inputItem = focusItem;
compositionModel()->setInputItem( focusItem );
inputItemChanged = true;
}
}
@ -228,7 +236,7 @@ void QskInputContext::setFocusObject( QObject* focusObject )
if( inputItemChanged )
{
QInputMethodQueryEvent queryEvent( Qt::ImEnabled );
if ( !QCoreApplication::sendEvent( m_inputItem, &queryEvent ) )
if ( !QCoreApplication::sendEvent( m_data->inputItem, &queryEvent ) )
return;
if ( !queryEvent.value( Qt::ImEnabled ).toBool() )
@ -241,54 +249,44 @@ void QskInputContext::setFocusObject( QObject* focusObject )
update( Qt::InputMethodQuery( Qt::ImQueryAll & ~Qt::ImEnabled ) );
}
void QskInputContext::inputMethodRegistered( const QLocale& locale, QskInputCompositionModel* model )
void QskInputContext::inputMethodRegistered(
const QLocale& locale, QskInputCompositionModel* model )
{
auto oldModel = m_inputModels.value( locale, nullptr );
if( oldModel != nullptr )
{
if ( auto oldModel = m_data->inputModels.value( locale, nullptr ) )
oldModel->deleteLater();
}
m_inputModels.insert( locale, model );
m_data->inputModels.insert( locale, model );
}
QskInputCompositionModel* QskInputContext::compositionModelForLocale( const QLocale& locale ) const
QskInputCompositionModel* QskInputContext::compositionModel() const
{
return m_inputModels.value( locale, m_defaultInputCompositionModel );
}
QskInputCompositionModel* QskInputContext::currentInputCompositionModel() const
{
return m_inputModels.value( locale(), m_defaultInputCompositionModel );
}
void QskInputContext::resetCandidates()
{
m_inputPanel->setPreeditCandidates( {} );
return m_data->inputModels.value( locale(), m_data->compositionModel );
}
void QskInputContext::invokeAction( QInputMethod::Action action, int cursorPosition )
{
Q_UNUSED( cursorPosition );
if ( !m_inputPanel )
return;
auto model = compositionModel();
switch ( static_cast< QskVirtualKeyboard::Action >( action ) )
{
case QskVirtualKeyboard::Compose:
currentInputCompositionModel()->composeKey( static_cast< Qt::Key >( cursorPosition ) );
{
model->composeKey( static_cast< Qt::Key >( cursorPosition ) );
break;
}
case QskVirtualKeyboard::SelectGroup:
currentInputCompositionModel()->setGroupIndex( cursorPosition );
{
model->setGroupIndex( cursorPosition );
break;
}
case QskVirtualKeyboard::SelectCandidate:
currentInputCompositionModel()->commitCandidate( cursorPosition );
resetCandidates();
{
model->commitCandidate( cursorPosition );
if ( m_data->inputPanel )
m_data->inputPanel->setPreeditCandidates( QVector< QString >() );
break;
}
}
}
@ -299,32 +297,32 @@ void QskInputContext::emitAnimatingChanged()
void QskInputContext::handleCandidatesChanged()
{
QVector< QString > candidates( currentInputCompositionModel()->candidateCount() );
const auto model = compositionModel();
QVector< QString > candidates( model->candidateCount() );
for( int i = 0; i < candidates.length(); ++i )
{
candidates[i] = currentInputCompositionModel()->candidate( i );
}
candidates[i] = model->candidate( i );
m_inputPanel->setPreeditCandidates( candidates );
m_data->inputPanel->setPreeditCandidates( candidates );
}
void QskInputContext::setInputPanel( QskVirtualKeyboard* inputPanel )
{
if ( m_inputPanel == inputPanel )
if ( m_data->inputPanel == inputPanel )
return;
auto compositionModel = currentInputCompositionModel();
auto model = compositionModel();
if ( m_inputPanel )
if ( m_data->inputPanel )
{
m_inputPanel->disconnect( this );
m_data->inputPanel->disconnect( this );
if ( compositionModel )
compositionModel->disconnect( m_inputPanel );
if ( model )
model->disconnect( m_data->inputPanel );
}
m_inputPanel = inputPanel;
m_data->inputPanel = inputPanel;
if ( inputPanel )
{
@ -337,12 +335,12 @@ void QskInputContext::setInputPanel( QskVirtualKeyboard* inputPanel )
connect( inputPanel, &QskVirtualKeyboard::localeChanged,
this, &QPlatformInputContext::emitLocaleChanged );
if ( compositionModel )
if ( model )
{
inputPanel->setCandidateBarVisible(
compositionModel->supportsSuggestions() );
model->supportsSuggestions() );
connect( compositionModel, &QskInputCompositionModel::groupsChanged,
connect( model, &QskInputCompositionModel::groupsChanged,
inputPanel, &QskVirtualKeyboard::setPreeditGroups );
}
}

View File

@ -7,10 +7,6 @@
#define QSK_INPUT_CONTEXT_H
#include <qpa/qplatforminputcontext.h>
#include <QHash>
#include <QQuickItem>
#include <QPointer>
#include <memory>
class QskVirtualKeyboard;
@ -24,36 +20,35 @@ class QskInputContext : public QPlatformInputContext
public:
QskInputContext();
~QskInputContext() override;
virtual ~QskInputContext();
bool isValid() const override;
void update( Qt::InputMethodQueries ) override;
void invokeAction( QInputMethod::Action, int ) override;
QRectF keyboardRect() const override;
bool isAnimating() const override;
void showInputPanel() override;
void hideInputPanel() override;
bool isInputPanelVisible() const override;
QLocale locale() const override;
void setFocusObject( QObject* ) override;
virtual bool isValid() const override;
QskInputCompositionModel* compositionModelForLocale( const QLocale& locale ) const;
virtual void update( Qt::InputMethodQueries ) override;
virtual void invokeAction( QInputMethod::Action, int ) override;
virtual QRectF keyboardRect() const override;
virtual bool isAnimating() const override;
virtual void showInputPanel() override;
virtual void hideInputPanel() override;
virtual bool isInputPanelVisible() const override;
virtual void setFocusObject( QObject* ) override;
virtual QLocale locale() const override;
private Q_SLOTS:
void emitAnimatingChanged();
void handleCandidatesChanged();
void setInputPanel( QskVirtualKeyboard* );
void inputMethodRegistered( const QLocale& locale, QskInputCompositionModel* model );
void inputMethodRegistered( const QLocale&, QskInputCompositionModel* );
private:
QskInputCompositionModel* currentInputCompositionModel() const;
void resetCandidates();
QskInputCompositionModel* compositionModel() const;
QPointer< QObject > m_focusObject;
QPointer< QQuickItem > m_inputItem;
QPointer< QskVirtualKeyboard > m_inputPanel;
QskInputCompositionModel* m_defaultInputCompositionModel;
QHash< QLocale, QskInputCompositionModel* > m_inputModels;
class PrivateData;
std::unique_ptr< PrivateData > m_data;
};
#endif

View File

@ -7,16 +7,18 @@
#include "QskInputContext.h"
class QskInputContextPlugin : public QPlatformInputContextPlugin
class QskInputContextPlugin final : public QPlatformInputContextPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA( IID QPlatformInputContextFactoryInterface_iid FILE "metadata.json" )
public:
QPlatformInputContext* create( const QString& system, const QStringList& params ) override
virtual QPlatformInputContext* create(
const QString& system, const QStringList& ) override
{
Q_UNUSED( params );
if ( system.compare( system, QLatin1String( "skinny" ), Qt::CaseInsensitive ) == 0 )
if ( system.compare( QStringLiteral( "skinny" ), Qt::CaseInsensitive ) == 0 )
return new QskInputContext;
return nullptr;
}
};

View File

@ -9,11 +9,12 @@
#include <QDebug>
#include <QVector>
#include <QStringList>
class QskPinyinCompositionModel::PrivateData
{
public:
QList< QString > candidates;
QStringList candidates;
QVector< Qt::Key > groups;
};
@ -46,12 +47,15 @@ bool QskPinyinCompositionModel::supportsSuggestions() const
int QskPinyinCompositionModel::candidateCount() const
{
return qMax( 0, m_data->candidates.count() );
return m_data->candidates.count();
}
QString QskPinyinCompositionModel::candidate( int index ) const
{
return m_data->candidates.at( index );
if ( ( index >= 0 ) && ( index < m_data->candidates.count() ) )
return m_data->candidates[ index ];
return QString();
}
QVector< Qt::Key > QskPinyinCompositionModel::groups() const
@ -77,7 +81,7 @@ QString QskPinyinCompositionModel::polishPreedit( const QString& preedit )
if( numSearchResults > 0 )
{
QList< QString > newCandidates;
QStringList newCandidates;
newCandidates.reserve( 1 );
QVector< QChar > candidateBuffer;

View File

@ -4,21 +4,11 @@
*****************************************************************************/
#include "QskVirtualKeyboard.h"
#include "QskTextOptions.h"
#include "QskLinearBox.h"
#include "QskAspect.h"
#include <QskPushButton.h>
#include <QskTextLabel.h>
#include <QskDialog.h>
#include <QGuiApplication>
#include <QStyleHints>
#include <QskLinearBox.h>
#include <QskTextOptions.h>
#include <QTimer>
#include <cmath>
#include <unordered_map>
namespace
{
@ -131,24 +121,15 @@ static qreal qskRowStretch( const QskVirtualKeyboard::KeyRow& keyRow )
static bool qskIsAutorepeat( int key )
{
return ( key != Qt::Key_Return && key != Qt::Key_Enter
&& key != Qt::Key_Shift && key!= Qt::Key_CapsLock
&& key != Qt::Key_Mode_switch );
}
namespace
{
struct KeyCounter
{
int keyIndex;
int count;
};
&& key != Qt::Key_Shift && key != Qt::Key_CapsLock
&& key != Qt::Key_Mode_switch );
}
QSK_SUBCONTROL( QskVirtualKeyboardCandidateButton, Panel )
QSK_SUBCONTROL( QskVirtualKeyboardCandidateButton, Text )
QskVirtualKeyboardCandidateButton::QskVirtualKeyboardCandidateButton(QskVirtualKeyboard* inputPanel, QQuickItem* parent ) :
QskVirtualKeyboardCandidateButton::QskVirtualKeyboardCandidateButton(
QskVirtualKeyboard* inputPanel, QQuickItem* parent ) :
Inherited( parent ),
m_inputPanel( inputPanel ),
m_index( -1 )
@ -195,7 +176,8 @@ QSK_SUBCONTROL( QskVirtualKeyboardButton, Panel )
QSK_SUBCONTROL( QskVirtualKeyboardButton, Text )
QSK_SUBCONTROL( QskVirtualKeyboardButton, TextCancelButton )
QskVirtualKeyboardButton::QskVirtualKeyboardButton( int keyIndex, QskVirtualKeyboard* inputPanel, QQuickItem* parent ) :
QskVirtualKeyboardButton::QskVirtualKeyboardButton(
int keyIndex, QskVirtualKeyboard* inputPanel, QQuickItem* parent ) :
Inherited( parent ),
m_keyIndex( keyIndex ),
m_inputPanel( inputPanel )
@ -218,26 +200,21 @@ QskVirtualKeyboardButton::QskVirtualKeyboardButton( int keyIndex, QskVirtualKeyb
updateText();
connect( this, &QskVirtualKeyboardButton::pressed, this, [ this ]()
{
m_inputPanel->handleKey( m_keyIndex );
} );
connect( this, &QskVirtualKeyboardButton::pressed, this,
[ this ]() { m_inputPanel->handleKey( m_keyIndex ); } );
connect( m_inputPanel, &QskVirtualKeyboard::modeChanged, this, &QskVirtualKeyboardButton::updateText );
connect( m_inputPanel, &QskVirtualKeyboard::modeChanged,
this, &QskVirtualKeyboardButton::updateText );
}
QskAspect::Subcontrol QskVirtualKeyboardButton::effectiveSubcontrol( QskAspect::Subcontrol subControl ) const
QskAspect::Subcontrol QskVirtualKeyboardButton::effectiveSubcontrol(
QskAspect::Subcontrol subControl ) const
{
if( subControl == QskPushButton::Panel )
{
return QskVirtualKeyboardButton::Panel;
}
if( subControl == QskPushButton::Text )
{
// ### we could also introduce a state to not always query the button
return isCancelButton() ? QskVirtualKeyboardButton::TextCancelButton : QskVirtualKeyboardButton::Text;
}
return isCancelButton() ? TextCancelButton : Text;
return subControl;
}
@ -271,40 +248,39 @@ bool QskVirtualKeyboardButton::isCancelButton() const
class QskVirtualKeyboard::PrivateData
{
public:
PrivateData():
currentLayout( nullptr ),
mode( QskVirtualKeyboard::LowercaseMode ),
selectedGroup( -1 ),
candidateOffset( 0 ),
candidateBox( nullptr ),
buttonsBox( nullptr ),
isUIInitialized( false ),
candidateBoxVisible( false )
{
}
public:
PrivateData():
currentLayout( nullptr ),
mode( QskVirtualKeyboard::LowercaseMode ),
selectedGroup( -1 ),
candidateOffset( 0 ),
candidateBox( nullptr ),
buttonsBox( nullptr ),
isUIInitialized( false ),
candidateBoxVisible( false )
{
}
public:
const QskVirtualKeyboardLayouts::Layout* currentLayout;
QskVirtualKeyboard::Mode mode;
public:
const QskVirtualKeyboardLayouts::Layout* currentLayout;
QskVirtualKeyboard::Mode mode;
qint16 selectedGroup;
qint32 candidateOffset;
qint16 selectedGroup;
qint32 candidateOffset;
QLocale locale;
QLocale locale;
QVector< Qt::Key > groups;
QVector< QString > candidates;
QVector< Qt::Key > groups;
QVector< QString > candidates;
std::unordered_map< int, KeyCounter > activeKeys;
KeyTable keyTable[ ModeCount ];
KeyTable keyTable[ ModeCount ];
QList< QskVirtualKeyboardCandidateButton* > candidateButtons;
QskLinearBox* candidateBox;
QskLinearBox* buttonsBox;
QList< QskVirtualKeyboardButton* > keyButtons;
bool isUIInitialized;
bool candidateBoxVisible;
QList< QskVirtualKeyboardCandidateButton* > candidateButtons;
QskLinearBox* candidateBox;
QskLinearBox* buttonsBox;
QList< QskVirtualKeyboardButton* > keyButtons;
bool isUIInitialized;
bool candidateBoxVisible;
};
QskVirtualKeyboard::QskVirtualKeyboard( QQuickItem* parent ):
@ -320,8 +296,8 @@ QskVirtualKeyboard::QskVirtualKeyboard( QQuickItem* parent ):
updateLocale( locale() );
QObject::connect( this, &QskControl::localeChanged,
this, &QskVirtualKeyboard::updateLocale );
connect( this, &QskControl::localeChanged,
this, &QskVirtualKeyboard::updateLocale );
setFlag( ItemIsFocusScope, true );
@ -331,47 +307,43 @@ QskVirtualKeyboard::QskVirtualKeyboard( QQuickItem* parent ):
setAutoLayoutChildren( true );
auto& panelKeyData = keyData();
m_data->buttonsBox = new QskLinearBox( Qt::Vertical, this );
m_data->buttonsBox->setAutoAddChildren( true );
const auto& panelKeyData = keyData();
for( const auto& keyRow : panelKeyData )
{
QskLinearBox* rowBox = new QskLinearBox( Qt::Horizontal, m_data->buttonsBox );
auto rowBox = new QskLinearBox( Qt::Horizontal, m_data->buttonsBox );
rowBox->setAutoAddChildren( true );
for( const auto& keyData : keyRow )
{
if( !keyData.key )
{
continue;
}
int keyIndex = m_data->keyTable[ m_data->mode ].indexOf( &keyData );
QskVirtualKeyboardButton* button = new QskVirtualKeyboardButton( keyIndex, this, rowBox );
const int keyIndex = m_data->keyTable[ m_data->mode ].indexOf( &keyData );
auto button = new QskVirtualKeyboardButton( keyIndex, this, rowBox );
rowBox->setRetainSizeWhenHidden( button, true );
m_data->keyButtons.append( button );
}
}
connect( this, &QskVirtualKeyboard::modeChanged, this, [ this ]() {
updateLayout();
});
connect( this, &QskVirtualKeyboard::modeChanged,
this, [ this ]() { updateLayout(); } );
}
QskVirtualKeyboard::~QskVirtualKeyboard()
{
}
QskAspect::Subcontrol QskVirtualKeyboard::effectiveSubcontrol( QskAspect::Subcontrol subControl ) const
QskAspect::Subcontrol QskVirtualKeyboard::effectiveSubcontrol(
QskAspect::Subcontrol subControl ) const
{
if( subControl == QskBox::Panel )
{
return QskVirtualKeyboard::Panel;
}
return subControl;
}
@ -459,22 +431,22 @@ QString QskVirtualKeyboard::displayLanguageName() const
return QStringLiteral( "Eλληνικά" );
case QLocale::English:
{
switch( locale.country() )
{
switch( locale.country() )
{
case QLocale::Canada:
case QLocale::UnitedStates:
case QLocale::UnitedStatesMinorOutlyingIslands:
case QLocale::UnitedStatesVirginIslands:
return QStringLiteral( "English (US)" );
case QLocale::Canada:
case QLocale::UnitedStates:
case QLocale::UnitedStatesMinorOutlyingIslands:
case QLocale::UnitedStatesVirginIslands:
return QStringLiteral( "English (US)" );
default:
return QStringLiteral( "English (UK)" );
}
break;
default:
return QStringLiteral( "English (UK)" );
}
break;
}
case QLocale::Spanish:
return QStringLiteral( "Español" );
@ -572,30 +544,31 @@ void QskVirtualKeyboard::setCandidateOffset( int candidateOffset )
for( int i = 0; i < count; ++i )
{
auto button = m_data->candidateButtons[i];
if( continueLeft && i == 0 )
{
m_data->candidateButtons.at( i )->setIndexAndText( i, textForKey( Qt::Key_ApplicationLeft ) );
button->setIndexAndText( i, textForKey( Qt::Key_ApplicationLeft ) );
}
else if( continueRight && ( i == KeyCount - groupCount - 1 ) )
{
m_data->candidateButtons.at( i )->setIndexAndText( i, textForKey( Qt::Key_ApplicationRight ) );
button->setIndexAndText( i, textForKey( Qt::Key_ApplicationRight ) );
}
else
{
int index = i + m_data->candidateOffset;
QString text = m_data->candidates.at( index );
m_data->candidateButtons.at( i )->setIndexAndText( index, text );
const int index = i + m_data->candidateOffset;
button->setIndexAndText( index, m_data->candidates[index] );
}
}
for( int i = count; i < QskVirtualKeyboardCandidateButton::maxCandidates(); ++i )
{
m_data->candidateButtons.at( i )->setIndexAndText( -1, QStringLiteral( "" ) );
m_data->candidateButtons[i]->setIndexAndText( -1, QString() );
}
}
void QskVirtualKeyboard::registerCompositionModelForLocale( const QLocale& locale,
QskInputCompositionModel* model )
void QskVirtualKeyboard::registerCompositionModelForLocale(
const QLocale& locale, QskInputCompositionModel* model )
{
Q_EMIT inputMethodRegistered( locale, model );
}
@ -604,7 +577,6 @@ void QskVirtualKeyboard::geometryChanged(
const QRectF& newGeometry, const QRectF& oldGeometry )
{
Inherited::geometryChanged( newGeometry, oldGeometry );
Q_EMIT keyboardRectChanged();
}
@ -637,8 +609,6 @@ void QskVirtualKeyboard::updateLayout()
void QskVirtualKeyboard::createUI()
{
// deferring the UI creation until we are visible so that the contentsRect() returns the proper value
setAutoLayoutChildren( true );
auto outerBox = new QskLinearBox( Qt::Vertical, this );
@ -655,21 +625,22 @@ void QskVirtualKeyboard::createUI()
// ### Can this be done with the layout engine or so?
QRectF rect = layoutRect();
auto candidateButtonWidth = rect.width() / QskVirtualKeyboardCandidateButton::maxCandidates()
- m_data->candidateBox->spacing() * QskVirtualKeyboardCandidateButton::maxCandidates();
- m_data->candidateBox->spacing() * QskVirtualKeyboardCandidateButton::maxCandidates();
for( int a = 0; a < QskVirtualKeyboardCandidateButton::maxCandidates(); ++a )
{
auto candidateButton = new QskVirtualKeyboardCandidateButton( this, m_data->candidateBox );
qreal height = candidateButton->sizeHint().height();
#if 1
// should be done by margins/paddings
candidateButton->setPreferredHeight( height + 10 );
#endif
candidateButton->setPreferredWidth( candidateButtonWidth );
candidateButton->installEventFilter( this );
auto button = new QskVirtualKeyboardCandidateButton( this, m_data->candidateBox );
m_data->candidateBox->setRetainSizeWhenHidden( candidateButton, true );
m_data->candidateButtons.append( candidateButton );
qreal height = button->sizeHint().height();
#if 1
// should be done by margins/paddings
button->setPreferredHeight( height + 10 );
#endif
button->setPreferredWidth( candidateButtonWidth );
button->installEventFilter( this );
m_data->candidateBox->setRetainSizeWhenHidden( button, true );
m_data->candidateButtons.append( button );
}
m_data->candidateBox->setVisible( m_data->candidateBoxVisible );
@ -678,16 +649,15 @@ void QskVirtualKeyboard::createUI()
void QskVirtualKeyboard::updateUI()
{
for( QskVirtualKeyboardButton* button : qskAsConst( m_data->keyButtons ) )
{
for( auto button : qskAsConst( m_data->keyButtons ) )
button->updateText();
}
}
QskVirtualKeyboard::KeyData& QskVirtualKeyboard::keyDataAt( int keyIndex ) const
{
const auto row = keyIndex / KeyCount;
const auto col = keyIndex % KeyCount;
return m_data->keyTable[ m_data->mode ].data[ row ][ col ];
}
@ -711,8 +681,8 @@ void QskVirtualKeyboard::handleKey( int keyIndex )
case Qt::Key_Mode_switch: // Cycle through modes, but skip caps
setMode( static_cast< QskVirtualKeyboard::Mode >(
m_data->mode ? ( ( m_data->mode + 1 ) % QskVirtualKeyboard::ModeCount )
: SpecialCharacterMode ) );
m_data->mode ? ( ( m_data->mode + 1 ) % QskVirtualKeyboard::ModeCount )
: SpecialCharacterMode ) );
return;
// This is (one of) the cancel symbol, not Qt::Key_Cancel:
@ -822,24 +792,24 @@ void QskVirtualKeyboard::updateLocale( const QLocale& locale )
break;
case QLocale::English:
{
switch( locale.country() )
{
switch( locale.country() )
{
case QLocale::Canada:
case QLocale::UnitedStates:
case QLocale::UnitedStatesMinorOutlyingIslands:
case QLocale::UnitedStatesVirginIslands:
m_data->currentLayout = &qskKeyboardLayouts.en_US;
break;
case QLocale::Canada:
case QLocale::UnitedStates:
case QLocale::UnitedStatesMinorOutlyingIslands:
case QLocale::UnitedStatesVirginIslands:
m_data->currentLayout = &qskKeyboardLayouts.en_US;
break;
default:
m_data->currentLayout = &qskKeyboardLayouts.en_GB;
break;
}
break;
default:
m_data->currentLayout = &qskKeyboardLayouts.en_GB;
break;
}
break;
}
case QLocale::Spanish:
m_data->currentLayout = &qskKeyboardLayouts.es;
break;

View File

@ -39,27 +39,27 @@ private:
class QSK_EXPORT QskVirtualKeyboardButton : public QskPushButton
{
Q_OBJECT
Q_OBJECT
using Inherited = QskPushButton;
using Inherited = QskPushButton;
public:
QSK_SUBCONTROLS( Panel, Text, TextCancelButton )
public:
QSK_SUBCONTROLS( Panel, Text, TextCancelButton )
QskVirtualKeyboardButton( int keyIndex, QskVirtualKeyboard* inputPanel, QQuickItem* parent = nullptr );
QskVirtualKeyboardButton( int keyIndex, QskVirtualKeyboard* inputPanel, QQuickItem* parent = nullptr );
virtual QskAspect::Subcontrol effectiveSubcontrol( QskAspect::Subcontrol subControl ) const override;
virtual QskAspect::Subcontrol effectiveSubcontrol( QskAspect::Subcontrol subControl ) const override;
int keyIndex() const;
int keyIndex() const;
public Q_SLOTS:
void updateText();
public Q_SLOTS:
void updateText();
private:
bool isCancelButton() const;
private:
bool isCancelButton() const;
const int m_keyIndex;
QskVirtualKeyboard* m_inputPanel;
const int m_keyIndex;
QskVirtualKeyboard* m_inputPanel;
};
class QSK_EXPORT QskVirtualKeyboard : public QskBox
@ -67,7 +67,7 @@ class QSK_EXPORT QskVirtualKeyboard : public QskBox
Q_OBJECT
Q_PROPERTY( QString displayLanguageName READ displayLanguageName
NOTIFY displayLanguageNameChanged )
NOTIFY displayLanguageNameChanged )
using Inherited = QskBox;
@ -125,19 +125,18 @@ public:
QString displayLanguageName() const;
// takes ownership:
void registerCompositionModelForLocale( const QLocale& locale,
QskInputCompositionModel* model );
void registerCompositionModelForLocale( const QLocale&, QskInputCompositionModel* );
void handleKey( int keyIndex );
KeyData& keyDataAt( int ) const;
QString currentTextForKeyIndex( int keyIndex ) const;
void handleCandidateKey( int index, const QString &text );
void handleCandidateKey( int index, const QString& text );
void setCandidateBarVisible( bool visible );
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;