File: bindingextension.cpp

package info (click to toggle)
gammaray 3.3.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 21,612 kB
  • sloc: cpp: 94,643; ansic: 2,227; sh: 336; python: 164; yacc: 90; lex: 82; xml: 61; makefile: 26
file content (103 lines) | stat: -rw-r--r-- 2,989 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/*
  bindingextension.cpp

  This file is part of GammaRay, the Qt application inspection and manipulation tool.

  SPDX-FileCopyrightText: 2017 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>

  SPDX-License-Identifier: GPL-2.0-or-later

  Contact KDAB at <info@kdab.com> for commercial licensing options.
*/

// Own
#include "bindingextension.h"
#include "bindingmodel.h"

#include <core/abstractbindingprovider.h>
#include <core/bindingaggregator.h>
#include <core/bindingnode.h>
#include <core/objectdataprovider.h>
#include <core/probe.h>
#include <core/problemcollector.h>
#include <core/propertycontroller.h>
#include <common/objectbroker.h>

// Qt
#include <QMetaProperty>
#include <QMetaObject>

using namespace GammaRay;

BindingExtension::BindingExtension(PropertyController *controller)
    : QObject(controller)
    , PropertyControllerExtension(controller->objectBaseName() + ".bindings")
    , m_object(nullptr)
    , m_bindingModel(new BindingModel(this))
{
    ObjectBroker::registerObject(controller->objectBaseName() + ".bindingsExtension", this);
    controller->registerModel(m_bindingModel, QStringLiteral("bindingModel"));
}

BindingExtension::~BindingExtension() = default;

void BindingExtension::clear()
{
    if (m_object)
        disconnect(m_object, nullptr, this, nullptr);

    m_bindingModel->aboutToClear();
    m_bindings.clear();
    m_object = nullptr;
    m_bindingModel->cleared();
}

bool BindingExtension::setQObject(QObject *object)
{
    if (m_object)
        disconnect(m_object, nullptr, this, nullptr);

    if (object) {
        if (!BindingAggregator::providerAvailableFor(object)) {
            m_bindings.clear();
            m_bindingModel->setObject(nullptr, m_bindings);
            m_object = nullptr;
            return false;
        }

        m_bindings = BindingAggregator::bindingTreeForObject(object);
        for (const auto &node : m_bindings) {
            int signalIndex = node->property().notifySignalIndex();
            if (signalIndex != -1) {
                QMetaObject::connect(object, signalIndex, this, metaObject()->indexOfMethod("propertyChanged()"), Qt::UniqueConnection);
            }
        }
        connect(object, &QObject::destroyed, this, &BindingExtension::clear);
    } else {
        m_bindings.clear();
    }

    m_bindingModel->setObject(object, m_bindings);
    m_object = object;
    return true;
}


void BindingExtension::propertyChanged()
{
    Q_ASSERT(sender() == m_object);

    for (size_t i = 0; i < m_bindings.size(); ++i) {
        const auto &bindingNode = m_bindings[i].get();
        if (bindingNode->property().notifySignalIndex() == senderSignalIndex()) {
            m_bindingModel->refresh(i, BindingAggregator::findDependenciesFor(bindingNode));
            // There can be more than one property with the same notify signal,
            // so no break here...
        }
    }
}

BindingModel *BindingExtension::model() const
{
    return m_bindingModel;
}