TransactionListener.cpp 5.1 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/***************************************************************************
 *   Copyright © 2010 Jonathan Thomas <echidnaman@kubuntu.org>             *
 *   Copyright © 2012 Aleix Pol Gonzalez <aleixpol@blue-systems.com>       *
 *                                                                         *
 *   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 <http://www.gnu.org/licenses/>. *
 ***************************************************************************/

#include "TransactionListener.h"

#include "TransactionModel.h"
Aleix Pol Gonzalez's avatar
Aleix Pol Gonzalez committed
25
26
#include <QMetaProperty>
#include <QDebug>
27
28
29
30
31
32

TransactionListener::TransactionListener(QObject *parent)
    : QObject(parent)
    , m_resource(nullptr)
    , m_transaction(nullptr)
{
Aleix Pol Gonzalez's avatar
Aleix Pol Gonzalez committed
33
    connect(TransactionModel::global(), &TransactionModel::transactionAdded, this, &TransactionListener::transactionAdded);
34
35
}

36
37
38
39
40
41
42
43
void TransactionListener::cancel()
{
    if(!isCancellable()) {
        return;
    }
    m_transaction->cancel();
}

44
45
bool TransactionListener::isCancellable() const
{
46
    return m_transaction && m_transaction->isCancellable();
47
48
49
50
}

bool TransactionListener::isActive() const
{
51
    return m_transaction && m_transaction->status() != Transaction::SetupStatus;
52
53
54
55
56
57
58
59
60
61
}

QString TransactionListener::statusText() const
{
    QModelIndex index = TransactionModel::global()->indexOf(m_resource);

    return index.data(TransactionModel::StatusTextRole).toString();
}

void TransactionListener::setResource(AbstractResource *resource)
62
63
64
65
66
67
68
{
    setResourceInternal(resource);
    // Catch already-started transactions
    setTransaction(TransactionModel::global()->transactionFromResource(resource));
}

void TransactionListener::setResourceInternal(AbstractResource* resource)
69
{
Aleix Pol Gonzalez's avatar
Aleix Pol Gonzalez committed
70
71
72
    if (m_resource == resource)
        return;

73
74
75
76
77
78
79
80
81
    m_resource = resource;
    emit resourceChanged();
}

void TransactionListener::transactionAdded(Transaction *trans)
{
    if (trans->resource() != m_resource)
        return;

82
83
84
    setTransaction(trans);
}

Aleix Pol Gonzalez's avatar
Aleix Pol Gonzalez committed
85
86
87
88
89
class CheckChange
{
public:
    CheckChange(QObject* obj, const QByteArray& prop)
        : m_object(obj)
Aleix Pol Gonzalez's avatar
Aleix Pol Gonzalez committed
90
        , m_prop(obj->metaObject()->property(obj->metaObject()->indexOfProperty(prop.constData())))
Aleix Pol Gonzalez's avatar
Aleix Pol Gonzalez committed
91
92
        , m_oldValue(m_prop.read(obj))
    {
Aleix Pol Gonzalez's avatar
Aleix Pol Gonzalez committed
93
        Q_ASSERT(obj->metaObject()->indexOfProperty(prop.constData())>=0);
Aleix Pol Gonzalez's avatar
Aleix Pol Gonzalez committed
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
    }

    ~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;
};

110
111
void TransactionListener::setTransaction(Transaction* trans)
{
Aleix Pol Gonzalez's avatar
Aleix Pol Gonzalez committed
112
113
114
115
    if (m_transaction == trans) {
        return;
    }

116
    if(m_transaction) {
Aleix Pol Gonzalez's avatar
Aleix Pol Gonzalez committed
117
        disconnect(m_transaction, nullptr, this, nullptr);
118
    }
Aleix Pol Gonzalez's avatar
Aleix Pol Gonzalez committed
119
120

    CheckChange change1(this, "isCancellable");
Aleix Pol Gonzalez's avatar
Aleix Pol Gonzalez committed
121
    CheckChange change2(this, "isActive");
Aleix Pol Gonzalez's avatar
Aleix Pol Gonzalez committed
122
123
124
    CheckChange change3(this, "statusText");
    CheckChange change4(this, "progress");

125
    m_transaction = trans;
126
    if(m_transaction) {
Aleix Pol Gonzalez's avatar
Aleix Pol Gonzalez committed
127
128
129
        connect(m_transaction, &Transaction::cancellableChanged, this, &TransactionListener::cancellableChanged);
        connect(m_transaction, &Transaction::statusChanged, this, &TransactionListener::transactionStatusChanged);
        connect(m_transaction, &Transaction::progressChanged, this, &TransactionListener::progressChanged);
130
131
132
133
        connect(m_transaction, &QObject::destroyed, this, [this]() {
            qDebug() << "destroyed transaction before finishing";
            setTransaction(nullptr);
        });
134
        setResourceInternal(trans->resource());
135
    }
136
    Q_EMIT transactionChanged(trans);
137
138
139
140
141
}

void TransactionListener::transactionStatusChanged(Transaction::Status status)
{
    switch (status) {
142
143
144
145
    case Transaction::CancelledStatus:
        setTransaction(nullptr);
        emit cancelled();
        break;
146
    case Transaction::DoneStatus:
147
        setTransaction(nullptr);
148
149
150
151
152
153
154
        break;
    default:
        break;
    }

    emit statusTextChanged();
}
155

156
157
158
159
int TransactionListener::progress() const
{
    return m_transaction ? m_transaction->progress() : 0;
}