Browse Source

qml: add export TX and scan of TX

master
Sander van Grieken 3 years ago
parent
commit
26d9c06e0c
  1. 101
      electrum/gui/qml/components/ExportTxDialog.qml
  2. 21
      electrum/gui/qml/components/SendDialog.qml
  3. 24
      electrum/gui/qml/components/TxDetails.qml
  4. 4
      electrum/gui/qml/components/WalletMainView.qml
  5. 2
      electrum/gui/qml/qebitcoin.py
  6. 15
      electrum/gui/qml/qetxdetails.py

101
electrum/gui/qml/components/ExportTxDialog.qml

@ -0,0 +1,101 @@
import QtQuick 2.6
import QtQuick.Layouts 1.0
import QtQuick.Controls 2.14
import QtQuick.Controls.Material 2.0
import "controls"
ElDialog {
id: dialog
property QtObject txdetails
property string text
property string text_qr
// if text_qr is undefined text will be used
property string text_help
title: qsTr('Export Transaction')
parent: Overlay.overlay
modal: true
standardButtons: Dialog.Close
width: parent.width
height: parent.height
Overlay.modal: Rectangle {
color: "#aa000000"
}
Flickable {
anchors.fill: parent
contentHeight: rootLayout.height
clip:true
interactive: height < contentHeight
ColumnLayout {
id: rootLayout
width: parent.width
spacing: constants.paddingMedium
Item {
Layout.fillWidth: true
Layout.preferredHeight: qr.height
Layout.topMargin: constants.paddingSmall
Layout.bottomMargin: constants.paddingSmall
QRImage {
id: qr
qrdata: dialog.text_qr
anchors.centerIn: parent
}
}
Label {
visible: dialog.text_help
text: dialog.text_help
wrapMode: Text.Wrap
Layout.fillWidth: true
}
Rectangle {
height: 1
Layout.preferredWidth: qr.width
Layout.alignment: Qt.AlignHCenter
color: Material.accentColor
}
RowLayout {
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter
FlatButton {
text: qsTr('Copy')
icon.source: '../../icons/copy_bw.png'
onClicked: AppController.textToClipboard(dialog.text)
}
FlatButton {
text: qsTr('Share')
icon.source: '../../icons/share.png'
onClicked: {
AppController.doShare(dialog.text, dialog.title)
}
}
}
}
}
Connections {
target: dialog.enter
function onRunningChanged() {
if (!dialog.enter.running) {
qr.render = true
}
}
}
Component.onCompleted: {
text = dialog.txdetails.serializedTx(false)
text_qr = dialog.txdetails.serializedTx(true)
}
}

21
electrum/gui/qml/components/SendDialog.qml

@ -12,6 +12,8 @@ ElDialog {
property InvoiceParser invoiceParser property InvoiceParser invoiceParser
signal txFound(data: string)
parent: Overlay.overlay parent: Overlay.overlay
modal: true modal: true
standardButtons: Dialog.Close standardButtons: Dialog.Close
@ -28,6 +30,15 @@ ElDialog {
qrscan.restart() qrscan.restart()
} }
function dispatch(data) {
if (bitcoin.isRawTx(data)) {
// app.stack.push(Qt.resolvedUrl('TxDetails.qml'), { rawtx: text })
txFound(data)
} else {
invoiceParser.recipient = data
}
}
ColumnLayout { ColumnLayout {
anchors.fill: parent anchors.fill: parent
spacing: 0 spacing: 0
@ -37,7 +48,7 @@ ElDialog {
Layout.preferredWidth: parent.width Layout.preferredWidth: parent.width
Layout.fillHeight: true Layout.fillHeight: true
onFound: invoiceParser.recipient = scanData onFound: dialog.dispatch(scanData)
} }
FlatButton { FlatButton {
@ -47,7 +58,7 @@ ElDialog {
onClicked: { onClicked: {
var _mid = manualInputDialog.createObject(mainView) var _mid = manualInputDialog.createObject(mainView)
_mid.accepted.connect(function() { _mid.accepted.connect(function() {
invoiceParser.recipient = _mid.recipient dialog.dispatch(_mid.recipient)
}) })
_mid.open() _mid.open()
} }
@ -57,7 +68,7 @@ ElDialog {
Layout.fillWidth: true Layout.fillWidth: true
icon.source: '../../icons/paste.png' icon.source: '../../icons/paste.png'
text: qsTr('Paste from clipboard') text: qsTr('Paste from clipboard')
onClicked: invoiceParser.recipient = AppController.clipboardToText() onClicked: dialog.dispatch(AppController.clipboardToText())
} }
} }
@ -102,4 +113,8 @@ ElDialog {
onClosed: destroy() onClosed: destroy()
} }
} }
Bitcoin {
id: bitcoin
}
} }

24
electrum/gui/qml/components/TxDetails.qml

