From 5fb65b7618a549f78eb9321cb4e9436c4c504630 Mon Sep 17 00:00:00 2001 From: arkpar Date: Thu, 11 Dec 2014 11:39:08 +0100 Subject: [PATCH] continue transaction dialog implementation --- mix/TransactionListModel.cpp | 80 ++++++++++++++++++ mix/TransactionListModel.h | 74 +++++++++++++++- mix/TransactionListView.cpp | 7 +- mix/TransactionListView.h | 16 ---- mix/qml/TransactionDialog.qml | 155 ++++++++++++++++++++++++++++++++++ mix/qml/TransactionList.qml | 71 ++++++++++++---- mix/qml/main.qml | 10 +-- 7 files changed, 366 insertions(+), 47 deletions(-) diff --git a/mix/TransactionListModel.cpp b/mix/TransactionListModel.cpp index 498bec45f..b4cbfc83c 100644 --- a/mix/TransactionListModel.cpp +++ b/mix/TransactionListModel.cpp @@ -21,4 +21,84 @@ */ #include +#include #include "TransactionListModel.h" + +namespace dev +{ +namespace mix +{ +TransactionListModel::TransactionListModel(QObject* _parent) : + QAbstractListModel(_parent) +{ + m_transactions.push_back(Transaction(0, "testTr", 0, 0, 0)); +} + +QHash TransactionListModel::roleNames() const +{ + QHash roles; + roles[TitleRole] = "title"; + roles[IdRole] = "transactionId"; + return roles; +} + +int TransactionListModel::rowCount(QModelIndex const& _parent) const +{ + Q_UNUSED(_parent); + return m_transactions.size(); +} + +QVariant TransactionListModel::data(QModelIndex const& _index, int role) const +{ + if(_index.row() < 0 || _index.row() >= (int)m_transactions.size()) + return QVariant(); + auto const& transaction = m_transactions.at(_index.row()); + switch(role) + { + case TitleRole: + return QVariant(transaction.title); + case IdRole: + return QVariant(transaction.id); + default: + return QVariant(); + } +} + +QObject* TransactionListModel::getItem(int _index) +{ + Transaction const& transaction = (_index >=0 && _index < (int)m_transactions.size()) ? m_transactions[_index] : Transaction(); + QObject* item = new TransactionListItem(transaction, nullptr); + QQmlEngine::setObjectOwnership(item, QQmlEngine::JavaScriptOwnership); + return item; +} + +void TransactionListModel::edit(QObject* _data) +{ + //these properties come from TransactionDialog QML object + int id = _data->property("transactionId").toInt(); + const QString title = _data->property("transactionTitle").toString(); + + + if (id >= 0 && id < (int)m_transactions.size()) + { + beginRemoveRows(QModelIndex(), id, id); + m_transactions.erase(m_transactions.begin() + id); + endRemoveRows(); + } + else + id = rowCount(QModelIndex()); + + beginInsertRows(QModelIndex(), id, id); + m_transactions.push_back(Transaction(id, title, 0, 0, 0)); + emit transactionAdded(); + emit countChanged(); + endInsertRows(); +} + +int TransactionListModel::getCount() const +{ + return rowCount(QModelIndex()); +} + +} +} diff --git a/mix/TransactionListModel.h b/mix/TransactionListModel.h index e08dd56a7..10bb3c61b 100644 --- a/mix/TransactionListModel.h +++ b/mix/TransactionListModel.h @@ -23,18 +23,88 @@ #pragma once #include +#include +#include +#include +#include +#include namespace dev { namespace mix { -class TransactionListModel +struct TransacionParameterValue { + QVariant value; +}; + +struct Transaction +{ + Transaction(): + id(-1), value(0), gas(10000), gasPrice(10) {} + + Transaction(int _id, QString const& _title, u256 _value, u256 _gas, u256 _gasPrice): + id(_id), title(_title), value(_value), gas(_gas), gasPrice(_gasPrice) {} + + int id; + QString title; + u256 value; + u256 gas; + u256 gasPrice; + QString functionId; + std::vector parameterValues; +}; + +class TransactionListItem: public QObject +{ + Q_OBJECT + Q_PROPERTY(int transactionId READ transactionId CONSTANT) + Q_PROPERTY(QString title READ title CONSTANT) + Q_PROPERTY(bool selected READ selected CONSTANT) public: - TransactionListModel() {} + TransactionListItem(Transaction const& _t, QObject* _parent): + QObject(_parent), m_id(_t.id), m_title(_t.title), m_selected(false) {} + QString title() { return m_title; } + int transactionId() { return m_id; } + bool selected() { return m_selected; } + +private: + int m_id; + QString m_title; + bool m_selected; +}; + + +class TransactionListModel: public QAbstractListModel +{ + Q_OBJECT + Q_PROPERTY(int count READ getCount() NOTIFY countChanged()) + +enum Roles + { + TitleRole = Qt::DisplayRole, + IdRole = Qt::UserRole + 1 + }; + +public: + TransactionListModel(QObject* _parent); ~TransactionListModel() {} + + QHash roleNames() const override; + int rowCount(QModelIndex const& _parent) const override; + QVariant data(QModelIndex const& _index, int _role) const override; + int getCount() const; + Q_INVOKABLE void edit(QObject* _data); + Q_INVOKABLE QObject* getItem(int _index); + +signals: + void transactionAdded(); + void countChanged(); + +private: + std::vector m_transactions; }; } diff --git a/mix/TransactionListView.cpp b/mix/TransactionListView.cpp index 052c38c6a..0c5a4913e 100644 --- a/mix/TransactionListView.cpp +++ b/mix/TransactionListView.cpp @@ -24,7 +24,6 @@ #include #include #include -//#include #include #include "TransactionListView.h" #include "TransactionListModel.h" @@ -33,10 +32,8 @@ using namespace dev::mix; TransactionListView::TransactionListView(QTextDocument* _doc): Extension(ExtensionDisplayBehavior::RightTab) { m_editor = _doc; - m_model.reset(new TransactionListModel()); - QList list; - list.append(new TransactionListItem("Sample", false, nullptr)); - m_appEngine->rootContext()->setContextProperty("transactionListModel", QVariant::fromValue(list)); + m_model.reset(new TransactionListModel(this)); + m_appEngine->rootContext()->setContextProperty("transactionListModel", m_model.get()); } TransactionListView::~TransactionListView() diff --git a/mix/TransactionListView.h b/mix/TransactionListView.h index 2d79c9dec..cfb1fe1eb 100644 --- a/mix/TransactionListView.h +++ b/mix/TransactionListView.h @@ -30,22 +30,6 @@ namespace mix class TransactionListModel; -class TransactionListItem: public QObject -{ - Q_OBJECT - Q_PROPERTY(QString title READ title) - Q_PROPERTY(int selected READ selected) - -public: - TransactionListItem(QString _title, bool _selected, QObject* _parent): QObject(_parent), m_title(_title), m_selected(_selected) {} - QString title() { return m_title; } - bool selected() { return m_selected; } - -private: - QString m_title; - bool m_selected; -}; - class TransactionListView: public Extension { Q_OBJECT diff --git a/mix/qml/TransactionDialog.qml b/mix/qml/TransactionDialog.qml index e69de29bb..58d071f9d 100644 --- a/mix/qml/TransactionDialog.qml +++ b/mix/qml/TransactionDialog.qml @@ -0,0 +1,155 @@ +import QtQuick 2.3 +import QtQuick.Controls 1.2 +import QtQuick.Dialogs 1.2 +import QtQuick.Layouts 1.1 +import QtQuick.Window 2.0 + +Dialog { + modality: Qt.WindowModal + standardButtons: StandardButton.Ok | StandardButton.Cancel + + width:640 + height:480 + + property alias focus : titleField.focus + property alias transactionTitle : titleField.text + property int transactionId + property int transactionParams; + + function reset(id, model) { + var item = model.getItem(id); + transactionId = id; + transactionTitle = item.title; + } + + GridLayout { + columns: 2 + anchors.fill: parent + anchors.margins: 10 + rowSpacing: 10 + columnSpacing: 10 + + Label { + text: qsTr("Title") + } + TextField { + id: titleField + focus: true + Layout.fillWidth: true + } + + Label { + text: qsTr("Function") + } + TextField { + id: functionField + Layout.fillWidth: true + } + + Label { + text: qsTr("Value") + } + TextField { + id: valueField + Layout.fillWidth: true + } + + Label { + text: qsTr("Gas") + } + TextField { + id: gasField + Layout.fillWidth: true + } + + Label { + text: qsTr("Gas price") + } + TextField { + id: gasPriceField + Layout.fillWidth: true + } + + Label { + text: qsTr("Parameters") + } + TableView { + model: paramsModel + Layout.fillWidth: true + + TableViewColumn { + role: "name" + title: "Name" + width: 120 + } + TableViewColumn { + role: "type" + title: "Type" + width: 120 + } + TableViewColumn { + role: "value" + title: "Value" + width: 120 + } + + itemDelegate: { + return editableDelegate; + } + } + + } + ListModel { + id: paramsModel + Component.onCompleted: { + for (var i=0 ; i < 3 ; ++i) + paramsModel.append({"name":"Param " + i , "Type": "int", "value": i}) + } + } + + Component { + id: editableDelegate + Item { + + Text { + width: parent.width + anchors.margins: 4 + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + elide: styleData.elideMode + text: styleData.value !== undefined ? styleData.value : "" + color: styleData.textColor + visible: !styleData.selected + } + Loader { + id: loaderEditor + anchors.fill: parent + anchors.margins: 4 + Connections { + target: loaderEditor.item + onAccepted: { + //if (typeof styleData.value === 'number') + // paramsModel.setProperty(styleData.row, styleData.role, Number(parseFloat(loaderEditor.item.text).toFixed(0))) + //else + // paramsModel.setProperty(styleData.row, styleData.role, loaderEditor.item.text) + } + } + sourceComponent: styleData.selected ? editor : null + Component { + id: editor + TextInput { + id: textinput + color: styleData.textColor + text: styleData.value + MouseArea { + id: mouseArea + anchors.fill: parent + hoverEnabled: true + onClicked: textinput.forceActiveFocus() + } + } + } + } + } + } +} diff --git a/mix/qml/TransactionList.qml b/mix/qml/TransactionList.qml index cb36c1847..3d6e2840d 100644 --- a/mix/qml/TransactionList.qml +++ b/mix/qml/TransactionList.qml @@ -11,29 +11,36 @@ Rectangle { focus: true anchors.topMargin: 10 anchors.left: parent.left - height: parent.height - 30 - width: parent.width * 0.5 + height: parent.height + width: parent.width ListView { anchors.top: parent.top height: parent.height width: parent.width - anchors.horizontalCenter: parent.horizontalCenter - id: statesList + id: transactionList model: transactionListModel delegate: renderDelegate - highlight: highlightBar - highlightFollowsCurrentItem: true } - Component { - id: highlightBar - Rectangle { - height: statesList.currentItem.height - width: statesList.currentItem.width - border.color: "orange" - border.width: 1 - Behavior on y { SpringAnimation { spring: 2; damping: 0.1 } } + Button { + anchors.bottom: parent.bottom + text: qsTr("Add") + onClicked: + { + // Set next id here to work around Qt bug + // https://bugreports.qt-project.org/browse/QTBUG-41327 + // Second call to signal handle would just edit the item that was just created, no harm done + transactionDialog.reset(transactionListModel.count, transactionListModel); + transactionDialog.open(); + transactionDialog.focus = true; + } + } + + TransactionDialog { + id: transactionDialog + onAccepted: { + transactionListModel.edit(transactionDialog); } } @@ -43,10 +50,38 @@ Rectangle { id: wrapperItem height: 20 width: parent.width - Text { - anchors.centerIn: parent - text: title - font.pointSize: 9 + RowLayout + { + anchors.fill: parent + Text { + //anchors.fill: parent + Layout.fillWidth: true + Layout.fillHeight: true + text: title + font.pointSize: 12 + verticalAlignment: Text.AlignBottom + } + ToolButton { + text: qsTr("Edit"); + Layout.fillHeight: true + onClicked: { + transactionDialog.reset(transactionId, transactionListModel); + transactionDialog.open(); + transactionDialog.focus = true; + } + } + ToolButton { + text: qsTr("Delete"); + Layout.fillHeight: true + onClicked: { + } + } + ToolButton { + text: qsTr("Run"); + Layout.fillHeight: true + onClicked: { + } + } } } } diff --git a/mix/qml/main.qml b/mix/qml/main.qml index 05b29eb62..44f7a15d4 100644 --- a/mix/qml/main.qml +++ b/mix/qml/main.qml @@ -9,8 +9,6 @@ import CodeEditorExtensionManager 1.0 ApplicationWindow { id: mainApplication visible: true - x: Screen.width / 2 - width / 2 - y: Screen.height / 2 - height / 2 width: 1200 height: 600 minimumWidth: 400 @@ -26,13 +24,15 @@ ApplicationWindow { } } } + Component.onCompleted: { + setX(Screen.width / 2 - width / 2); + setY(Screen.height / 2 - height / 2); + } MainContent { } Dialog { - x: mainApplication.x + (mainApplication.width - width) / 2 - y: mainApplication.y + (mainApplication.height - height) / 2 objectName: "dialog" id: dialog height: 400 @@ -44,8 +44,6 @@ ApplicationWindow { } Dialog { - x: mainApplication.x + (mainApplication.width - width) / 2 - y: mainApplication.y + (mainApplication.height - height) / 2 objectName: "messageDialog" id: messageDialog height: 150