[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 ) 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 ) static inline QRectF qskFocusIndicatorRect( const QQuickItem* item )
{ {
if ( auto control = qobject_cast< const QskControl* >( item ) ) if ( auto control = qobject_cast< const QskControl* >( item ) )
@ -45,13 +23,26 @@ static inline QRectF qskFocusIndicatorRect( const QQuickItem* item )
return item->boundingRect(); 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 ): 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 ); setTransparentForPositioner( true );
resetConnections();
connectWindow( window(), true ); connectWindow( window(), true );
} }
@ -64,9 +55,15 @@ void QskFocusIndicator::onFocusItemGeometryChanged()
updateFocusFrame(); updateFocusFrame();
} }
void QskFocusIndicator::onFocusItemDestroyed()
{
m_data->resetConnections();
setVisible( false );
}
void QskFocusIndicator::onFocusItemChanged() void QskFocusIndicator::onFocusItemChanged()
{ {
disconnect( this, SLOT( onFocusItemGeometryChanged() ) ); m_data->resetConnections();
if ( window() == nullptr ) if ( window() == nullptr )
return; return;
@ -89,8 +86,7 @@ void QskFocusIndicator::onFocusItemChanged()
return; return;
} }
qskSetupGeometryConnections( focusItem, m_data->connections += connectItem( focusItem );
this, SLOT( onFocusItemGeometryChanged() ) );
const QQuickItem* item = focusItem; const QQuickItem* item = focusItem;
while ( item->parentItem() ) while ( item->parentItem() )
@ -118,8 +114,7 @@ void QskFocusIndicator::onFocusItemChanged()
item = itemParent; item = itemParent;
qskSetupGeometryConnections( item, m_data->connections += connectItem( item );
this, SLOT( onFocusItemGeometryChanged() ) );
} }
updateFocusFrame(); updateFocusFrame();
@ -156,23 +151,14 @@ QRectF QskFocusIndicator::focusRect() const
return QRectF(); return QRectF();
} }
void QskFocusIndicator::resetConnections()
{
disconnect( this, SLOT( updateFocusFrame() ) );
QQuickItem* item = parentItem();
if ( item )
{
qskSetupGeometryConnections( item, this, SLOT( updateFocusFrame() ) );
}
}
void QskFocusIndicator::windowChangeEvent( QskWindowChangeEvent* event ) void QskFocusIndicator::windowChangeEvent( QskWindowChangeEvent* event )
{ {
Inherited::windowChangeEvent( event ); Inherited::windowChangeEvent( event );
connectWindow( event->oldWindow(), false ); connectWindow( event->oldWindow(), false );
connectWindow( event->window(), true ); connectWindow( event->window(), true );
onFocusItemChanged();
} }
void QskFocusIndicator::connectWindow( const QQuickWindow* window, bool on ) 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" #include "moc_QskFocusIndicator.cpp"

View File

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