void recurseObjectIdList(const QDeclarativeDebugObjectReference &ref, QList<int> &debugIds, QList<QString> &objectIds)
{
    debugIds << ref.debugId();
    objectIds << ref.idString();
    foreach (const QDeclarativeDebugObjectReference &child, ref.children())
        recurseObjectIdList(child, debugIds, objectIds);
}
QString ObjectPropertiesView::propertyBaseClass(const QDeclarativeDebugObjectReference &object, const QDeclarativeDebugPropertyReference &property, int &depth)
{
    ExtensionSystem::PluginManager *pluginManager = ExtensionSystem::PluginManager::instance();
    QmlJSEditor::ModelManagerInterface *modelManager = pluginManager->getObject<QmlJSEditor::ModelManagerInterface>();
    QmlJS::Snapshot snapshot = modelManager->snapshot();

    QmlJS::Document::Ptr document = snapshot.document(object.source().url().path());
    if (document.isNull()) {

        QFile inFile(object.source().url().path());
        QString contents;
        if (inFile.open(QIODevice::ReadOnly)) {
            QTextStream ins(&inFile);
            contents = ins.readAll();
            inFile.close();
        }

        document = QmlJS::Document::create(object.source().url().path());
        document->setSource(contents);
        if (!document->parse())
            return QString();

        snapshot.insert(document);
    }

    PropertyTypeFinder find(document, snapshot, modelManager->importPaths());
    QString baseClassName = find(object.source().lineNumber(), object.source().columnNumber(), property.name());

    if (baseClassName.isEmpty()) {
        if (!object.idString().isEmpty())
            baseClassName = object.idString();
        else
            baseClassName = QString("<%1>").arg(object.className());
    }

    depth = find.depth();

    return baseClassName;

}
void ObjectPropertiesView::setObject(const QDeclarativeDebugObjectReference &object)
{
    m_object = object;
    m_tree->clear();

    QHash<QString, PropertiesViewItem*> baseClassItems;
    PropertiesViewItem* currentParentItem = 0;

    QList<QString> insertedPropertyNames;

    QList<QDeclarativeDebugPropertyReference> properties = object.properties();
    for (int i=0; i<properties.count(); ++i) {
        const QDeclarativeDebugPropertyReference &p = properties[i];

        // ignore overridden/redefined/shadowed properties; and do special ignore for QGraphicsObject* parent,
        // which is useless while debugging.
        if (insertedPropertyNames.contains(p.name())
            || (p.name() == "parent" && p.valueTypeName() == "QGraphicsObject*"))
        {
            continue;
        }
        insertedPropertyNames.append(p.name());

        if (m_showUnwatchableProperties || p.hasNotifySignal()) {

            PropertiesViewItem *item = 0;

            if (m_groupByItemType) {
                int depth = 0;
                QString baseClassName = propertyBaseClass(object, p, depth);
                if (!baseClassItems.contains(baseClassName)) {
                    PropertiesViewItem *baseClassItem = new PropertiesViewItem(m_tree, PropertiesViewItem::ClassType);
                    baseClassItem->setData(0, PropertiesViewItem::CanEditRole, false);
                    baseClassItem->setData(0, PropertiesViewItem::ClassDepthRole, depth);
                    baseClassItem->setText(0, baseClassName);

                    QFont font = m_tree->font();
                    font.setBold(true);
                    baseClassItem->setFont(0, font);

                    baseClassItems.insert(baseClassName, baseClassItem);

                }
                currentParentItem = baseClassItems.value(baseClassName);
                item = new PropertiesViewItem(currentParentItem);
            } else
                item = new PropertiesViewItem(m_tree);

            item->property = p;
            item->setData(0, PropertiesViewItem::ObjectIdStringRole, object.idString());
            item->setText(0, p.name());
            Qt::ItemFlags itemFlags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;

            bool canEdit = object.idString().length() && QmlInspector::instance()->canEditProperty(item->property.valueTypeName());
            item->setData(0, PropertiesViewItem::CanEditRole, canEdit);

            if (canEdit)
                itemFlags |= Qt::ItemIsEditable;

            item->setFlags(itemFlags);
            if (m_watchTableModel.data() && m_watchTableModel.data()->isWatchingProperty(p)) {
                QFont font = m_tree->font();
                font.setBold(true);
                item->setFont(0, font);
            }

            setPropertyValue(item, p.value(), !p.hasNotifySignal());

            item->setText(2, p.valueTypeName());

            // binding is set after property value to ensure it is added to the end of the
            // list, if the value is a list
            if (!p.binding().isEmpty()) {
                PropertiesViewItem *binding = new PropertiesViewItem(item, PropertiesViewItem::BindingType);
                binding->setText(1, p.binding());
                binding->setForeground(1, Qt::darkGreen);
            }

        }
    }
    if (m_groupByItemType)
        sortBaseClassItems();
    m_tree->expandAll();

}