qskinny/inputcontext/QskInputContextPlugin.cpp

288 lines
6.6 KiB
C++
Raw Normal View History

2018-02-06 14:55:35 +01:00
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* This file may be used under the terms of the QSkinny License, Version 1.0
*****************************************************************************/
#include <qpa/qplatforminputcontext.h>
2018-08-03 08:15:28 +02:00
#include <qpa/qplatforminputcontextplugin_p.h>
2017-07-21 18:21:34 +02:00
#include "QskInputContext.h"
#define HUNSPELL 0
#if HUNSPELL
#include "QskHunspellTextPredictor.h"
#endif
2018-08-03 08:15:28 +02:00
#include <QEvent>
#include <QLocale>
#include <QRectF>
namespace
{
2018-06-12 08:20:48 +02:00
class InputContextFactory : public QskInputContextFactory
{
2018-08-03 08:15:28 +02:00
public:
2018-06-12 08:20:48 +02:00
virtual QskTextPredictor* createPredictor( const QLocale& locale ) const
{
#if HUNSPELL
/*
For the moment we manage the text prediction in the context
plugin - but of course it has to be moved somewhere else
*/
if ( locale.language() == QLocale::English )
return new QskHunspellTextPredictor();
#endif
2018-06-12 08:20:48 +02:00
return QskInputContextFactory::createPredictor( locale );
}
};
}
/*
QPlatformInputContext is no stable public API.
So we forward everything to QskInputContext
*/
class QskPlatformInputContext final : public QPlatformInputContext
{
Q_OBJECT
using Inherited = QPlatformInputContext;
2018-08-03 08:15:28 +02:00
public:
QskPlatformInputContext();
virtual ~QskPlatformInputContext() = default;
2018-07-31 17:32:25 +02:00
bool isValid() const override;
bool hasCapability( Capability ) const override;
2018-07-31 17:32:25 +02:00
void update( Qt::InputMethodQueries ) override;
Q_INVOKABLE void update( const QQuickItem*, Qt::InputMethodQueries );
2018-07-31 17:32:25 +02:00
void invokeAction( QInputMethod::Action, int ) override;
2018-07-31 17:32:25 +02:00
QRectF keyboardRect() const override;
bool isAnimating() const override;
2018-07-31 17:32:25 +02:00
void showInputPanel() override;
void hideInputPanel() override;
Q_INVOKABLE void setInputPanelVisible( const QQuickItem*, bool );
2018-07-31 17:32:25 +02:00
bool isInputPanelVisible() const override;
2018-07-31 17:32:25 +02:00
void reset() override;
void commit() override;
2018-07-31 17:32:25 +02:00
void setFocusObject( QObject* ) override;
2018-07-31 17:32:25 +02:00
QLocale locale() const override;
Qt::LayoutDirection inputDirection() const override;
2018-07-31 17:32:25 +02:00
bool filterEvent( const QEvent* ) override;
2018-08-03 08:15:28 +02:00
protected:
2018-07-31 17:32:25 +02:00
bool event( QEvent* ) override;
2018-08-03 08:15:28 +02:00
private:
void updateContext();
void updateLocale();
QLocale m_locale;
QPointer< QskInputContext > m_context;
};
QskPlatformInputContext::QskPlatformInputContext()
{
auto context = QskInputContext::instance();
if ( context == nullptr )
{
2018-06-12 08:20:48 +02:00
context = new QskInputContext();
context->setFactory( new InputContextFactory() );
QskInputContext::setInstance( context );
}
updateContext();
updateLocale();
}
void QskPlatformInputContext::updateContext()
{
if ( m_context )
m_context->disconnect( this );
m_context = QskInputContext::instance();
if ( m_context )
{
connect( m_context, &QskInputContext::activeChanged,
this, &QPlatformInputContext::emitInputPanelVisibleChanged );
connect( m_context, &QskInputContext::panelRectChanged,
this, &QPlatformInputContext::emitKeyboardRectChanged );
}
}
void QskPlatformInputContext::updateLocale()
{
if ( m_context )
{
const auto oldLocale = m_locale;
m_locale = m_context->locale();
2018-08-03 08:15:28 +02:00
if ( oldLocale != m_locale )
emitLocaleChanged();
2018-08-03 08:15:28 +02:00
if ( m_locale.textDirection() != oldLocale.textDirection() )
2018-08-03 08:15:28 +02:00
emitInputDirectionChanged( m_locale.textDirection() );
}
}
bool QskPlatformInputContext::isValid() const
{
return true;
}
bool QskPlatformInputContext::hasCapability( Capability ) const
{
// what is QPlatformInputContext::HiddenTextCapability ???
return true;
}
void QskPlatformInputContext::update( Qt::InputMethodQueries queries )
{
if ( m_context )
m_context->update( nullptr, queries );
}
void QskPlatformInputContext::update(
const QQuickItem* item, Qt::InputMethodQueries queries )
{
if ( m_context )
m_context->update( item, queries );
}
void QskPlatformInputContext::invokeAction(
QInputMethod::Action action, int cursorPosition )
{
2018-08-03 08:15:28 +02:00
if ( m_context )
m_context->invokeAction( action, cursorPosition );
}
QRectF QskPlatformInputContext::keyboardRect() const
{
if ( m_context )
return m_context->panelRect();
return QRectF();
}
bool QskPlatformInputContext::isAnimating() const
{
// who is interested in this ?
// also: emitAnimatingChanged
return false;
}
void QskPlatformInputContext::showInputPanel()
{
setInputPanelVisible( nullptr, true );
}
void QskPlatformInputContext::hideInputPanel()
{
setInputPanelVisible( nullptr, false );
}
void QskPlatformInputContext::setInputPanelVisible(
const QQuickItem* item, bool on )
{
if ( m_context )
m_context->setInputPanelVisible( item, on );
}
bool QskPlatformInputContext::isInputPanelVisible() const
{
if ( m_context )
return m_context->isInputPanelVisible();
return false;
}
void QskPlatformInputContext::reset()
{
if ( m_context )
m_context->commitPrediction( false );
}
void QskPlatformInputContext::commit()
{
if ( m_context )
m_context->commitPrediction( true );
}
void QskPlatformInputContext::setFocusObject( QObject* object )
{
if ( m_context )
m_context->setFocusObject( object );
}
QLocale QskPlatformInputContext::locale() const
{
return m_locale;
}
Qt::LayoutDirection QskPlatformInputContext::inputDirection() const
{
return m_locale.textDirection();
}
bool QskPlatformInputContext::filterEvent( const QEvent* )
{
// called from QXcbKeyboard, but what about other platforms
return false;
}
bool QskPlatformInputContext::event( QEvent* event )
{
2018-08-03 08:15:28 +02:00
switch ( event->type() )
{
case QEvent::LocaleChange:
{
updateLocale();
break;
}
case QEvent::PlatformPanel:
{
updateContext();
break;
}
default:
break;
}
return Inherited::event( event );
}
2017-07-21 18:21:34 +02:00
2018-04-01 12:47:44 +02:00
class QskInputContextPlugin final : public QPlatformInputContextPlugin
2017-07-21 18:21:34 +02:00
{
Q_OBJECT
Q_PLUGIN_METADATA( IID QPlatformInputContextFactoryInterface_iid FILE "metadata.json" )
2018-04-01 12:47:44 +02:00
2018-08-03 08:15:28 +02:00
public:
2018-07-31 17:32:25 +02:00
QPlatformInputContext* create(
2018-04-01 12:47:44 +02:00
const QString& system, const QStringList& ) override
2017-07-21 18:21:34 +02:00
{
2018-04-01 12:47:44 +02:00
if ( system.compare( QStringLiteral( "skinny" ), Qt::CaseInsensitive ) == 0 )
{
auto context = new QskPlatformInputContext();
return context;
}
2018-04-01 12:47:44 +02:00
2017-07-21 18:21:34 +02:00
return nullptr;
}
};
#include "QskInputContextPlugin.moc"