forked from qt-creator/qt-creator
		
	QmlInspector: Modifiable properties from inspector property table
This commit is contained in:
		@@ -29,15 +29,18 @@
 | 
			
		||||
#include "objectpropertiesview.h"
 | 
			
		||||
#include "inspectorcontext.h"
 | 
			
		||||
#include "watchtable.h"
 | 
			
		||||
#include "qmlinspector.h"
 | 
			
		||||
 | 
			
		||||
#include <QtCore/QDebug>
 | 
			
		||||
 | 
			
		||||
#include <QtGui/QApplication>
 | 
			
		||||
#include <QtGui/QTreeWidget>
 | 
			
		||||
#include <QtGui/QLayout>
 | 
			
		||||
#include <QtGui/QHeaderView>
 | 
			
		||||
#include <QtGui/QMenu>
 | 
			
		||||
#include <QtGui/QContextMenuEvent>
 | 
			
		||||
 | 
			
		||||
#include <QtCore/QDebug>
 | 
			
		||||
 | 
			
		||||
namespace Qml {
 | 
			
		||||
namespace Internal {
 | 
			
		||||
 | 
			
		||||
@@ -53,9 +56,14 @@ public:
 | 
			
		||||
 | 
			
		||||
    PropertiesViewItem(QTreeWidget *widget, Type type = OtherType);
 | 
			
		||||
    PropertiesViewItem(QTreeWidgetItem *parent, Type type = OtherType);
 | 
			
		||||
    QVariant data (int column, int role) const;
 | 
			
		||||
    void setData (int column, int role, const QVariant & value);
 | 
			
		||||
 | 
			
		||||
    QDeclarativeDebugPropertyReference property;
 | 
			
		||||
    Type type;
 | 
			
		||||
private:
 | 
			
		||||
    QString objectIdString() const;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
PropertiesViewItem::PropertiesViewItem(QTreeWidget *widget, Type type)
 | 
			
		||||
@@ -68,6 +76,36 @@ PropertiesViewItem::PropertiesViewItem(QTreeWidgetItem *parent, Type type)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QVariant PropertiesViewItem::data (int column, int role) const
 | 
			
