diff --git a/libdiscover/Transaction/TransactionListener.cpp b/libdiscover/Transaction/TransactionListener.cpp index b344445b..d9952a17 100644 --- a/libdiscover/Transaction/TransactionListener.cpp +++ b/libdiscover/Transaction/TransactionListener.cpp @@ -1,155 +1,159 @@ /*************************************************************************** * Copyright © 2010 Jonathan Thomas * * Copyright © 2012 Aleix Pol Gonzalez * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * * published by the Free Software Foundation; either version 2 of * * the License or (at your option) version 3 or any later version * * accepted by the membership of KDE e.V. (or its successor approved * * by the membership of KDE e.V.), which shall act as a proxy * * defined in Section 14 of version 3 of the license. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * ***************************************************************************/ #include "TransactionListener.h" #include "TransactionModel.h" #include #include TransactionListener::TransactionListener(QObject *parent) : QObject(parent) , m_resource(nullptr) , m_transaction(nullptr) { connect(TransactionModel::global(), &TransactionModel::transactionAdded, this, &TransactionListener::transactionAdded); } void TransactionListener::cancel() { if(!isCancellable()) { return; } m_transaction->cancel(); } bool TransactionListener::isCancellable() const { return m_transaction && m_transaction->isCancellable(); } bool TransactionListener::isActive() const { return m_transaction && m_transaction->status() != Transaction::SetupStatus; } QString TransactionListener::statusText() const { QModelIndex index = TransactionModel::global()->indexOf(m_resource); return index.data(TransactionModel::StatusTextRole).toString(); } void TransactionListener::setResource(AbstractResource *resource) { setResourceInternal(resource); // Catch already-started transactions setTransaction(TransactionModel::global()->transactionFromResource(resource)); } void TransactionListener::setResourceInternal(AbstractResource* resource) { if (m_resource == resource) return; m_resource = resource; emit resourceChanged(); } void TransactionListener::transactionAdded(Transaction *trans) { if (trans->resource() != m_resource) return; setTransaction(trans); } class CheckChange { public: CheckChange(QObject* obj, const QByteArray& prop) : m_object(obj) , m_prop(obj->metaObject()->property(obj->metaObject()->indexOfProperty(prop.constData()))) , m_oldValue(m_prop.read(obj)) { Q_ASSERT(obj->metaObject()->indexOfProperty(prop.constData())>=0); } ~CheckChange() { const QVariant newValue = m_prop.read(m_object); if (newValue != m_oldValue) { QMetaMethod m = m_prop.notifySignal(); m.invoke(m_object, Qt::DirectConnection); } } private: QObject* m_object; QMetaProperty m_prop; QVariant m_oldValue; }; void TransactionListener::setTransaction(Transaction* trans) { if (m_transaction == trans) { return; } if(m_transaction) { disconnect(m_transaction, nullptr, this, nullptr); } CheckChange change1(this, "isCancellable"); CheckChange change2(this, "isActive"); CheckChange change3(this, "statusText"); CheckChange change4(this, "progress"); m_transaction = trans; if(m_transaction) { connect(m_transaction, &Transaction::cancellableChanged, this, &TransactionListener::cancellableChanged); connect(m_transaction, &Transaction::statusChanged, this, &TransactionListener::transactionStatusChanged); connect(m_transaction, &Transaction::progressChanged, this, &TransactionListener::progressChanged); + connect(m_transaction, &QObject::destroyed, this, [this]() { + qDebug() << "destroyed transaction before finishing"; + setTransaction(nullptr); + }); setResourceInternal(trans->resource()); } Q_EMIT transactionChanged(trans); } void TransactionListener::transactionStatusChanged(Transaction::Status status) { switch (status) { case Transaction::CancelledStatus: setTransaction(nullptr); emit cancelled(); break; case Transaction::DoneStatus: setTransaction(nullptr); break; default: break; } emit statusTextChanged(); } int TransactionListener::progress() const { return m_transaction ? m_transaction->progress() : 0; }