diff --git a/programs/light_client/Operations.cpp b/programs/light_client/Operations.cpp index bca91508..f1109ebb 100644 --- a/programs/light_client/Operations.cpp +++ b/programs/light_client/Operations.cpp @@ -28,12 +28,25 @@ TransferOperation* OperationBuilder::transfer(ObjectId sender, ObjectId receiver QString TransferOperation::memo() const { if (!m_op.memo) return QString::null; + if (memoIsEncrypted()) + return tr("Encrypted Memo"); QString memo = QString::fromStdString(m_op.memo->get_message({}, {})); while (memo.endsWith('\0')) memo.chop(1); return memo; } +bool TransferOperation::memoIsEncrypted() const +{ + if (!m_op.memo) + return false; + if (m_op.memo->message.empty()) + return false; + if (m_op.memo->from == public_key_type() && m_op.memo->to == public_key_type()) + return false; + return true; +} + bool TransferOperation::canEncryptMemo(Wallet* wallet, ChainDataModel* model) const { if (!m_op.memo) return false; diff --git a/programs/light_client/Operations.hpp b/programs/light_client/Operations.hpp index 2a226ed6..e56d5852 100644 --- a/programs/light_client/Operations.hpp +++ b/programs/light_client/Operations.hpp @@ -35,6 +35,7 @@ class TransferOperation : public OperationBase { Q_PROPERTY(qint64 amount READ amount WRITE setAmount NOTIFY amountChanged) Q_PROPERTY(ObjectId amountType READ amountType WRITE setAmountType NOTIFY amountTypeChanged) Q_PROPERTY(QString memo READ memo WRITE setMemo NOTIFY memoChanged) + Q_PROPERTY(bool memoIsEncrypted READ memoIsEncrypted NOTIFY memoChanged) graphene::chain::transfer_operation m_op; @@ -60,6 +61,7 @@ public: /// performed by calling encryptMemo() QString memo() const; + bool memoIsEncrypted()const; Q_INVOKABLE bool canEncryptMemo(Wallet* wallet, ChainDataModel* model) const; Q_INVOKABLE bool canDecryptMemo(Wallet* wallet, ChainDataModel* model) const; Q_INVOKABLE QString decryptedMemo(Wallet* wallet, ChainDataModel* model) const; diff --git a/programs/light_client/qml/TransactionConfirmationForm.qml b/programs/light_client/qml/TransactionConfirmationForm.qml index 2924665c..ff195962 100644 --- a/programs/light_client/qml/TransactionConfirmationForm.qml +++ b/programs/light_client/qml/TransactionConfirmationForm.qml @@ -62,36 +62,19 @@ FormBase { Loader { sourceComponent: trx && Array.prototype.slice.call(trx.operations).length > 0? transactionDelegate : undefined } - RowLayout { + UnlockingFinishButtons { + app: base.app Layout.fillWidth: true - Item { Layout.fillWidth: true } - Button { - text: qsTr("Cancel") - onClicked: { - canceled({}) - trx = null - } + onLeftButtonClicked: { + canceled({}) + trx = null } - TextField { - id: passwordField - Layout.preferredWidth: app.wallet.isLocked? Scaling.cm(4) : 0 - echoMode: TextInput.Password - placeholderText: qsTr("Wallet password") - visible: width > 0 - onAccepted: finishButton.clicked() - - Behavior on Layout.preferredWidth { NumberAnimation { duration: 200; easing.type: Easing.InOutQuad } } - } - Button { - id: finishButton - text: app.wallet.isLocked? qsTr("Unlock") : qsTr("Finish") - onClicked: { - if (app.wallet.isLocked) - app.wallet.unlock(passwordField.text) - else { - app.wallet.sign(trx) - completed(trx) - } + onRightButtonClicked: { + if (app.wallet.isLocked) + app.wallet.unlock(passwordField.text) + else { + app.wallet.sign(trx) + completed(trx) } } } diff --git a/programs/light_client/qml/TransferForm.qml b/programs/light_client/qml/TransferForm.qml index 310a2765..f4c99dd9 100644 --- a/programs/light_client/qml/TransferForm.qml +++ b/programs/light_client/qml/TransferForm.qml @@ -1,6 +1,5 @@ import QtQuick 2.5 import QtQuick.Controls 1.4 -import QtQuick.Dialogs 1.2 import QtQuick.Layouts 1.2 import Graphene.Client 0.1 @@ -19,7 +18,7 @@ FormBase { property alias receiverAccount: recipientPicker.account function operation() { - if (!transferButton.enabled) return app.operationBuilder.transfer(0,0,0,0, memoField.text, 0) + if (!finishLine.rightButtonEnabled) return app.operationBuilder.transfer(0,0,0,0, memoField.text, 0) return app.operationBuilder.transfer(senderPicker.account.id, recipientPicker.account.id, amountField.value * amountField.precisionAdjustment, @@ -56,10 +55,18 @@ FormBase { placeholderText: qsTr("Recipient") layoutDirection: Qt.RightToLeft } - TextField { - id: memoField + RowLayout { Layout.fillWidth: true - placeholderText: qsTr("Memo") + TextField { + id: memoField + Layout.fillWidth: true + placeholderText: qsTr("Memo") + } + CheckBox { + id: encryptMemoField + text: qsTr("Encrypt Memo") + checked: true + } } RowLayout { Layout.fillWidth: true @@ -97,18 +104,25 @@ FormBase { return qsTr("Fee:
") + amountField.maxBalance.type.formatAmount(operation().fee) + " CORE" } } - Item { Layout.fillWidth: true } - Button { - text: qsTr("Cancel") - onClicked: canceled({}) - } - Button { - id: transferButton - text: !senderAccount || + } + UnlockingFinishButtons { + id: finishLine + app: base.app + rightButtonText: { + return !senderAccount || !senderAccount.isLoaded || senderPicker.accountControlLevel >= 1? qsTr("Transfer") : qsTr("Propose") - enabled: senderPicker.account && recipientPicker.account && senderPicker.account !== recipientPicker.account && amountField.value - onClicked: completed([operation()]) + } + rightButtonEnabled: senderPicker.account && recipientPicker.account && senderPicker.account !== recipientPicker.account && amountField.value + requiresUnlocking: encryptMemoField.checked + Layout.fillWidth: true + + onLeftButtonClicked: canceled({}) + onRightButtonClicked: { + var op = operation() + if (encryptMemoField.checked) + op.encryptMemo(app.wallet, app.model) + completed([op]) } } } diff --git a/programs/light_client/qml/UnlockingFinishButtons.qml b/programs/light_client/qml/UnlockingFinishButtons.qml new file mode 100644 index 00000000..b566ac4a --- /dev/null +++ b/programs/light_client/qml/UnlockingFinishButtons.qml @@ -0,0 +1,50 @@ +import QtQuick 2.5 +import QtQuick.Controls 1.4 +import QtQuick.Layouts 1.2 + +import "." + +import Graphene.Client 0.1 + +RowLayout { + property string leftButtonText: qsTr("Cancel") + property string unlockButtonText: qsTr("Unlock") + property string rightButtonText: qsTr("Finish") + property bool leftButtonEnabled: true + property bool rightButtonEnabled: true + property bool requiresUnlocking: true + property GrapheneApplication app + + signal leftButtonClicked + signal rightButtonClicked + + Item { Layout.fillWidth: true } + Button { + text: leftButtonText + onClicked: leftButtonClicked() + } + TextField { + id: passwordField + property bool shown: requiresUnlocking && app.wallet.isLocked + property real desiredWidth: shown? Scaling.cm(4) : 0 + Layout.preferredWidth: desiredWidth + echoMode: TextInput.Password + placeholderText: qsTr("Wallet password") + visible: desiredWidth > 0 + onAccepted: rightButton.clicked() + + Behavior on desiredWidth { NumberAnimation { duration: 200; easing.type: Easing.InOutQuad } } + } + Button { + id: rightButton + text: passwordField.shown? unlockButtonText : rightButtonText + enabled: rightButtonEnabled + onClicked: { + if (passwordField.visible) + return app.wallet.unlock(passwordField.text) + + rightButtonClicked() + } + Behavior on implicitWidth { NumberAnimation {} } + } +} diff --git a/programs/light_client/qml/qml.qrc b/programs/light_client/qml/qml.qrc index ae4c86f6..9d8847b5 100644 --- a/programs/light_client/qml/qml.qrc +++ b/programs/light_client/qml/qml.qrc @@ -6,6 +6,7 @@ TransactionConfirmationForm.qml FormBox.qml FormFlipper.qml + UnlockingFinishButtons.qml Scaling.qml Identicon.qml AccountPicker.qml