2015-04-01 08:56:05 +00:00
|
|
|
// Copyright (c) 2014-2015, The Monero Project
|
|
|
|
//
|
|
|
|
// All rights reserved.
|
|
|
|
//
|
|
|
|
// Redistribution and use in source and binary forms, with or without modification, are
|
|
|
|
// permitted provided that the following conditions are met:
|
|
|
|
//
|
|
|
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
|
|
|
// conditions and the following disclaimer.
|
|
|
|
//
|
|
|
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
|
|
|
// of conditions and the following disclaimer in the documentation and/or other
|
|
|
|
// materials provided with the distribution.
|
|
|
|
//
|
|
|
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
|
|
|
// used to endorse or promote products derived from this software without specific
|
|
|
|
// prior written permission.
|
|
|
|
//
|
|
|
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
|
|
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
|
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
|
|
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
|
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
|
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
|
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
|
|
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
|
2014-07-07 17:08:30 +00:00
|
|
|
import QtQuick 2.2
|
|
|
|
import QtQuick.Window 2.0
|
|
|
|
import QtQuick.Controls 1.1
|
|
|
|
import QtQuick.Controls.Styles 1.1
|
2016-06-28 19:37:14 +00:00
|
|
|
import QtQuick.Dialogs 1.2
|
2016-06-15 13:34:55 +00:00
|
|
|
import Qt.labs.settings 1.0
|
|
|
|
import Bitmonero.Wallet 1.0
|
2016-06-16 14:13:46 +00:00
|
|
|
import Bitmonero.PendingTransaction 1.0
|
2016-06-15 10:25:45 +00:00
|
|
|
|
2016-07-13 12:24:40 +00:00
|
|
|
|
2014-07-07 17:08:30 +00:00
|
|
|
import "components"
|
2014-08-19 12:58:02 +00:00
|
|
|
import "wizard"
|
2014-07-07 17:08:30 +00:00
|
|
|
|
|
|
|
ApplicationWindow {
|
|
|
|
id: appWindow
|
2016-08-17 12:14:43 +00:00
|
|
|
|
|
|
|
|
2014-07-09 14:18:48 +00:00
|
|
|
property var currentItem
|
2014-07-07 17:08:30 +00:00
|
|
|
property bool whatIsEnable: false
|
2014-07-13 12:27:50 +00:00
|
|
|
property bool ctrlPressed: false
|
2016-06-20 19:08:09 +00:00
|
|
|
property bool rightPanelExpanded: false
|
2014-07-16 12:40:09 +00:00
|
|
|
property bool osx: false
|
2016-06-15 13:34:55 +00:00
|
|
|
property alias persistentSettings : persistentSettings
|
2016-08-18 18:55:34 +00:00
|
|
|
property var currentWallet;
|
2016-06-28 19:37:14 +00:00
|
|
|
property var transaction;
|
2016-08-17 12:14:43 +00:00
|
|
|
property alias password : passwordDialog.password
|
2014-07-16 08:24:59 +00:00
|
|
|
|
2016-07-13 12:24:40 +00:00
|
|
|
|
2014-07-13 12:27:50 +00:00
|
|
|
function altKeyReleased() { ctrlPressed = false; }
|
2016-06-15 13:34:55 +00:00
|
|
|
|
2014-07-13 12:27:50 +00:00
|
|
|
function showPageRequest(page) {
|
|
|
|
middlePanel.state = page
|
|
|
|
leftPanel.selectItem(page)
|
|
|
|
}
|
2016-06-15 13:34:55 +00:00
|
|
|
|
2014-07-13 12:27:50 +00:00
|
|
|
function sequencePressed(obj, seq) {
|
2014-07-09 14:18:48 +00:00
|
|
|
if(seq === undefined)
|
|
|
|
return
|
2014-07-13 12:27:50 +00:00
|
|
|
if(seq === "Ctrl") {
|
|
|
|
ctrlPressed = true
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if(seq === "Ctrl+D") middlePanel.state = "Dashboard"
|
|
|
|
else if(seq === "Ctrl+H") middlePanel.state = "History"
|
|
|
|
else if(seq === "Ctrl+T") middlePanel.state = "Transfer"
|
|
|
|
else if(seq === "Ctrl+B") middlePanel.state = "AddressBook"
|
|
|
|
else if(seq === "Ctrl+M") middlePanel.state = "Mining"
|
|
|
|
else if(seq === "Ctrl+S") middlePanel.state = "Settings"
|
2014-07-16 12:40:09 +00:00
|
|
|
else if(seq === "Ctrl+Tab" || seq === "Alt+Tab") {
|
2014-07-13 12:27:50 +00:00
|
|
|
if(middlePanel.state === "Dashboard") middlePanel.state = "Transfer"
|
|
|
|
else if(middlePanel.state === "Transfer") middlePanel.state = "History"
|
|
|
|
else if(middlePanel.state === "History") middlePanel.state = "AddressBook"
|
|
|
|
else if(middlePanel.state === "AddressBook") middlePanel.state = "Mining"
|
|
|
|
else if(middlePanel.state === "Mining") middlePanel.state = "Settings"
|
|
|
|
else if(middlePanel.state === "Settings") middlePanel.state = "Dashboard"
|
2014-07-16 12:40:09 +00:00
|
|
|
} else if(seq === "Ctrl+Shift+Backtab" || seq === "Alt+Shift+Backtab") {
|
2014-07-13 12:27:50 +00:00
|
|
|
if(middlePanel.state === "Dashboard") middlePanel.state = "Settings"
|
|
|
|
else if(middlePanel.state === "Settings") middlePanel.state = "Mining"
|
|
|
|
else if(middlePanel.state === "Mining") middlePanel.state = "AddressBook"
|
|
|
|
else if(middlePanel.state === "AddressBook") middlePanel.state = "History"
|
|
|
|
else if(middlePanel.state === "History") middlePanel.state = "Transfer"
|
|
|
|
else if(middlePanel.state === "Transfer") middlePanel.state = "Dashboard"
|
|
|
|
}
|
|
|
|
|
2014-07-09 16:03:37 +00:00
|
|
|
leftPanel.selectItem(middlePanel.state)
|
2014-07-09 14:18:48 +00:00
|
|
|
}
|
2014-07-13 12:27:50 +00:00
|
|
|
|
|
|
|
function sequenceReleased(obj, seq) {
|
|
|
|
if(seq === "Ctrl")
|
|
|
|
ctrlPressed = false
|
|
|
|
}
|
|
|
|
|
2014-07-09 14:18:48 +00:00
|
|
|
function mousePressed(obj, mouseX, mouseY) {
|
2016-08-17 12:14:43 +00:00
|
|
|
// if(obj.objectName === "appWindow")
|
|
|
|
// obj = rootItem
|
|
|
|
|
|
|
|
// var tmp = rootItem.mapFromItem(obj, mouseX, mouseY)
|
|
|
|
// if(tmp !== undefined) {
|
|
|
|
// mouseX = tmp.x
|
|
|
|
// mouseY = tmp.y
|
|
|
|
// }
|
|
|
|
|
|
|
|
// if(currentItem !== undefined) {
|
|
|
|
// var tmp_x = rootItem.mapToItem(currentItem, mouseX, mouseY).x
|
|
|
|
// var tmp_y = rootItem.mapToItem(currentItem, mouseX, mouseY).y
|
|
|
|
|
|
|
|
// if(!currentItem.containsPoint(tmp_x, tmp_y)) {
|
|
|
|
// currentItem.hide()
|
|
|
|
// currentItem = undefined
|
|
|
|
// }
|
|
|
|
// }
|
2014-07-09 14:18:48 +00:00
|
|
|
}
|
2014-07-13 12:27:50 +00:00
|
|
|
|
2014-07-09 14:18:48 +00:00
|
|
|
function mouseReleased(obj, mouseX, mouseY) {
|
|
|
|
|
|
|
|
}
|
2014-07-07 17:08:30 +00:00
|
|
|
|
2016-06-15 13:34:55 +00:00
|
|
|
|
|
|
|
function initialize() {
|
2016-07-13 12:24:40 +00:00
|
|
|
console.log("initializing..")
|
2016-07-19 20:45:12 +00:00
|
|
|
|
|
|
|
// setup language
|
|
|
|
var locale = persistentSettings.locale
|
|
|
|
if (locale !== "") {
|
|
|
|
translationManager.setLanguage(locale.split("_")[0]);
|
|
|
|
}
|
|
|
|
|
2016-06-16 14:13:46 +00:00
|
|
|
middlePanel.paymentClicked.connect(handlePayment);
|
2016-08-23 13:07:52 +00:00
|
|
|
// basicPanel.paymentClicked.connect(handlePayment);
|
2016-06-16 14:13:46 +00:00
|
|
|
|
2016-07-19 20:45:12 +00:00
|
|
|
|
2016-08-19 11:44:44 +00:00
|
|
|
// wallet already opened with wizard, we just need to initialize it
|
2016-06-15 13:34:55 +00:00
|
|
|
if (typeof wizard.settings['wallet'] !== 'undefined') {
|
2016-08-19 11:44:44 +00:00
|
|
|
connectWallet(wizard.settings['wallet'])
|
2016-06-15 13:34:55 +00:00
|
|
|
} else {
|
2016-08-16 20:21:46 +00:00
|
|
|
var wallet_path = walletPath();
|
2016-08-19 11:44:44 +00:00
|
|
|
console.log("opening wallet at: ", wallet_path, "with password: ", appWindow.password);
|
2016-08-18 18:55:34 +00:00
|
|
|
walletManager.openWalletAsync(wallet_path, appWindow.password,
|
2016-08-17 12:14:43 +00:00
|
|
|
persistentSettings.testnet);
|
2016-06-15 13:34:55 +00:00
|
|
|
}
|
2016-06-17 13:35:07 +00:00
|
|
|
}
|
|
|
|
|
2016-08-19 11:44:44 +00:00
|
|
|
|
|
|
|
function connectWallet(wallet) {
|
2016-08-23 08:55:51 +00:00
|
|
|
showProcessingSplash()
|
2016-08-19 11:44:44 +00:00
|
|
|
currentWallet = wallet
|
|
|
|
currentWallet.refreshed.connect(onWalletRefresh)
|
|
|
|
currentWallet.updated.connect(onWalletUpdate)
|
|
|
|
console.log("initializing with daemon address: ", persistentSettings.daemon_address)
|
|
|
|
currentWallet.initAsync(persistentSettings.daemon_address, 0);
|
|
|
|
}
|
|
|
|
|
2016-08-16 20:21:46 +00:00
|
|
|
function walletPath() {
|
|
|
|
var wallet_path = persistentSettings.wallet_path + "/" + persistentSettings.account_name + "/"
|
|
|
|
+ persistentSettings.account_name;
|
|
|
|
return wallet_path;
|
|
|
|
}
|
|
|
|
|
2016-08-18 18:55:34 +00:00
|
|
|
function onWalletOpened(wallet) {
|
|
|
|
console.log(">>> wallet opened: " + wallet)
|
|
|
|
if (wallet.status !== Wallet.Status_Ok) {
|
2016-08-19 11:44:44 +00:00
|
|
|
if (appWindow.password === '') {
|
2016-08-18 18:55:34 +00:00
|
|
|
console.error("Error opening wallet with empty password: ", wallet.errorString);
|
2016-08-19 11:44:44 +00:00
|
|
|
console.log("closing wallet async : " + wallet.address)
|
2016-08-18 18:55:34 +00:00
|
|
|
walletManager.closeWalletAsync(wallet)
|
|
|
|
// try to open wallet with password;
|
|
|
|
passwordDialog.open();
|
|
|
|
} else {
|
|
|
|
// opening with password but password doesn't match
|
|
|
|
console.error("Error opening wallet with password: ", wallet.errorString);
|
2016-08-19 11:44:44 +00:00
|
|
|
|
2016-08-18 18:55:34 +00:00
|
|
|
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
|
|
|
informationPopup.text = qsTr("Couldn't open wallet: ") + wallet.errorString;
|
|
|
|
informationPopup.icon = StandardIcon.Critical
|
2016-08-19 11:44:44 +00:00
|
|
|
console.log("closing wallet async : " + wallet.address)
|
|
|
|
walletManager.closeWalletAsync(wallet);
|
2016-08-18 18:55:34 +00:00
|
|
|
informationPopup.open()
|
2016-08-19 11:44:44 +00:00
|
|
|
informationPopup.onCloseCallback = function() {
|
|
|
|
passwordDialog.open()
|
|
|
|
}
|
2016-08-18 18:55:34 +00:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// wallet opened successfully, subscribing for wallet updates
|
2016-08-19 11:44:44 +00:00
|
|
|
connectWallet(wallet)
|
2016-08-18 18:55:34 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function onWalletClosed(walletAddress) {
|
|
|
|
console.log(">>> wallet closed: " + walletAddress)
|
|
|
|
}
|
2016-08-16 20:21:46 +00:00
|
|
|
|
2016-06-17 13:35:07 +00:00
|
|
|
function onWalletUpdate() {
|
2016-07-13 12:24:40 +00:00
|
|
|
console.log(">>> wallet updated")
|
2016-08-19 11:44:44 +00:00
|
|
|
basicPanel.unlockedBalanceText = leftPanel.unlockedBalanceText =
|
|
|
|
walletManager.displayAmount(currentWallet.unlockedBalance);
|
|
|
|
basicPanel.balanceText = leftPanel.balanceText = walletManager.displayAmount(currentWallet.balance);
|
2016-07-13 12:24:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function onWalletRefresh() {
|
|
|
|
console.log(">>> wallet refreshed")
|
2016-08-23 08:55:51 +00:00
|
|
|
if (splash.visible) {
|
|
|
|
hideProcessingSplash()
|
|
|
|
}
|
|
|
|
|
2016-08-19 11:44:44 +00:00
|
|
|
leftPanel.networkStatus.connected = currentWallet.connected
|
2016-07-14 10:09:39 +00:00
|
|
|
onWalletUpdate();
|
2016-06-15 13:34:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-06-07 13:26:25 +00:00
|
|
|
function walletsFound() {
|
|
|
|
var wallets = walletManager.findWallets(moneroAccountsDir);
|
|
|
|
if (wallets.length === 0) {
|
|
|
|
wallets = walletManager.findWallets(applicationDirectory);
|
|
|
|
}
|
|
|
|
print(wallets);
|
|
|
|
return wallets.length > 0;
|
|
|
|
}
|
|
|
|
|
2016-06-28 19:37:14 +00:00
|
|
|
|
2016-08-17 12:14:43 +00:00
|
|
|
|
|
|
|
|
2016-06-28 19:37:14 +00:00
|
|
|
// called on "transfer"
|
2016-06-27 12:45:48 +00:00
|
|
|
function handlePayment(address, paymentId, amount, mixinCount, priority) {
|
|
|
|
console.log("Creating transaction: ")
|
|
|
|
console.log("\taddress: ", address,
|
|
|
|
", payment_id: ", paymentId,
|
|
|
|
", amount: ", amount,
|
|
|
|
", mixins: ", mixinCount,
|
|
|
|
", priority: ", priority);
|
|
|
|
|
2016-06-16 14:13:46 +00:00
|
|
|
|
2016-08-23 13:07:52 +00:00
|
|
|
// validate amount;
|
|
|
|
var amountxmr = walletManager.amountFromString(amount);
|
2016-06-16 14:13:46 +00:00
|
|
|
console.log("integer amount: ", amountxmr);
|
2016-08-23 13:07:52 +00:00
|
|
|
if (amountxmr <= 0) {
|
|
|
|
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
|
|
|
informationPopup.text = qsTr("Amount is wrong: expected number from %1 to %2")
|
|
|
|
.arg(walletManager.displayAmount(0))
|
|
|
|
.arg(walletManager.maximumAllowedAmountAsSting())
|
|
|
|
+ translationManager.emptyString
|
|
|
|
|
|
|
|
informationPopup.icon = StandardIcon.Critical
|
|
|
|
informationPopup.onCloseCallback = null
|
|
|
|
informationPopup.open()
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// validate address;
|
|
|
|
transaction = currentWallet.createTransaction(address, paymentId, amountxmr, mixinCount, priority);
|
2016-06-28 19:37:14 +00:00
|
|
|
if (transaction.status !== PendingTransaction.Status_Ok) {
|
|
|
|
console.error("Can't create transaction: ", transaction.errorString);
|
2016-07-20 19:28:11 +00:00
|
|
|
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
2016-06-28 19:37:14 +00:00
|
|
|
informationPopup.text = qsTr("Can't create transaction: ") + transaction.errorString
|
|
|
|
informationPopup.icon = StandardIcon.Critical
|
2016-08-17 12:14:43 +00:00
|
|
|
informationPopup.onCloseCallback = null
|
2016-06-28 19:37:14 +00:00
|
|
|
informationPopup.open();
|
|
|
|
// deleting transaction object, we don't want memleaks
|
2016-08-23 13:07:52 +00:00
|
|
|
currentWallet.disposeTransaction(transaction);
|
2016-06-28 19:37:14 +00:00
|
|
|
|
2016-06-16 14:13:46 +00:00
|
|
|
} else {
|
2016-06-28 19:37:14 +00:00
|
|
|
console.log("Transaction created, amount: " + walletManager.displayAmount(transaction.amount)
|
|
|
|
+ ", fee: " + walletManager.displayAmount(transaction.fee));
|
|
|
|
|
|
|
|
// here we show confirmation popup;
|
|
|
|
|
2016-07-20 19:28:11 +00:00
|
|
|
transactionConfirmationPopup.title = qsTr("Confirmation") + translationManager.emptyString
|
2016-06-28 19:37:14 +00:00
|
|
|
transactionConfirmationPopup.text = qsTr("Please confirm transaction:\n\n")
|
2016-07-13 12:24:40 +00:00
|
|
|
+ qsTr("\nAddress: ") + address
|
|
|
|
+ qsTr("\nPayment ID: ") + paymentId
|
|
|
|
+ qsTr("\nAmount: ") + walletManager.displayAmount(transaction.amount)
|
|
|
|
+ qsTr("\nFee: ") + walletManager.displayAmount(transaction.fee)
|
2016-07-20 19:28:11 +00:00
|
|
|
+ translationManager.emptyString
|
2016-06-28 19:37:14 +00:00
|
|
|
transactionConfirmationPopup.icon = StandardIcon.Question
|
|
|
|
transactionConfirmationPopup.open()
|
|
|
|
// committing transaction
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// called after user confirms transaction
|
|
|
|
function handleTransactionConfirmed() {
|
|
|
|
if (!transaction.commit()) {
|
|
|
|
console.log("Error committing transaction: " + transaction.errorString);
|
2016-07-20 19:28:11 +00:00
|
|
|
informationPopup.title = qsTr("Error") + translationManager.emptyString
|
2016-06-28 19:37:14 +00:00
|
|
|
informationPopup.text = qsTr("Couldn't send the money: ") + transaction.errorString
|
|
|
|
informationPopup.icon = StandardIcon.Critical
|
|
|
|
} else {
|
2016-07-20 19:28:11 +00:00
|
|
|
informationPopup.title = qsTr("Information") + translationManager.emptyString
|
|
|
|
informationPopup.text = qsTr("Money sent successfully") + translationManager.emptyString
|
2016-06-28 19:37:14 +00:00
|
|
|
informationPopup.icon = StandardIcon.Information
|
2016-06-16 14:13:46 +00:00
|
|
|
}
|
2016-08-17 12:14:43 +00:00
|
|
|
informationPopup.onCloseCallback = null
|
2016-06-28 19:37:14 +00:00
|
|
|
informationPopup.open()
|
2016-08-23 13:07:52 +00:00
|
|
|
currentWallet.refresh()
|
|
|
|
currentWallet.disposeTransaction(transaction)
|
2016-06-16 14:13:46 +00:00
|
|
|
}
|
|
|
|
|
2016-08-17 12:14:43 +00:00
|
|
|
// blocks UI if wallet can't be opened or no connection to the daemon
|
|
|
|
function enableUI(enable) {
|
|
|
|
middlePanel.enabled = enable;
|
|
|
|
leftPanel.enabled = enable;
|
|
|
|
rightPanel.enabled = enable;
|
|
|
|
basicPanel.enabled = enable;
|
|
|
|
}
|
|
|
|
|
2016-08-23 08:55:51 +00:00
|
|
|
function showProcessingSplash(message) {
|
|
|
|
console.log("Displaying processing splash")
|
|
|
|
if (typeof message != 'undefined') {
|
|
|
|
splash.message = message
|
|
|
|
}
|
|
|
|
splash.show()
|
|
|
|
}
|
|
|
|
|
|
|
|
function hideProcessingSplash() {
|
|
|
|
console.log("Hiding processing splash")
|
|
|
|
splash.hide()
|
|
|
|
}
|
|
|
|
|
2016-06-28 19:37:14 +00:00
|
|
|
|
2016-08-17 12:14:43 +00:00
|
|
|
objectName: "appWindow"
|
2014-07-07 17:08:30 +00:00
|
|
|
visible: true
|
2014-07-16 08:24:59 +00:00
|
|
|
width: rightPanelExpanded ? 1269 : 1269 - 300
|
2014-07-09 15:44:13 +00:00
|
|
|
height: 800
|
2014-07-07 17:08:30 +00:00
|
|
|
color: "#FFFFFF"
|
|
|
|
flags: Qt.FramelessWindowHint | Qt.WindowSystemMenuHint | Qt.Window | Qt.WindowMinimizeButtonHint
|
2014-07-19 14:07:40 +00:00
|
|
|
onWidthChanged: x -= 0
|
|
|
|
|
2016-08-17 12:14:43 +00:00
|
|
|
|
2014-07-19 14:07:40 +00:00
|
|
|
Component.onCompleted: {
|
|
|
|
x = (Screen.width - width) / 2
|
|
|
|
y = (Screen.height - height) / 2
|
2016-06-07 13:26:25 +00:00
|
|
|
//
|
2016-08-18 18:55:34 +00:00
|
|
|
walletManager.walletOpened.connect(onWalletOpened);
|
|
|
|
walletManager.walletClosed.connect(onWalletClosed);
|
|
|
|
|
2016-06-07 13:26:25 +00:00
|
|
|
rootItem.state = walletsFound() ? "normal" : "wizard";
|
2016-06-15 13:34:55 +00:00
|
|
|
if (rootItem.state === "normal") {
|
|
|
|
initialize(persistentSettings)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-21 08:58:06 +00:00
|
|
|
onRightPanelExpandedChanged: {
|
|
|
|
if (rightPanelExpanded) {
|
|
|
|
rightPanel.updateTweets()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-17 12:14:43 +00:00
|
|
|
|
2016-06-15 13:34:55 +00:00
|
|
|
Settings {
|
|
|
|
id: persistentSettings
|
|
|
|
property string language
|
2016-07-19 20:45:12 +00:00
|
|
|
property string locale
|
2016-06-15 13:34:55 +00:00
|
|
|
property string account_name
|
|
|
|
property string wallet_path
|
|
|
|
property bool auto_donations_enabled : true
|
|
|
|
property int auto_donations_amount : 50
|
|
|
|
property bool allow_background_mining : true
|
|
|
|
property bool testnet: true
|
|
|
|
property string daemon_address: "localhost:38081"
|
2016-06-26 15:04:45 +00:00
|
|
|
property string payment_id
|
2014-07-19 14:07:40 +00:00
|
|
|
}
|
2014-07-07 17:08:30 +00:00
|
|
|
|
2016-06-28 19:37:14 +00:00
|
|
|
// TODO: replace with customized popups
|
|
|
|
|
|
|
|
// Information dialog
|
|
|
|
MessageDialog {
|
2016-08-17 12:14:43 +00:00
|
|
|
// dynamically change onclose handler
|
|
|
|
property var onCloseCallback
|
2016-06-28 19:37:14 +00:00
|
|
|
id: informationPopup
|
|
|
|
standardButtons: StandardButton.Ok
|
2016-08-17 12:14:43 +00:00
|
|
|
onAccepted: {
|
|
|
|
if (onCloseCallback) {
|
|
|
|
onCloseCallback()
|
|
|
|
}
|
|
|
|
}
|
2016-06-28 19:37:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Confrirmation aka question dialog
|
|
|
|
MessageDialog {
|
|
|
|
id: transactionConfirmationPopup
|
|
|
|
standardButtons: StandardButton.Ok + StandardButton.Cancel
|
|
|
|
onAccepted: {
|
|
|
|
handleTransactionConfirmed()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-16 20:21:46 +00:00
|
|
|
PasswordDialog {
|
|
|
|
id: passwordDialog
|
|
|
|
standardButtons: StandardButton.Ok + StandardButton.Cancel
|
|
|
|
onAccepted: {
|
2016-08-19 11:44:44 +00:00
|
|
|
appWindow.currentWallet = null
|
|
|
|
appWindow.initialize();
|
2016-08-16 20:21:46 +00:00
|
|
|
}
|
2016-08-17 12:14:43 +00:00
|
|
|
onRejected: {
|
|
|
|
appWindow.enableUI(false)
|
|
|
|
}
|
|
|
|
onDiscard: {
|
|
|
|
appWindow.enableUI(false)
|
|
|
|
}
|
2016-08-16 20:21:46 +00:00
|
|
|
}
|
|
|
|
|
2016-08-23 08:55:51 +00:00
|
|
|
|
|
|
|
ProcessingSplash {
|
|
|
|
id: splash
|
|
|
|
width: appWindow.width / 2
|
|
|
|
height: appWindow.height / 2
|
|
|
|
x: (appWindow.width - width) / 2 + appWindow.x
|
|
|
|
y: (appWindow.height - height) / 2 + appWindow.y
|
|
|
|
message: qsTr("Please wait...")
|
2016-07-13 12:24:40 +00:00
|
|
|
}
|
|
|
|
|
2016-06-28 19:37:14 +00:00
|
|
|
|
2016-08-23 08:55:51 +00:00
|
|
|
|
2014-07-07 17:08:30 +00:00
|
|
|
Item {
|
|
|
|
id: rootItem
|
|
|
|
anchors.fill: parent
|
2014-07-19 14:07:40 +00:00
|
|
|
clip: true
|
2014-07-07 17:08:30 +00:00
|
|
|
|
2014-08-19 12:58:02 +00:00
|
|
|
state: "wizard"
|
|
|
|
states: [
|
|
|
|
State {
|
|
|
|
name: "wizard"
|
|
|
|
PropertyChanges { target: leftPanel; visible: false }
|
|
|
|
PropertyChanges { target: rightPanel; visible: false }
|
|
|
|
PropertyChanges { target: middlePanel; visible: false }
|
|
|
|
PropertyChanges { target: titleBar; basicButtonVisible: false }
|
|
|
|
PropertyChanges { target: wizard; visible: true }
|
2014-08-21 10:09:52 +00:00
|
|
|
PropertyChanges { target: appWindow; width: 930; }
|
|
|
|
PropertyChanges { target: appWindow; height: 595; }
|
|
|
|
PropertyChanges { target: resizeArea; visible: false }
|
2014-08-22 09:03:10 +00:00
|
|
|
PropertyChanges { target: titleBar; maximizeButtonVisible: false }
|
|
|
|
PropertyChanges { target: frameArea; blocked: true }
|
|
|
|
PropertyChanges { target: titleBar; y: 0 }
|
2016-07-20 19:28:11 +00:00
|
|
|
PropertyChanges { target: titleBar; title: qsTr("Program setup wizard") + translationManager.emptyString }
|
2014-08-22 09:03:10 +00:00
|
|
|
}, State {
|
2014-08-19 12:58:02 +00:00
|
|
|
name: "normal"
|
|
|
|
PropertyChanges { target: leftPanel; visible: true }
|
|
|
|
PropertyChanges { target: rightPanel; visible: true }
|
|
|
|
PropertyChanges { target: middlePanel; visible: true }
|
|
|
|
PropertyChanges { target: titleBar; basicButtonVisible: true }
|
|
|
|
PropertyChanges { target: wizard; visible: false }
|
2014-08-21 10:09:52 +00:00
|
|
|
PropertyChanges { target: appWindow; width: rightPanelExpanded ? 1269 : 1269 - 300; }
|
|
|
|
PropertyChanges { target: appWindow; height: 800; }
|
|
|
|
PropertyChanges { target: resizeArea; visible: true }
|
2014-08-22 09:03:10 +00:00
|
|
|
PropertyChanges { target: titleBar; maximizeButtonVisible: true }
|
|
|
|
PropertyChanges { target: frameArea; blocked: false }
|
|
|
|
PropertyChanges { target: titleBar; y: -titleBar.height }
|
2016-08-10 12:09:05 +00:00
|
|
|
PropertyChanges { target: titleBar; title: qsTr("Monero") + translationManager.emptyString }
|
2014-08-19 12:58:02 +00:00
|
|
|
}
|
|
|
|
]
|
|
|
|
|
2014-07-07 17:08:30 +00:00
|
|
|
LeftPanel {
|
|
|
|
id: leftPanel
|
|
|
|
anchors.left: parent.left
|
|
|
|
anchors.bottom: parent.bottom
|
2014-07-19 14:07:40 +00:00
|
|
|
height: parent.height
|
2014-07-07 17:08:30 +00:00
|
|
|
onDashboardClicked: middlePanel.state = "Dashboard"
|
|
|
|
onHistoryClicked: middlePanel.state = "History"
|
|
|
|
onTransferClicked: middlePanel.state = "Transfer"
|
2016-06-26 15:04:45 +00:00
|
|
|
onReceiveClicked: middlePanel.state = "Receive"
|
2014-07-07 17:08:30 +00:00
|
|
|
onAddressBookClicked: middlePanel.state = "AddressBook"
|
|
|
|
onMiningClicked: middlePanel.state = "Minning"
|
|
|
|
onSettingsClicked: middlePanel.state = "Settings"
|
|
|
|
}
|
|
|
|
|
|
|
|
RightPanel {
|
|
|
|
id: rightPanel
|
|
|
|
anchors.right: parent.right
|
|
|
|
anchors.bottom: parent.bottom
|
2014-07-19 14:07:40 +00:00
|
|
|
height: parent.height
|
2014-07-16 08:24:59 +00:00
|
|
|
width: appWindow.rightPanelExpanded ? 300 : 0
|
|
|
|
visible: appWindow.rightPanelExpanded
|
2014-07-07 17:08:30 +00:00
|
|
|
}
|
|
|
|
|
2016-07-14 10:40:27 +00:00
|
|
|
|
2014-07-07 17:08:30 +00:00
|
|
|
MiddlePanel {
|
|
|
|
id: middlePanel
|
|
|
|
anchors.bottom: parent.bottom
|
|
|
|
anchors.left: leftPanel.right
|
|
|
|
anchors.right: rightPanel.left
|
2014-07-19 14:07:40 +00:00
|
|
|
height: parent.height
|
2016-06-26 15:04:45 +00:00
|
|
|
state: "Transfer"
|
2014-07-07 17:08:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TipItem {
|
|
|
|
id: tipItem
|
2016-07-20 19:28:11 +00:00
|
|
|
text: qsTr("send to the same destination") + translationManager.emptyString
|
2014-07-07 17:08:30 +00:00
|
|
|
visible: false
|
|
|
|
}
|
2014-07-15 14:03:39 +00:00
|
|
|
|
2014-07-19 14:07:40 +00:00
|
|
|
BasicPanel {
|
|
|
|
id: basicPanel
|
|
|
|
x: 0
|
|
|
|
anchors.bottom: parent.bottom
|
2016-08-10 13:21:58 +00:00
|
|
|
anchors.top: parent.top
|
|
|
|
anchors.left: parent.left
|
|
|
|
anchors.right: parent.right
|
2014-07-19 14:07:40 +00:00
|
|
|
visible: false
|
|
|
|
}
|
|
|
|
|
2014-07-15 14:03:39 +00:00
|
|
|
MouseArea {
|
|
|
|
id: frameArea
|
2014-07-19 14:07:40 +00:00
|
|
|
property bool blocked: false
|
2014-07-15 14:03:39 +00:00
|
|
|
anchors.top: parent.top
|
|
|
|
anchors.left: parent.left
|
|
|
|
anchors.right: parent.right
|
|
|
|
height: 30
|
|
|
|
z: 1
|
|
|
|
hoverEnabled: true
|
2014-07-19 14:07:40 +00:00
|
|
|
onEntered: if(!blocked) titleBar.y = 0
|
|
|
|
onExited: if(!blocked) titleBar.y = -titleBar.height
|
2014-07-15 14:03:39 +00:00
|
|
|
propagateComposedEvents: true
|
|
|
|
onPressed: mouse.accepted = false
|
|
|
|
onReleased: mouse.accepted = false
|
2014-07-22 12:29:20 +00:00
|
|
|
onMouseXChanged: titleBar.mouseX = mouseX
|
|
|
|
onContainsMouseChanged: titleBar.containsMouse = containsMouse
|
2014-07-15 14:03:39 +00:00
|
|
|
}
|
|
|
|
|
2014-07-19 14:07:40 +00:00
|
|
|
SequentialAnimation {
|
|
|
|
id: goToBasicAnimation
|
|
|
|
PropertyAction {
|
|
|
|
target: appWindow
|
|
|
|
properties: "visibility"
|
|
|
|
value: Window.Windowed
|
|
|
|
}
|
|
|
|
PropertyAction {
|
|
|
|
target: titleBar
|
|
|
|
properties: "maximizeButtonVisible"
|
|
|
|
value: false
|
|
|
|
}
|
|
|
|
PropertyAction {
|
|
|
|
target: frameArea
|
|
|
|
properties: "blocked"
|
|
|
|
value: true
|
|
|
|
}
|
2014-08-22 09:03:10 +00:00
|
|
|
PropertyAction {
|
|
|
|
target: resizeArea
|
|
|
|
properties: "visible"
|
|
|
|
value: false
|
|
|
|
}
|
2014-07-19 14:07:40 +00:00
|
|
|
NumberAnimation {
|
|
|
|
target: appWindow
|
|
|
|
properties: "height"
|
|
|
|
to: 30
|
|
|
|
easing.type: Easing.InCubic
|
|
|
|
duration: 200
|
|
|
|
}
|
|
|
|
NumberAnimation {
|
|
|
|
target: appWindow
|
|
|
|
properties: "width"
|
|
|
|
to: 470
|
|
|
|
easing.type: Easing.InCubic
|
|
|
|
duration: 200
|
|
|
|
}
|
|
|
|
PropertyAction {
|
|
|
|
targets: [leftPanel, middlePanel, rightPanel]
|
|
|
|
properties: "visible"
|
|
|
|
value: false
|
|
|
|
}
|
|
|
|
PropertyAction {
|
|
|
|
target: basicPanel
|
|
|
|
properties: "visible"
|
|
|
|
value: true
|
|
|
|
}
|
|
|
|
NumberAnimation {
|
|
|
|
target: appWindow
|
|
|
|
properties: "height"
|
2014-07-19 14:52:05 +00:00
|
|
|
to: basicPanel.height
|
2014-07-19 14:07:40 +00:00
|
|
|
easing.type: Easing.InCubic
|
|
|
|
duration: 200
|
|
|
|
}
|
|
|
|
|
|
|
|
onStopped: {
|
|
|
|
middlePanel.visible = false
|
|
|
|
rightPanel.visible = false
|
|
|
|
leftPanel.visible = false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
SequentialAnimation {
|
|
|
|
id: goToProAnimation
|
|
|
|
NumberAnimation {
|
|
|
|
target: appWindow
|
|
|
|
properties: "height"
|
|
|
|
to: 30
|
|
|
|
easing.type: Easing.InCubic
|
|
|
|
duration: 200
|
|
|
|
}
|
|
|
|
PropertyAction {
|
|
|
|
target: basicPanel
|
|
|
|
properties: "visible"
|
|
|
|
value: false
|
|
|
|
}
|
|
|
|
PropertyAction {
|
2014-08-22 09:03:10 +00:00
|
|
|
targets: [leftPanel, middlePanel, rightPanel, resizeArea]
|
2014-07-19 14:07:40 +00:00
|
|
|
properties: "visible"
|
|
|
|
value: true
|
|
|
|
}
|
|
|
|
NumberAnimation {
|
|
|
|
target: appWindow
|
|
|
|
properties: "width"
|
|
|
|
to: rightPanelExpanded ? 1269 : 1269 - 300
|
|
|
|
easing.type: Easing.InCubic
|
|
|
|
duration: 200
|
|
|
|
}
|
|
|
|
NumberAnimation {
|
|
|
|
target: appWindow
|
|
|
|
properties: "height"
|
|
|
|
to: 800
|
|
|
|
easing.type: Easing.InCubic
|
|
|
|
duration: 200
|
|
|
|
}
|
|
|
|
PropertyAction {
|
|
|
|
target: frameArea
|
|
|
|
properties: "blocked"
|
|
|
|
value: false
|
|
|
|
}
|
|
|
|
PropertyAction {
|
|
|
|
target: titleBar
|
|
|
|
properties: "maximizeButtonVisible"
|
|
|
|
value: true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-19 12:58:02 +00:00
|
|
|
WizardMain {
|
|
|
|
id: wizard
|
|
|
|
anchors.fill: parent
|
2016-06-15 13:34:55 +00:00
|
|
|
onUseMoneroClicked: {
|
|
|
|
rootItem.state = "normal" // TODO: listen for this state change in appWindow;
|
|
|
|
appWindow.initialize();
|
|
|
|
}
|
2014-08-19 12:58:02 +00:00
|
|
|
}
|
|
|
|
|
2014-07-22 14:55:25 +00:00
|
|
|
property int maxWidth: leftPanel.width + 655 + rightPanel.width
|
2014-07-23 10:39:35 +00:00
|
|
|
property int maxHeight: 700
|
|
|
|
MouseArea {
|
2014-08-21 10:09:52 +00:00
|
|
|
id: resizeArea
|
2014-07-23 10:39:35 +00:00
|
|
|
hoverEnabled: true
|
|
|
|
anchors.right: parent.right
|
|
|
|
anchors.bottom: parent.bottom
|
2014-07-23 11:27:27 +00:00
|
|
|
height: 30
|
|
|
|
width: 30
|
2014-07-23 10:39:35 +00:00
|
|
|
|
|
|
|
Rectangle {
|
|
|
|
anchors.fill: parent
|
2014-07-23 11:59:26 +00:00
|
|
|
color: parent.containsMouse || parent.pressed ? "#111111" : "transparent"
|
2014-07-23 10:39:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Image {
|
|
|
|
anchors.centerIn: parent
|
|
|
|
source: parent.containsMouse || parent.pressed ? "images/resizeHovered.png" :
|
|
|
|
"images/resize.png"
|
|
|
|
}
|
|
|
|
|
2016-02-03 15:37:10 +00:00
|
|
|
property var previousPosition
|
2016-06-16 14:13:46 +00:00
|
|
|
|
2014-07-23 10:39:35 +00:00
|
|
|
onPressed: {
|
2016-02-03 15:37:10 +00:00
|
|
|
previousPosition = globalCursor.getPosition()
|
2014-07-23 10:39:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
onPositionChanged: {
|
|
|
|
if(!pressed) return
|
2016-02-03 15:37:10 +00:00
|
|
|
var pos = globalCursor.getPosition()
|
|
|
|
//var delta = previousPosition - pos
|
|
|
|
var dx = previousPosition.x - pos.x
|
|
|
|
var dy = previousPosition.y - pos.y
|
2014-07-23 10:39:35 +00:00
|
|
|
|
|
|
|
if(appWindow.width - dx > parent.maxWidth)
|
|
|
|
appWindow.width -= dx
|
|
|
|
else appWindow.width = parent.maxWidth
|
|
|
|
|
|
|
|
if(appWindow.height - dy > parent.maxHeight)
|
|
|
|
appWindow.height -= dy
|
|
|
|
else appWindow.height = parent.maxHeight
|
2016-02-03 15:37:10 +00:00
|
|
|
previousPosition = pos
|
2014-07-23 10:39:35 +00:00
|
|
|
}
|
|
|
|
}
|
2014-07-22 14:55:25 +00:00
|
|
|
|
2014-07-15 14:03:39 +00:00
|
|
|
TitleBar {
|
|
|
|
id: titleBar
|
|
|
|
anchors.left: parent.left
|
|
|
|
anchors.right: parent.right
|
2014-07-19 14:07:40 +00:00
|
|
|
onGoToBasicVersion: {
|
|
|
|
if(yes) goToBasicAnimation.start()
|
|
|
|
else goToProAnimation.start()
|
|
|
|
}
|
2014-07-22 12:16:05 +00:00
|
|
|
|
|
|
|
MouseArea {
|
|
|
|
property var previousPosition
|
|
|
|
anchors.fill: parent
|
|
|
|
propagateComposedEvents: true
|
2016-02-03 15:37:10 +00:00
|
|
|
onPressed: previousPosition = globalCursor.getPosition()
|
2014-07-22 12:16:05 +00:00
|
|
|
onPositionChanged: {
|
|
|
|
if (pressedButtons == Qt.LeftButton) {
|
2016-02-03 15:37:10 +00:00
|
|
|
var pos = globalCursor.getPosition()
|
|
|
|
var dx = pos.x - previousPosition.x
|
|
|
|
var dy = pos.y - previousPosition.y
|
|
|
|
|
2014-07-22 12:16:05 +00:00
|
|
|
appWindow.x += dx
|
|
|
|
appWindow.y += dy
|
2016-02-03 15:37:10 +00:00
|
|
|
previousPosition = pos
|
2014-07-22 12:16:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-07-15 14:03:39 +00:00
|
|
|
}
|
2014-07-07 17:08:30 +00:00
|
|
|
}
|
|
|
|
}
|