File indexing completed on 2024-05-12 05:29:05
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 0061 m_resource = resource; 0062 Q_EMIT resourceChanged(); 0063 } 0064 0065 void TransactionListener::transactionAdded(Transaction *trans) 0066 { 0067 if (trans->resource() != m_resource) { 0068 return; 0069 } 0070 0071 setTransaction(trans); 0072 } 0073 0074 class CheckChange 0075 { 0076 public: 0077 CheckChange(QObject *obj, const QByteArray &prop) 0078 : m_object(obj) 0079 , m_prop(obj->metaObject()->property(obj->metaObject()->indexOfProperty(prop.constData()))) 0080 , m_oldValue(m_prop.read(obj)) 0081 { 0082 Q_ASSERT(obj->metaObject()->indexOfProperty(prop.constData()) >= 0); 0083 } 0084 0085 ~CheckChange() 0086 { 0087 const QVariant newValue = m_prop.read(m_object); 0088 if (newValue != m_oldValue) { 0089 QMetaMethod m = m_prop.notifySignal(); 0090 m.invoke(m_object, Qt::DirectConnection); 0091 } 0092 } 0093 0094 private: 0095 QObject *m_object; 0096 QMetaProperty m_prop; 0097 QVariant m_oldValue; 0098 }; 0099 0100 void TransactionListener::setTransaction(Transaction *trans) 0101 { 0102 if (m_transaction == trans) { 0103 return; 0104 } 0105 0106 if (m_transaction) { 0107 disconnect(m_transaction, nullptr, this, nullptr); 0108 } 0109 0110 CheckChange change1(this, "isCancellable"); 0111 CheckChange change2(this, "isActive"); 0112 CheckChange change3(this, "statusText"); 0113 CheckChange change4(this, "progress"); 0114 0115 m_transaction = trans; 0116 if (m_transaction) { 0117 connect(m_transaction, &Transaction::cancellableChanged, this, &TransactionListener::cancellableChanged); 0118 connect(m_transaction, &Transaction::statusChanged, this, &TransactionListener::transactionStatusChanged); 0119 connect(m_transaction, &Transaction::progressChanged, this, &TransactionListener::progressChanged); 0120 connect(m_transaction, &QObject::destroyed, this, [this]() { 0121 qCDebug(LIBDISCOVER_LOG) << "destroyed transaction before finishing"; 0122 setTransaction(nullptr); 0123 }); 0124 setResourceInternal(trans->resource()); 0125 } 0126 Q_EMIT transactionChanged(trans); 0127 } 0128 0129 void TransactionListener::transactionStatusChanged(Transaction::Status status) 0130 { 0131 switch (status) { 0132 case Transaction::CancelledStatus: 0133 setTransaction(nullptr); 0134 Q_EMIT cancelled(); 0135 break; 0136 case Transaction::DoneWithErrorStatus: 0137 case Transaction::DoneStatus: 0138 setTransaction(nullptr); 0139 break; 0140 default: 0141 break; 0142 } 0143 0144 Q_EMIT statusTextChanged(); 0145 } 0146 0147 int TransactionListener::progress() const 0148 { 0149 return m_transaction ? m_transaction->progress() : 0; 0150 } 0151 0152 #include "moc_TransactionListener.cpp"