<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (<EMAIL>)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/

#include "objectnodeinstance.h"

#include "qmlgraphicsitemnodeinstance.h"
#include "graphicsobjectnodeinstance.h"
#include "graphicsviewnodeinstance.h"
#include "graphicsscenenodeinstance.h"
#include "graphicswidgetnodeinstance.h"
#include "qmlviewnodeinstance.h"
#include "widgetnodeinstance.h"
#include "proxywidgetnodeinstance.h"

#include <invalidreparentingexception.h>
#include <invalidnodeinstanceexception.h>
#include <notimplementedexception.h>
#include <noanchoringpossibleexception.h>

#include <variantproperty.h>
#include <nodelistproperty.h>
#include <metainfo.h>
#include <propertymetainfo.h>

#include <QEvent>
#include <QGraphicsScene>
#include <QDeclarativeContext>
#include <QDeclarativeError>
#include <QDeclarativeEngine>
#include <QDeclarativeProperty>
#include <QSharedPointer>
#include <QFileInfo>
#include <QFileSystemWatcher>
#include <QPixmapCache>

#include <private/qdeclarativebinding_p.h>
#include <private/qdeclarativemetatype_p.h>
#include <private/qdeclarativevaluetype_p.h>

namespace QmlDesigner {
namespace Internal {


ChildrenChangeEventFilter::ChildrenChangeEventFilter(QObject *parent)
    : QObject(parent)
{
}


bool ChildrenChangeEventFilter::eventFilter(QObject * /*object*/, QEvent *event)
{
    switch (event->type()) {
        case QEvent::ChildAdded:
        case QEvent::ChildRemoved:
            {
                QChildEvent *childEvent = static_cast<QChildEvent*>(event);
                emit childrenChanged(childEvent->child()); break;
            }
        default: break;
    }

    return false;
}

ObjectNodeInstance::ObjectNodeInstance(QObject *object)
    : m_deleteHeldInstance(true),
    m_object(object),
    m_metaObject(0)
{

}

ObjectNodeInstance::~ObjectNodeInstance()
{
    destroy();
}

static bool isChildrenProperty(const QString &name)
{
    return name == "data" || name == "children" || name == "resources";
}

static void specialRemoveParentForQmlGraphicsItemChildren(QObject *object)
{
    QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(object);
    if (item && item->scene())
        item->scene()->removeItem(item);

    object->setParent(0);
}

void ObjectNodeInstance::destroy()
{
    if (deleteHeldInstance()) {
        // Remove from old property
        if (object() && modelNode().isValid() && modelNode().parentProperty().isValid()) {
            NodeAbstractProperty parentProperty = modelNode().parentProperty();
            ModelNode parentNode = parentProperty.parentModelNode();
            if (parentNode.isValid() && nodeInstanceView()->hasInstanceForNode(parentNode)) {
                NodeInstance parentInstance = nodeInstanceView()->instanceForNode(parentNode);
                reparent(parentInstance, parentProperty.name(), NodeInstance() , QString());
            }
        }

        if (!m_id.isEmpty()) {
            context()->engine()->rootContext()->setContextProperty(m_id, 0);
        }

        if (object()) {
            QObject *obj = object();
            m_object.clear();
            delete obj;
        }
    }
}

ModelNode ObjectNodeInstance::modelNode() const
{
    return m_modelNode;
}

void ObjectNodeInstance::setModelNode(const ModelNode &node)
{
    m_modelNode = node;
}

NodeInstanceView *ObjectNodeInstance::nodeInstanceView() const
{
    return m_nodeInstanceView.data();
}

void ObjectNodeInstance::setNodeInstanceView(NodeInstanceView *view)
{
    Q_ASSERT(!m_nodeInstanceView.data());

    m_nodeInstanceView = view;
}

static bool hasPropertiesWitoutNotifications(const QMetaObject *metaObject)
{
    for(int propertyIndex = QObject::staticMetaObject.propertyCount(); propertyIndex < metaObject->propertyCount(); propertyIndex++) {
        if (!metaObject->property(propertyIndex).hasNotifySignal())
            return true;
    }

    return false;
}

void ObjectNodeInstance::initializePropertyWatcher(const ObjectNodeInstance::Pointer &objectNodeInstance)
{
    m_metaObject = new NodeInstanceMetaObject(objectNodeInstance);
    const QMetaObject *metaObject = objectNodeInstance->object()->metaObject();
    for(int propertyIndex = QObject::staticMetaObject.propertyCount(); propertyIndex < metaObject->propertyCount(); propertyIndex++) {
        if (QDeclarativeMetaType::isQObject(metaObject->property(propertyIndex).userType())) {
            QObject *propertyObject = QDeclarativeMetaType::toQObject(metaObject->property(propertyIndex).read(objectNodeInstance->object()));
            if (propertyObject && hasPropertiesWitoutNotifications(propertyObject->metaObject())) {
                new NodeInstanceMetaObject(objectNodeInstance, propertyObject, metaObject->property(propertyIndex).name());
            }
        }
    }

    m_signalSpy.setObjectNodeInstance(objectNodeInstance);
}

void ObjectNodeInstance::setId(const QString &id)
{
    if (!m_id.isEmpty()) {
        context()->engine()->rootContext()->setContextProperty(m_id, 0);
    }

    if (!id.isEmpty()) {
        context()->engine()->rootContext()->setContextProperty(id, object()); // will also force refresh of all bindings
    }

    m_id = id;
}<commit_msg>Don't use NodeInstanceMetaObject for Components<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (<EMAIL>)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/

#include "objectnodeinstance.h"

#include "qmlgraphicsitemnodeinstance.h"
#include "graphicsobjectnodeinstance.h"
#include "graphicsviewnodeinstance.h"
#include "graphicsscenenodeinstance.h"
#include "graphicswidgetnodeinstance.h"
#include "qmlviewnodeinstance.h"
#include "widgetnodeinstance.h"
#include "proxywidgetnodeinstance.h"

#include <invalidreparentingexception.h>
#include <invalidnodeinstanceexception.h>
#include <notimplementedexception.h>
#include <noanchoringpossibleexception.h>

#include <variantproperty.h>
#include <nodelistproperty.h>
#include <metainfo.h>
#include <propertymetainfo.h>

#include <QEvent>
#include <QGraphicsScene>
#include <QDeclarativeContext>
#include <QDeclarativeError>
#include <QDeclarativeEngine>
#include <QDeclarativeProperty>
#include <QSharedPointer>
#include <QFileInfo>
#include <QFileSystemWatcher>
#include <QPixmapCache>

#include <private/qdeclarativebinding_p.h>
#include <private/qdeclarativemetatype_p.h>
#include <private/qdeclarativevaluetype_p.h>

namespace QmlDesigner {
namespace Internal {


ChildrenChangeEventFilter::ChildrenChangeEventFilter(QObject *parent)
    : QObject(parent)
{
}


bool ChildrenChangeEventFilter::eventFilter(QObject * /*object*/, QEvent *event)
{
    switch (event->type()) {
        case QEvent::ChildAdded:
        case QEvent::ChildRemoved:
            {
                QChildEvent *childEvent = static_cast<QChildEvent*>(event);
                emit childrenChanged(childEvent->child()); break;
            }
        default: break;
    }

    return false;
}

ObjectNodeInstance::ObjectNodeInstance(QObject *object)
    : m_deleteHeldInstance(true),
    m_object(object),
    m_metaObject(0)
{

}

ObjectNodeInstance::~ObjectNodeInstance()
{
    destroy();
}

static bool isChildrenProperty(const QString &name)
{
    return name == "data" || name == "children" || name == "resources";
}

static void specialRemoveParentForQmlGraphicsItemChildren(QObject *object)
{
    QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(object);
    if (item && item->scene())
        item->scene()->removeItem(item);

    object->setParent(0);
}

void ObjectNodeInstance::destroy()
{
    if (deleteHeldInstance()) {
        // Remove from old property
        if (object() && modelNode().isValid() && modelNode().parentProperty().isValid()) {
            NodeAbstractProperty parentProperty = modelNode().parentProperty();
            ModelNode parentNode = parentProperty.parentModelNode();
            if (parentNode.isValid() && nodeInstanceView()->hasInstanceForNode(parentNode)) {
                NodeInstance parentInstance = nodeInstanceView()->instanceForNode(parentNode);
                reparent(parentInstance, parentProperty.name(), NodeInstance() , QString());
            }
        }

        if (!m_id.isEmpty()) {
            context()->engine()->rootContext()->setContextProperty(m_id, 0);
        }

        if (object()) {
            QObject *obj = object();
            m_object.clear();
            delete obj;
        }
    }
}

ModelNode ObjectNodeInstance::modelNode() const
{
    return m_modelNode;
}

void ObjectNodeInstance::setModelNode(const ModelNode &node)
{
    m_modelNode = node;
}

NodeInstanceView *ObjectNodeInstance::nodeInstanceView() const
{
    return m_nodeInstanceView.data();
}

void ObjectNodeInstance::setNodeInstanceView(NodeInstanceView *view)
{
    Q_ASSERT(!m_nodeInstanceView.data());

    m_nodeInstanceView = view;
}

static bool hasPropertiesWitoutNotifications(const QMetaObject *metaObject)
{
    for(int propertyIndex = QObject::staticMetaObject.propertyCount(); propertyIndex < metaObject->propertyCount(); propertyIndex++) {
        if (!metaObject->property(propertyIndex).hasNotifySignal())
            return true;
    }

    return false;
}

void ObjectNodeInstance::initializePropertyWatcher(const ObjectNodeInstance::Pointer &objectNodeInstance)
{
    if (!objectNodeInstance->modelNode().metaInfo().isComponent()) { // TODO: this is a nasty workaround which needs to be removed
        const QMetaObject *metaObject = objectNodeInstance->object()->metaObject();
        m_metaObject = new NodeInstanceMetaObject(objectNodeInstance);
        for(int propertyIndex = QObject::staticMetaObject.propertyCount(); propertyIndex < metaObject->propertyCount(); propertyIndex++) {
            if (QDeclarativeMetaType::isQObject(metaObject->property(propertyIndex).userType())) {
                QObject *propertyObject = QDeclarativeMetaType::toQObject(metaObject->property(propertyIndex).read(objectNodeInstance->object()));
                qDebug() << metaObject->property(propertyIndex).name();
                if (propertyObject && hasPropertiesWitoutNotifications(propertyObject->metaObject())) {
                    new NodeInstanceMetaObject(objectNodeInstance, propertyObject, metaObject->property(propertyIndex).name());
                }
            }
        }
    }

    m_signalSpy.setObjectNodeInstance(objectNodeInstance);
}

void ObjectNodeInstance::setId(const QString &id)
{
    if (!m_id.isEmpty()) {
        context()->engine()->rootContext()->setContextProperty(m_id, 0);
    }

    if (!id.isEmpty()) {
        context()->engine()->rootContext()->setContextProperty(id, object()); // will also force refresh of all bindings
    }

    m_id = id;
}
{'fraction_non_alphanumeric': 0.13754358775668346, 'fraction_numerical': 0.002169701666020922, 'mean_word_length': 4.402260359983257, 'pattern_counts': {'":': 0, '<': 57, '<?xml version=': 0, '>': 107, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7248410', 'n_tokens_mistral': 3530, 'n_tokens_neox': 3438, 'n_words': 801}