File indexing completed on 2024-05-05 17:33:23
0001 /* 0002 * SPDX-FileCopyrightText: 2010 Jonathan Thomas <echidnaman@kubuntu.org> 0003 * SPDX-FileCopyrightText: 2012 Aleix Pol Gonzalez <aleixpol@blue-systems.com> 0004 * 0005 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0006 */ 0007 0008 #include "TransactionListener.h" 0009 0010 #include "../resources/AbstractResource.h" 0011 #include "TransactionModel.h" 0012 #include "libdiscover_debug.h" 0013 #include <QMetaProperty> 0014 0015 TransactionListener::TransactionListener(QObject *parent) 0016 : QObject(parent) 0017 , m_resource(nullptr) 0018 , m_transaction(nullptr) 0019 { 0020 connect(TransactionModel::global(), &TransactionModel::transactionAdded, this, &TransactionListener::transactionAdded); 0021 } 0022 0023 void TransactionListener::cancel() 0024 { 0025 if (!isCancellable()) { 0026 return; 0027 } 0028 m_transaction->cancel(); 0029 } 0030 0031 bool TransactionListener::isCancellable() const 0032 { 0033 return m_transaction && m_transaction->isCancellable(); 0034 } 0035 0036 bool TransactionListener::isActive() const 0037 { 0038 return m_transaction && m_transaction->status() != Transaction::SetupStatus; 0039 } 0040 0041 QString TransactionListener::statusText() const 0042 { 0043 QModelIndex index = TransactionModel::global()->indexOf(m_resource); 0044 0045 return index.data(TransactionModel::StatusTextRole).toString(); 0046 } 0047 0048 void TransactionListener::setResource(AbstractResource *resource) 0049 { 0050 setResourceInternal(resource); 0051 // Catch already-started transactions 0052 setTransaction(TransactionModel::global()->transactionFromResource(resource)); 0053 } 0054 0055 void TransactionListener::setResourceInternal(AbstractResource *resource) 0056 { 0057 if (m_resource == resource) 0058 return; 0059 0060 m_resource = resource; 0061 Q_EMIT resourceChanged(); 0062 } 0063 0064 void TransactionListener::transactionAdded(Transaction *trans) 0065 { 0066 if (trans->resource() != m_resource) 0067 return; 0068 0069 setTransaction(trans); 0070 } 0071 0072 class CheckChange 0073 { 0074 public: 0075 CheckChange(QObject *obj, const QByteArray &prop) 0076 : m_object(obj) 0077 , m_prop(obj->metaObject()->property(obj->metaObject()->indexOfProperty(prop.constData()))) 0078 , m_oldValue(m_prop.read(obj)) 0079 { 0080 Q_ASSERT(obj->metaObject()->indexOfProperty(prop.constData()) >= 0); 0081 } 0082 0083 ~CheckChange() 0084 { 0085 const QVariant newValue = m_prop.read(m_object); 0086 if (newValue != m_oldValue) { 0087 QMetaMethod m = m_prop.notifySignal(); 0088 m.invoke(m_object, Qt::DirectConnection); 0089 } 0090 } 0091 0092 private: 0093 QObject *m_object; 0094 QMetaProperty m_prop; 0095 QVariant m_oldValue; 0096 }; 0097 0098 void TransactionListener::setTransaction(Transaction *trans) 0099 { 0100 if (m_transaction == trans) { 0101 return; 0102 } 0103 0104 if (m_transaction) { 0105 disconnect(m_transaction, nullptr, this, nullptr); 0106 } 0107 0108 CheckChange change1(this, "isCancellable"); 0109 CheckChange change2(this, "isActive"); 0110 CheckChange change3(this, "statusText"); 0111 CheckChange change4(this, "progress"); 0112 0113 m_transaction = trans; 0114 if (m_transaction) { 0115 connect(m_transaction, &Transaction::cancellableChanged, this, &TransactionListener::cancellableChanged); 0116 connect(m_transaction, &Transaction::statusChanged, this, &TransactionListener::transactionStatusChanged); 0117 connect(m_transaction, &Transaction::progressChanged, this, &TransactionListener::progressChanged); 0118 connect(m_transaction, &QObject::destroyed, this, [this]() { 0119 qCDebug(LIBDISCOVER_LOG) << "destroyed transaction before finishing"; 0120 setTransaction(nullptr); 0121 }); 0122 setResourceInternal(trans->resource()); 0123 } 0124 Q_EMIT transactionChanged(trans); 0125 } 0126 0127 void TransactionListener::transactionStatusChanged(Transaction::Status status) 0128 { 0129 switch (status) { 0130 case Transaction::CancelledStatus: 0131 setTransaction(nullptr); 0132 Q_EMIT cancelled(); 0133 break; 0134 case Transaction::DoneWithErrorStatus: 0135 case Transaction::DoneStatus: 0136 setTransaction(nullptr); 0137 break; 0138 default: 0139 break; 0140 } 0141 0142 Q_EMIT statusTextChanged(); 0143 } 0144 0145 int TransactionListener::progress() const 0146 { 0147 return m_transaction ? m_transaction->progress() : 0; 0148 } 0149 0150 #include "moc_TransactionListener.cpp"