Browse Source

Merge pull request #1156 from yann300/ui_improvement2

mix - UI improvement
cl-refactor
Arkadiy Paronyan 10 years ago
parent
commit
03478e943d
  1. 1
      mix/AppContext.cpp
  2. 21
      mix/ClientModel.cpp
  3. 25
      mix/ClientModel.h
  4. 6
      mix/MixClient.cpp
  5. 2
      mix/MixClient.h
  6. 56
      mix/qml/Debugger.qml
  7. 28
      mix/qml/FilesSection.qml
  8. 6
      mix/qml/MainContent.qml
  9. 2
      mix/qml/ProjectFilesStyle.qml
  10. 18
      mix/qml/ProjectList.qml
  11. 72
      mix/qml/StatusPane.qml
  12. 39
      mix/qml/TransactionLog.qml
  13. 60
      mix/qml/WebPreview.qml
  14. 13
      mix/qml/main.qml

1
mix/AppContext.cpp

@ -73,6 +73,7 @@ void AppContext::load()
qmlRegisterType<QHashType>("org.ethereum.qml.QHashType", 1, 0, "QHashType"); qmlRegisterType<QHashType>("org.ethereum.qml.QHashType", 1, 0, "QHashType");
qmlRegisterType<QBoolType>("org.ethereum.qml.QBoolType", 1, 0, "QBoolType"); qmlRegisterType<QBoolType>("org.ethereum.qml.QBoolType", 1, 0, "QBoolType");
qmlRegisterType<QVariableDeclaration>("org.ethereum.qml.QVariableDeclaration", 1, 0, "QVariableDeclaration"); qmlRegisterType<QVariableDeclaration>("org.ethereum.qml.QVariableDeclaration", 1, 0, "QVariableDeclaration");
qmlRegisterType<RecordLogEntry>("org.ethereum.qml.RecordLogEntry", 1, 0, "RecordLogEntry");
QQmlComponent projectModelComponent(m_applicationEngine, QUrl("qrc:/qml/ProjectModel.qml")); QQmlComponent projectModelComponent(m_applicationEngine, QUrl("qrc:/qml/ProjectModel.qml"));
QObject* projectModel = projectModelComponent.create(); QObject* projectModel = projectModelComponent.create();
if (projectModelComponent.isError()) if (projectModelComponent.isError())

21
mix/ClientModel.cpp

@ -82,7 +82,7 @@ ClientModel::ClientModel(AppContext* _context):
qRegisterMetaType<QInstruction*>("QInstruction"); qRegisterMetaType<QInstruction*>("QInstruction");
qRegisterMetaType<QCode*>("QCode"); qRegisterMetaType<QCode*>("QCode");
qRegisterMetaType<QCallData*>("QCallData"); qRegisterMetaType<QCallData*>("QCallData");
qRegisterMetaType<RecordLogEntry*>("RecordLogEntry"); qRegisterMetaType<RecordLogEntry*>("RecordLogEntry*");
connect(this, &ClientModel::runComplete, this, &ClientModel::showDebugger, Qt::QueuedConnection); connect(this, &ClientModel::runComplete, this, &ClientModel::showDebugger, Qt::QueuedConnection);
m_client.reset(new MixClient(QStandardPaths::writableLocation(QStandardPaths::TempLocation).toStdString())); m_client.reset(new MixClient(QStandardPaths::writableLocation(QStandardPaths::TempLocation).toStdString()));
@ -325,6 +325,11 @@ void ClientModel::showDebuggerForTransaction(ExecutionResult const& _t)
debugDataReady(debugData); debugDataReady(debugData);
} }
void ClientModel::emptyRecord()
{
debugDataReady(new QDebugData());
}
void ClientModel::debugRecord(unsigned _index) void ClientModel::debugRecord(unsigned _index)
{ {
@ -349,6 +354,18 @@ void ClientModel::callContract(Address const& _contract, bytes const& _data, Tra
m_client->transact(m_client->userAccount().secret(), _tr.value, _contract, _data, _tr.gas, _tr.gasPrice); m_client->transact(m_client->userAccount().secret(), _tr.value, _contract, _data, _tr.gas, _tr.gasPrice);
} }
RecordLogEntry* ClientModel::lastBlock() const
{
eth::BlockInfo blockInfo = m_client->blockInfo();
std::stringstream strGas;
strGas << blockInfo.gasUsed;
std::stringstream strNumber;
strNumber << blockInfo.number;
RecordLogEntry* record = new RecordLogEntry(0, QString::fromStdString(strNumber.str()), tr(" - Block - "), tr("Hash: ") + QString(QString::fromStdString(toHex(blockInfo.hash.ref()))), tr("Gas Used: ") + QString::fromStdString(strGas.str()), QString(), QString(), false, RecordLogEntry::RecordType::Block);
QQmlEngine::setObjectOwnership(record, QQmlEngine::JavaScriptOwnership);
return record;
}
void ClientModel::onStateReset() void ClientModel::onStateReset()
{ {
m_contractAddresses.clear(); m_contractAddresses.clear();
@ -424,7 +441,7 @@ void ClientModel::onNewTransaction()
} }
} }
RecordLogEntry* log = new RecordLogEntry(recordIndex, transactionIndex, contract, function, value, address, returned, tr.isCall()); RecordLogEntry* log = new RecordLogEntry(recordIndex, transactionIndex, contract, function, value, address, returned, tr.isCall(), RecordLogEntry::RecordType::Transaction);
QQmlEngine::setObjectOwnership(log, QQmlEngine::JavaScriptOwnership); QQmlEngine::setObjectOwnership(log, QQmlEngine::JavaScriptOwnership);
emit newRecord(log); emit newRecord(log);
} }

