This commit is contained in:
Daniel Larimer 2015-08-03 16:22:23 -04:00
commit 13d83904c9
7 changed files with 100 additions and 36 deletions

View file

@ -88,6 +88,10 @@ Asset* ChainDataModel::getAsset(QString symbol)
return *itr; return *itr;
} }
QDateTime ChainDataModel::chainTime() const {
return QDateTime::fromTime_t(m_dynamic_global_properties.time.sec_since_epoch());
}
void ChainDataModel::processUpdatedObject(const fc::variant& update) void ChainDataModel::processUpdatedObject(const fc::variant& update)
{ {
if (update.is_null()) if (update.is_null())

View file

@ -8,6 +8,7 @@
#include "Asset.hpp" #include "Asset.hpp"
#include "Account.hpp" #include "Account.hpp"
#include <QDateTime>
#include <QObject> #include <QObject>
using graphene::chain::by_id; using graphene::chain::by_id;
@ -37,6 +38,7 @@ typedef multi_index_container<
class Transaction; class Transaction;
class ChainDataModel : public QObject { class ChainDataModel : public QObject {
Q_OBJECT Q_OBJECT
Q_PROPERTY(QDateTime chainTime READ chainTime NOTIFY blockReceived)
void processUpdatedObject(const fc::variant& update); void processUpdatedObject(const fc::variant& update);
@ -49,6 +51,8 @@ public:
Q_INVOKABLE Asset* getAsset(ObjectId id); Q_INVOKABLE Asset* getAsset(ObjectId id);
Q_INVOKABLE Asset* getAsset(QString symbol); Q_INVOKABLE Asset* getAsset(QString symbol);
QDateTime chainTime() const;
ChainDataModel(){} ChainDataModel(){}
ChainDataModel(fc::thread& t, QObject* parent = nullptr); ChainDataModel(fc::thread& t, QObject* parent = nullptr);
@ -64,6 +68,7 @@ public Q_SLOTS:
Q_SIGNALS: Q_SIGNALS:
void queueExecute(const std::function<void()>&); void queueExecute(const std::function<void()>&);
void exceptionThrown(QString message); void exceptionThrown(QString message);
void blockReceived();
private: private:
fc::thread* m_rpc_thread = nullptr; fc::thread* m_rpc_thread = nullptr;

View file

@ -3,8 +3,10 @@
#include <graphene/chain/protocol/transaction.hpp> #include <graphene/chain/protocol/transaction.hpp>
#include <QDateTime>
#include <QObject> #include <QObject>
#include <QQmlListProperty> #include <QQmlListProperty>
#include <QDebug>
class OperationBase; class OperationBase;
class Transaction : public QObject { class Transaction : public QObject {
@ -26,13 +28,19 @@ public:
return m_transaction; return m_transaction;
} }
public slots: QDateTime expiration() const
{
return QDateTime::fromTime_t(m_transaction.expiration.sec_since_epoch());
}
public Q_SLOTS:
void setStatus(Status status) void setStatus(Status status)
{ {
if (status == m_status) if (status == m_status)
return; return;
m_status = status; m_status = status;
qDebug() << status;
emit statusChanged(status); emit statusChanged(status);
} }
@ -46,13 +54,26 @@ public slots:
Q_EMIT operationsChanged(); Q_EMIT operationsChanged();
} }
void setExpiration(QDateTime expiration)
{
fc::time_point_sec exp(expiration.toTime_t());
if (exp == m_transaction.expiration)
return;
m_transaction.expiration = exp;
emit expirationChanged(expiration);
}
signals: signals:
void statusChanged(Status status); void statusChanged(Status status);
void operationsChanged(); void operationsChanged();
void expirationChanged(QDateTime expiration);
private: private:
Q_PROPERTY(Status status READ status WRITE setStatus NOTIFY statusChanged) Q_PROPERTY(Status status READ status WRITE setStatus NOTIFY statusChanged)
Q_PROPERTY(QQmlListProperty<OperationBase> operations READ operations NOTIFY operationsChanged) Q_PROPERTY(QQmlListProperty<OperationBase> operations READ operations NOTIFY operationsChanged)
Q_PROPERTY(QDateTime expiration READ expiration WRITE setExpiration NOTIFY expirationChanged)
Status m_status = Unbroadcasted; Status m_status = Unbroadcasted;
graphene::chain::signed_transaction m_transaction; graphene::chain::signed_transaction m_transaction;

View file

@ -56,6 +56,12 @@ int main(int argc, char *argv[])
engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
#else #else
engine.load(QUrl(QStringLiteral("qml/main.qml"))); engine.load(QUrl(QStringLiteral("qml/main.qml")));
QFileSystemWatcher watcher;
qDebug() << watcher.addPath("qml/");
QObject::connect(&watcher, &QFileSystemWatcher::directoryChanged, &engine, [&](QString path) {
qDebug() << "Changed file" << path;
engine.clearComponentCache();
});
#endif #endif
return app.exec(); return app.exec();

View file

@ -16,8 +16,8 @@ Flipable {
property bool flipped: false property bool flipped: false
Component.onCompleted: { Component.onCompleted: {
back = backComponent.createObject(flipable, {app: app, enabled: Qt.binding(function(){return flipped})}) back = backComponent.createObject(flipable, {app: app, enabled: Qt.binding(function(){return rotation.angle > 90})})
front = frontComponent.createObject(flipable, {app: app, enabled: Qt.binding(function(){return !flipped})}) front = frontComponent.createObject(flipable, {app: app, enabled: Qt.binding(function(){return rotation.angle < 90})})
front.canceled.connect(function() { canceled.apply(this, arguments) }) front.canceled.connect(function() { canceled.apply(this, arguments) })
front.completed.connect(function() { front.completed.connect(function() {
back.display.apply(this, arguments) back.display.apply(this, arguments)

View file

@ -17,6 +17,8 @@ Canvas {
Jdenticon.draw(identicon, name) Jdenticon.draw(identicon, name)
else { else {
var context = identicon.context var context = identicon.context
if (!context) return
context.reset() context.reset()
var draw_circle = function(context, x, y, radius) { var draw_circle = function(context, x, y, radius) {
context.beginPath() context.beginPath()

View file

@ -2,6 +2,7 @@ import QtQuick 2.5
import QtQuick.Controls 1.4 import QtQuick.Controls 1.4
import QtQuick.Dialogs 1.2 import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.2 import QtQuick.Layouts 1.2
import QtGraphicalEffects 1.0
import Graphene.Client 0.1 import Graphene.Client 0.1
@ -17,63 +18,88 @@ import "."
FormBase { FormBase {
id: base id: base
property Transaction trx readonly property alias trx: __trx
Component.onCompleted: console.log("Made a transaction confirmation form") Component.onCompleted: console.log("Made a transaction confirmation form")
Component.onDestruction: console.log("Destroyed a transaction confirmation form") Component.onDestruction: console.log("Destroyed a transaction confirmation form")
onDisplay: { onDisplay: {
trx = app.createTransaction() trx.clearOperations()
for (var op in arg) for (var op in arg)
trx.appendOperation(arg[op]) trx.appendOperation(arg[op])
} }
Component { Transaction {
id: transactionDelegate id: __trx
}
Rectangle { Rectangle {
width: Scaling.cm(10) id: trxBackground
height: childrenRect.height + Scaling.cm(1) anchors.fill: trxColumn
radius: Scaling.mm(3) anchors.margins: Scaling.mm(-2)
color: "#EEEEEE" layer.enabled: true
border.width: Scaling.mm(.25) layer.effect: DropShadow {
border.color: "black" radius: 8.0
samples: 16
horizontalOffset: Scaling.mm(.5)
verticalOffset: Scaling.mm(.5)
source: trxBackground
color: "#80000000"
transparentBorder: true
}
}
Column {
id: trxColumn
Layout.preferredWidth: Scaling.cm(10)
spacing: Scaling.mm(2)
Column { Repeater {
y: Scaling.cm(.5) Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
x: y model: trx.operations
width: parent.width - Scaling.cm(1) Label {
Repeater { property Asset transferAsset: app.model.getAsset(modelData.amountType)
model: trx.operations property Asset feeAsset: app.model.getAsset(modelData.feeType)
Label { text: {
property Asset transferAsset: app.model.getAsset(modelData.amountType) return qsTr("Transfer %1 %2 from %3 to %4\nFee: %5 %6").arg(transferAsset.formatAmount(modelData.amount))
property Asset feeAsset: app.model.getAsset(modelData.feeType) .arg(transferAsset.symbol)
text: qsTr("Transfer %1 %2 from %3 to %4\nFee: %5 %6").arg(transferAsset.formatAmount(modelData.amount)) .arg(app.model.getAccount(modelData.sender).name)
.arg(transferAsset.symbol) .arg(app.model.getAccount(modelData.receiver).name)
.arg(app.model.getAccount(modelData.sender).name) .arg(feeAsset.formatAmount(modelData.fee))
.arg(app.model.getAccount(modelData.receiver).name) .arg(feeAsset.symbol)
.arg(feeAsset.formatAmount(modelData.fee))
.arg(feeAsset.symbol)
}
} }
} }
} }
} }
Loader { RowLayout {
sourceComponent: trx && Array.prototype.slice.call(trx.operations).length > 0? transactionDelegate : undefined Label {
text: qsTr("Transaction expires in")
}
ComboBox {
id: expirationSelector
model: [qsTr("five seconds"), qsTr("thirty seconds"), qsTr("a minute"), qsTr("an hour"), qsTr("a month"), qsTr("a year")]
function getExpiration() {
switch(expirationSelector.currentIndex) {
case 0: return new Date(app.model.chainTime.getTime() + 1000*5)
case 1: return new Date(app.model.chainTime.getTime() + 1000*30)
case 2: return new Date(app.model.chainTime.getTime() + 1000*60)
case 3: return new Date(app.model.chainTime.getTime() + 1000*60*60)
case 4: return new Date(app.model.chainTime.getTime() + 1000*60*60*24*30)
case 5: return new Date(app.model.chainTime.getTime() + 1000*60*60*24*365)
}
}
}
} }
UnlockingFinishButtons { UnlockingFinishButtons {
app: base.app app: base.app
Layout.fillWidth: true Layout.fillWidth: true
rightButtonText: qsTr("Commit") rightButtonText: qsTr("Commit")
onLeftButtonClicked: { onLeftButtonClicked: canceled({})
canceled({})
trx = null
}
onRightButtonClicked: { onRightButtonClicked: {
if (app.wallet.isLocked) if (app.wallet.isLocked)
app.wallet.unlock(passwordField.text) app.wallet.unlock(passwordField.text)
else { else {
trx.setExpiration(expirationSelector.getExpiration())
app.signTransaction(trx) app.signTransaction(trx)
app.model.broadcast(trx) app.model.broadcast(trx)
completed(trx) completed(trx)