aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorluigi1111 <luigi1111w@gmail.com>2019-01-09 17:43:31 -0600
committerluigi1111 <luigi1111w@gmail.com>2019-01-09 17:43:31 -0600
commit5a682b37ecef5407ff44ca5d32b1610750702bbb (patch)
tree5d3c10979773aedca3d67c781dfc74a790231d56
parent97de72b27d56e7869c5e3c13ed3a15db033d0043 (diff)
parent85cd428dcb46763e626c1c9bae1c27b44d617d4f (diff)
downloadmonzero-gui-5a682b37ecef5407ff44ca5d32b1610750702bbb.tar.gz
monzero-gui-5a682b37ecef5407ff44ca5d32b1610750702bbb.tar.xz
monzero-gui-5a682b37ecef5407ff44ca5d32b1610750702bbb.zip
Merge pull request #1793
85cd428 Merchant page (xmrdsc)
-rw-r--r--LeftPanel.qml28
-rw-r--r--MiddlePanel.qml24
-rw-r--r--components/Style.qml1
-rw-r--r--components/TitleBar.qml58
-rw-r--r--images/merchant/arrow_right.pngbin0 -> 18203 bytes
-rw-r--r--images/merchant/bg.pngbin0 -> 18041 bytes
-rw-r--r--images/merchant/input_box.pngbin0 -> 15459 bytes
-rw-r--r--js/TxUtils.js11
-rw-r--r--js/Utils.js36
-rw-r--r--main.qml23
-rw-r--r--monero-wallet-gui.pro5
-rw-r--r--pages/AddressBook.qml2
-rw-r--r--pages/Keys.qml2
-rw-r--r--pages/Mining.qml2
-rw-r--r--pages/Receive.qml486
-rw-r--r--pages/SharedRingDB.qml2
-rw-r--r--pages/Sign.qml7
-rw-r--r--pages/Transfer.qml4
-rw-r--r--pages/TxKey.qml2
-rw-r--r--pages/merchant/Merchant.qml699
-rw-r--r--pages/merchant/MerchantCheckbox.qml63
-rw-r--r--pages/merchant/MerchantTrackingList.qml231
-rw-r--r--pages/settings/SettingsInfo.qml2
-rw-r--r--pages/settings/SettingsLayout.qml2
-rw-r--r--pages/settings/SettingsLog.qml2
-rw-r--r--pages/settings/SettingsNode.qml2
-rw-r--r--pages/settings/SettingsWallet.qml2
-rw-r--r--qml.qrc6
28 files changed, 1250 insertions, 452 deletions
diff --git a/LeftPanel.qml b/LeftPanel.qml
index d7cd0ee8..16b1a8f9 100644
--- a/LeftPanel.qml
+++ b/LeftPanel.qml
@@ -61,6 +61,7 @@ Rectangle {
signal miningClicked()
signal signClicked()
signal keysClicked()
+ signal merchantClicked()
function selectItem(pos) {
menuColumn.previousButton.checked = false
@@ -68,6 +69,7 @@ Rectangle {
else if(pos === "History") menuColumn.previousButton = historyButton
else if(pos === "Transfer") menuColumn.previousButton = transferButton
else if(pos === "Receive") menuColumn.previousButton = receiveButton
+ else if(pos === "Merchant") menuColumn.previousButton = merchantButton
else if(pos === "AddressBook") menuColumn.previousButton = addressBookButton
else if(pos === "Mining") menuColumn.previousButton = miningButton
else if(pos === "TxKey") menuColumn.previousButton = txkeyButton
@@ -446,6 +448,32 @@ Rectangle {
height: 1
}
+ // ------------- Merchant tab ---------------
+
+ MoneroComponents.MenuButton {
+ id: merchantButton
+ anchors.left: parent.left
+ anchors.right: parent.right
+ text: qsTr("Merchant") + translationManager.emptyString
+ symbol: qsTr("U") + translationManager.emptyString
+ dotColor: "#FF4F41"
+ under: receiveButton
+ onClicked: {
+ parent.previousButton.checked = false
+ parent.previousButton = merchantButton
+ panel.merchantClicked()
+ }
+ }
+
+ Rectangle {
+ visible: merchantButton.present
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.leftMargin: 16
+ color: "#313131"
+ height: 1
+ }
+
// ------------- History tab ---------------
MoneroComponents.MenuButton {
diff --git a/MiddlePanel.qml b/MiddlePanel.qml
index d47e3685..69d14d0f 100644
--- a/MiddlePanel.qml
+++ b/MiddlePanel.qml
@@ -38,6 +38,8 @@ import moneroComponents.Wallet 1.0
import "components" as MoneroComponents
import "./pages"
import "./pages/settings"
+import "./pages/merchant"
+import "components" as MoneroComponents
Rectangle {
id: root
@@ -56,6 +58,7 @@ Rectangle {
property Transfer transferView: Transfer { }
property Receive receiveView: Receive { }
+ property Merchant merchantView: Merchant { }
property TxKey txkeyView: TxKey { }
property SharedRingDB sharedringdbView: SharedRingDB { }
property History historyView: History { }
@@ -72,11 +75,16 @@ Rectangle {
signal getProofClicked(string txid, string address, string message);
signal checkProofClicked(string txid, string address, string message, string signature);
+ Rectangle {
+ // grey background on merchantView
+ visible: currentView === merchantView
+ color: MoneroComponents.Style.moneroGrey
+ anchors.fill: parent
+ }
+
Image {
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: parent.top
- anchors.bottom: parent.bottom
+ anchors.fill: parent
+ visible: currentView !== merchantView
source: "../images/middlePanelBg.jpg"
}
@@ -124,6 +132,10 @@ Rectangle {
PropertyChanges { target: root; currentView: receiveView }
PropertyChanges { target: mainFlickable; contentHeight: receiveView.receiveHeight + 100 }
}, State {
+ name: "Merchant"
+ PropertyChanges { target: root; currentView: merchantView }
+ PropertyChanges { target: mainFlickable; contentHeight: merchantView.merchantHeight + 100 }
+ }, State {
name: "TxKey"
PropertyChanges { target: root; currentView: txkeyView }
PropertyChanges { target: mainFlickable; contentHeight: 1200 * scaleRatio }
@@ -172,8 +184,8 @@ Rectangle {
ColumnLayout {
anchors.fill: parent
- anchors.margins: 18
- anchors.topMargin: appWindow.persistentSettings.customDecorations ? 50 : 0
+ anchors.margins: currentView !== merchantView ? 20 * scaleRatio : 0
+ anchors.topMargin: appWindow.persistentSettings.customDecorations ? 50 * scaleRatio : 0
spacing: 0
Flickable {
diff --git a/components/Style.qml b/components/Style.qml
index 9c6fded4..b5926dab 100644
--- a/components/Style.qml
+++ b/components/Style.qml
@@ -12,6 +12,7 @@ QtObject {
property string orange: "#FF6C3C"
property string white: "#FFFFFF"
property string green: "#2EB358"
+ property string moneroGrey: "#4C4C4C"
property string defaultFontColor: "white"
property string dimmedFontColor: "#BBBBBB"
diff --git a/components/TitleBar.qml b/components/TitleBar.qml
index a759adce..6c9bfb1e 100644
--- a/components/TitleBar.qml
+++ b/components/TitleBar.qml
@@ -47,7 +47,7 @@ Rectangle {
property string title
property int mouseX: 0
property bool containsMouse: false
- property alias basicButtonVisible: goToBasicVersionButton.visible
+ property bool basicButtonVisible: false
property bool customDecorations: persistentSettings.customDecorations
property bool showWhatIsButton: true
property bool showMinimizeButton: false
@@ -56,6 +56,9 @@ Rectangle {
property bool showMoneroLogo: false
property bool small: false
property alias titleBarGradientImageOpacity: titleBarGradientImage.opacity
+ property bool orange: false
+ property string buttonHoverColor: "#262626"
+ property string buttonHoverColorOrange: "#44FFFFFF"
signal closeClicked
signal maximizeClicked
@@ -70,11 +73,19 @@ Rectangle {
Image {
id: titleBarGradientImage
+ visible: !titleBar.orange
anchors.fill: parent
height: titleBar.height
width: titleBar.width
source: "../images/titlebarGradient.jpg"
}
+
+ Rectangle {
+ visible: titleBar.orange
+ width: parent.width
+ height: parent.height
+ color: "#ff6600"
+ }
}
Item {
@@ -82,11 +93,11 @@ Rectangle {
width: 125
height: parent.height
anchors.centerIn: parent
- visible: customDecorations && showMoneroLogo
+ visible: customDecorations
z: parent.z + 1
Image {
- visible: !isMobile
+ visible: !isMobile && showMoneroLogo && !titleBar.orange
anchors.left: parent.left
anchors.top: parent.top
anchors.topMargin: 11
@@ -94,6 +105,16 @@ Rectangle {
height: 28
source: "../images/titlebarLogo.png"
}
+
+ Image {
+ visible: !isMobile && showMoneroLogo && titleBar.orange
+ anchors.left: parent.left
+ anchors.top: parent.top
+ anchors.topMargin: 11
+ width: 132
+ height: 22
+ source: "../images/moneroLogo_white.png"
+ }
}
Label {
@@ -115,7 +136,7 @@ Rectangle {
color: "transparent"
height: titleBar.height
width: height
- visible: isMobile
+ visible: !titleBar.orange && titleBar.basicButtonVisible
z: parent.z + 2
Image {
@@ -130,7 +151,7 @@ Rectangle {
hoverEnabled: true
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
- onEntered: goToBasicVersionButton.color = "#262626";
+ onEntered: { goToBasicVersionButton.color = titleBar.orange ? titleBar.buttonHoverColorOrange : titleBar.buttonHoverColor }
onExited: goToBasicVersionButton.color = "transparent";
onClicked: {
releaseFocus()
@@ -166,7 +187,13 @@ Rectangle {
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
- onEntered: minimizeButton.color = "#262626";
+ onEntered: {
+ if(titleBar.orange){
+ minimizeButton.color = titleBar.buttonHoverColorOrange;
+ } else {
+ minimizeButton.color = titleBar.buttonHoverColor;
+ }
+ }
onExited: minimizeButton.color = "transparent";
onClicked: minimizeClicked();
}
@@ -193,7 +220,13 @@ Rectangle {
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
- onEntered: maximizeButton.color = "#262626";
+ onEntered: {
+ if(titleBar.orange){
+ maximizeButton.color = titleBar.buttonHoverColorOrange;
+ } else {
+ maximizeButton.color = titleBar.buttonHoverColor;
+ }
+ }
onExited: maximizeButton.color = "transparent";
onClicked: maximizeClicked();
}
@@ -219,7 +252,13 @@ Rectangle {
onClicked: closeClicked();
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
- onEntered: closeButton.color = "#262626";
+ onEntered: {
+ if(titleBar.orange){
+ closeButton.color = titleBar.buttonHoverColorOrange;
+ } else {
+ closeButton.color = titleBar.buttonHoverColor;
+ }
+ }
onExited: closeButton.color = "transparent";
}
}
@@ -227,6 +266,7 @@ Rectangle {
// window borders
Rectangle {
+ visible: !titleBar.orange
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.left: parent.left
@@ -236,10 +276,10 @@ Rectangle {
}
Rectangle {
+ visible: titleBar.small && !titleBar.orange
anchors.top: parent.top
anchors.right: parent.right
anchors.left: parent.left
- visible: titleBar.small
height: 1
color: "#2F2F2F"
z: parent.z + 1
diff --git a/images/merchant/arrow_right.png b/images/merchant/arrow_right.png
new file mode 100644
index 00000000..6d0d6aca
--- /dev/null
+++ b/images/merchant/arrow_right.png
Binary files differ
diff --git a/images/merchant/bg.png b/images/merchant/bg.png
new file mode 100644
index 00000000..b6687a40
--- /dev/null
+++ b/images/merchant/bg.png
Binary files differ
diff --git a/images/merchant/input_box.png b/images/merchant/input_box.png
new file mode 100644
index 00000000..66a49e55
--- /dev/null
+++ b/images/merchant/input_box.png
Binary files differ
diff --git a/js/TxUtils.js b/js/TxUtils.js
index a6cca114..c78436d7 100644
--- a/js/TxUtils.js
+++ b/js/TxUtils.js
@@ -64,3 +64,14 @@ function isValidOpenAliasAddress(address) {
// we can get an awful lot of valid domains, including non ASCII chars... accept anything
return true
}
+
+function makeQRCodeString(addr, amount) {
+ var XMR_URI_SCHEME = "monero:"
+ var XMR_AMOUNT = "tx_amount"
+ var qrCodeString =""
+ qrCodeString += (XMR_URI_SCHEME + addr)
+ if (amount !== undefined && amount !== ""){
+ qrCodeString += ("?" + XMR_AMOUNT + "=" + amount)
+ }
+ return qrCodeString
+}
diff --git a/js/Utils.js b/js/Utils.js
index dad1f143..8ba7fa85 100644
--- a/js/Utils.js
+++ b/js/Utils.js
@@ -48,4 +48,38 @@ function showSeedPage() {
passwordDialog.open();
if(isMobile) hideMenu();
updateBalance();
-} \ No newline at end of file
+}
+
+function ago(epoch) {
+ // Returns '<delta> [seconds|minutes|hours|days] ago' string given an epoch
+
+ var now = new Date().getTime() / 1000;
+ var delta = now - epoch;
+
+ if(delta < 60) {
+ return delta + " " + qsTr("seconds ago")
+ } else if (delta >= 60 && delta <= 3600) {
+ if(delta >= 60 && delta < 120){
+ return 1 + " " + qsTr("minute ago")
+ } else {
+ return parseInt(Math.floor(delta / 60)) + " " + qsTr("minutes ago")
+ }
+ } else if (delta >= 3600 && delta <= 86400) {
+ if(delta >= 3600 && delta < 7200) {
+ return 1 + " " + qsTr("hour ago")
+ } else {
+ return parseInt(Math.floor(delta / 60 / 60)) + " " + qsTr("hours ago")
+ }
+ } else if (delta >= 86400){
+ if(delta >= 86400 && delta < 172800) {
+ return 1 + " " + qsTr("day ago")
+ } else {
+ var _delta = parseInt(Math.floor(delta / 24 / 60 / 60));
+ if(_delta === 1) {
+ return 1 + " " + qsTr("day ago")
+ } else {
+ return _delta + " " + qsTr("days ago")
+ }
+ }
+ }
+}
diff --git a/main.qml b/main.qml
index d23cb5e5..4cde64e3 100644
--- a/main.qml
+++ b/main.qml
@@ -86,6 +86,11 @@ ApplicationWindow {
// true if wallet ever synchronized
property bool walletInitialized : false
+ // Current selected address / subaddress (Receive page)
+ property var current_address
+ property var current_address_label: "Primary"
+ property int current_subaddress_table_index: 0
+
function altKeyReleased() { ctrlPressed = false; }
function showPageRequest(page) {
@@ -1371,6 +1376,15 @@ ApplicationWindow {
updateBalance();
}
+ onMerchantClicked: {
+ middlePanel.state = "Merchant";
+ middlePanel.flickable.contentY = 0;
+ if(isMobile) {
+ hideMenu();
+ }
+ updateBalance();
+ }
+
onTxkeyClicked: {
middlePanel.state = "TxKey";
middlePanel.flickable.contentY = 0;
@@ -1825,6 +1839,15 @@ ApplicationWindow {
onTriggered: checkUpdates()
}
+ function titlebarToggleOrange(flag){
+ // toggle titlebar orange style
+ if(flag !== undefined){
+ titleBar.orange = flag;
+ } else {
+ titleBar.orange = !titleBar.orange;
+ }
+ }
+
function releaseFocus() {
// Workaround to release focus from textfield when scrolling (https://bugreports.qt.io/browse/QTBUG-34867)
if(isAndroid) {
diff --git a/monero-wallet-gui.pro b/monero-wallet-gui.pro
index 7213544a..2662c5c9 100644
--- a/monero-wallet-gui.pro
+++ b/monero-wallet-gui.pro
@@ -97,6 +97,7 @@ SOURCES = *.qml \
components/*.qml \
pages/*.qml \
pages/settings/*.qml \
+ pages/merchant/*.qml \
wizard/*.qml \
wizard/*js
}
@@ -458,7 +459,9 @@ OTHER_FILES += \
DISTFILES += \
notes.txt \
monero/src/wallet/CMakeLists.txt \
- components/MobileHeader.qml
+ components/MobileHeader.qml \
+ pages/merchant/Merchant.qml \
+ pages/merchant/MerchantCheckbox.qml
# windows application icon
diff --git a/pages/AddressBook.qml b/pages/AddressBook.qml
index 596210cb..36de37d5 100644
--- a/pages/AddressBook.qml
+++ b/pages/AddressBook.qml
@@ -39,7 +39,7 @@ Rectangle {
ColumnLayout {
id: columnLayout
- anchors.margins: (isMobile)? 17 : 40
+ anchors.margins: (isMobile)? 17 * scaleRatio : 20 * scaleRatio
anchors.left: parent.left
anchors.top: parent.top
anchors.right: parent.right
diff --git a/pages/Keys.qml b/pages/Keys.qml
index 0694c83b..2e2758c5 100644
--- a/pages/Keys.qml
+++ b/pages/Keys.qml
@@ -53,7 +53,7 @@ Rectangle {
anchors.top: parent.top
anchors.right: parent.right
- anchors.margins: (isMobile)? 17 : 20
+ anchors.margins: (isMobile)? 17 * scaleRatio : 20 * scaleRatio
anchors.topMargin: 40 * scaleRatio
spacing: 30 * scaleRatio
diff --git a/pages/Mining.qml b/pages/Mining.qml
index e4bcbd76..92afaf6a 100644
--- a/pages/Mining.qml
+++ b/pages/Mining.qml
@@ -39,10 +39,10 @@ Rectangle {
ColumnLayout {
id: mainLayout
+ anchors.margins: (isMobile)? 17 * scaleRatio : 20 * scaleRatio
anchors.left: parent.left
anchors.top: parent.top
anchors.right: parent.right
- anchors.margins: 40 * scaleRatio
spacing: 20 * scaleRatio
Layout.fillWidth: true
diff --git a/pages/Receive.qml b/pages/Receive.qml
index a65e3da0..2c840ab4 100644
--- a/pages/Receive.qml
+++ b/pages/Receive.qml
@@ -32,7 +32,7 @@ import QtQuick.Controls.Styles 1.4
import QtQuick.Layouts 1.1
import QtQuick.Dialogs 1.2
-import "../components"
+import "../components" as MoneroComponents
import moneroComponents.Clipboard 1.0
import moneroComponents.Wallet 1.0
import moneroComponents.WalletManager 1.0
@@ -46,115 +46,7 @@ Rectangle {
id: pageReceive
color: "transparent"
property var model
- property var current_address
- property int current_subaddress_table_index: 0
property alias receiveHeight: mainLayout.height
- property alias addressText : pageReceive.current_address
-
- function makeQRCodeString() {
- var XMR_URI_SCHEME = "monero:"
- var XMR_AMOUNT = "tx_amount"
- var qrCodeString =""
- var amount = amountToReceiveLine.text
- qrCodeString += (XMR_URI_SCHEME + current_address)
- if (amount !== ""){
- qrCodeString += ("?" + XMR_AMOUNT + "=" + amount)
- }
- return qrCodeString
- }
-
- function update() {
- const max_tracking = 3;
-
- if (!appWindow.currentWallet || !trackingEnabled.checked) {
- trackingLineText.text = "";
- trackingModel.clear();
- return
- }
- if (appWindow.currentWallet.connected() == Wallet.ConnectionStatus_Disconnected) {
- trackingLineText.text = qsTr("WARNING: no connection to daemon");
- trackingModel.clear();
- return
- }
-
- var model = appWindow.currentWallet.historyModel
- var count = model.rowCount()
- var totalAmount = 0
- var nTransactions = 0
- var blockchainHeight = null
- var txs = []
-
- for (var i = 0; i < count && txs.length < max_tracking; ++i) {
- var idx = model.index(i, 0)
- var isout = model.data(idx, TransactionHistoryModel.TransactionIsOutRole);
- var subaddrAccount = model.data(idx, TransactionHistoryModel.TransactionSubaddrAccountRole);
- var subaddrIndex = model.data(idx, TransactionHistoryModel.TransactionSubaddrIndexRole);
- if (!isout && subaddrAccount == appWindow.currentWallet.currentSubaddressAccount && subaddrIndex == current_subaddress_table_index) {
- var amount = model.data(idx, TransactionHistoryModel.TransactionAtomicAmountRole);
- totalAmount = walletManager.addi(totalAmount, amount)
- nTransactions += 1
-
- var txid = model.data(idx, TransactionHistoryModel.TransactionHashRole);
- var blockHeight = model.data(idx, TransactionHistoryModel.TransactionBlockHeightRole);
-
- var in_txpool = false;
- var confirmations = 0;
- var displayAmount = 0;
-
- if (blockHeight == 0) {
- in_txpool = true;
- } else {
- if (blockchainHeight == null)
- blockchainHeight = appWindow.currentWallet.blockChainHeight()
- confirmations = blockchainHeight - blockHeight - 1
- displayAmount = model.data(idx, TransactionHistoryModel.TransactionDisplayAmountRole);
- }
-
- txs.push({
- "amount": displayAmount,
- "confirmations": confirmations,
- "blockheight": blockHeight,
- "in_txpool": in_txpool,
- "txid": txid
- })
- }
- }
-
- // Update tracking status label
- if (nTransactions == 0) {
- trackingLineText.text = qsTr("No transaction found yet...") + translationManager.emptyString
- return
- }
- else if(nTransactions === 1){
- trackingLineText.text = qsTr("Transaction found") + ":" + translationManager.emptyString;
- } else {
- trackingLineText.text = qsTr("%1 transactions found").arg(nTransactions) + ":" + translationManager.emptyString
- }
-
- toReceiveSatisfiedLine.text = "";
- var expectedAmount = walletManager.amountFromString(amountToReceiveLine.text)
- if (expectedAmount && expectedAmount != amount) {
- var displayTotalAmount = walletManager.displayAmount(totalAmount)
- if (amount > expectedAmount) toReceiveSatisfiedLine.text += qsTr("With more Monero");
- else if (amount < expectedAmount) toReceiveSatisfiedLine.text = qsTr("With not enough Monero")
- toReceiveSatisfiedLine.text += ": " + "<br>" +
- qsTr("Expected") + ": " + amountToReceiveLine.text + "<br>" +
- qsTr("Total received") + ": " + displayTotalAmount + translationManager.emptyString;
- }
-
- trackingModel.clear();
- txs.forEach(function(tx){
- trackingModel.append({
- "amount": tx.amount,
- "confirmations": tx.confirmations,
- "blockheight": tx.blockHeight,
- "in_txpool": tx.in_txpool,
- "txid": tx.txid
- });
- });
-
- //setTrackingLineText(text + "<br>" + list.join("<br>"))
- }
function renameSubaddressLabel(_index){
inputDialog.labelText = qsTr("Set the label of the selected address:") + translationManager.emptyString;
@@ -171,7 +63,7 @@ Rectangle {
/* main layout */
ColumnLayout {
id: mainLayout
- anchors.margins: (isMobile)? 17 : 40
+ anchors.margins: (isMobile)? 17 * scaleRatio : 20 * scaleRatio
anchors.topMargin: 40 * scaleRatio
anchors.left: parent.left
@@ -188,24 +80,10 @@ Rectangle {
id: addressRow
spacing: 0
- LabelSubheader {
+ MoneroComponents.LabelSubheader {
Layout.fillWidth: true
textFormat: Text.RichText
- text: "<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style>" +
- qsTr("Addresses") +
- "<font size='2'> </font><a href='#'>" +
- qsTr("Help") + "</a>" +
- translationManager.emptyString
- onLinkActivated: {
- receivePageDialog.title = qsTr("Tracking payments") + translationManager.emptyString;
- receivePageDialog.text = qsTr(
- "<p>This QR code includes the address you selected above and" +
- "the amount you entered below. Share it with others (right-click->Save) " +
- "so they can more easily send you exact amounts.</p>"
- )
- receivePageDialog.icon = StandardIcon.Information
- receivePageDialog.open()
- }
+ text: qsTr("Addresses")
}
ColumnLayout {
@@ -245,9 +123,9 @@ Rectangle {
anchors.rightMargin: 80
color: "transparent"
- Label {
+ MoneroComponents.Label {
id: idLabel
- color: index === current_subaddress_table_index ? "white" : "#757575"
+ color: index === appWindow.current_subaddress_table_index ? "white" : "#757575"
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: 6
@@ -256,7 +134,7 @@ Rectangle {
text: "#" + index
}
- Label {
+ MoneroComponents.Label {
id: nameLabel
color: "#a5a5a5"
anchors.verticalCenter: parent.verticalCenter
@@ -267,7 +145,7 @@ Rectangle {
text: label
}
- Label {
+ MoneroComponents.Label {
color: "white"
anchors.verticalCenter: parent.verticalCenter
anchors.left: nameLabel.right
@@ -299,7 +177,7 @@ Rectangle {
}
}
- IconButton {
+ MoneroComponents.IconButton {
id: renameButton
imageSource: "../images/editIcon.png"
anchors.verticalCenter: parent.verticalCenter
@@ -313,7 +191,7 @@ Rectangle {
}
}
- IconButton {
+ MoneroComponents.IconButton {
id: copyButton
imageSource: "../images/copyToClipboard.png"
anchors.verticalCenter: parent.verticalCenter
@@ -329,20 +207,17 @@ Rectangle {
}
onCurrentItemChanged: {
// reset global vars
- current_subaddress_table_index = subaddressListView.currentIndex;
- current_address = appWindow.currentWallet.address(
+ appWindow.current_subaddress_table_index = subaddressListView.currentIndex;
+ appWindow.current_address = appWindow.currentWallet.address(
appWindow.currentWallet.currentSubaddressAccount,
subaddressListView.currentIndex
);
-
- // reset tracking table
- trackingModel.clear();
}
}
}
// 'fake' row for 'create new address'
- ColumnLayout{
+ ColumnLayout {
id: createAddressRow
Layout.fillWidth: true
spacing: 0
@@ -353,13 +228,13 @@ Rectangle {
height: 1
}
- Rectangle{
+ Rectangle {
id: createAddressRect
Layout.preferredHeight: subaddressListRow.subaddressListItemHeight
color: "transparent"
Layout.fillWidth: true
- Label {
+ MoneroComponents.Label {
color: "#757575"
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
@@ -396,7 +271,8 @@ Rectangle {
}
RowLayout {
- CheckBox2 {
+ Layout.topMargin: 22 * scaleRatio
+ MoneroComponents.CheckBox2 {
id: showAdvancedCheckbox
checked: persistentSettings.receiveShowAdvanced
onClicked: {
@@ -405,282 +281,72 @@ Rectangle {
text: qsTr("Advanced options") + translationManager.emptyString
}
}
-
- GridLayout {
- id: advancedRow
- columns: (isMobile)? 1 : 2
- Layout.fillWidth: true
- columnSpacing: 32 * scaleRatio
+
+ RowLayout {
+ Layout.topMargin: 6 * scaleRatio
visible: persistentSettings.receiveShowAdvanced
+ Layout.fillWidth: true
- ColumnLayout {
- Layout.alignment: Qt.AlignTop
+ MoneroComponents.LineEditMulti {
+ id: paymentUrl
Layout.fillWidth: true
- spacing: 20 * scaleRatio
-
- LabelSubheader {
- Layout.fillWidth: true
- textFormat: Text.RichText
- text: "<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style>" +
- qsTr("QR Code") +
- "<font size='2'> </font><a href='#'>" +
- qsTr("Help") + "</a>" +
- translationManager.emptyString
- onLinkActivated: {
- receivePageDialog.title = qsTr("QR Code") + translationManager.emptyString;
- receivePageDialog.text = qsTr(
- "<p>This QR code includes the address you selected above and " +
- "the amount you entered below. Share it with others (right-click->Save) " +
- "so they can more easily send you exact amounts.</p>"
- )
- receivePageDialog.icon = StandardIcon.Information
- receivePageDialog.open()
- }
- }
-
- ColumnLayout {
- id: amountRow
-
- Layout.fillWidth: true
- Layout.minimumWidth: 200
- spacing: parent.spacing
-
- LineEdit {
- id: amountToReceiveLine
- Layout.fillWidth: true
- labelText: qsTr("Amount") + translationManager.emptyString
- placeholderText: qsTr("Amount to receive") + translationManager.emptyString
- fontBold: true
- inlineIcon: true
- onTextChanged: {
- if(amountToReceiveLine.text.indexOf('.') === 0){
- amountToReceiveLine.text = '0' + amountToReceiveLine.text;
- }
- }
- validator: RegExpValidator {
- regExp: /^(\d{1,8})?([\.]\d{1,12})?$/
- }
- }
-
- Rectangle {
- color: "white"
-
- Layout.fillWidth: true
- Layout.maximumWidth: mainLayout.qrCodeSize
- Layout.preferredHeight: width
- radius: 4
-
- Image {
- id: qrCode
- anchors.fill: parent
- anchors.margins: 1
- smooth: false
- fillMode: Image.PreserveAspectFit
- source: "image://qrcode/" + makeQRCodeString()
- MouseArea {
- anchors.fill: parent
- acceptedButtons: Qt.RightButton
- onClicked: {
- if (mouse.button == Qt.RightButton)
- qrMenu.open()
- }
- onPressAndHold: qrFileDialog.open()
- }
- }
-
- Menu {
- id: qrMenu
- title: "QrCode"
- y: parent.height / 2
-
- MenuItem {
- text: qsTr("Save As") + translationManager.emptyString;
- onTriggered: qrFileDialog.open()
- }
- }
- }
-
- LineEditMulti {
- id: paymentUrl
- Layout.fillWidth: true
- labelText: qsTr("Payment URL") + translationManager.emptyString
- text: makeQRCodeString()
- readOnly: true
- copyButton: true
- wrapMode: Text.WrapAnywhere
- }
- }
+ labelText: qsTr("Payment URL") + translationManager.emptyString
+ text: TxUtils.makeQRCodeString(appWindow.current_address)
+ readOnly: true
+ copyButton: true
+ wrapMode: Text.WrapAnywhere
}
+ }
- ColumnLayout {
- id: trackingRow
- Layout.alignment: Qt.AlignTop
- Layout.fillWidth: true
- spacing: 0 * scaleRatio
-
- LabelSubheader {
- Layout.fillWidth: true
- textFormat: Text.RichText
- text: "<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style>" +
- qsTr("Tracking") +
- "<font size='2'> </font><a href='#'>" +
- qsTr("Help") + "</a>" +
- translationManager.emptyString
- onLinkActivated: {
- receivePageDialog.title = qsTr("Tracking payments") + translationManager.emptyString;
- receivePageDialog.text = qsTr(
- "<p><font size='+2'>This is a simple sales tracker:</font></p>" +
- "<p>Let your customer scan that QR code to make a payment (if that customer has software which " +
- "supports QR code scanning).</p>" +
- "<p>This page will automatically scan the blockchain and the tx pool " +
- "for incoming transactions using this QR code. If you input an amount, it will also check " +
- "that incoming transactions total up to that amount.</p>" +
- "<p>It's up to you whether to accept unconfirmed transactions or not. It is likely they'll be " +
- "confirmed in short order, but there is still a possibility they might not, so for larger " +
- "values you may want to wait for one or more confirmation(s).</p>"
- )
- receivePageDialog.icon = StandardIcon.Information
- receivePageDialog.open()
- }
- }
-
- ListModel {
- id: trackingModel
- }
-
- RowLayout{
- Layout.topMargin: 14
- Layout.bottomMargin: 10
- visible: trackingTableRow.visible
+ GridLayout{
+ visible: persistentSettings.receiveShowAdvanced
+ Layout.topMargin: 10 * scaleRatio
+ columns: 2
+ columnSpacing: 30 * scaleRatio
- Label {
- id: trackingLineText
- color: "white"
- fontFamily: Style.fontLight.name
- fontSize: 16 * scaleRatio
- text: ""
- }
- }
+ RowLayout {
+ property int qrSize: 220 * scaleRatio
+ Layout.fillWidth: true
- ColumnLayout {
- id: trackingTableRow
- visible: trackingListView.count >= 1
- Layout.fillWidth: true
- Layout.minimumWidth: 240
- Layout.preferredHeight: 46 * trackingListView.count
+ Rectangle {
+ id: qrContainer
+ radius: 4 * scaleRatio
+ color: "white"
+ Layout.preferredWidth: parent.qrSize
+ Layout.preferredHeight: parent.qrSize
- ListView {
- id: trackingListView
- Layout.fillWidth: true
+ Image {
+ id: qrCode
anchors.fill: parent
- clip: true
- boundsBehavior: ListView.StopAtBounds
- model: trackingModel
- delegate: Item {
- id: trackingTableItem
- height: 46
- width: parent.width
- Layout.fillWidth: true
-
- Rectangle{
- anchors.right: parent.right
- anchors.left: parent.left
- anchors.top: parent.top
- height: 1
- color: "#404040"
- visible: index !== 0
- }
-
- Image {
- id: arrowImage
- source: "../images/upArrow-green.png"
- height: 18 * scaleRatio
- width: 12 * scaleRatio
- anchors.verticalCenter: parent.verticalCenter
- anchors.left: parent.left
- anchors.leftMargin: 8
- }
+ anchors.margins: 1 * scaleRatio
- Label {
- id: trackingConfirmationLine
- color: "white"
- anchors.top: parent.top
- anchors.topMargin: 6
- anchors.left: arrowImage.right
- anchors.leftMargin: 10
- fontSize: 14 * scaleRatio
- text: {
- if(in_txpool){
- return "Awaiting in txpool"
- } else {
- if(confirmations > 1){
- if(confirmations > 100){
- return "100+ " + qsTr("confirmations") + translationManager.emptyString;
- } else {
- return confirmations + " " + qsTr("confirmations") + translationManager.emptyString;
- }
- } else {
- return "1 " + qsTr("confirmation") + translationManager.emptyString;
- }
- }
- }
- }
+ smooth: false
+ fillMode: Image.PreserveAspectFit
+ source: "image://qrcode/" + TxUtils.makeQRCodeString(appWindow.current_address)
- Label {
- id: trackingAmountLine
- color: "#2eb358"
- anchors.top: trackingConfirmationLine.bottom
- anchors.left: arrowImage.right
- anchors.leftMargin: 10
- fontSize: 14 * scaleRatio
- fontBold: true
- text: amount
- }
-
- IconButton {
- id: clipboardButton
- imageSource: "../images/copyToClipboard.png"
-
- onClicked: {
- console.log("tx_id copied to clipboard");
- clipboard.setText(txid);
- appWindow.showStatusMessage(qsTr("Transaction ID copied to clipboard"),3);
+ MouseArea {
+ anchors.fill: parent
+ acceptedButtons: Qt.RightButton
+ onClicked: {
+ if (mouse.button == Qt.RightButton){
+ qrMenu.x = this.mouseX;
+ qrMenu.y = this.mouseY;
+ qrMenu.open()
}
-
- anchors.right: parent.right
- anchors.top: undefined
- anchors.verticalCenter: parent.verticalCenter
}
+ onPressAndHold: qrFileDialog.open()
}
}
- }
-
- RowLayout {
- visible: trackingTableRow.visible && x.text !== "" && amountToReceiveLine.text !== ""
- Layout.topMargin: 14 * scaleRatio
- Layout.fillWidth: true
- Layout.preferredHeight: 40 * scaleRatio
- Label {
- id: toReceiveSatisfiedLine
- color: "white"
- fontFamily: Style.fontLight.name
- fontSize: 14 * scaleRatio
- textFormat: Text.RichText
- text: ""
- height: 40 * scaleRatio
- }
- }
+ Menu {
+ id: qrMenu
+ title: "QrCode"
- RowLayout {
- Layout.fillWidth: true
- Layout.minimumWidth: 200
- Layout.topMargin: trackingTableRow.visible ? 20 * scaleRatio : 32 * scaleRatio
-
- CheckBox {
- id: trackingEnabled
- text: qsTr("Enable") + translationManager.emptyString
+ MenuItem {
+ text: qsTr("Save As") + translationManager.emptyString;
+ onTriggered: qrFileDialog.open()
+ }
}
}
}
@@ -693,12 +359,12 @@ Rectangle {
FileDialog {
id: qrFileDialog
- title: "Please choose a name"
+ title: qsTr("Please choose a name")
folder: shortcuts.pictures
selectExisting: false
nameFilters: ["Image (*.png)"]
onAccepted: {
- if(!walletManager.saveQrCode(makeQRCodeString(), walletManager.urlToLocalPath(fileUrl))) {
+ if(!walletManager.saveQrCode(TxUtils.makeQRCodeString(appWindow.current_address), walletManager.urlToLocalPath(fileUrl))) {
console.log("Failed to save QrCode to file " + walletManager.urlToLocalPath(fileUrl) )
receivePageDialog.title = qsTr("Save QrCode") + translationManager.emptyString;
receivePageDialog.text = qsTr("Failed to save QrCode to ") + walletManager.urlToLocalPath(fileUrl) + translationManager.emptyString;
@@ -709,27 +375,14 @@ Rectangle {
}
}
- Timer {
- id: timer
- interval: 2000; running: false; repeat: true
- onTriggered: update()
- }
-
function onPageCompleted() {
console.log("Receive page loaded");
subaddressListView.model = appWindow.currentWallet.subaddressModel;
if (appWindow.currentWallet) {
- current_address = appWindow.currentWallet.address(appWindow.currentWallet.currentSubaddressAccount, 0)
+ appWindow.current_address = appWindow.currentWallet.address(appWindow.currentWallet.currentSubaddressAccount, 0)
appWindow.currentWallet.subaddress.refresh(appWindow.currentWallet.currentSubaddressAccount)
- current_subaddress_table_index = 0;
- subaddressListView.currentIndex = 0;
}
-
- update()
- timer.running = true
-
- trackingEnabled.checked = false
}
function clearFields() {
@@ -737,8 +390,5 @@ Rectangle {
}
function onPageClosed() {
- timer.running = false
- trackingEnabled.checked = false
- trackingModel.clear()
}
}
diff --git a/pages/SharedRingDB.qml b/pages/SharedRingDB.qml
index 82d4fd96..b28b3ac6 100644
--- a/pages/SharedRingDB.qml
+++ b/pages/SharedRingDB.qml
@@ -79,7 +79,7 @@ Rectangle {
/* main layout */
ColumnLayout {
id: mainLayout
- anchors.margins: (isMobile)? 17 : 20
+ anchors.margins: (isMobile)? 17 * scaleRatio : 20 * scaleRatio
anchors.topMargin: 40 * scaleRatio
anchors.left: parent.left
diff --git a/pages/Sign.qml b/pages/Sign.qml
index c6df06a6..04e88996 100644
--- a/pages/Sign.qml
+++ b/pages/Sign.qml
@@ -86,12 +86,9 @@ Rectangle {
// sign / verify
ColumnLayout {
- id: root
- spacing: 20 * scaleRatio
- anchors.margins: (isMobile ? 17 : 20) * scaleRatio
- anchors.topMargin: 40 * scaleRatio
- anchors.left: parent.left
anchors.top: parent.top
+ anchors.margins: (isMobile)? 17 * scaleRatio : 20 * scaleRatio
+ anchors.left: parent.left
anchors.right: parent.right
Rectangle {
diff --git a/pages/Transfer.qml b/pages/Transfer.qml
index 0b480414..f2939caa 100644
--- a/pages/Transfer.qml
+++ b/pages/Transfer.qml
@@ -103,7 +103,7 @@ Rectangle {
ColumnLayout {
id: pageRoot
- anchors.margins: (isMobile)? 17 : 20
+ anchors.margins: (isMobile)? 17 * scaleRatio : 20 * scaleRatio
anchors.topMargin: 40 * scaleRatio
anchors.left: parent.left
@@ -421,7 +421,7 @@ Rectangle {
anchors.top: pageRoot.bottom
anchors.left: parent.left
anchors.right: parent.right
- anchors.margins: (isMobile)? 17 : 20
+ anchors.margins: (isMobile)? 17 * scaleRatio : 20 * scaleRatio
anchors.topMargin: 32 * scaleRatio
spacing: 26 * scaleRatio
enabled: !viewOnly || pageRoot.enabled
diff --git a/pages/TxKey.qml b/pages/TxKey.qml
index 22174f3e..04da3c65 100644
--- a/pages/TxKey.qml
+++ b/pages/TxKey.qml
@@ -45,7 +45,7 @@ Rectangle {
/* main layout */
ColumnLayout {
id: mainLayout
- anchors.margins: 40 * scaleRatio
+ anchors.margins: (isMobile)? 17 * scaleRatio : 20 * scaleRatio
anchors.left: parent.left
anchors.top: parent.top
anchors.right: parent.right
diff --git a/pages/merchant/Merchant.qml b/pages/merchant/Merchant.qml
new file mode 100644
index 00000000..5f816782
--- /dev/null
+++ b/pages/merchant/Merchant.qml
@@ -0,0 +1,699 @@
+import QtQuick 2.7
+import QtQuick.Layouts 1.1
+import QtQuick.Controls 2.0
+import QtGraphicalEffects 1.0
+import QtQuick.Controls.Styles 1.4
+import QtQuick.Dialogs 1.2
+
+import moneroComponents.Clipboard 1.0
+import moneroComponents.Wallet 1.0
+import moneroComponents.WalletManager 1.0
+import moneroComponents.TransactionHistory 1.0
+import moneroComponents.TransactionHistoryModel 1.0
+import moneroComponents.Subaddress 1.0
+import moneroComponents.SubaddressModel 1.0
+
+import "../../js/Windows.js" as Windows
+import "../../js/TxUtils.js" as TxUtils
+import "../../js/Utils.js" as Utils
+import "../../components" as MoneroComponents
+import "../../pages"
+import "."
+
+Item {
+ id: root
+ anchors.margins: 0
+
+ property int minWidth: 900 * scaleRatio
+ property int qrCodeSize: 220 * scaleRatio
+ property bool enableTracking: false
+ property string trackingError: "" // setting this will show a message @ tracking table
+ property alias merchantHeight: mainLayout.height
+ property string addressLabel: ""
+ property var hiddenAmounts: []
+
+ function onPageCompleted() {
+ appWindow.titlebarToggleOrange();
+ appWindow.hideMenu();
+
+ // prepare tracking
+ trackingCheckbox.checked = root.enableTracking
+ root.update();
+ timer.running = true;
+
+ // set currently selected account indication
+ var _addressLabel = appWindow.currentWallet.getSubaddressLabel(
+ appWindow.currentWallet.currentSubaddressAccount,
+ appWindow.current_subaddress_table_index);
+ if(_addressLabel === ""){
+ root.addressLabel = "#" + appWindow.current_subaddress_table_index;
+ } else {
+ root.addressLabel = _addressLabel;
+ }
+ }
+
+ function onPageClosed() {
+ appWindow.titlebarToggleOrange();
+
+ // reset component objects
+ timer.running = false
+ root.enableTracking = false
+ trackingModel.clear()
+
+ appWindow.showMenu();
+ }
+
+ Image {
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.right: parent.right
+ height: 300 * scaleRatio
+ source: "../../images/merchant/bg.png"
+ smooth: false
+ }
+
+ ColumnLayout {
+ id: mainLayout
+ visible: parent.width >= root.minWidth
+ spacing: 0
+
+ // emulates max-width + center for container
+ property int maxWidth: 1200 * scaleRatio
+ property int defaultMargin: 50 * scaleRatio
+ property int horizontalMargin: {
+ if(appWindow.width >= maxWidth){
+ return ((appWindow.width - maxWidth) / 2) + defaultMargin;
+ } else {
+ return defaultMargin;
+ }
+ }
+
+ anchors.leftMargin: horizontalMargin
+ anchors.rightMargin: horizontalMargin
+ anchors.margins: defaultMargin
+ anchors.left: parent.left
+ anchors.top: parent.top
+ anchors.right: parent.right
+
+ Item {
+ height: 220 * scaleRatio
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+ Rectangle {
+ id: tracker
+ anchors.left: parent.left
+ anchors.top: parent.top
+ height: 220 * scaleRatio
+ width: (parent.width - qrImg.width) - 50 * scaleRatio
+ radius: 5
+
+ ColumnLayout {
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.right: parent.right
+ spacing: 0
+
+ RowLayout {
+ spacing: 0
+ height: 56 * scaleRatio
+
+ RowLayout {
+ Layout.alignment: Qt.AlignLeft
+ Layout.preferredWidth: 260 * scaleRatio
+ Layout.preferredHeight: parent.height
+ Layout.fillHeight: true
+ spacing: 8 * scaleRatio
+
+ Item {
+ Layout.preferredWidth: 10 * scaleRatio
+ }
+
+ Text {
+ font.pixelSize: 16 * scaleRatio
+ font.bold: true
+ color: "#767676"
+ text: qsTr("Sales")
+ }
+
+ Item {
+ Layout.fillWidth: true
+ }
+ }
+
+ Item {
+ Layout.fillWidth: true
+ }
+ }
+
+ Rectangle {
+ Layout.fillWidth: true
+ Layout.preferredHeight: 1 * scaleRatio
+ color: "#d9d9d9"
+ }
+
+ MerchantTrackingList {
+ Layout.fillWidth: true
+ Layout.preferredHeight: 400 * scaleRatio
+ model: trackingModel
+ message: {
+ if(!root.enableTracking){
+ return qsTr(
+ "<style>p{font-size:14px;}</style>" +
+ "<p>This page will automatically scan the blockchain and the tx pool " +
+ "for incoming transactions using the QR code.</p>" +
+ "<p>It's up to you whether to accept unconfirmed transactions or not. It is likely they'll be " +
+ "confirmed in short order, but there is still a possibility they might not, so for larger " +
+ "values you may want to wait for one or more confirmation(s).</p>"
+ );
+ } else if(root.trackingError !== ""){
+ return root.trackingError;
+ } else if(trackingModel.count < 1){
+ return qsTr("Currently monitoring incoming transactions, none found yet.");
+ } else {
+ return ""
+ }
+ }
+ onHideAmountToggled: {
+ if(root.hiddenAmounts.indexOf(txid) < 0){
+ root.hiddenAmounts.push(txid);
+ } else {
+ root.hiddenAmounts = root.hiddenAmounts.filter(function(_txid) { return _txid !== txid });
+ }
+ }
+ }
+ }
+ }
+
+ DropShadow {
+ anchors.fill: source
+ cached: true
+ horizontalOffset: 3
+ verticalOffset: 3
+ radius: 8.0
+ samples: 16
+ color: "#20000000"
+ smooth: true
+ source: tracker
+ }
+
+ Rectangle {
+ id: qrImg
+ color: "white"
+
+ anchors.right: parent.right
+ anchors.top: parent.top
+
+ height: root.qrCodeSize
+ width: root.qrCodeSize
+
+ Layout.maximumWidth: root.qrCodeSize
+ Layout.preferredHeight: width
+ radius: 5
+
+ Image {
+ id: qrCode
+ anchors.fill: parent
+ anchors.margins: 1 * scaleRatio
+
+ smooth: false
+ fillMode: Image.PreserveAspectFit
+ source: "image://qrcode/" + TxUtils.makeQRCodeString(appWindow.current_address, amountToReceive.text)
+
+ MouseArea {
+ anchors.fill: parent
+ acceptedButtons: Qt.RightButton
+ onClicked: {
+ if (mouse.button == Qt.RightButton){
+ qrMenu.x = this.mouseX;
+ qrMenu.y = this.mouseY;
+ qrMenu.open()
+ }
+ }
+ onPressAndHold: qrFileDialog.open()
+ }
+ }
+
+ Menu {
+ id: qrMenu
+ title: "QrCode"
+
+ MenuItem {
+ text: qsTr("Save As") + translationManager.emptyString;
+ onTriggered: qrFileDialog.open()
+ }
+ }
+ }
+
+ DropShadow {
+ anchors.fill: source
+ cached: true
+ horizontalOffset: 3
+ verticalOffset: 3
+ radius: 8.0
+ samples: 16
+ color: "#30000000"
+ smooth: true
+ source: qrImg
+ }
+ }
+
+ Item {
+ Layout.preferredHeight: 40 * scaleRatio
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+ Item {
+ width: (parent.width - qrImg.width) - (50 * scaleRatio)
+ height: 32 * scaleRatio
+
+ Text {
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.horizontalCenter: parent.horizontalCenter
+ font.pixelSize: 12 * scaleRatio
+ font.bold: false
+ color: "white"
+ text: "<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 12px;}</style>Currently selected address: " + addressLabel + " <a href='#'>(Change)</a>"
+ textFormat: Text.RichText
+
+ MouseArea {
+ anchors.fill: parent
+ hoverEnabled: true
+ cursorShape: Qt.PointingHandCursor
+ onClicked: appWindow.showPageRequest("Receive")
+ }
+ }
+ }
+
+ Item {
+ anchors.right: parent.right
+ anchors.top: parent.top
+ width: 220 * scaleRatio
+ height: 32 * scaleRatio
+
+ Text {
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.horizontalCenter: parent.horizontalCenter
+ font.pixelSize: 12 * scaleRatio
+ font.bold: false
+ color: "white"
+ text: qsTr("(right-click, save as)")
+ }
+ }
+ }
+
+ Item {
+ Layout.preferredHeight: 120 * scaleRatio
+ Layout.topMargin: 20 * scaleRatio
+ Layout.fillWidth: true
+
+ Rectangle {
+ id: payment_url_container
+ anchors.left: parent.left
+ anchors.top: parent.top
+ implicitHeight: 120 * scaleRatio
+ width: (parent.width - qrImg.width) - (50 * scaleRatio)
+ radius: 5
+
+ ColumnLayout {
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.right: parent.right
+ spacing: 0
+
+ RowLayout {
+ spacing: 0
+ height: 56 * scaleRatio
+
+ RowLayout {
+ Layout.alignment: Qt.AlignLeft
+ Layout.preferredWidth: 260 * scaleRatio
+ Layout.preferredHeight: parent.height
+ Layout.fillHeight: true
+ spacing: 8
+
+ Item {
+ Layout.preferredWidth: 10 * scaleRatio
+ }
+
+ Text {
+ font.pixelSize: 14 * scaleRatio
+ font.bold: true
+ color: "#767676"
+ text: qsTr("Payment URL")
+ }
+
+ Item {
+ Layout.fillWidth: true
+ }
+ }
+
+ // @TODO: PaymentURL explanation
+// Rectangle {
+// // help box
+// Layout.alignment: Qt.AlignLeft
+// Layout.preferredWidth: 40 * scaleRatio
+// Layout.fillHeight: true
+// color: "transparent"
+
+// Text {
+// anchors.verticalCenter: parent.verticalCenter
+// anchors.right: parent.right
+// anchors.rightMargin: 20 * scaleRatio
+// font.pixelSize: 16 * scaleRatio
+// font.bold: true
+// color: "#767676"
+// text:"?"
+// }
+
+// MouseArea {
+// anchors.fill: parent
+// cursorShape: Qt.PointingHandCursor
+// onClicked: {
+// merchantPageDialog.title = qsTr("Payment URL") + translationManager.emptyString;
+// merchantPageDialog.text = qsTr("payment url explanation")
+// merchantPageDialog.icon = StandardIcon.Information
+// merchantPageDialog.open()
+// }
+// }
+// }
+
+ Item {
+ Layout.fillWidth: true
+ }
+ }
+
+ Rectangle {
+ Layout.fillWidth: true
+ Layout.preferredHeight: 1
+
+ color: "#d9d9d9"
+ }
+
+ Text {
+ property string _color: "#767676"
+ Layout.fillWidth: true
+ Layout.margins: 20 * scaleRatio
+ Layout.topMargin: 10 * scaleRatio
+
+ wrapMode: Text.WrapAnywhere
+ elide: Text.ElideRight
+
+ font.pixelSize: 12 * scaleRatio
+ font.bold: true
+ color: _color
+ text: TxUtils.makeQRCodeString(appWindow.current_address, amountToReceive.text)
+
+ MouseArea {
+ anchors.fill: parent
+ hoverEnabled: true
+ cursorShape: Qt.PointingHandCursor
+ onEntered: {
+ parent.color = MoneroComponents.Style.orange
+ }
+ onExited: {
+ parent.color = parent._color
+ }
+ onClicked: {
+ console.log("Copied to clipboard");
+ clipboard.setText(parent.text);
+ appWindow.showStatusMessage(qsTr("Copied to clipboard"), 3);
+ }
+ }
+ }
+ }
+ }
+
+ DropShadow {
+ anchors.fill: source
+ cached: true
+ horizontalOffset: 3
+ verticalOffset: 3
+ radius: 8.0
+ samples: 16
+ color: "#20000000"
+ smooth: true
+ source: payment_url_container
+ }
+
+ Item {
+ anchors.right: parent.right
+ anchors.top: parent.top
+ width: 220 * scaleRatio
+ height: 32 * scaleRatio
+
+ ColumnLayout {
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+ Text {
+ font.pixelSize: 14 * scaleRatio
+ font.bold: false
+ color: "white"
+ text: qsTr("Amount to receive") + " (XMR)"
+ }
+
+ Image {
+ height: 28 * scaleRatio
+ width: 220 * scaleRatio
+ source: "../../images/merchant/input_box.png"
+
+ TextField {
+ id: amountToReceive
+ topPadding: 0
+ leftPadding: 10 * scaleRatio
+
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.top: parent.top
+ anchors.topMargin: 3 * scaleRatio
+ font.pixelSize: 16 * scaleRatio
+ font.bold: true
+ horizontalAlignment: TextInput.AlignLeft
+ verticalAlignment: TextInput.AlignVCenter
+ selectByMouse: true
+ color: "#424242"
+ selectionColor: "#3f3fe3"
+ selectedTextColor: "white"
+
+ background: Rectangle {
+ color: "transparent"
+ }
+ onTextChanged: {
+ if (amountToReceive.text.indexOf('.') === 0) {
+ amountToReceive.text = '0' + amountToReceive.text;
+ }
+ }
+ validator: RegExpValidator {
+ regExp: /^(\d{1,8})?([\.]\d{1,12})?$/
+ }
+ }
+ }
+
+ Item {
+ height: 2 * scaleRatio
+ width: 220 * scaleRatio
+ }
+
+ Text {
+ // @TODO: When we have XMR/USD rate avi. in the future.
+ visible: false
+ font.pixelSize: 14 * scaleRatio
+ font.bold: false
+ color: "white"
+ text: qsTr("Amount to receive") + " (USD)"
+ opacity: 0.2
+ }
+
+ Image {
+ visible: false
+ height: 28 * scaleRatio
+ width: 220 * scaleRatio
+ source: "../../images/merchant/input_box.png"
+ opacity: 0.2
+ }
+ }
+ }
+ }
+
+ Item {
+ Layout.topMargin: 32 * scaleRatio
+ Layout.preferredHeight: 40 * scaleRatio
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+ ColumnLayout {
+ spacing: 16 * scaleRatio
+
+ MerchantCheckbox {
+ id: trackingCheckbox
+ checked: root.enableTracking
+ text: qsTr("Enable sales tracker")
+
+ onChanged: {
+ root.enableTracking = this.checked;
+ }
+ }
+
+ Text {
+ id: content
+ font.pixelSize: 14 * scaleRatio
+ font.bold: false
+ color: "white"
+ text: qsTr("Leave this page")
+
+ MouseArea {
+ anchors.fill: parent
+ hoverEnabled: true
+ cursorShape: Qt.PointingHandCursor
+ onClicked: appWindow.showPageRequest("Receive")
+ }
+ }
+ }
+ }
+ }
+
+ Rectangle {
+ // Shows when the window is too small
+ visible: parent.width < root.minWidth
+ anchors.top: parent.top
+ anchors.topMargin: 100 * scaleRatio;
+ anchors.horizontalCenter: parent.horizontalCenter
+ height: 120 * scaleRatio
+ width: 400 * scaleRatio
+ radius: 5
+
+ Text {
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.verticalCenter: parent.verticalCenter
+ font.pixelSize: 14 * scaleRatio
+ font.bold: true
+ color: MoneroComponents.Style.moneroGrey
+ text: qsTr("The merchant page requires a larger window")
+ }
+ }
+
+ function update() {
+ const max_tracking = 3;
+
+ if (!appWindow.currentWallet || !root.enableTracking) {
+ root.trackingError = "";
+ trackingModel.clear();
+ return
+ }
+
+ if (appWindow.currentWallet.connected() == Wallet.ConnectionStatus_Disconnected) {
+ root.trackingError = qsTr("WARNING: no connection to daemon");
+ trackingModel.clear();
+ return
+ }
+
+ var model = appWindow.currentWallet.historyModel
+ var count = model.rowCount()
+ var totalAmount = 0
+ var nTransactions = 0
+ var blockchainHeight = null
+ var txs = []
+
+ // Currently selected subaddress as per Receive page
+ var current_subaddress_table_index = appWindow.current_subaddress_table_index;
+
+ for (var i = 0; i < count && txs.length < max_tracking; ++i) {
+ var idx = model.index(i, 0)
+ var isout = model.data(idx, TransactionHistoryModel.TransactionIsOutRole);
+ var timeDate = model.data(idx, TransactionHistoryModel.TransactionDateRole);
+ var timeHour = model.data(idx, TransactionHistoryModel.TransactionTimeRole);
+ var timeEpoch = new Date(timeDate + "T" + timeHour + "Z") .getTime() / 1000;
+ var subaddrAccount = model.data(idx, TransactionHistoryModel.TransactionSubaddrAccountRole);
+ var subaddrIndex = model.data(idx, TransactionHistoryModel.TransactionSubaddrIndexRole);
+
+ if (!isout && subaddrAccount == appWindow.currentWallet.currentSubaddressAccount && subaddrIndex == current_subaddress_table_index) {
+ var amount = model.data(idx, TransactionHistoryModel.TransactionAtomicAmountRole);
+ totalAmount = walletManager.addi(totalAmount, amount)
+ nTransactions += 1
+
+ var txid = model.data(idx, TransactionHistoryModel.TransactionHashRole);
+ var blockHeight = model.data(idx, TransactionHistoryModel.TransactionBlockHeightRole);
+
+ var in_txpool = false;
+ var confirmations = 0;
+ var displayAmount = 0;
+
+ if (blockHeight == 0) {
+ in_txpool = true;
+ } else {
+ if (blockchainHeight == null)
+ blockchainHeight = appWindow.currentWallet.blockChainHeight()
+ confirmations = blockchainHeight - blockHeight - 1
+ displayAmount = model.data(idx, TransactionHistoryModel.TransactionDisplayAmountRole);
+ }
+
+ txs.push({
+ "amount": displayAmount,
+ "confirmations": confirmations,
+ "blockheight": blockHeight,
+ "in_txpool": in_txpool,
+ "txid": txid,
+ "time_epoch": timeEpoch,
+ "time_date": timeDate + " " + timeHour,
+ "hide_amount": root.hiddenAmounts.indexOf(txid) >= 0
+ })
+ }
+ }
+
+ // Update tracking status label
+ if (nTransactions == 0) {
+ root.trackingError = qsTr("Currently monitoring incoming transactions, none found yet.") + translationManager.emptyString
+ return
+ }
+
+ trackingModel.clear();
+ txs.forEach(function(tx){
+ trackingModel.append({
+ "amount": tx.amount,
+ "blockheight": tx.blockheight,
+ "confirmations": tx.confirmations,
+ "blockheight": tx.blockHeight,
+ "in_txpool": tx.in_txpool,
+ "txid": tx.txid,
+ "time_epoch": tx.time_epoch,
+ "time_date": tx.time_date,
+ "hide_amount": tx.hide_amount
+ });
+ });
+ }
+
+ ListModel {
+ id: trackingModel
+ }
+
+ Timer {
+ id: timer
+ interval: 3000; running: false; repeat: true
+ onTriggered: update()
+ }
+
+ MessageDialog {
+ id: merchantPageDialog
+ standardButtons: StandardButton.Ok
+ }
+
+ FileDialog {
+ id: qrFileDialog
+ title: "Please choose a name"
+ folder: shortcuts.pictures
+ selectExisting: false
+ nameFilters: ["Image (*.png)"]
+ onAccepted: {
+ if(!walletManager.saveQrCode(TxUtils.makeQRCodeString(appWindow.current_address, amountToReceive.text), walletManager.urlToLocalPath(fileUrl))) {
+ console.log("Failed to save QrCode to file " + walletManager.urlToLocalPath(fileUrl) )
+ receivePageDialog.title = qsTr("Save QrCode") + translationManager.emptyString;
+ receivePageDialog.text = qsTr("Failed to save QrCode to ") + walletManager.urlToLocalPath(fileUrl) + translationManager.emptyString;
+ receivePageDialog.icon = StandardIcon.Error
+ receivePageDialog.open()
+ }
+ }
+ }
+
+ Clipboard { id: clipboard }
+}
diff --git a/pages/merchant/MerchantCheckbox.qml b/pages/merchant/MerchantCheckbox.qml
new file mode 100644
index 00000000..49ffbc7f
--- /dev/null
+++ b/pages/merchant/MerchantCheckbox.qml
@@ -0,0 +1,63 @@
+import QtQuick 2.7
+import QtQuick.Layouts 1.1
+import QtGraphicalEffects 1.0
+
+
+RowLayout {
+ id: root
+ spacing: 10 * scaleRatio
+ property bool checked: false;
+ property alias text: content.text
+ signal changed;
+
+ Rectangle {
+ id: checkbox
+ anchors.left: parent.left
+ anchors.top: parent.top
+ implicitHeight: 22 * scaleRatio
+ width: 22 * scaleRatio
+ radius: 5
+
+ Image {
+ id: imageChecked
+ visible: root.checked
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.horizontalCenter: parent.horizontalCenter
+ source: "../../images/checkedBlackIcon.png"
+ opacity: 0.6
+ width: 12 * scaleRatio
+ height: 8 * scaleRatio
+ }
+ }
+
+ Text {
+ id: content
+ font.pixelSize: 14 * scaleRatio
+ font.bold: false
+ color: "white"
+ text: ""
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ hoverEnabled: true
+
+ cursorShape: Qt.PointingHandCursor
+ onClicked: {
+ root.checked = !root.checked;
+ changed();
+ }
+ }
+
+ DropShadow {
+ anchors.fill: source
+ cached: true
+ horizontalOffset: 3
+ verticalOffset: 3
+ radius: 8.0
+ samples: 16
+ color: "#20000000"
+ smooth: true
+ source: checkbox
+ }
+}
diff --git a/pages/merchant/MerchantTrackingList.qml b/pages/merchant/MerchantTrackingList.qml
new file mode 100644
index 00000000..33a756fc
--- /dev/null
+++ b/pages/merchant/MerchantTrackingList.qml
@@ -0,0 +1,231 @@
+import QtQuick 2.0
+import QtQuick.Controls 2.0
+import QtQuick.Controls.Styles 1.4
+import QtQuick.Layouts 1.1
+import QtQuick.Dialogs 1.2
+
+import "../../js/Utils.js" as Utils
+import "../../components" as MoneroComponents
+
+ListView {
+ id: trackingListView
+
+ // items will not be drawn when a message is set
+ property string message: ""
+
+ boundsBehavior: ListView.StopAtBounds
+ Layout.fillWidth: true
+ clip: true
+
+ signal hideAmountToggled(string txid)
+
+ function viewTx(txid){
+ // @TODO: implement blockexplorer-like page. Redirect to history for now
+ appWindow.showPageRequest("History");
+ }
+
+ TextEdit {
+ // message box
+ visible: parent.message !== ""
+ anchors.fill: parent
+ anchors.margins: 20 * scaleRatio
+ anchors.topMargin: 10 * scaleRatio
+ wrapMode: Text.Wrap
+
+ font.pixelSize: 14 * scaleRatio
+ font.bold: false
+ color: "#767676"
+ textFormat: Text.RichText
+ text: parent.message
+ selectionColor: MoneroComponents.Style.dimmedFontColor
+ selectByMouse: true
+ readOnly: true
+ onFocusChanged: {if(focus === false) deselect() }
+ }
+
+ delegate: Item {
+ id: trackingTableItem
+ visible: trackingListView.message === ""
+ height: 53 * scaleRatio
+ width: parent.width
+ Layout.fillWidth: true
+
+ RowLayout {
+ id: container
+ height: parent.height
+ width: parent.width
+ spacing: 0
+
+ Item {
+ Layout.preferredHeight: parent.height
+ Layout.preferredWidth: 20 * scaleRatio
+ }
+
+ ColumnLayout {
+ spacing: 0
+ Layout.preferredHeight: 40 * scaleRatio
+ Layout.preferredWidth: 240 * scaleRatio
+
+ Item {
+ Layout.preferredWidth: parent.width
+ Layout.preferredHeight: 18 * scaleRatio
+
+ TextEdit {
+ id: dateString
+ anchors.verticalCenter: parent.verticalCenter
+ font.pixelSize: 12 * scaleRatio
+ font.bold: false
+ color: "#707070"
+ text: time_date + " (" + Utils.ago(time_epoch) + ") "
+ selectionColor: MoneroComponents.Style.dimmedFontColor
+ selectByMouse: true
+ readOnly: true
+ onFocusChanged: {if(focus === false) deselect() }
+ }
+
+ Rectangle {
+ anchors.left: dateString.right
+ anchors.leftMargin: 2
+ width: hideAmount.width + 2
+ height: 20
+ color: 'transparent'
+
+ TextEdit {
+ id: hideAmount
+ anchors.top: parent.top
+ anchors.topMargin: 1 * scaleRatio
+ anchors.left: parent.left
+ anchors.verticalCenter: parent.verticalCenter
+ readOnly: true
+ font.pixelSize: 12 * scaleRatio
+ font.bold: false
+ color: "#707070"
+ text: hide_amount ? "(" + qsTr("show") + ")" : "(" + qsTr("hide") + ")"
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ hoverEnabled: true
+ cursorShape: Qt.PointingHandCursor
+ onClicked: {
+ trackingListView.hideAmountToggled(txid);
+ hide_amount = !hide_amount;
+ }
+ }
+ }
+ }
+
+ Item {
+ Layout.preferredWidth: parent.width
+ Layout.preferredHeight: 18 * scaleRatio
+
+ TextEdit {
+ id: amountText
+ anchors.verticalCenter: parent.verticalCenter
+ font.pixelSize: 14 * scaleRatio
+ font.bold: true
+ color: hide_amount ? "#707070" : "#009F1E"
+ text: hide_amount ? '-' : '+' + amount
+ selectionColor: MoneroComponents.Style.dimmedFontColor
+ selectByMouse: true
+ readOnly: true
+ onFocusChanged: {if(focus === false) deselect() }
+ }
+ }
+ }
+
+ Item {
+ Layout.fillWidth: true
+ }
+
+ RowLayout {
+ spacing: 0
+ Layout.preferredHeight: parent.height
+ Layout.preferredWidth: 240 * scaleRatio
+
+ Item {
+ Layout.fillWidth: true
+ Layout.preferredHeight: parent.height
+ }
+
+ Item {
+ Layout.preferredWidth: 150 * scaleRatio
+ Layout.preferredHeight: parent.height
+
+ TextEdit {
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.verticalCenter: parent.verticalCenter
+ font.pixelSize: 12 * scaleRatio
+ font.bold: false
+ color: "#a8a8a8"
+ text: {
+ if(in_txpool){
+ return qsTr("Awaiting in txpool") + translationManager.emptyString;
+ } else {
+ if(confirmations > 1){
+ if(confirmations > 100){
+ return "100+ " + qsTr("confirmations") + translationManager.emptyString;
+ } else {
+ return confirmations + " " + qsTr("confirmations") + translationManager.emptyString;
+ }
+ } else {
+ return "1 " + qsTr("confirmation") + translationManager.emptyString;
+ }
+ }
+ }
+ selectionColor: MoneroComponents.Style.dimmedFontColor
+ selectByMouse: true
+ readOnly: true
+ onFocusChanged: {if(focus === false) deselect() }
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ hoverEnabled: true
+
+ cursorShape: Qt.PointingHandCursor
+ onClicked: {
+ viewTx(txid);
+ }
+ }
+ }
+
+ Item {
+ Layout.preferredWidth: 30 * scaleRatio
+ Layout.preferredHeight: parent.height
+
+ Image {
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.horizontalCenter: parent.horizontalCenter
+ Layout.preferredWidth: 12 * scaleRatio
+ Layout.preferredHeight: 21 * scaleRatio
+ source: "../../images/merchant/arrow_right.png"
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ hoverEnabled: true
+
+ cursorShape: Qt.PointingHandCursor
+ onClicked: {
+ viewTx(txid);
+ }
+ }
+ }
+
+ Item {
+ Layout.preferredWidth: 10 * scaleRatio
+ Layout.preferredHeight: parent.height
+ }
+ }
+ }
+
+ Rectangle {
+ anchors.right: parent.right
+ anchors.left: parent.left
+ anchors.top: container.bottom
+ height: 1
+ color: "#F0F0F0"
+ }
+ }
+}
diff --git a/pages/settings/SettingsInfo.qml b/pages/settings/SettingsInfo.qml
index 6cec2e04..8d1a98e5 100644
--- a/pages/settings/SettingsInfo.qml
+++ b/pages/settings/SettingsInfo.qml
@@ -46,7 +46,7 @@ Rectangle {
anchors.left: parent.left
anchors.top: parent.top
anchors.right: parent.right
- anchors.margins: (isMobile)? 17 : 20
+ anchors.margins: (isMobile)? 17 * scaleRatio : 20 * scaleRatio
anchors.topMargin: 0
spacing: 30 * scaleRatio
diff --git a/pages/settings/SettingsLayout.qml b/pages/settings/SettingsLayout.qml
index 6914a438..1ae870e3 100644
--- a/pages/settings/SettingsLayout.qml
+++ b/pages/settings/SettingsLayout.qml
@@ -55,7 +55,7 @@ Rectangle {
anchors.left: parent.left
anchors.top: parent.top
anchors.right: parent.right
- anchors.margins: (isMobile)? 17 : 20
+ anchors.margins: (isMobile)? 17 * scaleRatio : 20 * scaleRatio
anchors.topMargin: 0
spacing: 6 * scaleRatio
diff --git a/pages/settings/SettingsLog.qml b/pages/settings/SettingsLog.qml
index 23234862..1933ae93 100644
--- a/pages/settings/SettingsLog.qml
+++ b/pages/settings/SettingsLog.qml
@@ -47,7 +47,7 @@ Rectangle {
anchors.left: parent.left
anchors.top: parent.top
anchors.right: parent.right
- anchors.margins: (isMobile)? 17 : 20
+ anchors.margins: (isMobile)? 17 * scaleRatio : 20 * scaleRatio
anchors.topMargin: 0
spacing: 10
diff --git a/pages/settings/SettingsNode.qml b/pages/settings/SettingsNode.qml
index bdfc906c..3b62a43f 100644
--- a/pages/settings/SettingsNode.qml
+++ b/pages/settings/SettingsNode.qml
@@ -39,7 +39,7 @@ Rectangle{
/* main layout */
ColumnLayout {
id: root
- anchors.margins: (isMobile)? 17 : 20
+ anchors.margins: (isMobile)? 17 * scaleRatio : 20 * scaleRatio
anchors.topMargin: 0
anchors.left: parent.left
diff --git a/pages/settings/SettingsWallet.qml b/pages/settings/SettingsWallet.qml
index 004a0bec..7998a328 100644
--- a/pages/settings/SettingsWallet.qml
+++ b/pages/settings/SettingsWallet.qml
@@ -46,7 +46,7 @@ Rectangle {
anchors.left: parent.left
anchors.top: parent.top
anchors.right: parent.right
- anchors.margins: (isMobile)? 17 : 20
+ anchors.margins: (isMobile)? 17 * scaleRatio : 20 * scaleRatio
anchors.topMargin: 0
spacing: 0
diff --git a/qml.qrc b/qml.qrc
index 2f00e2a2..f3cbd454 100644
--- a/qml.qrc
+++ b/qml.qrc
@@ -247,5 +247,11 @@
<file>images/miningxmr@2x.png</file>
<file>images/eyeHide.png</file>
<file>images/eyeShow.png</file>
+ <file>pages/merchant/Merchant.qml</file>
+ <file>pages/merchant/MerchantCheckbox.qml</file>
+ <file>pages/merchant/MerchantTrackingList.qml</file>
+ <file>images/merchant/arrow_right.png</file>
+ <file>images/merchant/bg.png</file>
+ <file>images/merchant/input_box.png</file>
</qresource>
</RCC>