diff --git a/libevmcore/Assembly.cpp b/libevmcore/Assembly.cpp index 0301c9325..904903761 100644 --- a/libevmcore/Assembly.cpp +++ b/libevmcore/Assembly.cpp @@ -34,9 +34,9 @@ void Assembly::append(Assembly const& _a) for (AssemblyItem i: _a.m_items) { if (i.type() == Tag || i.type() == PushTag) - i.m_data += m_usedTags; + i.setData(i.data() + m_usedTags); else if (i.type() == PushSub || i.type() == PushSubSize) - i.m_data += m_subs.size(); + i.setData(i.data() + m_usedTags); append(i); } m_deposit = newDeposit; @@ -106,34 +106,34 @@ ostream& Assembly::stream(ostream& _out, string const& _prefix, StringMap const& for (AssemblyItem const& i: m_items) { _out << _prefix; - switch (i.m_type) + switch (i.type()) { case Operation: _out << " " << instructionInfo(i.instruction()).name << "\t" << i.getJumpTypeAsString(); break; case Push: - _out << " PUSH " << i.m_data; + _out << " PUSH " << i.data(); break; case PushString: - _out << " PUSH \"" << m_strings.at((h256)i.m_data) << "\""; + _out << " PUSH \"" << m_strings.at((h256)i.data()) << "\""; break; case PushTag: - _out << " PUSH [tag" << i.m_data << "]"; + _out << " PUSH [tag" << i.data() << "]"; break; case PushSub: - _out << " PUSH [$" << h256(i.m_data).abridged() << "]"; + _out << " PUSH [$" << h256(i.data()).abridged() << "]"; break; case PushSubSize: - _out << " PUSH #[$" << h256(i.m_data).abridged() << "]"; + _out << " PUSH #[$" << h256(i.data()).abridged() << "]"; break; case PushProgramSize: _out << " PUSHSIZE"; break; case Tag: - _out << "tag" << i.m_data << ": " << endl << _prefix << " JUMPDEST"; + _out << "tag" << i.data() << ": " << endl << _prefix << " JUMPDEST"; break; case PushData: - _out << " PUSH [" << hex << (unsigned)i.m_data << "]"; + _out << " PUSH [" << hex << (unsigned)i.data() << "]"; break; default: BOOST_THROW_EXCEPTION(InvalidOpcode()); @@ -189,7 +189,7 @@ Assembly& Assembly::optimise(bool _enable) return *this; std::vector>> rules; // jump to next instruction - rules.push_back({ { PushTag, Instruction::JUMP, Tag }, [](AssemblyItemsConstRef m) -> AssemblyItems { if (m[0].m_data == m[2].m_data) return {m[2]}; else return m.toVector(); }}); + rules.push_back({ { PushTag, Instruction::JUMP, Tag }, [](AssemblyItemsConstRef m) -> AssemblyItems { if (m[0].data() == m[2].data()) return {m[2]}; else return m.toVector(); }}); unsigned total = 0; for (unsigned count = 1; count > 0; total += count) @@ -331,16 +331,16 @@ bytes Assembly::assemble() const // m_data must not change from here on for (AssemblyItem const& i: m_items) - switch (i.m_type) + switch (i.type()) { case Operation: - ret.push_back((byte)i.m_data); + ret.push_back((byte)i.data()); break; case PushString: { ret.push_back((byte)Instruction::PUSH32); unsigned ii = 0; - for (auto j: m_strings.at((h256)i.m_data)) + for (auto j: m_strings.at((h256)i.data())) if (++ii > 32) break; else @@ -351,30 +351,30 @@ bytes Assembly::assemble() const } case Push: { - byte b = max(1, dev::bytesRequired(i.m_data)); + byte b = max(1, dev::bytesRequired(i.data())); ret.push_back((byte)Instruction::PUSH1 - 1 + b); ret.resize(ret.size() + b); bytesRef byr(&ret.back() + 1 - b, b); - toBigEndian(i.m_data, byr); + toBigEndian(i.data(), byr); break; } case PushTag: { ret.push_back(tagPush); - tagRef[ret.size()] = (unsigned)i.m_data; + tagRef[ret.size()] = (unsigned)i.data(); ret.resize(ret.size() + bytesPerTag); break; } case PushData: case PushSub: { ret.push_back(dataRefPush); - dataRef.insert(make_pair((h256)i.m_data, ret.size())); + dataRef.insert(make_pair((h256)i.data(), ret.size())); ret.resize(ret.size() + bytesPerDataRef); break; } case PushSubSize: { - auto s = m_data[i.m_data].size(); + auto s = m_data[i.data()].size(); byte b = max(1, dev::bytesRequired(s)); ret.push_back((byte)Instruction::PUSH1 - 1 + b); ret.resize(ret.size() + b); @@ -390,7 +390,7 @@ bytes Assembly::assemble() const break; } case Tag: - tagPos[(unsigned)i.m_data] = ret.size(); + tagPos[(unsigned)i.data()] = ret.size(); ret.push_back((byte)Instruction::JUMPDEST); break; default: diff --git a/libevmcore/Assembly.h b/libevmcore/Assembly.h index 315e6aaed..2744af900 100644 --- a/libevmcore/Assembly.h +++ b/libevmcore/Assembly.h @@ -65,7 +65,7 @@ public: template Assembly& operator<<(T const& _d) { append(_d); return *this; } AssemblyItems const& getItems() const { return m_items; } AssemblyItem const& back() const { return m_items.back(); } - std::string backString() const { return m_items.size() && m_items.back().m_type == PushString ? m_strings.at((h256)m_items.back().m_data) : std::string(); } + std::string backString() const { return m_items.size() && m_items.back().type() == PushString ? m_strings.at((h256)m_items.back().data()) : std::string(); } void onePath() { if (asserts(!m_totalDeposit && !m_baseDeposit)) BOOST_THROW_EXCEPTION(InvalidDeposit()); m_baseDeposit = m_deposit; m_totalDeposit = INT_MAX; } void otherPath() { donePath(); m_totalDeposit = m_deposit; m_deposit = m_baseDeposit; } diff --git a/libevmcore/AssemblyItem.h b/libevmcore/AssemblyItem.h index e7beced39..3e222a6eb 100644 --- a/libevmcore/AssemblyItem.h +++ b/libevmcore/AssemblyItem.h @@ -40,8 +40,6 @@ class Assembly; class AssemblyItem { - friend class Assembly; - public: enum class JumpType { Ordinary, IntoFunction, OutOfFunction }; @@ -54,6 +52,9 @@ public: AssemblyItemType type() const { return m_type; } u256 const& data() const { return m_data; } + void setType(AssemblyItemType const _type) { m_type = _type; } + void setData(u256 const& _data) { m_data = _data; } + /// @returns the instruction of this item (only valid if type() == Operation) Instruction instruction() const { return Instruction(byte(m_data)); } diff --git a/mix/qml.qrc b/mix/qml.qrc index bed954741..5ceaaced6 100644 --- a/mix/qml.qrc +++ b/mix/qml.qrc @@ -61,5 +61,6 @@ qml/js/TransactionHelper.js qml/main.qml qml/qmldir + qml/StatesComboBox.qml diff --git a/mix/qml/Debugger.qml b/mix/qml/Debugger.qml index 358750b24..9ab2f03a4 100644 --- a/mix/qml/Debugger.qml +++ b/mix/qml/Debugger.qml @@ -219,6 +219,33 @@ Rectangle { anchors.horizontalCenter: parent.horizontalCenter id: jumpButtons spacing: 3 + + StepActionImage + { + id: playAction + enabledStateImg: "qrc:/qml/img/play_button.png" + disableStateImg: "qrc:/qml/img/play_button.png" + onClicked: console.log("play"); + width: 30 + height: 30 + buttonShortcut: "Ctrl+Shift+F8" + buttonTooltip: qsTr("Play") + visible: true + } + + StepActionImage + { + id: pauseAction + enabledStateImg: "qrc:/qml/img/pause_button.png" + disableStateImg: "qrc:/qml/img/pause_button.png" + onClicked: console.log("pause"); + width: 30 + height: 30 + buttonShortcut: "Ctrl+Shift+F9" + buttonTooltip: qsTr("Pause") + visible: true + } + StepActionImage { id: runBackAction; diff --git a/mix/qml/StatesComboBox.qml b/mix/qml/StatesComboBox.qml new file mode 100644 index 000000000..34567d083 --- /dev/null +++ b/mix/qml/StatesComboBox.qml @@ -0,0 +1,245 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file StatesComboBox.qml + * @author Ali Mashatan ali@ethdev.com + * @date 2015 + * Ethereum IDE client. + */ + +import QtQuick 2.0 +import QtQuick.Controls 1.0 +import QtQuick.Layouts 1.1 +import QtGraphicalEffects 1.0 + +Rectangle { + id: statesComboBox + + width: 200 + height: 20 + + Component.onCompleted: { + var top = dropDownList + while (top.parent) { + top = top.parent + if (top.objectName == "debugPanel") + break + } + var coordinates = dropDownList.mapToItem(top, 0, 0) + //the order is important + dropDownShowdowList.parent = top + dropDownList.parent = top + + dropDownShowdowList.x = coordinates.x + dropDownShowdowList.y = coordinates.y + + dropDownList.x = coordinates.x + dropDownList.y = coordinates.y + } + + signal selectItem(real item) + signal editItem(real item) + signal selectCreate + property variant rowHeight: 25 + property variant items + property alias selectedItem: chosenItemText.text + property alias selectedIndex: listView.currentRow + function setSelectedIndex(index) { + listView.currentRow = index + chosenItemText.text = statesComboBox.items.get(index).title + } + + signal comboClicked + + property variant colorItem + property variant colorSelect + + smooth: true + Rectangle { + id: chosenItem + width: parent.width + height: statesComboBox.height + color: statesComboBox.color + smooth: true + Text { + id: chosenItemText + anchors.top: parent.top + anchors.left: parent.left + anchors.margins: 2 + color: statesComboBox.colorItem + text: "" + smooth: true + } + + MouseArea { + anchors.fill: parent + onClicked: { + statesComboBox.state = statesComboBox.state === "dropDown" ? "" : "dropDown" + } + } + } + + Rectangle { + id: dropDownShowdowList + width: statesComboBox.width + opacity: 0.3 + height: 0 + clip: true + radius: 4 + anchors.top: chosenItem.top + anchors.margins: 2 + color: "gray" + } + //ToDo: We need scrollbar for items + Rectangle { + id: dropDownList + width: statesComboBox.width + height: 0 + clip: true + radius: 4 + anchors.top: chosenItem.top + anchors.margins: 2 + color: statesComboBox.color + + ColumnLayout { + spacing: 2 + TableView { + id: listView + height: 20 + implicitHeight: 0 + width: statesComboBox.width + model: statesComboBox.items + horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff + currentRow: -1 + headerVisible: false + backgroundVisible: false + alternatingRowColors: false + frameVisible: false + + TableViewColumn { + role: "title" + title: "" + width: statesComboBox.width + delegate: mainItemDelegate + } + rowDelegate: Rectangle { + width: statesComboBox.width + height: statesComboBox.rowHeight + } + Component { + id: mainItemDelegate + Rectangle { + id: itemDelegate + width: statesComboBox.width + height: statesComboBox.height + Text { + id: textItemid + text: styleData.value + color: statesComboBox.colorItem + anchors.top: parent.top + anchors.left: parent.left + anchors.margins: 5 + } + Image { + id: imageItemid + height: 20 + width: 20 + anchors.right: parent.right + anchors.top: parent.top + anchors.margins: 5 + visible: false + fillMode: Image.PreserveAspectFit + source: "img/edit_combox.png" + } + + MouseArea { + anchors.fill: parent + hoverEnabled: true + + onEntered: { + imageItemid.visible = true + textItemid.color = statesComboBox.colorSelect + } + onExited: { + imageItemid.visible = false + textItemid.color = statesComboBox.colorItem + } + onClicked: { + if (mouseX > imageItemid.x + && mouseX < imageItemid.x + imageItemid.width + && mouseY > imageItemid.y + && mouseY < imageItemid.y + imageItemid.height) + statesComboBox.editItem(styleData.row) + else { + statesComboBox.state = "" + var prevSelection = chosenItemText.text + chosenItemText.text = styleData.value + listView.currentRow = styleData.row + statesComboBox.selectItem(styleData.row) + } + } + } + } //Item + } //Component + } //Table View + + RowLayout { + Rectangle { + width: 1 + } + Text { + id: createStateText + width: statesComboBox.width + height: statesComboBox.height + font.bold: true + text: qsTr("Create State ...") + MouseArea { + anchors.fill: parent + hoverEnabled: true + + onEntered: { + createStateText.color = statesComboBox.colorSelect + } + onExited: { + createStateText.color = statesComboBox.colorItem + } + onClicked: { + statesComboBox.state = "" + statesComboBox.selectCreate() + } + } + } + } + } + } + states: State { + name: "dropDown" + PropertyChanges { + target: dropDownList + height: (statesComboBox.rowHeight * (statesComboBox.items.count + 1)) + } + PropertyChanges { + target: dropDownShowdowList + width: statesComboBox.width + 3 + height: (statesComboBox.rowHeight * (statesComboBox.items.count + 1)) + 3 + } + PropertyChanges { + target: listView + height: 20 + implicitHeight: (statesComboBox.rowHeight * (statesComboBox.items.count)) + } + } +} diff --git a/mix/qml/TransactionLog.qml b/mix/qml/TransactionLog.qml index 43736a89a..3bcc6c270 100644 --- a/mix/qml/TransactionLog.qml +++ b/mix/qml/TransactionLog.qml @@ -6,30 +6,15 @@ import QtQuick.Layouts 1.1 import org.ethereum.qml.RecordLogEntry 1.0 Item { - property ListModel fullModel: ListModel{} property ListModel transactionModel: ListModel{} property ListModel callModel: ListModel{} - Action { - id: addStateAction - text: "Add State" - shortcut: "Ctrl+Alt+T" - enabled: codeModel.hasContract && !clientModel.running; - onTriggered: projectModel.stateListModel.addState(); - } - Action { - id: editStateAction - text: "Edit State" - shortcut: "Ctrl+Alt+T" - enabled: codeModel.hasContract && !clientModel.running && statesCombo.currentIndex >= 0 && projectModel.stateListModel.count > 0; - onTriggered: projectModel.stateListModel.editState(statesCombo.currentIndex); - } - ColumnLayout { anchors.fill: parent RowLayout { - + anchors.right: parent.right + anchors.left: parent.left Connections { id: compilationStatus @@ -60,37 +45,24 @@ Item { projectModel.stateListModel.debugDefaultState(); } } - - ComboBox { + StatesComboBox + { id: statesCombo - model: projectModel.stateListModel - width: 150 - editable: false - textRole: "title" - onActivated: { - model.runState(index); - } + items: projectModel.stateListModel + onSelectCreate: projectModel.stateListModel.addState(); + onEditItem: projectModel.stateListModel.editState(item) + colorItem: "black" + colorSelect: "blue" + color: "white" Connections { target: projectModel.stateListModel onStateRun: { - if (statesCombo.currentIndex !== index) - statesCombo.currentIndex = index; + if (statesCombo.selectedIndex !== index) + statesCombo.setSelectedIndex( index ); } } } Button - { - anchors.rightMargin: 9 - anchors.verticalCenter: parent.verticalCenter - action: editStateAction - } - Button - { - anchors.rightMargin: 9 - anchors.verticalCenter: parent.verticalCenter - action: addStateAction - } - Button { anchors.rightMargin: 9 anchors.verticalCenter: parent.verticalCenter @@ -163,16 +135,11 @@ Item { Keys.onPressed: { if ((event.modifiers & Qt.ControlModifier) && event.key === Qt.Key_C && currentRow >=0 && currentRow < logTable.model.count) { var item = logTable.model.get(currentRow); - clipboard.text = item.returned; + appContext.toClipboard(item.returned); } } } - Rectangle { - height: 6 - color: "transparent" - } } - Connections { target: clientModel onStateCleared: { diff --git a/mix/qml/img/edit_combox.png b/mix/qml/img/edit_combox.png new file mode 100644 index 000000000..be3b35942 Binary files /dev/null and b/mix/qml/img/edit_combox.png differ diff --git a/mix/qml/img/pause_button.png b/mix/qml/img/pause_button.png new file mode 100755 index 000000000..e87889551 Binary files /dev/null and b/mix/qml/img/pause_button.png differ diff --git a/mix/qml/img/pause_button2x.png b/mix/qml/img/pause_button2x.png new file mode 100755 index 000000000..6f45b3236 Binary files /dev/null and b/mix/qml/img/pause_button2x.png differ diff --git a/mix/qml/img/play_button.png b/mix/qml/img/play_button.png new file mode 100755 index 000000000..01a5c85cb Binary files /dev/null and b/mix/qml/img/play_button.png differ diff --git a/mix/qml/img/play_button2x.png b/mix/qml/img/play_button2x.png new file mode 100755 index 000000000..24eaa0659 Binary files /dev/null and b/mix/qml/img/play_button2x.png differ diff --git a/mix/res.qrc b/mix/res.qrc index e981f22ae..24bbc3830 100644 --- a/mix/res.qrc +++ b/mix/res.qrc @@ -48,10 +48,15 @@ qml/img/projecticon.png qml/img/run.png qml/img/search_filled.png + qml/img/play_button2x.png + qml/img/play_button.png + qml/img/pause_button2x.png + qml/img/pause_button.png res/mix_256x256x32.png stdc/config.sol stdc/namereg.sol stdc/std.sol + qml/img/edit_combox.png qml/img/clearicon.png qml/img/cleariconactive.png qml/img/copyicon.png