25
mix/ClientModel.h

@ -72,6 +72,7 @@ struct TransactionSettings
class RecordLogEntry: public QObject class RecordLogEntry: public QObject
{ {
Q_OBJECT Q_OBJECT
Q_ENUMS(RecordType)
/// Recording index /// Recording index
Q_PROPERTY(unsigned recordIndex MEMBER m_recordIndex CONSTANT) Q_PROPERTY(unsigned recordIndex MEMBER m_recordIndex CONSTANT)
/// Human readable transaction bloack and transaction index /// Human readable transaction bloack and transaction index
@ -88,13 +89,20 @@ class RecordLogEntry: public QObject
Q_PROPERTY(QString returned MEMBER m_returned CONSTANT) Q_PROPERTY(QString returned MEMBER m_returned CONSTANT)
/// true if call, false if transaction /// true if call, false if transaction
Q_PROPERTY(bool call MEMBER m_call CONSTANT) Q_PROPERTY(bool call MEMBER m_call CONSTANT)
/// @returns record type
Q_PROPERTY(RecordType type MEMBER m_type CONSTANT)
public: public:
enum RecordType
{
Transaction,
Block
};
RecordLogEntry(): RecordLogEntry():
m_recordIndex(0), m_call(false) {} m_recordIndex(0), m_call(false), m_type(RecordType::Transaction) {}
RecordLogEntry(unsigned _recordIndex, QString _transactionIndex, QString _contract, QString _function, QString _value, QString _address, QString _returned, bool _call): RecordLogEntry(unsigned _recordIndex, QString _transactionIndex, QString _contract, QString _function, QString _value, QString _address, QString _returned, bool _call, RecordType _type):
m_recordIndex(_recordIndex), m_transactionIndex(_transactionIndex), m_contract(_contract), m_function(_function), m_value(_value), m_address(_address), m_returned(_returned), m_call(_call) {} m_recordIndex(_recordIndex), m_transactionIndex(_transactionIndex), m_contract(_contract), m_function(_function), m_value(_value), m_address(_address), m_returned(_returned), m_call(_call), m_type(_type) {}
private: private:
unsigned m_recordIndex; unsigned m_recordIndex;
@ -105,6 +113,7 @@ private:
QString m_address; QString m_address;
QString m_returned; QString m_returned;
bool m_call; bool m_call;
RecordType m_type;
}; };
/** /**
@ -123,11 +132,12 @@ public:
Q_PROPERTY(bool mining MEMBER m_mining NOTIFY miningStateChanged) Q_PROPERTY(bool mining MEMBER m_mining NOTIFY miningStateChanged)
/// @returns deployed contracts addresses /// @returns deployed contracts addresses
Q_PROPERTY(QVariantMap contractAddresses READ contractAddresses NOTIFY contractAddressesChanged) Q_PROPERTY(QVariantMap contractAddresses READ contractAddresses NOTIFY contractAddressesChanged)
// @returns the last block
Q_PROPERTY(RecordLogEntry* lastBlock READ lastBlock CONSTANT)
/// ethereum.js RPC request entry point /// ethereum.js RPC request entry point
/// @param _message RPC request in Json format /// @param _message RPC request in Json format
/// @returns RPC response in Json format /// @returns RPC response in Json format
Q_INVOKABLE QString apiCall(QString const& _message); Q_INVOKABLE QString apiCall(QString const& _message);
/// Simulate mining. Creates a new block /// Simulate mining. Creates a new block
Q_INVOKABLE void mine(); Q_INVOKABLE void mine();
@ -139,6 +149,8 @@ public slots:
void setupState(QVariantMap _state); void setupState(QVariantMap _state);
/// Show the debugger for a specified record /// Show the debugger for a specified record
Q_INVOKABLE void debugRecord(unsigned _index); Q_INVOKABLE void debugRecord(unsigned _index);
/// Show the debugger for an empty record
Q_INVOKABLE void emptyRecord();
private slots: private slots:
/// Update UI with machine states result. Display a modal dialog. /// Update UI with machine states result. Display a modal dialog.
@ -177,6 +189,7 @@ signals:
void stateCleared(); void stateCleared();
private: private:
RecordLogEntry* lastBlock() const;
QVariantMap contractAddresses() const; QVariantMap contractAddresses() const;
void executeSequence(std::vector<TransactionSettings> const& _sequence, u256 _balance); void executeSequence(std::vector<TransactionSettings> const& _sequence, u256 _balance);
dev::Address deployContract(bytes const& _code, TransactionSettings const& _tr = TransactionSettings()); dev::Address deployContract(bytes const& _code, TransactionSettings const& _tr = TransactionSettings());
@ -199,3 +212,5 @@ private:
} }
} }
Q_DECLARE_METATYPE(dev::mix::RecordLogEntry*)

6
mix/MixClient.cpp

@ -436,6 +436,12 @@ h256 MixClient::hashFromNumber(unsigned _number) const
eth::BlockInfo MixClient::blockInfo(h256 _hash) const eth::BlockInfo MixClient::blockInfo(h256 _hash) const
{ {
return BlockInfo(bc().block(_hash)); return BlockInfo(bc().block(_hash));
}
eth::BlockInfo MixClient::blockInfo() const
{
return BlockInfo(bc().block());
} }
eth::BlockDetails MixClient::blockDetails(h256 _hash) const eth::BlockDetails MixClient::blockDetails(h256 _hash) const

2
mix/MixClient.h

@ -89,6 +89,8 @@ public:
eth::MineProgress miningProgress() const override; eth::MineProgress miningProgress() const override;
std::pair<h256, u256> getWork() override { return std::pair<h256, u256>(); } std::pair<h256, u256> getWork() override { return std::pair<h256, u256>(); }
bool submitNonce(h256 const&) override { return false; } bool submitNonce(h256 const&) override { return false; }
/// @returns the last mined block information
eth::BlockInfo blockInfo() const;
private: private:
void executeTransaction(dev::eth::Transaction const& _t, eth::State& _state, bool _call); void executeTransaction(dev::eth::Transaction const& _t, eth::State& _state, bool _call);

56
mix/qml/Debugger.qml

@ -12,7 +12,7 @@ Rectangle {
id: debugPanel id: debugPanel
property alias transactionLog : transactionLog property alias transactionLog : transactionLog
property string compilationErrorMessage
objectName: "debugPanel" objectName: "debugPanel"
color: "#ededed" color: "#ededed"
clip: true clip: true
@ -23,25 +23,30 @@ Rectangle {
forceActiveFocus(); forceActiveFocus();
} }
function update(data, giveFocus) function displayCompilationErrorIfAny()
{
if (statusPane && codeModel.hasContract)
{
Debugger.init(data);
debugScrollArea.visible = true;
compilationErrorArea.visible = false;
machineStates.visible = true;
}
else
{ {
debugScrollArea.visible = false; debugScrollArea.visible = false;
compilationErrorArea.visible = true; compilationErrorArea.visible = true;
machineStates.visible = false; machineStates.visible = false;
var errorInfo = ErrorLocationFormater.extractErrorInfo(statusPane.result.compilerMessage, false); var errorInfo = ErrorLocationFormater.extractErrorInfo(compilationErrorMessage, false);
errorLocation.text = errorInfo.errorLocation; errorLocation.text = errorInfo.errorLocation;
errorDetail.text = errorInfo.errorDetail; errorDetail.text = errorInfo.errorDetail;
errorLine.text = errorInfo.errorLine; errorLine.text = errorInfo.errorLine;
} }
function update(data, giveFocus)
{
if (data === null)
Debugger.init(null);
else if (data.states.length === 0)
Debugger.init(null);
else if (codeModel.hasContract)
{
Debugger.init(data);
debugScrollArea.visible = true;
compilationErrorArea.visible = false;
machineStates.visible = true;
}
if (giveFocus) if (giveFocus)
forceActiveFocus(); forceActiveFocus();
} }
@ -55,7 +60,15 @@ Rectangle {
Connections { Connections {
target: codeModel target: codeModel
onCompilationComplete: update(null, false); onCompilationComplete:
{
debugPanel.compilationErrorMessage = "";
update(null, false);
}
onCompilationError: {
debugPanel.compilationErrorMessage = _error;
}
} }
Settings { Settings {
@ -73,7 +86,7 @@ Rectangle {
visible: false; visible: false;
id: compilationErrorArea id: compilationErrorArea
width: parent.width - 20 width: parent.width - 20
height: 500 height: 600
color: "#ededed" color: "#ededed"
anchors.left: parent.left anchors.left: parent.left
anchors.top: parent.top anchors.top: parent.top
@ -82,7 +95,20 @@ Rectangle {
{ {
width: parent.width width: parent.width
anchors.top: parent.top anchors.top: parent.top
spacing: 25 spacing: 15
Rectangle
{
height: 15
Button {
text: qsTr("Back to Debugger")
onClicked: {
debugScrollArea.visible = true;
compilationErrorArea.visible = false;
machineStates.visible = true;
}
}
}
RowLayout RowLayout
{ {
height: 100 height: 100

28
mix/qml/FilesSection.qml

@ -6,17 +6,19 @@ import QtQuick.Controls.Styles 1.3
import "." import "."
ColumnLayout { Rectangle
{
Layout.fillWidth: true
Layout.minimumHeight: hiddenHeightTopLevel()
height: hiddenHeightTopLevel()
Layout.maximumHeight: hiddenHeightTopLevel()
id: wrapperItem id: wrapperItem
signal documentSelected(string doc, string groupName) signal documentSelected(string doc, string groupName)
property alias model: filesList.model property alias model: filesList.model
property string sectionName; property string sectionName;
property variant selManager; property variant selManager;
Layout.fillWidth: true property int index;
Layout.minimumHeight: hiddenHeightTopLevel() color: index % 2 === 0 ? "transparent" : ProjectFilesStyle.title.background
height: hiddenHeightTopLevel()
Layout.maximumHeight: hiddenHeightTopLevel()
spacing: 0
function hiddenHeightTopLevel() function hiddenHeightTopLevel()
{ {
@ -48,6 +50,10 @@ ColumnLayout {
model.remove(i); model.remove(i);
} }
ColumnLayout {
anchors.fill: parent
spacing: 0
SourceSansProRegular SourceSansProRegular
{ {
id: fileNameFont id: fileNameFont
@ -62,8 +68,9 @@ ColumnLayout {
{ {
anchors.top: parent.top anchors.top: parent.top
id: rowCol id: rowCol
width: parent.width
height: ProjectFilesStyle.documentsList.height height: ProjectFilesStyle.documentsList.height
Layout.fillWidth: true
Image { Image {
source: "qrc:/qml/img/opentriangleindicator_filesproject.png" source: "qrc:/qml/img/opentriangleindicator_filesproject.png"
@ -73,7 +80,7 @@ ColumnLayout {
anchors.right: section.left anchors.right: section.left
anchors.rightMargin: 8 anchors.rightMargin: 8
anchors.top: parent.top anchors.top: parent.top
anchors.topMargin: 6 anchors.topMargin: 10
} }
Text Text
@ -117,6 +124,7 @@ ColumnLayout {
width: parent.width width: parent.width
visible: section.state !== "hidden" visible: section.state !== "hidden"
spacing: 0 spacing: 0
Repeater Repeater
{ {
id: filesList id: filesList
@ -130,7 +138,7 @@ ColumnLayout {
Layout.preferredHeight: wrapperItem.hiddenHeightElement() Layout.preferredHeight: wrapperItem.hiddenHeightElement()
Layout.maximumHeight: wrapperItem.hiddenHeightElement() Layout.maximumHeight: wrapperItem.hiddenHeightElement()
height: wrapperItem.hiddenHeightElement() height: wrapperItem.hiddenHeightElement()
color: isSelected ? ProjectFilesStyle.documentsList.highlightColor : ProjectFilesStyle.documentsList.background color: isSelected ? ProjectFilesStyle.documentsList.highlightColor : "transparent"
property bool isSelected property bool isSelected
property bool renameMode property bool renameMode
Text { Text {
@ -244,5 +252,5 @@ ColumnLayout {
} }
} }
} }
}
} }

6
mix/qml/MainContent.qml

@ -75,6 +75,12 @@ Rectangle {
codeWebSplitter.orientation = (codeWebSplitter.orientation === Qt.Vertical ? Qt.Horizontal : Qt.Vertical); codeWebSplitter.orientation = (codeWebSplitter.orientation === Qt.Vertical ? Qt.Horizontal : Qt.Vertical);
} }
function displayCompilationErrorIfAny()
{
rightView.visible = true;
rightView.displayCompilationErrorIfAny();
}
CodeEditorExtensionManager { CodeEditorExtensionManager {
headerView: headerPaneTabs; headerView: headerPaneTabs;
} }

2
mix/qml/ProjectFilesStyle.qml

@ -25,7 +25,7 @@ QtObject {
property string sectionColor: "#808080" property string sectionColor: "#808080"
property string selectedColor: "white" property string selectedColor: "white"
property string highlightColor: "#4a90e2" property string highlightColor: "#4a90e2"
property int height: 25 property int height: 35
property int fileNameHeight: 30 property int fileNameHeight: 30
property int fontSize: absoluteSize(2)// 13 property int fontSize: absoluteSize(2)// 13
property int sectionFontSize: absoluteSize(2)// 13 property int sectionFontSize: absoluteSize(2)// 13

18
mix/qml/ProjectList.qml

@ -26,11 +26,9 @@ Item {
Image { Image {
id: projectIcon id: projectIcon
source: "qrc:/qml/img/dappProjectIcon.png" source: "qrc:/qml/img/dappProjectIcon.png"
//sourceSize.height: 32
anchors.right: projectTitle.left anchors.right: projectTitle.left
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: 6 anchors.rightMargin: 6
//anchors.centerIn: parent
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
width: 32 width: 32
height: 32 height: 32
@ -65,7 +63,7 @@ Item {
Rectangle Rectangle
{ {
Layout.fillWidth: true Layout.fillWidth: true
height: 10 height: 3
color: ProjectFilesStyle.documentsList.background color: ProjectFilesStyle.documentsList.background
} }
@ -82,14 +80,24 @@ Item {
anchors.top: parent.top anchors.top: parent.top
width: parent.width width: parent.width
spacing: 0 spacing: 0
Repeater { Repeater {
model: [qsTr("Contracts"), qsTr("Javascript"), qsTr("Web Pages"), qsTr("Styles"), qsTr("Images"), qsTr("Misc")]; model: [qsTr("Contracts"), qsTr("Javascript"), qsTr("Web Pages"), qsTr("Styles"), qsTr("Images"), qsTr("Misc")];
signal selected(string doc, string groupName) signal selected(string doc, string groupName)
property int incr: -1;
id: sectionRepeater id: sectionRepeater
FilesSection FilesSection
{ {
id: section;
sectionName: modelData sectionName: modelData
index:
{
for (var k in sectionRepeater.model)
{
if (sectionRepeater.model[k] === modelData)
return k;
}
}
model: sectionModel model: sectionModel
selManager: sectionRepeater selManager: sectionRepeater
@ -170,10 +178,10 @@ Item {
projectModel.openDocument(newDoc.documentId); projectModel.openDocument(newDoc.documentId);
sectionRepeater.selected(newDoc.documentId, modelData); sectionRepeater.selected(newDoc.documentId, modelData);
} }
} }
} }
} }
} }
} }
} }

72
mix/qml/StatusPane.qml

@ -1,6 +1,7 @@
import QtQuick 2.2 import QtQuick 2.2
import QtQuick.Controls 1.1 import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1 import QtQuick.Layouts 1.1
import QtQuick.Controls.Styles 1.3
import "js/ErrorLocationFormater.js" as ErrorLocationFormater import "js/ErrorLocationFormater.js" as ErrorLocationFormater
import "." import "."
@ -13,7 +14,7 @@ Rectangle {
if (!message) if (!message)
{ {
status.state = ""; status.state = "";
status.text = qsTr("Compile without errors."); status.text = qsTr("Compile successfully.");
logslink.visible = false; logslink.visible = false;
debugImg.state = "active"; debugImg.state = "active";
} }
@ -64,6 +65,7 @@ Rectangle {
color: "transparent" color: "transparent"
anchors.fill: parent anchors.fill: parent
Rectangle { Rectangle {
id: statusContainer id: statusContainer
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
@ -72,18 +74,21 @@ Rectangle {
width: 500 width: 500
height: 30 height: 30
color: "#fcfbfc" color: "#fcfbfc"
RowLayout {
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
spacing: 5
Text { Text {
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
font.pointSize: StatusPaneStyle.general.statusFontSize font.pointSize: StatusPaneStyle.general.statusFontSize
height: 9 height: 15
font.family: "sans serif" font.family: "sans serif"
objectName: "status" objectName: "status"
wrapMode: Text.WrapAnywhere
elide: Text.ElideRight
maximumLineCount: 1
clip: true
id: status id: status
states:[ states: [
State { State {
name: "error" name: "error"
PropertyChanges { PropertyChanges {
@ -96,24 +101,59 @@ Rectangle {
} }
} }
] ]
onTextChanged:
{
updateWidth()
toolTipInfo.tooltip = text;
} }
Text { function updateWidth()
{
if (text.length > 80)
width = parent.width - 10
else
width = undefined
}
}
Button
{
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.right
anchors.leftMargin: 10
width: 38
height: 28
visible: false visible: false
font.pointSize: StatusPaneStyle.general.logLinkFontSize text: qsTr("Log")
height: 9
text: qsTr("See Log.")
font.family: "Monospace"
objectName: "status" objectName: "status"
id: logslink id: logslink
color: "#8c8a74" action: displayLogAction
MouseArea { }
Action {
id: displayLogAction
onTriggered: {
mainContent.displayCompilationErrorIfAny();
}
}
Button
{
anchors.fill: parent anchors.fill: parent
onClicked: { id: toolTip
mainContent.ensureRightView(); action: toolTipInfo
text: ""
style:
ButtonStyle {
background:Rectangle {
color: "transparent"
} }
} }
} }
Action {
id: toolTipInfo
tooltip: ""
} }
} }

39
mix/qml/TransactionLog.qml

@ -3,15 +3,13 @@ import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1 import QtQuick.Controls.Styles 1.1
import QtQuick.Dialogs 1.1 import QtQuick.Dialogs 1.1
import QtQuick.Layouts 1.1 import QtQuick.Layouts 1.1
import org.ethereum.qml.RecordLogEntry 1.0
Item { Item {
property bool showLogs: true
property ListModel fullModel: ListModel{} property ListModel fullModel: ListModel{}
property ListModel transactionModel: ListModel{} property ListModel transactionModel: ListModel{}
onShowLogsChanged: { property ListModel callModel: ListModel{}
logTable.model = showLogs ? fullModel : transactionModel
}
Action { Action {
id: addStateAction id: addStateAction
@ -78,13 +76,24 @@ Item {
action: mineAction action: mineAction
} }
CheckBox { ComboBox {
id: recording id: itemFilter
text: qsTr("Record transactions");
checked: true
Layout.fillWidth: true
function getCurrentModel()
{
return currentIndex === 0 ? fullModel : currentIndex === 1 ? transactionModel : currentIndex === 2 ? callModel : fullModel;
}
model: ListModel {
ListElement { text: qsTr("Calls and Transactions"); value: 0; }
ListElement { text: qsTr("Only Transactions"); value: 1; }
ListElement { text: qsTr("Only Calls"); value: 2; }
}
onCurrentIndexChanged:
{
logTable.model = itemFilter.getCurrentModel();
}
} }
} }
TableView { TableView {
@ -125,7 +134,10 @@ Item {
} }
onActivated: { onActivated: {
var item = logTable.model.get(row); var item = logTable.model.get(row);
if (item.type === RecordLogEntry.Transaction)
clientModel.debugRecord(item.recordIndex); clientModel.debugRecord(item.recordIndex);
else
clientModel.emptyRecord();
} }
Keys.onPressed: { Keys.onPressed: {
if ((event.modifiers & Qt.ControlModifier) && event.key === Qt.Key_C && currentRow >=0 && currentRow < logTable.model.count) { if ((event.modifiers & Qt.ControlModifier) && event.key === Qt.Key_C && currentRow >=0 && currentRow < logTable.model.count) {
@ -141,15 +153,18 @@ Item {
onStateCleared: { onStateCleared: {
fullModel.clear(); fullModel.clear();
transactionModel.clear(); transactionModel.clear();
callModel.clear();
} }
onNewRecord: { onNewRecord: {
if (recording.checked)
{
fullModel.append(_r); fullModel.append(_r);
if (!_r.call) if (!_r.call)
transactionModel.append(_r); transactionModel.append(_r);
else
callModel.append(_r);
} }
onMiningComplete: {
fullModel.append(clientModel.lastBlock);
transactionModel.append(clientModel.lastBlock);
} }
} }
} }

60
mix/qml/WebPreview.qml

@ -26,7 +26,8 @@ Item {
function reload() { function reload() {
if (initialized) { if (initialized) {
updateContract(); updateContract();
webView.runJavaScript("reloadPage()"); //webView.runJavaScript("reloadPage()");
setPreviewUrl(urlInput.text);
} }
} }
@ -55,11 +56,13 @@ Item {
} }
function changePage() { function changePage() {
if (pageCombo.currentIndex >= 0 && pageCombo.currentIndex < pageListModel.count) { setPreviewUrl(urlInput.text);
/*if (pageCombo.currentIndex >= 0 && pageCombo.currentIndex < pageListModel.count) {
urlInput.text = httpServer.url + "/" + pageListModel.get(pageCombo.currentIndex).documentId;
setPreviewUrl(httpServer.url + "/" + pageListModel.get(pageCombo.currentIndex).documentId); setPreviewUrl(httpServer.url + "/" + pageListModel.get(pageCombo.currentIndex).documentId);
} else { } else {
setPreviewUrl(""); setPreviewUrl("");
} }*/
} }
Connections { Connections {
target: appContext target: appContext
@ -98,24 +101,16 @@ Item {
updateDocument(documentId, function(i) { pageListModel.set(i, projectModel.getDocument(documentId)) } ) updateDocument(documentId, function(i) { pageListModel.set(i, projectModel.getDocument(documentId)) } )
} }
onDocumentOpened: {
if (!document.isHtml)
return;
for (var i = 0; i < pageListModel.count; i++) {
var doc = pageListModel.get(i);
if (doc.documentId === document.documentId) {
pageCombo.currentIndex = i;
}
}
}
onProjectLoading: { onProjectLoading: {
for (var i = 0; i < target.listModel.count; i++) { for (var i = 0; i < target.listModel.count; i++) {
var document = target.listModel.get(i); var document = target.listModel.get(i);
if (document.isHtml) { if (document.isHtml) {
pageListModel.append(document); pageListModel.append(document);
if (pageListModel.count === 1) //first page added if (pageListModel.count === 1) //first page added
changePage(); {
urlInput.text = httpServer.url + "/" + document.documentId;
setPreviewUrl(httpServer.url + "/" + document.documentId);
}
} }
} }
} }
@ -151,13 +146,20 @@ Item {
else else
{ {
//document request //document request
if (urlPath === "/")
urlPath = "/index.html";
var documentId = urlPath.substr(urlPath.lastIndexOf("/") + 1); var documentId = urlPath.substr(urlPath.lastIndexOf("/") + 1);
var content = ""; var content = "";
if (projectModel.codeEditor.isDocumentOpen(documentId)) if (projectModel.codeEditor.isDocumentOpen(documentId))
content = projectModel.codeEditor.getDocumentText(documentId); content = projectModel.codeEditor.getDocumentText(documentId);
else else
content = fileIo.readFile(projectModel.getDocument(documentId).path); {
if (documentId === pageListModel.get(pageCombo.currentIndex).documentId) { var doc = projectModel.getDocument(documentId);
if (doc !== undefined)
content = fileIo.readFile(doc.path);
}
if (documentId === urlInput.text.replace(httpServer.url + "/", "")) {
//root page, inject deployment script //root page, inject deployment script
content = "<script>web3=parent.web3;contracts=parent.contracts;</script>\n" + content; content = "<script>web3=parent.web3;contracts=parent.contracts;</script>\n" + content;
_request.setResponseContentType("text/html"); _request.setResponseContentType("text/html");
@ -181,19 +183,23 @@ Item {
anchors.fill: parent anchors.fill: parent
anchors.leftMargin: 3 anchors.leftMargin: 3
spacing: 3 spacing: 3
DefaultLabel {
text: qsTr("Preview of")
anchors.verticalCenter: parent.verticalCenter
}
ComboBox { DefaultTextField
id: pageCombo {
model: pageListModel id: urlInput
textRole: "name"
currentIndex: -1
onCurrentIndexChanged: changePage()
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
height: 21 height: 21
width: 300
Keys.onEnterPressed:
{
setPreviewUrl(text);
}
Keys.onReturnPressed:
{
setPreviewUrl(text);
}
focus: true
} }
Action { Action {

13
mix/qml/main.qml

@ -56,7 +56,7 @@ ApplicationWindow {
MenuItem { action: toggleTransactionLogAction } MenuItem { action: toggleTransactionLogAction }
MenuItem { action: toggleWebPreviewAction } MenuItem { action: toggleWebPreviewAction }
MenuItem { action: toggleWebPreviewOrientationAction } MenuItem { action: toggleWebPreviewOrientationAction }
MenuItem { action: toggleCallsInLog } //MenuItem { action: toggleCallsInLog }
} }
} }
@ -92,7 +92,7 @@ ApplicationWindow {
Action { Action {
id: mineAction id: mineAction
text: qsTr("Mine") text: qsTr("New Block")
shortcut: "Ctrl+M" shortcut: "Ctrl+M"
onTriggered: clientModel.mine(); onTriggered: clientModel.mine();
enabled: codeModel.hasContract && !clientModel.running && !clientModel.mining enabled: codeModel.hasContract && !clientModel.running && !clientModel.mining
@ -165,15 +165,6 @@ ApplicationWindow {
onTriggered: mainContent.toggleWebPreviewOrientation(); onTriggered: mainContent.toggleWebPreviewOrientation();
} }
Action {
id: toggleCallsInLog
text: qsTr("Show Calls in Transaction Log")
shortcut: ""
checkable: true
checked: mainContent.rightPane.transactionLog.showLogs
onTriggered: mainContent.rightPane.transactionLog.showLogs = !mainContent.rightPane.transactionLog.showLogs
}
Action { Action {
id: toggleRunOnLoadAction id: toggleRunOnLoadAction
text: qsTr("Load State on Startup") text: qsTr("Load State on Startup")

Loading…
Cancel
Save