@ -27,6 +27,16 @@ Pane {
property QtObject menu: Menu { property QtObject menu: Menu {
id: menu id: menu
MenuItem {
icon.color: 'transparent'
action: Action {
text: qsTr('Export')
onTriggered: {
var dialog = exportTxDialog.createObject(root, { txdetails: txdetails })
dialog.open()
}
}
}
MenuItem { MenuItem {
icon.color: 'transparent' icon.color: 'transparent'
action: Action { action: Action {
@ -292,7 +302,7 @@ Pane {
RowLayout { RowLayout {
width: parent.width width: parent.width
Label { Label {
text: root.txid text: txdetails.txid
font.pixelSize: constants.fontSizeLarge font.pixelSize: constants.fontSizeLarge
font.family: FixedFont font.family: FixedFont
Layout.fillWidth: true Layout.fillWidth: true
@ -301,10 +311,10 @@ Pane {
ToolButton { ToolButton {
icon.source: '../../icons/share.png' icon.source: '../../icons/share.png'
icon.color: 'transparent' icon.color: 'transparent'
enabled: root.txid enabled: txdetails.txid
onClicked: { onClicked: {
var dialog = app.genericShareDialog.createObject(root, var dialog = app.genericShareDialog.createObject(root,
{ title: qsTr('Transaction ID'), text: root.txid } { title: qsTr('Transaction ID'), text: txdetails.txid }
) )
dialog.open() dialog.open()
} }
@ -354,7 +364,7 @@ Pane {
Layout.columnSpan: 2 Layout.columnSpan: 2
Button { Button {
text: qsTr('Sign') text: qsTr('Sign')
enabled: !txdetails.isComplete enabled: txdetails.canSign
onClicked: txdetails.sign() onClicked: txdetails.sign()
} }
Button { Button {
@ -401,4 +411,10 @@ Pane {
} }
} }
Component {
id: exportTxDialog
ExportTxDialog {
onClosed: destroy()
}
}
} }

4
electrum/gui/qml/components/WalletMainView.qml

@ -278,6 +278,10 @@ Item {
width: parent.width width: parent.width
height: parent.height height: parent.height
onTxFound: {
app.stack.push(Qt.resolvedUrl('TxDetails.qml'), { rawtx: data })
close()
}
onClosed: destroy() onClosed: destroy()
} }
} }

2
electrum/gui/qml/qebitcoin.py

@ -154,7 +154,7 @@ class QEBitcoin(QObject):
return create_bip21_uri(address, satoshis.satsInt, message, extra_query_params=extra_params) return create_bip21_uri(address, satoshis.satsInt, message, extra_query_params=extra_params)
@pyqtSlot(str, result=bool) @pyqtSlot(str, result=bool)
def verify_raw_tx(self, rawtx): def isRawTx(self, rawtx):
try: try:
tx_from_any(rawtx) tx_from_any(rawtx)
return True return True

15
electrum/gui/qml/qetxdetails.py

@ -35,9 +35,9 @@ class QETxDetails(QObject):
_can_cpfp = False _can_cpfp = False
_can_save_as_local = False _can_save_as_local = False
_can_remove = False _can_remove = False
_can_sign = False
_is_unrelated = False _is_unrelated = False
_is_complete = False _is_complete = False
_is_mined = False _is_mined = False
_mempool_depth = '' _mempool_depth = ''
@ -186,6 +186,10 @@ class QETxDetails(QObject):
def canRemove(self): def canRemove(self):
return self._can_remove return self._can_remove
@pyqtProperty(bool, notify=detailsChanged)
def canSign(self):
return self._can_sign
@pyqtProperty(bool, notify=detailsChanged) @pyqtProperty(bool, notify=detailsChanged)
def isUnrelated(self): def isUnrelated(self):
return self._is_unrelated return self._is_unrelated
@ -249,6 +253,7 @@ class QETxDetails(QObject):
self._can_cpfp = txinfo.can_cpfp self._can_cpfp = txinfo.can_cpfp
self._can_save_as_local = txinfo.can_save_as_local self._can_save_as_local = txinfo.can_save_as_local
self._can_remove = txinfo.can_remove self._can_remove = txinfo.can_remove
self._can_sign = not self._is_complete and self._wallet.wallet.can_sign(self._tx)
self.detailsChanged.emit() self.detailsChanged.emit()
@ -326,3 +331,11 @@ class QETxDetails(QObject):
self._wallet.wallet.adb.remove_transaction(txid) self._wallet.wallet.adb.remove_transaction(txid)
self._wallet.wallet.save_db() self._wallet.wallet.save_db()
@pyqtSlot(result=str)
@pyqtSlot(bool, result=str)
def serializedTx(self, for_qr=False):
if for_qr:
return self._tx.to_qr_data()
else:
return str(self._tx)

Loading…
Cancel
Save