[GUI] Add option to encrypt transfer memos

Also, refactor common unlocking finish/cancel buttons into a reusable
component
This commit is contained in:
Nathan Hourt 2015-07-31 11:16:19 -04:00
parent 8a8130f620
commit 02682e761c
6 changed files with 106 additions and 43 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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)
}
}
}

View file

@ -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:<br/>") + 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])
}
}
}

View file

@ -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 {} }
}
}

View file

@ -6,6 +6,7 @@
<file>TransactionConfirmationForm.qml</file>
<file>FormBox.qml</file>
<file>FormFlipper.qml</file>
<file>UnlockingFinishButtons.qml</file>
<file>Scaling.qml</file>
<file>Identicon.qml</file>
<file>AccountPicker.qml</file>