		||||
{
 | 
			
		||||
    if (column == 1) {
 | 
			
		||||
        if (role == Qt::ForegroundRole) {
 | 
			
		||||
            bool canEdit = data(0, ObjectPropertiesView::CanEditRole).toBool();
 | 
			
		||||
            return canEdit ? qApp->palette().color(QPalette::Foreground) : qApp->palette().color(QPalette::Disabled, QPalette::Foreground);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return QTreeWidgetItem::data(column, role);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PropertiesViewItem::setData (int column, int role, const QVariant & value)
 | 
			
		||||
{
 | 
			
		||||
    if (role == Qt::EditRole) {
 | 
			
		||||
        if (column == 1) {
 | 
			
		||||
            qDebug() << "editing prop item w/role" << role << "and value" << value;
 | 
			
		||||
            QmlInspector::instance()->executeExpression(property.objectDebugId(), objectIdString(), property.name(), value);
 | 
			
		||||
        }
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    QTreeWidgetItem::setData(column, role, value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QString PropertiesViewItem::objectIdString() const
 | 
			
		||||
{
 | 
			
		||||
    return data(0, ObjectPropertiesView::ObjectIdStringRole).toString();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ObjectPropertiesView::ObjectPropertiesView(WatchTableModel *watchTableModel,
 | 
			
		||||
                                           QDeclarativeEngineDebug *client, QWidget *parent)
 | 
			
		||||
    : QWidget(parent),
 | 
			
		||||
@@ -87,6 +125,8 @@ ObjectPropertiesView::ObjectPropertiesView(WatchTableModel *watchTableModel,
 | 
			
		||||
    m_tree->setAlternatingRowColors(true);
 | 
			
		||||
    m_tree->setExpandsOnDoubleClick(false);
 | 
			
		||||
    m_tree->setRootIsDecorated(false);
 | 
			
		||||
    m_tree->setEditTriggers(QAbstractItemView::NoEditTriggers);
 | 
			
		||||
 | 
			
		||||
    m_tree->setHeaderLabels(QStringList()
 | 
			
		||||
            << tr("Name") << tr("Value") << tr("Type"));
 | 
			
		||||
    QObject::connect(m_tree, SIGNAL(itemActivated(QTreeWidgetItem *, int)),
 | 
			
		||||
@@ -222,9 +262,17 @@ void ObjectPropertiesView::setObject(const QDeclarativeDebugObjectReference &obj
 | 
			
		||||
 | 
			
		||||
            PropertiesViewItem *item = new PropertiesViewItem(m_tree);
 | 
			
		||||
            item->property = p;
 | 
			
		||||
 | 
			
		||||
            item->setData(0, ObjectIdStringRole, object.idString());
 | 
			
		||||
            item->setText(0, p.name());
 | 
			
		||||
            item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
 | 
			
		||||
            Qt::ItemFlags itemFlags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
 | 
			
		||||
 | 
			
		||||
            bool canEdit = object.idString().length() && QmlInspector::instance()->canEditProperty(item->property.valueTypeName());
 | 
			
		||||
            item->setData(0, 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);
 | 
			
		||||
@@ -295,9 +343,12 @@ void ObjectPropertiesView::valueChanged(const QByteArray &name, const QVariant &
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ObjectPropertiesView::itemDoubleClicked(QTreeWidgetItem *item, int /*column*/)
 | 
			
		||||
void ObjectPropertiesView::itemDoubleClicked(QTreeWidgetItem *item, int column)
 | 
			
		||||
{
 | 
			
		||||
    toggleWatch(item);
 | 
			
		||||
    if (column == 0)
 | 
			
		||||
        toggleWatch(item);
 | 
			
		||||
    else if (column == 1)
 | 
			
		||||
        m_tree->editItem(item, column);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ObjectPropertiesView::addWatch()
 | 
			
		||||
 
 | 
			
		||||
@@ -56,6 +56,12 @@ public:
 | 
			
		||||
    void setEngineDebug(QDeclarativeEngineDebug *client);
 | 
			
		||||
    void clear();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    enum DataRoles {
 | 
			
		||||
        CanEditRole = Qt::UserRole + 1,
 | 
			
		||||
        ObjectIdStringRole = Qt::UserRole + 50
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
signals:
 | 
			
		||||
    void watchToggleRequested(const QDeclarativeDebugObjectReference &, const QDeclarativeDebugPropertyReference &);
 | 
			
		||||
    void contextHelpIdChanged(const QString &contextHelpId);
 | 
			
		||||
 
 | 
			
		||||
@@ -27,6 +27,7 @@
 | 
			
		||||
**
 | 
			
		||||
**************************************************************************/
 | 
			
		||||
#include "watchtable.h"
 | 
			
		||||
#include "qmlinspector.h"
 | 
			
		||||
 | 
			
		||||
#include <QtCore/QEvent>
 | 
			
		||||
#include <QtGui/QAction>
 | 
			
		||||
@@ -51,7 +52,7 @@ WatchTableModel::WatchTableModel(QDeclarativeEngineDebug *client, QObject *paren
 | 
			
		||||
    : QAbstractTableModel(parent),
 | 
			
		||||
      m_client(client)
 | 
			
		||||
{
 | 
			
		||||
    m_editablePropertyTypes << "qreal" << "bool" << "QString" << "int" << "QVariant" << "QUrl";
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
WatchTableModel::~WatchTableModel()
 | 
			
		||||
@@ -167,7 +168,7 @@ QVariant WatchTableModel::data(const QModelIndex &idx, int role) const
 | 
			
		||||
            return QVariant(m_entities.at(idx.row()).value);
 | 
			
		||||
        } else if (role == CanEditRole || role == Qt::ForegroundRole) {
 | 
			
		||||
            const WatchedEntity &entity = m_entities.at(idx.row());
 | 
			
		||||
            bool canEdit = entity.objectId.length() > 0 && canEditProperty(entity.objectPropertyType);
 | 
			
		||||
            bool canEdit = entity.objectId.length() > 0 && QmlInspector::instance()->canEditProperty(entity.objectPropertyType);
 | 
			
		||||
 | 
			
		||||
            if (role == Qt::ForegroundRole)
 | 
			
		||||
                return canEdit ? qApp->palette().color(QPalette::Foreground) : qApp->palette().color(QPalette::Disabled, QPalette::Foreground);
 | 
			
		||||
@@ -197,43 +198,13 @@ bool WatchTableModel::setData ( const QModelIndex & index, const QVariant & valu
 | 
			
		||||
        if (index.row() >= 0 && index.row() < m_entities.length()) {
 | 
			
		||||
            WatchedEntity &entity = m_entities[index.row()];
 | 
			
		||||
 | 
			
		||||
            qDebug() << entity.property << entity.title << entity.objectId;
 | 
			
		||||
            if (entity.objectId.length()) {
 | 
			
		||||
 | 
			
		||||
                QString quoteWrappedValue = value.toString();
 | 
			
		||||
                if (addQuotesForData(value))
 | 
			
		||||
                    quoteWrappedValue = QString("'%1'").arg(quoteWrappedValue);
 | 
			
		||||
 | 
			
		||||
                QString constructedExpression = entity.objectId + "." + entity.property + "=" + quoteWrappedValue;
 | 
			
		||||
                qDebug() << "EXPRESSION:" << constructedExpression;
 | 
			
		||||
                m_client->queryExpressionResult(entity.objectDebugId, constructedExpression, this);
 | 
			
		||||
            }
 | 
			
		||||
            QmlInspector::instance()->executeExpression(entity.objectDebugId, entity.objectId, entity.property, value);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool WatchTableModel::canEditProperty(const QString &propertyType) const
 | 
			
		||||
{
 | 
			
		||||
    return m_editablePropertyTypes.contains(propertyType);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool WatchTableModel::addQuotesForData(const QVariant &value) const
 | 
			
		||||
{
 | 
			
		||||
    switch (value.type()) {
 | 
			
		||||
    case QVariant::String:
 | 
			
		||||
    case QVariant::Color:
 | 
			
		||||
    case QVariant::Date:
 | 
			
		||||
        return true;
 | 
			
		||||
    default:
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Qt::ItemFlags WatchTableModel::flags ( const QModelIndex & index ) const
 | 
			
		||||
{
 | 
			
		||||
    Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
 | 
			
		||||
@@ -367,6 +338,7 @@ WatchTableView::WatchTableView(WatchTableModel *model, QWidget *parent)
 | 
			
		||||
    setSelectionBehavior(QAbstractItemView::SelectItems);
 | 
			
		||||
    setShowGrid(false);
 | 
			
		||||
    setVerticalHeader(0);
 | 
			
		||||
 | 
			
		||||
    setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::EditKeyPressed);
 | 
			
		||||
    setFrameStyle(QFrame::NoFrame);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -87,8 +87,6 @@ private slots:
 | 
			
		||||
    void watchedValueChanged(const QByteArray &propertyName, const QVariant &value);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    bool canEditProperty(const QString &propertyType) const;
 | 
			
		||||
    bool addQuotesForData(const QVariant &value) const;
 | 
			
		||||
    void addWatch(const QDeclarativeDebugObjectReference &object, const QString &propertyType,
 | 
			
		||||
                  QDeclarativeDebugWatch *watch, const QString &title);
 | 
			
		||||
 | 
			
		||||
@@ -113,7 +111,6 @@ private:
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    QStringList m_editablePropertyTypes;
 | 
			
		||||
    QDeclarativeEngineDebug *m_client;
 | 
			
		||||
    QList<WatchedEntity> m_entities;
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -74,6 +74,8 @@
 | 
			
		||||
 | 
			
		||||
#include <extensionsystem/pluginmanager.h>
 | 
			
		||||
 | 
			
		||||
#include <private/qdeclarativedebug_p.h>
 | 
			
		||||
 | 
			
		||||
#include <QtCore/QDebug>
 | 
			
		||||
#include <QtCore/QStringList>
 | 
			
		||||
#include <QtCore/QTimer>
 | 
			
		||||
@@ -113,8 +115,6 @@ public:
 | 
			
		||||
    void clearEngines();
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    //virtual QString textFromValue(int value) const;
 | 
			
		||||
    //virtual int valueFromText(const QString &text) const;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    QList<EngineInfo> m_engines;
 | 
			
		||||
@@ -143,28 +143,12 @@ void EngineComboBox::addEngine(int engine, const QString &name)
 | 
			
		||||
void EngineComboBox::clearEngines()
 | 
			
		||||
{
 | 
			
		||||
    m_engines.clear();
 | 
			
		||||
    clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//QString EngineComboBox::textFromValue(int value) const
 | 
			
		||||
//{
 | 
			
		||||
//    for (int i=0; i<m_engines.count(); ++i) {
 | 
			
		||||
//        if (m_engines[i].id == value)
 | 
			
		||||
//            return m_engines[i].name;
 | 
			
		||||
//    }
 | 
			
		||||
//    return QLatin1String("<None>");
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//int EngineComboBox::valueFromText(const QString &text) const
 | 
			
		||||
//{
 | 
			
		||||
//    for (int i=0; i<m_engines.count(); ++i) {
 | 
			
		||||
//        if (m_engines[i].name == text)
 | 
			
		||||
//            return m_engines[i].id;
 | 
			
		||||
//    }
 | 
			
		||||
//    return -1;
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
} // Internal
 | 
			
		||||
 | 
			
		||||
QmlInspector *QmlInspector::m_instance = 0;
 | 
			
		||||
 | 
			
		||||
QmlInspector::QmlInspector(QObject *parent)
 | 
			
		||||
  : QObject(parent),
 | 
			
		||||
@@ -179,6 +163,7 @@ QmlInspector::QmlInspector(QObject *parent)
 | 
			
		||||
    m_connectionTimer(new QTimer(this)),
 | 
			
		||||
    m_connectionAttempts(0)
 | 
			
		||||
{
 | 
			
		||||
    m_instance = this;
 | 
			
		||||
    m_watchTableModel = new Internal::WatchTableModel(0, this);
 | 
			
		||||
 | 
			
		||||
    m_objectTreeWidget = new Internal::ObjectTree;
 | 
			
		||||
@@ -188,6 +173,10 @@ QmlInspector::QmlInspector(QObject *parent)
 | 
			
		||||
//    m_frameRateWidget = new Internal::CanvasFrameRate;
 | 
			
		||||
//    m_frameRateWidget->setObjectName(QLatin1String("QmlDebugFrameRate"));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    m_editablePropertyTypes = QStringList() << "qreal" << "bool" << "QString"
 | 
			
		||||
                                            << "int" << "QVariant" << "QUrl" << "QColor";
 | 
			
		||||
 | 
			
		||||
    connect(m_connectionTimer, SIGNAL(timeout()), SLOT(pollInspector()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -214,7 +203,6 @@ void QmlInspector::pollInspector()
 | 
			
		||||
 | 
			
		||||
bool QmlInspector::setDebugConfigurationDataFromProject(ProjectExplorer::Project *projectToDebug)
 | 
			
		||||
{
 | 
			
		||||
    //ProjectExplorer::Project *project = ProjectExplorer::ProjectExplorerPlugin::instance()->startupProject();
 | 
			
		||||
    if (!projectToDebug) {
 | 
			
		||||
        emit statusMessage(tr("Invalid project, debugging canceled."));
 | 
			
		||||
        return false;
 | 
			
		||||
@@ -611,7 +599,7 @@ void QmlInspector::enginesChanged()
 | 
			
		||||
 | 
			
		||||
    m_engineComboBox->setEnabled(true);
 | 
			
		||||
 | 
			
		||||
    for (int i=0; i<engines.count(); ++i)
 | 
			
		||||
    for (int i = 0; i < engines.count(); ++i)
 | 
			
		||||
        m_engineComboBox->addEngine(engines.at(i).debugId(), engines.at(i).name());
 | 
			
		||||
 | 
			
		||||
    if (engines.count() > 0) {
 | 
			
		||||
@@ -667,6 +655,48 @@ void QmlInspector::treeObjectActivated(const QDeclarativeDebugObjectReference &o
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool QmlInspector::canEditProperty(const QString &propertyType)
 | 
			
		||||
{
 | 
			
		||||
    return m_editablePropertyTypes.contains(propertyType);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QDeclarativeDebugExpressionQuery *QmlInspector::executeExpression(int objectDebugId, const QString &objectId,
 | 
			
		||||
                                                                  const QString &propertyName, const QVariant &value)
 | 
			
		||||
{
 | 
			
		||||
    //qDebug() << entity.property << entity.title << entity.objectId;
 | 
			
		||||
    if (objectId.length()) {
 | 
			
		||||
 | 
			
		||||
        QString quoteWrappedValue = value.toString();
 | 
			
		||||
        if (addQuotesForData(value))
 | 
			
		||||
            quoteWrappedValue = QString("'%1'").arg(quoteWrappedValue);
 | 
			
		||||
 | 
			
		||||
        QString constructedExpression = objectId + "." + propertyName + "=" + quoteWrappedValue;
 | 
			
		||||
        //qDebug() << "EXPRESSION:" << constructedExpression;
 | 
			
		||||
        return m_client->queryExpressionResult(objectDebugId, constructedExpression, this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool QmlInspector::addQuotesForData(const QVariant &value) const
 | 
			
		||||
{
 | 
			
		||||
    switch (value.type()) {
 | 
			
		||||
    case QVariant::String:
 | 
			
		||||
    case QVariant::Color:
 | 
			
		||||
    case QVariant::Date:
 | 
			
		||||
        return true;
 | 
			
		||||
    default:
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QmlInspector *QmlInspector::instance()
 | 
			
		||||
{
 | 
			
		||||
    return m_instance;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // Qml
 | 
			
		||||
 | 
			
		||||
#include "qmlinspector.moc"
 | 
			
		||||
 
 | 
			
		||||
@@ -47,6 +47,7 @@ class QLabel;
 | 
			
		||||
 | 
			
		||||
class QDeclarativeEngineDebug;
 | 
			
		||||
class QDeclarativeDebugConnection;
 | 
			
		||||
class QDeclarativeDebugExpressionQuery;
 | 
			
		||||
class QDeclarativeDebugEnginesQuery;
 | 
			
		||||
class QDeclarativeDebugRootContextQuery;
 | 
			
		||||
class QDeclarativeDebugObjectReference;
 | 
			
		||||
@@ -95,6 +96,11 @@ public:
 | 
			
		||||
    bool setDebugConfigurationDataFromProject(ProjectExplorer::Project *projectToDebug);
 | 
			
		||||
    void startConnectionTimer();
 | 
			
		||||
 | 
			
		||||
    static QmlInspector *instance();
 | 
			
		||||
    bool canEditProperty(const QString &propertyType);
 | 
			
		||||
    QDeclarativeDebugExpressionQuery *executeExpression(int objectDebugId, const QString &objectId,
 | 
			
		||||
                                                        const QString &propertyName, const QVariant &value);
 | 
			
		||||
 | 
			
		||||
signals:
 | 
			
		||||
    void statusMessage(const QString &text);
 | 
			
		||||
 | 
			
		||||
@@ -116,6 +122,7 @@ private slots:
 | 
			
		||||
    void pollInspector();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    bool addQuotesForData(const QVariant &value) const;
 | 
			
		||||
    void resetViews();
 | 
			
		||||
 | 
			
		||||
    QDeclarativeDebugConnection *m_conn;
 | 
			
		||||
@@ -149,6 +156,9 @@ private:
 | 
			
		||||
    Internal::InspectorSettings m_settings;
 | 
			
		||||
    QmlProjectManager::QmlProjectRunConfigurationDebugData m_runConfigurationDebugData;
 | 
			
		||||
 | 
			
		||||
    QStringList m_editablePropertyTypes;
 | 
			
		||||
 | 
			
		||||
    static QmlInspector *m_instance;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // Qml
 | 
			
		||||
 
 | 
			
		||||
@@ -75,10 +75,10 @@ QmlProjectRunConfiguration::QmlProjectRunConfiguration(Internal::QmlProjectTarge
 | 
			
		||||
    m_fileListModel(new QStringListModel(this)),
 | 
			
		||||
    m_projectTarget(parent)
 | 
			
		||||
{
 | 
			
		||||
    setMainScript(source->m_scriptFile);
 | 
			
		||||
    ctor();
 | 
			
		||||
    m_debugData.serverAddress = source->m_debugData.serverAddress;
 | 
			
		||||
    m_debugData.serverPort = source->m_debugData.serverPort;
 | 
			
		||||
    ctor();
 | 
			
		||||
    setMainScript(source->m_scriptFile);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool QmlProjectRunConfiguration::isEnabled(ProjectExplorer::BuildConfiguration *bc) const
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user