[Misc] bad disconnecting fixed

This commit is contained in:
Uwe Rathmann 2018-02-01 08:07:54 +01:00
parent bd68a86019
commit 2dc2278e6b
2 changed files with 71 additions and 47 deletions

View File

@ -12,28 +12,6 @@
QSK_SUBCONTROL( QskFocusIndicator, Panel )
static void qskSetupGeometryConnections(
const QQuickItem* sender, QQuickItem* receiver, const char* method )
{
QObject::connect( sender, SIGNAL( xChanged() ), receiver, method );
QObject::connect( sender, SIGNAL( yChanged() ), receiver, method );
QObject::connect( sender, SIGNAL( widthChanged() ), receiver, method );
QObject::connect( sender, SIGNAL( heightChanged() ), receiver, method );
QObject::connect( sender, SIGNAL( visibleChanged() ), receiver, method );
bool hasIndicatorSignal = ( qobject_cast< const QskControl* >( sender ) != nullptr );
if ( !hasIndicatorSignal )
{
const auto mo = sender->metaObject();
hasIndicatorSignal = ( mo->indexOfSignal( "focusIndicatorRectChanged()" ) >= 0 );
}
if ( hasIndicatorSignal )
{
QObject::connect( sender, SIGNAL( focusIndicatorRectChanged() ), receiver, method );
}
}
static inline QRectF qskFocusIndicatorRect( const QQuickItem* item )
{
if ( auto control = qobject_cast< const QskControl* >( item ) )
@ -46,12 +24,25 @@ static inline QRectF qskFocusIndicatorRect( const QQuickItem* item )
return item->boundingRect();
}
class QskFocusIndicator::PrivateData
{
public:
void resetConnections()
{
for ( const auto connection : connections )
QObject::disconnect( connection );
connections.clear();
}
QVector< QMetaObject::Connection > connections;
};
QskFocusIndicator::QskFocusIndicator( QQuickItem* parent ):
Inherited( parent ) // parentItem() might change, but parent() stays
Inherited( parent ), // parentItem() might change, but parent() stays
m_data( new PrivateData() )
{
setTransparentForPositioner( true );
resetConnections();
connectWindow( window(), true );
}
@ -64,9 +55,15 @@ void QskFocusIndicator::onFocusItemGeometryChanged()
updateFocusFrame();
}
void QskFocusIndicator::onFocusItemDestroyed()
{
m_data->resetConnections();
setVisible( false );
}
void QskFocusIndicator::onFocusItemChanged()
{
disconnect( this, SLOT( onFocusItemGeometryChanged() ) );
m_data->resetConnections();
if ( window() == nullptr )
return;
@ -89,8 +86,7 @@ void QskFocusIndicator::onFocusItemChanged()
return;
}
qskSetupGeometryConnections( focusItem,
this, SLOT( onFocusItemGeometryChanged() ) );
m_data->connections += connectItem( focusItem );
const QQuickItem* item = focusItem;
while ( item->parentItem() )
@ -118,8 +114,7 @@ void QskFocusIndicator::onFocusItemChanged()
item = itemParent;
qskSetupGeometryConnections( item,
this, SLOT( onFocusItemGeometryChanged() ) );
m_data->connections += connectItem( item );
}
updateFocusFrame();
@ -156,23 +151,14 @@ QRectF QskFocusIndicator::focusRect() const
return QRectF();
}
void QskFocusIndicator::resetConnections()
{
disconnect( this, SLOT( updateFocusFrame() ) );
QQuickItem* item = parentItem();
if ( item )
{
qskSetupGeometryConnections( item, this, SLOT( updateFocusFrame() ) );
}
}
void QskFocusIndicator::windowChangeEvent( QskWindowChangeEvent* event )
{
Inherited::windowChangeEvent( event );
connectWindow( event->oldWindow(), false );
connectWindow( event->window(), true );
onFocusItemChanged();
}
void QskFocusIndicator::connectWindow( const QQuickWindow* window, bool on )
@ -192,4 +178,36 @@ void QskFocusIndicator::connectWindow( const QQuickWindow* window, bool on )
}
}
QVector< QMetaObject::Connection > QskFocusIndicator::connectItem( const QQuickItem* sender )
{
QVector< QMetaObject::Connection > c;
c.reserve( 7 );
c += QObject::connect( sender, &QObject::destroyed,
this, &QskFocusIndicator::onFocusItemDestroyed );
const auto method = &QskFocusIndicator::onFocusItemGeometryChanged;
c += QObject::connect( sender, &QQuickItem::xChanged, this, method );
c += QObject::connect( sender, &QQuickItem::yChanged, this, method );
c += QObject::connect( sender, &QQuickItem::widthChanged, this, method );
c += QObject::connect( sender, &QQuickItem::heightChanged, this, method );
c += QObject::connect( sender, &QQuickItem::visibleChanged, this, method );
if ( const auto control = qobject_cast< const QskControl* >( sender ) )
{
c += QObject::connect( control, &QskControl::focusIndicatorRectChanged, this, method );
}
else
{
if ( sender->metaObject()->indexOfSignal( "focusIndicatorRectChanged()" ) >= 0 )
{
c += QObject::connect( sender, SIGNAL( focusIndicatorRectChanged() ),
this, SLOT( onFocusItemGeometryChanged() ) );
}
}
return c;
}
#include "moc_QskFocusIndicator.cpp"

View File

@ -8,6 +8,8 @@
#include "QskControl.h"
template class QVector< QMetaObject::Connection >;
class QSK_EXPORT QskFocusIndicator : public QskControl
{
Q_OBJECT
@ -22,17 +24,21 @@ public:
protected:
virtual void windowChangeEvent( QskWindowChangeEvent* ) override;
virtual QRectF focusRect() const;
private Q_SLOTS:
void updateFocusFrame();
void onFocusItemChanged();
void onFocusItemGeometryChanged();
private:
QRectF focusRect() const;
void onFocusItemChanged();
void onFocusItemDestroyed();
void updateFocusFrame();
void resetConnections();
void connectWindow( const QQuickWindow*, bool );
void connectWindow( const QQuickWindow*, bool on );
QVector< QMetaObject::Connection > connectItem( const QQuickItem* );
class PrivateData;
std::unique_ptr< PrivateData > m_data;
};
#endif