qskinny/qmlexport/QskShortcutQml.cpp

276 lines
6.0 KiB
C++
Raw Normal View History

2017-07-21 18:21:34 +02:00
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* This file may be used under the terms of the QSkinny License, Version 1.0
*****************************************************************************/
2019-05-12 13:54:22 +02:00
#include "QskShortcutQml.h"
#include <QskShortcutMap.h>
2018-07-19 14:10:48 +02:00
#include <qquickitem.h>
#include <qquickwindow.h>
QSK_QT_PRIVATE_BEGIN
2017-12-03 17:58:18 +01:00
#include <QtGui/private/qguiapplication_p.h>
2018-07-19 14:10:48 +02:00
QSK_QT_PRIVATE_END
2017-07-21 18:21:34 +02:00
2017-12-05 17:40:21 +01:00
static inline QShortcutMap& qskShortcutMap()
{
return QGuiApplicationPrivate::instance()->shortcutMap;
}
static bool qskContextMatcher( QObject* object, Qt::ShortcutContext context )
2017-07-21 18:21:34 +02:00
{
if ( context == Qt::ApplicationShortcut )
return true;
if ( context == Qt::WindowShortcut )
{
2019-05-12 13:54:22 +02:00
if ( const auto shortcut = qobject_cast< const QskShortcutQml* >( object ) )
return shortcut->isFocusInScope();
}
2017-07-21 18:21:34 +02:00
return false;
}
2017-12-05 17:40:21 +01:00
2019-05-12 13:54:22 +02:00
class QskShortcutQml::PrivateData
{
2018-08-03 08:15:28 +02:00
public:
PrivateData()
: id( 0 )
, autoRepeat( true )
, enabled( true )
, isWindowContext( true )
, isComplete( true )
{
}
2017-07-21 18:21:34 +02:00
~PrivateData()
{
if ( id != 0 )
qskShortcutMap().removeShortcut( id, nullptr );
}
2017-07-21 18:21:34 +02:00
2019-05-12 13:54:22 +02:00
void resetShortcut( QskShortcutQml* shortcut )
{
if ( !isComplete )
return;
auto& map = qskShortcutMap();
2017-07-21 18:21:34 +02:00
const int oldId = id;
2017-07-21 18:21:34 +02:00
if ( id != 0 )
{
map.removeShortcut( id, nullptr );
id = 0;
}
if ( !sequence.isEmpty() )
2017-12-03 17:58:18 +01:00
{
id = map.addShortcut( shortcut, sequence,
shortcut->context(), qskContextMatcher );
if ( !autoRepeat )
map.setShortcutAutoRepeat( false, id, shortcut );
if ( !enabled )
map.setShortcutEnabled( false, id, shortcut );
2017-12-03 17:58:18 +01:00
}
if ( oldId != id )
2018-08-03 11:11:42 +02:00
Q_EMIT shortcut->shortcutIdChanged( id );
}
2018-08-03 08:15:28 +02:00
public:
QKeySequence sequence;
int id;
2017-07-21 18:21:34 +02:00
bool autoRepeat : 1;
bool enabled : 1;
bool isWindowContext : 1;
bool isComplete : 1;
2017-07-21 18:21:34 +02:00
};
2019-05-12 13:54:22 +02:00
QskShortcutQml::QskShortcutQml( QObject* parent )
2018-08-03 08:15:28 +02:00
: Inherited( parent )
, m_data( new PrivateData )
{
}
2019-05-12 13:54:22 +02:00
QskShortcutQml::QskShortcutQml( const QKeySequence& sequence, QObject* parent )
: QskShortcutQml( sequence, Qt::WindowShortcut, parent )
2017-07-21 18:21:34 +02:00
{
}
2017-07-21 18:21:34 +02:00
2019-05-12 13:54:22 +02:00
QskShortcutQml::QskShortcutQml( const QKeySequence& sequence,
2018-08-03 08:15:28 +02:00
Qt::ShortcutContext context, QObject* parent )
: Inherited( parent )
, m_data( new PrivateData )
{
m_data->sequence = sequence;
m_data->isWindowContext = ( context == Qt::WindowShortcut );
m_data->resetShortcut( this );
}
2019-05-12 13:54:22 +02:00
QskShortcutQml::~QskShortcutQml()
{
}
2017-12-03 17:58:18 +01:00
2019-05-12 13:54:22 +02:00
int QskShortcutQml::shortcutId() const
{
return m_data->id;
2017-12-03 17:58:18 +01:00
}
2019-05-12 13:54:22 +02:00
Qt::ShortcutContext QskShortcutQml::context() const
2017-12-03 17:58:18 +01:00
{
return m_data->isWindowContext
? Qt::WindowShortcut : Qt::ApplicationShortcut;
}
2019-05-12 13:54:22 +02:00
void QskShortcutQml::setContext( Qt::ShortcutContext context )
{
2018-08-03 08:15:28 +02:00
if ( context == Qt::ApplicationShortcut ||
context == Qt::WindowShortcut )
2017-12-05 17:40:21 +01:00
{
const bool isWindowContext = ( context == Qt::WindowShortcut );
2017-12-03 17:58:18 +01:00
if ( isWindowContext != m_data->isWindowContext )
2017-12-05 17:40:21 +01:00
{
m_data->isWindowContext = isWindowContext;
m_data->resetShortcut( this );
Q_EMIT contextChanged();
}
}
2017-07-21 18:21:34 +02:00
}
2019-05-12 13:54:22 +02:00
void QskShortcutQml::setSequence( const QKeySequence& sequence )
2017-12-05 17:40:21 +01:00
{
if ( sequence != m_data->sequence )
2017-12-05 17:40:21 +01:00
{
m_data->sequence = sequence;
m_data->resetShortcut( this );
2017-12-05 17:40:21 +01:00
Q_EMIT sequenceChanged();
2017-12-05 17:40:21 +01:00
}
}
2017-12-05 17:40:21 +01:00
2019-05-12 13:54:22 +02:00
QKeySequence QskShortcutQml::sequence() const
{
return m_data->sequence;
}
2017-12-05 17:40:21 +01:00
2019-05-12 13:54:22 +02:00
void QskShortcutQml::setSequenceVariant( const QVariant& sequence )
{
if ( sequence.type() == QVariant::Int )
2018-08-03 08:15:28 +02:00
setSequence( static_cast< QKeySequence::StandardKey >( sequence.toInt() ) );
else
setSequence( QKeySequence::fromString( sequence.toString() ) );
2017-12-05 17:40:21 +01:00
}
2019-05-12 13:54:22 +02:00
QVariant QskShortcutQml::sequenceVariant() const
2017-12-03 17:58:18 +01:00
{
return m_data->sequence.toString();
}
2017-12-05 17:40:21 +01:00
2019-05-12 13:54:22 +02:00
void QskShortcutQml::setEnabled( bool on )
{
if ( on != m_data->enabled )
2017-12-03 17:58:18 +01:00
{
m_data->enabled = on;
if ( m_data->id != 0 )
qskShortcutMap().setShortcutEnabled( on, m_data->id, this );
2017-12-03 17:58:18 +01:00
Q_EMIT enabledChanged();
2017-12-03 17:58:18 +01:00
}
}
2019-05-12 13:54:22 +02:00
bool QskShortcutQml::isEnabled() const
2017-07-21 18:21:34 +02:00
{
return m_data->enabled;
}
2019-05-12 13:54:22 +02:00
void QskShortcutQml::setAutoRepeat( bool on )
{
if ( on != m_data->autoRepeat )
2017-07-21 18:21:34 +02:00
{
m_data->autoRepeat = on;
if ( m_data->id != 0 )
qskShortcutMap().setShortcutEnabled( on, m_data->id, this );
Q_EMIT autoRepeatChanged();
}
2017-07-21 18:21:34 +02:00
}
2019-05-12 13:54:22 +02:00
bool QskShortcutQml::autoRepeat() const
2017-07-21 18:21:34 +02:00
{
return m_data->autoRepeat;
2017-07-21 18:21:34 +02:00
}
2019-05-12 13:54:22 +02:00
bool QskShortcutQml::event( QEvent* event )
2017-07-21 18:21:34 +02:00
{
if ( event->type() == QEvent::Shortcut )
2017-07-21 18:21:34 +02:00
{
auto* shortcutEvent = static_cast< QShortcutEvent* >( event );
if ( shortcutEvent->shortcutId() == m_data->id )
2017-07-21 18:21:34 +02:00
{
if ( shortcutEvent->isAmbiguous() )
Q_EMIT activatedAmbiguously();
2017-12-03 17:58:18 +01:00
else
Q_EMIT activated();
2017-07-21 18:21:34 +02:00
return true;
}
2017-07-21 18:21:34 +02:00
}
return false;
}
2019-05-12 13:54:22 +02:00
bool QskShortcutQml::isFocusInScope() const
2017-07-21 18:21:34 +02:00
{
if ( !m_data->isWindowContext )
return true;
2017-07-21 18:21:34 +02:00
const QQuickItem* contextItem = nullptr;
2017-07-21 18:21:34 +02:00
if ( parent()->isWindowType() )
{
if ( auto window = qobject_cast< const QQuickWindow* >( parent() ) )
contextItem = window->contentItem();
}
else
{
contextItem = qobject_cast< const QQuickItem* >( parent() );
}
2017-12-03 17:58:18 +01:00
if ( contextItem )
{
return QskShortcutMap::contextMatcher( contextItem, Qt::WindowShortcut );
}
else
{
qWarning( "QskShortcut has no valid parent for Qt::WindowShortcut" );
return false;
}
2017-12-03 17:58:18 +01:00
}
2019-05-12 13:54:22 +02:00
void QskShortcutQml::classBegin()
2017-07-21 18:21:34 +02:00
{
m_data->isComplete = false;
2017-12-03 17:58:18 +01:00
}
2019-05-12 13:54:22 +02:00
void QskShortcutQml::componentComplete()
2017-12-03 17:58:18 +01:00
{
if ( m_data->isComplete == false )
{
m_data->isComplete = true;
m_data->resetShortcut( this );
}
2017-07-21 18:21:34 +02:00
}
2017-12-05 17:40:21 +01:00
2019-05-12 13:54:22 +02:00
#include "moc_QskShortcutQml.cpp"