Initial commit
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
.DS_Store
|
||||||
|
/build
|
||||||
|
/tags
|
201
CMakeLists.txt
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
cmake_minimum_required(VERSION 2.8)
|
||||||
|
|
||||||
|
include(CryptoNoteWallet.cmake)
|
||||||
|
|
||||||
|
project(${CN_PROJECT_NAME})
|
||||||
|
|
||||||
|
execute_process(COMMAND git log -1 --pretty=format:%h
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
|
OUTPUT_VARIABLE GIT_REVISION)
|
||||||
|
|
||||||
|
set(CRYPTONOTE_LIB cryptonote)
|
||||||
|
|
||||||
|
include_directories(${CMAKE_BINARY_DIR}
|
||||||
|
src
|
||||||
|
cryptonote/external
|
||||||
|
cryptonote/include
|
||||||
|
cryptonote/src
|
||||||
|
cryptonote/contrib/epee/include)
|
||||||
|
|
||||||
|
find_package(Qt5Gui REQUIRED)
|
||||||
|
find_package(Qt5Widgets REQUIRED)
|
||||||
|
|
||||||
|
set(Boost_USE_STATIC_LIBS ON)
|
||||||
|
if(WIN32)
|
||||||
|
set(Boost_USE_STATIC_RUNTIME OFF)
|
||||||
|
else(WIN32)
|
||||||
|
set(Boost_USE_STATIC_RUNTIME ON)
|
||||||
|
endif(WIN32)
|
||||||
|
|
||||||
|
find_package(Boost 1.55 REQUIRED COMPONENTS date_time filesystem program_options regex serialization system thread chrono)
|
||||||
|
if ((${Boost_MAJOR_VERSION} EQUAL 1) AND (${Boost_MINOR_VERSION} EQUAL 54))
|
||||||
|
message(SEND_ERROR "Boost version 1.54 is unsupported, more details are available here http://goo.gl/RrCFmA")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
include_directories(${Boost_INCLUDE_DIRS})
|
||||||
|
link_directories(${Boost_LIBRARY_DIRS})
|
||||||
|
|
||||||
|
set(VERSION "")
|
||||||
|
configure_file("cryptonote/src/version.h.in" "version.h")
|
||||||
|
configure_file("src/CryptoNoteWalletConfig.h.in" "CryptoNoteWalletConfig.h")
|
||||||
|
|
||||||
|
add_definitions(-DGIT_REVISION=\"${GIT_REVISION}\")
|
||||||
|
|
||||||
|
set(CMAKE_AUTOMOC ON)
|
||||||
|
|
||||||
|
set(CRYPTONOTE_SOURCES
|
||||||
|
cryptonote/contrib/epee/include/misc_log_ex.cpp
|
||||||
|
cryptonote/contrib/epee/include/misc_os_dependent.cpp
|
||||||
|
cryptonote/contrib/epee/include/string_tools.cpp
|
||||||
|
cryptonote/external/miniupnpc/connecthostport.c
|
||||||
|
cryptonote/external/miniupnpc/igd_desc_parse.c
|
||||||
|
cryptonote/external/miniupnpc/minisoap.c
|
||||||
|
cryptonote/external/miniupnpc/miniupnpc.c
|
||||||
|
cryptonote/external/miniupnpc/miniwget.c
|
||||||
|
cryptonote/external/miniupnpc/minixml.c
|
||||||
|
cryptonote/external/miniupnpc/portlistingparse.c
|
||||||
|
cryptonote/external/miniupnpc/receivedata.c
|
||||||
|
cryptonote/external/miniupnpc/upnpcommands.c
|
||||||
|
cryptonote/external/miniupnpc/upnpreplyparse.c
|
||||||
|
cryptonote/src/common/base58.cpp
|
||||||
|
cryptonote/src/common/command_line.cpp
|
||||||
|
cryptonote/src/common/util.cpp
|
||||||
|
cryptonote/src/crypto/blake256.c
|
||||||
|
cryptonote/src/crypto/chacha8.c
|
||||||
|
cryptonote/src/crypto/crypto-ops-data.c
|
||||||
|
cryptonote/src/crypto/crypto-ops.c
|
||||||
|
cryptonote/src/crypto/crypto.cpp
|
||||||
|
cryptonote/src/crypto/groestl.c
|
||||||
|
cryptonote/src/crypto/hash-extra-blake.c
|
||||||
|
cryptonote/src/crypto/hash-extra-groestl.c
|
||||||
|
cryptonote/src/crypto/hash-extra-jh.c
|
||||||
|
cryptonote/src/crypto/hash-extra-skein.c
|
||||||
|
cryptonote/src/crypto/hash.c
|
||||||
|
cryptonote/src/crypto/jh.c
|
||||||
|
cryptonote/src/crypto/keccak.c
|
||||||
|
cryptonote/src/crypto/oaes_lib.c
|
||||||
|
cryptonote/src/crypto/random.c
|
||||||
|
cryptonote/src/crypto/skein.c
|
||||||
|
cryptonote/src/crypto/slow-hash.c
|
||||||
|
cryptonote/src/crypto/slow-hash.cpp
|
||||||
|
cryptonote/src/crypto/tree-hash.c
|
||||||
|
cryptonote/src/cryptonote_core/BlockIndex.cpp
|
||||||
|
cryptonote/src/cryptonote_core/CoreConfig.cpp
|
||||||
|
cryptonote/src/cryptonote_core/Currency.cpp
|
||||||
|
cryptonote/src/cryptonote_core/MinerConfig.cpp
|
||||||
|
cryptonote/src/cryptonote_core/Transaction.cpp
|
||||||
|
cryptonote/src/cryptonote_core/account.cpp
|
||||||
|
cryptonote/src/cryptonote_core/blockchain_storage.cpp
|
||||||
|
cryptonote/src/cryptonote_core/checkpoints.cpp
|
||||||
|
cryptonote/src/cryptonote_core/cryptonote_basic_impl.cpp
|
||||||
|
cryptonote/src/cryptonote_core/cryptonote_core.cpp
|
||||||
|
cryptonote/src/cryptonote_core/cryptonote_format_utils.cpp
|
||||||
|
cryptonote/src/cryptonote_core/cryptonote_serialization.cpp
|
||||||
|
cryptonote/src/cryptonote_core/difficulty.cpp
|
||||||
|
cryptonote/src/cryptonote_core/miner.cpp
|
||||||
|
cryptonote/src/cryptonote_core/tx_pool.cpp
|
||||||
|
cryptonote/src/inprocess_node/InProcessNode.cpp
|
||||||
|
cryptonote/src/inprocess_node/InProcessNodeErrors.cpp
|
||||||
|
cryptonote/src/node_rpc_proxy/NodeErrors.cpp
|
||||||
|
cryptonote/src/node_rpc_proxy/NodeRpcProxy.cpp
|
||||||
|
cryptonote/src/p2p/NetNodeConfig.cpp
|
||||||
|
cryptonote/src/serialization/BinaryInputStreamSerializer.cpp
|
||||||
|
cryptonote/src/serialization/BinaryOutputStreamSerializer.cpp
|
||||||
|
cryptonote/src/transfers/BlockchainSynchronizer.cpp
|
||||||
|
cryptonote/src/transfers/SynchronizationState.cpp
|
||||||
|
cryptonote/src/transfers/TransfersConsumer.cpp
|
||||||
|
cryptonote/src/transfers/TransfersContainer.cpp
|
||||||
|
cryptonote/src/transfers/TransfersSubscription.cpp
|
||||||
|
cryptonote/src/transfers/TransfersSynchronizer.cpp
|
||||||
|
cryptonote/src/wallet/KeysStorage.cpp
|
||||||
|
cryptonote/src/wallet/Wallet.cpp
|
||||||
|
cryptonote/src/wallet/WalletAsyncContextCounter.cpp
|
||||||
|
cryptonote/src/wallet/WalletErrors.cpp
|
||||||
|
cryptonote/src/wallet/WalletSerializer.cpp
|
||||||
|
cryptonote/src/wallet/WalletSerialization.cpp
|
||||||
|
cryptonote/src/wallet/WalletTransactionSender.cpp
|
||||||
|
cryptonote/src/wallet/WalletUnconfirmedTransactions.cpp
|
||||||
|
cryptonote/src/wallet/WalletUserTransactionsCache.cpp
|
||||||
|
cryptonote/src/wallet/LegacyKeysImporter.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
file(GLOB_RECURSE SOURCES src/*.cpp)
|
||||||
|
file(GLOB_RECURSE HEADERS src/*.h)
|
||||||
|
file(GLOB_RECURSE FORMS src/gui/ui/*.ui)
|
||||||
|
|
||||||
|
set(QRC src/resources.qrc)
|
||||||
|
|
||||||
|
qt5_wrap_ui(UIS ${FORMS})
|
||||||
|
qt5_add_resources(RCC ${QRC})
|
||||||
|
|
||||||
|
|
||||||
|
if (WIN32)
|
||||||
|
if (NOT MSVC)
|
||||||
|
message(FATAL_ERROR "Only MSVC is supported on this platform")
|
||||||
|
endif ()
|
||||||
|
add_definitions(/D_CRT_SECURE_NO_WARNINGS /D_WIN32_WINNT=0x0600 /DSTATICLIB)
|
||||||
|
include_directories(cryptonote/src/platform/msc)
|
||||||
|
|
||||||
|
set(PLATFORM_DIR Windows)
|
||||||
|
set(BUILD_PLATFORM WIN32)
|
||||||
|
set(BUILD_RESOURCES src/cryptonotewallet.rc)
|
||||||
|
set(QTMAIN Qt5::WinMain)
|
||||||
|
|
||||||
|
elseif (UNIX)
|
||||||
|
set(CRYPTONOTE_SOURCES ${CRYPTONOTE_SOURCES} cryptonote/external/miniupnpc/minissdpc.c)
|
||||||
|
if (APPLE)
|
||||||
|
enable_language(ASM)
|
||||||
|
file(GLOB_RECURSE OBJC_SOURCES src/*.mm)
|
||||||
|
set(SOURCES ${SOURCES} ${OBJC_SOURCES})
|
||||||
|
set(PLATFORM_DIR OSX)
|
||||||
|
set(MACOSX_BUNDLE_INFO_STRING "Cryptonote GUI wallet")
|
||||||
|
set(MACOSX_BUNDLE_LONG_VERSION_STRING "${VERSION_VERSION}.${VERSION_MINOR}.${VERSION_PATCH}")
|
||||||
|
set(MACOSX_BUNDLE_BUNDLE_NAME CryptonoteWallet)
|
||||||
|
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${VERSION_VERSION}.${VERSION_MINOR}.${VERSION_PATCH}")
|
||||||
|
set(MACOSX_BUNDLE_BUNDLE_VERSION "$${VERSION_VERSION}.${VERSION_MINOR}.${VERSION_PATCH}")
|
||||||
|
|
||||||
|
find_package(Qt5PrintSupport REQUIRED)
|
||||||
|
|
||||||
|
include_directories(/usr/include/malloc)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes -std=c++11 -stdlib=libc++")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -maes -D_DARWIN_C_SOURCE")
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -framework Cocoa -framework OpenGL -framework CoreFoundation -framework Carbon -framework IOKit -L/usr/lib")
|
||||||
|
|
||||||
|
set(MACOSX_BUNDLE_ICON_FILE cryptonote.icns)
|
||||||
|
set(APPLICATION_ICON src/images/cryptonote.icns)
|
||||||
|
set_source_files_properties(${APPLICATION_ICON} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
|
||||||
|
|
||||||
|
set(BUILD_PLATFORM MACOSX_BUNDLE)
|
||||||
|
set(BUILD_RESOURCES ${APPLICATION_ICON})
|
||||||
|
|
||||||
|
GET_TARGET_PROPERTY(QT_LIB_DIR "${Qt5Widgets_LIBRARIES}" LOCATION)
|
||||||
|
GET_FILENAME_COMPONENT(QT_LIB_DIR "${QT_LIB_DIR}" PATH)
|
||||||
|
else(APPLE)
|
||||||
|
set(PLATFORM_DIR Linux)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes -std=c++11")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes -std=c11")
|
||||||
|
endif (APPLE)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
include_directories(cryptonote/src/Platform/${PLATFORM_DIR})
|
||||||
|
file(GLOB PLATFORM_SOURCES cryptonote/src/Platform/${PLATFORM_DIR}/System/*)
|
||||||
|
set(CRYPTONOTE_SOURCES ${CRYPTONOTE_SOURCES} ${PLATFORM_SOURCES})
|
||||||
|
|
||||||
|
add_library(${CRYPTONOTE_LIB} STATIC ${CRYPTONOTE_SOURCES})
|
||||||
|
set_target_properties(${CRYPTONOTE_LIB} PROPERTIES COMPILE_DEFINITIONS _GNU_SOURCE)
|
||||||
|
target_link_libraries(${CRYPTONOTE_LIB} ${Boost_LIBRARIES})
|
||||||
|
|
||||||
|
add_executable(${PROJECT_NAME} ${BUILD_PLATFORM} ${BUILD_RESOURCES} ${SOURCES} ${HEADERS} ${UIS} ${RCC})
|
||||||
|
set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_DEFINITIONS _GNU_SOURCE)
|
||||||
|
target_link_libraries(${PROJECT_NAME} ${Boost_LIBRARIES} ${QTMAIN} ${CRYPTONOTE_LIB})
|
||||||
|
|
||||||
|
if (APPLE)
|
||||||
|
qt5_use_modules(${PROJECT_NAME} PrintSupport)
|
||||||
|
elseif (UNIX)
|
||||||
|
target_link_libraries(${PROJECT_NAME} -lpthread)
|
||||||
|
elseif (WIN32)
|
||||||
|
target_link_libraries(${PROJECT_NAME} Imm32 Iphlpapi Winmm)
|
||||||
|
endif (APPLE)
|
||||||
|
|
||||||
|
qt5_use_modules(${PROJECT_NAME} Widgets Gui)
|
4
CryptoNoteWallet.cmake
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
set(CN_PROJECT_NAME "")
|
||||||
|
set(CN_CURRENCY_DISPLAY_NAME "")
|
||||||
|
set(CN_CURRENCY_TICKER "")
|
56
src/CommandLineParser.cpp
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#include <QCoreApplication>
|
||||||
|
|
||||||
|
#include <common/util.h>
|
||||||
|
|
||||||
|
#include "CommandLineParser.h"
|
||||||
|
#include "CurrencyAdapter.h"
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
CommandLineParser::CommandLineParser() : QObject(), m_parser(), m_help_option(m_parser.addHelpOption()),
|
||||||
|
m_version_option(m_parser.addVersionOption()),
|
||||||
|
m_data_dir_option("data-dir", tr("Specify data directory"), tr("directory"), QString::fromStdString(tools::get_default_data_dir())) {
|
||||||
|
m_parser.setApplicationDescription(QString(tr("%1 wallet")).arg(CurrencyAdapter::instance().getCurrencyDisplayName()));
|
||||||
|
m_parser.addHelpOption();
|
||||||
|
m_parser.addVersionOption();
|
||||||
|
m_parser.addOption(m_data_dir_option);
|
||||||
|
}
|
||||||
|
|
||||||
|
CommandLineParser::~CommandLineParser() {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CommandLineParser::process() {
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
return m_parser.parse(QCoreApplication::arguments());
|
||||||
|
#else
|
||||||
|
m_parser.process(*QCoreApplication::instance());
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CommandLineParser::hasHelpOption() const {
|
||||||
|
return m_parser.isSet(m_help_option);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CommandLineParser::hasVersionOption() const {
|
||||||
|
return m_parser.isSet(m_version_option);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CommandLineParser::errorText() const {
|
||||||
|
return m_parser.errorText();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CommandLineParser::helpText() const {
|
||||||
|
return m_parser.helpText();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CommandLineParser::getDataDir() const {
|
||||||
|
return m_parser.value(m_data_dir_option);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
35
src/CommandLineParser.h
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QCommandLineParser>
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
class CommandLineParser : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY(CommandLineParser)
|
||||||
|
|
||||||
|
public:
|
||||||
|
CommandLineParser();
|
||||||
|
~CommandLineParser();
|
||||||
|
|
||||||
|
bool process();
|
||||||
|
|
||||||
|
bool hasHelpOption() const;
|
||||||
|
bool hasVersionOption() const;
|
||||||
|
QString errorText() const;
|
||||||
|
QString helpText() const;
|
||||||
|
QString getDataDir() const;
|
||||||
|
private:
|
||||||
|
QCommandLineParser m_parser;
|
||||||
|
QCommandLineOption m_help_option;
|
||||||
|
QCommandLineOption m_version_option;
|
||||||
|
QCommandLineOption m_data_dir_option;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
265
src/CryptoNote.cpp
Normal file
|
@ -0,0 +1,265 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#include "CryptoNote.h"
|
||||||
|
#include "cryptonote_core/cryptonote_basic_impl.h"
|
||||||
|
#include "cryptonote_core/cryptonote_format_utils.h"
|
||||||
|
#include "cryptonote_core/Currency.h"
|
||||||
|
#include "node_rpc_proxy/NodeRpcProxy.h"
|
||||||
|
#include "cryptonote_core/CoreConfig.h"
|
||||||
|
#include "cryptonote_core/cryptonote_core.h"
|
||||||
|
#include "cryptonote_protocol/cryptonote_protocol_handler.h"
|
||||||
|
#include "inprocess_node/InProcessNode.h"
|
||||||
|
#include "p2p/net_node.h"
|
||||||
|
#include "wallet/Wallet.h"
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
bool parsePaymentId(const std::string& payment_id_str, crypto::hash& payment_id) {
|
||||||
|
cryptonote::blobdata payment_id_data;
|
||||||
|
if (!epee::string_tools::parse_hexstr_to_binbuff(payment_id_str, payment_id_data)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sizeof(crypto::hash) != payment_id_data.size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
payment_id = *reinterpret_cast<const crypto::hash*>(payment_id_data.data());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string convertPaymentId(const std::string& paymentIdString) {
|
||||||
|
if (paymentIdString.empty()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
crypto::hash paymentId;
|
||||||
|
if (!parsePaymentId(paymentIdString, paymentId)) {
|
||||||
|
std::stringstream errorStr;
|
||||||
|
errorStr << "Payment id has invalid format: \"" + paymentIdString + "\", expected 64-character string";
|
||||||
|
throw std::runtime_error(errorStr.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint8_t> extra;
|
||||||
|
std::string extra_nonce;
|
||||||
|
cryptonote::set_payment_id_to_tx_extra_nonce(extra_nonce, paymentId);
|
||||||
|
if (!cryptonote::add_extra_nonce_to_tx_extra(extra, extra_nonce)) {
|
||||||
|
std::stringstream errorStr;
|
||||||
|
errorStr << "Something went wrong with payment_id. Please check its format: \"" + paymentIdString + "\", expected 64-character string";
|
||||||
|
throw std::runtime_error(errorStr.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::string(extra.begin(), extra.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string extractPaymentId(const std::string& extra) {
|
||||||
|
std::vector<cryptonote::tx_extra_field> extraFields;
|
||||||
|
std::vector<uint8_t> extraVector;
|
||||||
|
std::copy(extra.begin(), extra.end(), std::back_inserter(extraVector));
|
||||||
|
|
||||||
|
if (!cryptonote::parse_tx_extra(extraVector, extraFields)) {
|
||||||
|
throw std::runtime_error("Can't parse extra");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string result;
|
||||||
|
cryptonote::tx_extra_nonce extra_nonce;
|
||||||
|
if (cryptonote::find_tx_extra_field_by_type(extraFields, extra_nonce)) {
|
||||||
|
crypto::hash paymentIdHash;
|
||||||
|
if (cryptonote::get_payment_id_from_tx_extra_nonce(extra_nonce.nonce, paymentIdHash)) {
|
||||||
|
unsigned char* buff = reinterpret_cast<unsigned char *>(&paymentIdHash);
|
||||||
|
for (size_t i = 0; i < sizeof(paymentIdHash); ++i) {
|
||||||
|
result.push_back("0123456789ABCDEF"[buff[i] >> 4]);
|
||||||
|
result.push_back("0123456789ABCDEF"[buff[i] & 15]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Node::~Node() {
|
||||||
|
}
|
||||||
|
|
||||||
|
class RpcNode : CryptoNote::INodeObserver, public Node {
|
||||||
|
public:
|
||||||
|
RpcNode(const cryptonote::Currency& currency, INodeCallback& callback, const std::string& nodeHost, unsigned short nodePort) :
|
||||||
|
m_callback(callback),
|
||||||
|
m_currency(currency),
|
||||||
|
m_node(nodeHost, nodePort) {
|
||||||
|
m_node.addObserver(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
~RpcNode() override {
|
||||||
|
}
|
||||||
|
|
||||||
|
void init(const std::function<void(std::error_code)>& callback) override {
|
||||||
|
m_node.init(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
void deinit() override {
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string convertPaymentId(const std::string& paymentIdString) override {
|
||||||
|
return WalletGui::convertPaymentId(paymentIdString);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string extractPaymentId(const std::string& extra) override {
|
||||||
|
return WalletGui::extractPaymentId(extra);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t getLastKnownBlockHeight() const override {
|
||||||
|
return m_node.getLastKnownBlockHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t getLastLocalBlockHeight() const override {
|
||||||
|
return m_node.getLastLocalBlockHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t getLastLocalBlockTimestamp() const override {
|
||||||
|
return m_node.getLastLocalBlockTimestamp();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t getPeerCount() const override {
|
||||||
|
return m_node.getPeerCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
CryptoNote::IWallet* createWallet() override {
|
||||||
|
return new CryptoNote::Wallet(m_currency, m_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
INodeCallback& m_callback;
|
||||||
|
const cryptonote::Currency& m_currency;
|
||||||
|
cryptonote::NodeRpcProxy m_node;
|
||||||
|
|
||||||
|
void peerCountUpdated(size_t count) {
|
||||||
|
m_callback.peerCountUpdated(*this, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void localBlockchainUpdated(uint64_t height) {
|
||||||
|
m_callback.localBlockchainUpdated(*this, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lastKnownBlockHeightUpdated(uint64_t height) {
|
||||||
|
m_callback.lastKnownBlockHeightUpdated(*this, height);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class InprocessNode : CryptoNote::INodeObserver, public Node {
|
||||||
|
public:
|
||||||
|
InprocessNode(const cryptonote::Currency& currency, INodeCallback& callback, const cryptonote::CoreConfig& coreConfig) :
|
||||||
|
m_callback(callback),
|
||||||
|
m_currency(currency),
|
||||||
|
m_coreConfig(coreConfig),
|
||||||
|
m_core(m_currency, nullptr),
|
||||||
|
m_protocolHandler(m_core, nullptr),
|
||||||
|
m_nodeServer(m_protocolHandler),
|
||||||
|
m_node(m_core, m_protocolHandler) {
|
||||||
|
|
||||||
|
m_core.set_cryptonote_protocol(&m_protocolHandler);
|
||||||
|
m_protocolHandler.set_p2p_endpoint(&m_nodeServer);
|
||||||
|
cryptonote::checkpoints checkpoints;
|
||||||
|
for (const cryptonote::CheckpointData& checkpoint : cryptonote::CHECKPOINTS) {
|
||||||
|
checkpoints.add_checkpoint(checkpoint.height, checkpoint.blockId);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_core.set_checkpoints(std::move(checkpoints));
|
||||||
|
}
|
||||||
|
|
||||||
|
~InprocessNode() override {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void init(const std::function<void(std::error_code)>& callback) override {
|
||||||
|
if (!m_core.init(m_coreConfig, cryptonote::MinerConfig(), true)) {
|
||||||
|
callback(make_error_code(cryptonote::error::NOT_INITIALIZED));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!m_nodeServer.init(nodetool::NetNodeConfig(), false)) {
|
||||||
|
m_core.deinit();
|
||||||
|
callback(make_error_code(cryptonote::error::NOT_INITIALIZED));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_node.init([this, callback](std::error_code ec) {
|
||||||
|
m_node.addObserver(this);
|
||||||
|
callback(ec);
|
||||||
|
});
|
||||||
|
m_nodeServer.run();
|
||||||
|
|
||||||
|
m_nodeServer.deinit();
|
||||||
|
m_core.deinit();
|
||||||
|
m_node.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
void deinit() override {
|
||||||
|
m_nodeServer.send_stop_signal();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string convertPaymentId(const std::string& paymentIdString) override {
|
||||||
|
return WalletGui::convertPaymentId(paymentIdString);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string extractPaymentId(const std::string& extra) override {
|
||||||
|
return WalletGui::extractPaymentId(extra);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t getLastKnownBlockHeight() const override {
|
||||||
|
return m_node.getLastKnownBlockHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t getLastLocalBlockHeight() const override {
|
||||||
|
return m_node.getLastLocalBlockHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t getLastLocalBlockTimestamp() const override {
|
||||||
|
return m_node.getLastLocalBlockTimestamp();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t getPeerCount() const override {
|
||||||
|
return m_node.getPeerCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
CryptoNote::IWallet* createWallet() override {
|
||||||
|
return new CryptoNote::Wallet(m_currency, m_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
INodeCallback& m_callback;
|
||||||
|
const cryptonote::Currency& m_currency;
|
||||||
|
cryptonote::CoreConfig m_coreConfig;
|
||||||
|
cryptonote::core m_core;
|
||||||
|
cryptonote::t_cryptonote_protocol_handler<cryptonote::core> m_protocolHandler;
|
||||||
|
nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core>> m_nodeServer;
|
||||||
|
CryptoNote::InProcessNode m_node;
|
||||||
|
std::future<bool> m_nodeServerFuture;
|
||||||
|
|
||||||
|
void peerCountUpdated(size_t count) {
|
||||||
|
m_callback.peerCountUpdated(*this, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void localBlockchainUpdated(uint64_t height) {
|
||||||
|
m_callback.localBlockchainUpdated(*this, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lastKnownBlockHeightUpdated(uint64_t height) {
|
||||||
|
m_callback.lastKnownBlockHeightUpdated(*this, height);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Node* createRpcNode(const cryptonote::Currency& currency, INodeCallback& callback, const std::string& nodeHost, unsigned short nodePort) {
|
||||||
|
return new RpcNode(currency, callback, nodeHost, nodePort);
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* createInprocessNode(const cryptonote::Currency& currency, INodeCallback& callback, const cryptonote::CoreConfig& coreConfig) {
|
||||||
|
return new InprocessNode(currency, callback, coreConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
56
src/CryptoNote.h
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <system_error>
|
||||||
|
|
||||||
|
#include <cryptonote_core/CoreConfig.h>
|
||||||
|
|
||||||
|
namespace cryptonote {
|
||||||
|
|
||||||
|
class Currency;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CryptoNote {
|
||||||
|
|
||||||
|
class INode;
|
||||||
|
class IWallet;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
class Node {
|
||||||
|
public:
|
||||||
|
virtual ~Node() = 0;
|
||||||
|
virtual void init(const std::function<void(std::error_code)>& callback) = 0;
|
||||||
|
virtual void deinit() = 0;
|
||||||
|
|
||||||
|
virtual std::string convertPaymentId(const std::string& paymentIdString) = 0;
|
||||||
|
virtual std::string extractPaymentId(const std::string& extra) = 0;
|
||||||
|
virtual uint64_t getLastKnownBlockHeight() const = 0;
|
||||||
|
virtual uint64_t getLastLocalBlockHeight() const = 0;
|
||||||
|
virtual uint64_t getLastLocalBlockTimestamp() const = 0;
|
||||||
|
virtual uint64_t getPeerCount() const = 0;
|
||||||
|
|
||||||
|
virtual CryptoNote::IWallet* createWallet() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class INodeCallback {
|
||||||
|
public:
|
||||||
|
virtual void peerCountUpdated(Node& node, size_t count) = 0;
|
||||||
|
virtual void localBlockchainUpdated(Node& node, uint64_t height) = 0;
|
||||||
|
virtual void lastKnownBlockHeightUpdated(Node& node, uint64_t height) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
Node* createRpcNode(const cryptonote::Currency& currency, INodeCallback& callback, const std::string& nodeHost, unsigned short nodePort);
|
||||||
|
Node* createInprocessNode(const cryptonote::Currency& currency, INodeCallback& callback, const cryptonote::CoreConfig& coreConfig);
|
||||||
|
|
||||||
|
}
|
9
src/CryptoNoteWalletConfig.h.in
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
const char WALLET_CURRENCY_DISPLAY_NAME[] = "@CN_CURRENCY_DISPLAY_NAME@";
|
||||||
|
const char WALLET_CURRENCY_TICKER[] = "@CN_CURRENCY_TICKER@";
|
||||||
|
|
||||||
|
}
|
105
src/CurrencyAdapter.cpp
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#include "CurrencyAdapter.h"
|
||||||
|
#include "CryptoNoteWalletConfig.h"
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
CurrencyAdapter& CurrencyAdapter::instance() {
|
||||||
|
static CurrencyAdapter inst;
|
||||||
|
return inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
CurrencyAdapter::CurrencyAdapter() : m_currency(cryptonote::CurrencyBuilder().currency()) {
|
||||||
|
}
|
||||||
|
|
||||||
|
CurrencyAdapter::~CurrencyAdapter() {
|
||||||
|
}
|
||||||
|
|
||||||
|
const cryptonote::Currency& CurrencyAdapter::getCurrency() {
|
||||||
|
return m_currency;
|
||||||
|
}
|
||||||
|
|
||||||
|
quintptr CurrencyAdapter::getNumberOfDecimalPlaces() const {
|
||||||
|
return m_currency.numberOfDecimalPlaces();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CurrencyAdapter::getCurrencyDisplayName() const {
|
||||||
|
return WALLET_CURRENCY_DISPLAY_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CurrencyAdapter::getCurrencyName() const {
|
||||||
|
return cryptonote::CRYPTONOTE_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CurrencyAdapter::getCurrencyTicker() const {
|
||||||
|
return WALLET_CURRENCY_TICKER;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CurrencyAdapter::formatAmount(quint64 _amount) const {
|
||||||
|
QString result = QString::number(_amount);
|
||||||
|
if (result.length() < getNumberOfDecimalPlaces() + 1) {
|
||||||
|
result = result.rightJustified(getNumberOfDecimalPlaces() + 1, '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
quint32 dot_pos = result.length() - getNumberOfDecimalPlaces();
|
||||||
|
for (quint32 pos = result.length() - 1; pos > dot_pos + 1; --pos) {
|
||||||
|
if (result[pos] == '0') {
|
||||||
|
result.remove(pos, 1);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result.insert(dot_pos, ".");
|
||||||
|
for (qint32 pos = dot_pos - 3; pos > 0; pos -= 3) {
|
||||||
|
if (result[pos - 1].isDigit()) {
|
||||||
|
result.insert(pos, ',');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
quint64 CurrencyAdapter::parseAmount(const QString& _amountString) const {
|
||||||
|
QString amountString = _amountString.trimmed();
|
||||||
|
amountString.remove(',');
|
||||||
|
|
||||||
|
int pointIndex = amountString.indexOf('.');
|
||||||
|
int fractionSize;
|
||||||
|
if (pointIndex != -1) {
|
||||||
|
fractionSize = amountString.length() - pointIndex - 1;
|
||||||
|
while (getNumberOfDecimalPlaces() < fractionSize && amountString.right(1) == "0") {
|
||||||
|
amountString.remove(amountString.length() - 1, 1);
|
||||||
|
--fractionSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getNumberOfDecimalPlaces() < fractionSize) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
amountString.remove(pointIndex, 1);
|
||||||
|
} else {
|
||||||
|
fractionSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (amountString.isEmpty()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (qint32 i = 0; i < getNumberOfDecimalPlaces() - fractionSize; ++i) {
|
||||||
|
amountString.append('0');
|
||||||
|
}
|
||||||
|
|
||||||
|
return amountString.toULongLong();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CurrencyAdapter::validateAddress(const QString& _address) const {
|
||||||
|
cryptonote::AccountPublicAddress internalAddress;
|
||||||
|
return m_currency.parseAccountAddressString(_address.toStdString(), internalAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
35
src/CurrencyAdapter.h
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
#include "cryptonote_core/Currency.h"
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
class CurrencyAdapter {
|
||||||
|
|
||||||
|
public:
|
||||||
|
static CurrencyAdapter& instance();
|
||||||
|
|
||||||
|
const cryptonote::Currency& getCurrency();
|
||||||
|
QString getCurrencyDisplayName() const;
|
||||||
|
QString getCurrencyName() const;
|
||||||
|
QString getCurrencyTicker() const;
|
||||||
|
quintptr getNumberOfDecimalPlaces() const;
|
||||||
|
QString formatAmount(quint64 _amount) const;
|
||||||
|
quint64 parseAmount(const QString& _amountString) const;
|
||||||
|
bool validateAddress(const QString& _address) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
cryptonote::Currency m_currency;
|
||||||
|
|
||||||
|
CurrencyAdapter();
|
||||||
|
~CurrencyAdapter();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
216
src/NodeAdapter.cpp
Normal file
|
@ -0,0 +1,216 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QUrl>
|
||||||
|
|
||||||
|
#include <wallet/WalletErrors.h>
|
||||||
|
|
||||||
|
#include "CurrencyAdapter.h"
|
||||||
|
#include "NodeAdapter.h"
|
||||||
|
#include "Settings.h"
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
class InProcessNodeInitializer : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY(InProcessNodeInitializer)
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void nodeInitCompletedSignal();
|
||||||
|
void nodeInitFailedSignal(int _errorCode);
|
||||||
|
void nodeDeinitCompletedSignal();
|
||||||
|
|
||||||
|
public:
|
||||||
|
InProcessNodeInitializer(QObject* _parent = nullptr) {
|
||||||
|
}
|
||||||
|
|
||||||
|
~InProcessNodeInitializer() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void start(Node** _node, const cryptonote::Currency* currency, INodeCallback* _callback, const cryptonote::CoreConfig& _coreConfig) {
|
||||||
|
(*_node) = createInprocessNode(*currency, *_callback, _coreConfig);
|
||||||
|
try {
|
||||||
|
(*_node)->init([this](std::error_code _err) {
|
||||||
|
if (_err) {
|
||||||
|
Q_EMIT nodeInitFailedSignal(_err.value());
|
||||||
|
QCoreApplication::processEvents();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_EMIT nodeInitCompletedSignal();
|
||||||
|
QCoreApplication::processEvents();
|
||||||
|
});
|
||||||
|
} catch (std::runtime_error& err) {
|
||||||
|
Q_EMIT nodeInitFailedSignal(cryptonote::error::INTERNAL_WALLET_ERROR);
|
||||||
|
QCoreApplication::processEvents();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete *_node;
|
||||||
|
*_node = nullptr;
|
||||||
|
Q_EMIT nodeDeinitCompletedSignal();
|
||||||
|
}
|
||||||
|
|
||||||
|
void stop(Node** _node) {
|
||||||
|
Q_CHECK_PTR(*_node);
|
||||||
|
(*_node)->deinit();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
NodeAdapter& NodeAdapter::instance() {
|
||||||
|
static NodeAdapter inst;
|
||||||
|
return inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeAdapter::NodeAdapter() : QObject(), m_node(nullptr), m_nodeInitializerThread(), m_nodeInitializer(new InProcessNodeInitializer) {
|
||||||
|
m_nodeInitializer->moveToThread(&m_nodeInitializerThread);
|
||||||
|
|
||||||
|
qRegisterMetaType<cryptonote::CoreConfig>("cryptonote::CoreConfig");
|
||||||
|
|
||||||
|
connect(m_nodeInitializer, &InProcessNodeInitializer::nodeInitCompletedSignal, this, &NodeAdapter::nodeInitCompletedSignal, Qt::QueuedConnection);
|
||||||
|
connect(this, &NodeAdapter::initNodeSignal, m_nodeInitializer, &InProcessNodeInitializer::start, Qt::QueuedConnection);
|
||||||
|
connect(this, &NodeAdapter::deinitNodeSignal, m_nodeInitializer, &InProcessNodeInitializer::stop, Qt::QueuedConnection);
|
||||||
|
|
||||||
|
QString logFileName = QCoreApplication::applicationName() + ".log";
|
||||||
|
epee::log_space::log_singletone::add_logger(LOGGER_FILE, logFileName.toLocal8Bit(),
|
||||||
|
Settings::instance().getDataDir().absolutePath().toLocal8Bit());
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeAdapter::~NodeAdapter() {
|
||||||
|
}
|
||||||
|
|
||||||
|
quintptr NodeAdapter::getPeerCount() const {
|
||||||
|
Q_ASSERT(m_node != nullptr);
|
||||||
|
return m_node->getPeerCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string NodeAdapter::convertPaymentId(const QString& _paymentIdString) const {
|
||||||
|
Q_CHECK_PTR(m_node);
|
||||||
|
try {
|
||||||
|
return m_node->convertPaymentId(_paymentIdString.toStdString());
|
||||||
|
} catch (std::runtime_error& err) {
|
||||||
|
}
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString NodeAdapter::extractPaymentId(const std::string& _extra) const {
|
||||||
|
Q_CHECK_PTR(m_node);
|
||||||
|
return QString::fromStdString(m_node->extractPaymentId(_extra));
|
||||||
|
}
|
||||||
|
|
||||||
|
CryptoNote::IWallet* NodeAdapter::createWallet() const {
|
||||||
|
Q_CHECK_PTR(m_node);
|
||||||
|
return m_node->createWallet();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NodeAdapter::init() {
|
||||||
|
Q_ASSERT(m_node == nullptr);
|
||||||
|
// TODO Insert the right URL for the local daemon
|
||||||
|
QUrl localNodeUrl = QUrl::fromUserInput("");
|
||||||
|
|
||||||
|
m_node = createRpcNode(CurrencyAdapter::instance().getCurrency(), *this, localNodeUrl.host().toStdString(), localNodeUrl.port());
|
||||||
|
|
||||||
|
QTimer initTimer;
|
||||||
|
initTimer.setInterval(3000);
|
||||||
|
initTimer.setSingleShot(true);
|
||||||
|
initTimer.start();
|
||||||
|
m_node->init([this](std::error_code _err) {
|
||||||
|
Q_UNUSED(_err);
|
||||||
|
});
|
||||||
|
QEventLoop waitLoop;
|
||||||
|
connect(&initTimer, &QTimer::timeout, &waitLoop, &QEventLoop::quit);
|
||||||
|
connect(this, &NodeAdapter::peerCountUpdatedSignal, &waitLoop, &QEventLoop::quit);
|
||||||
|
connect(this, &NodeAdapter::localBlockchainUpdatedSignal, &waitLoop, &QEventLoop::quit);
|
||||||
|
waitLoop.exec();
|
||||||
|
if (initTimer.isActive()) {
|
||||||
|
initTimer.stop();
|
||||||
|
Q_EMIT nodeInitCompletedSignal();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete m_node;
|
||||||
|
m_node = nullptr;
|
||||||
|
return initInProcessNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
quint64 NodeAdapter::getLastKnownBlockHeight() const {
|
||||||
|
Q_CHECK_PTR(m_node);
|
||||||
|
return m_node->getLastKnownBlockHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
quint64 NodeAdapter::getLastLocalBlockHeight() const {
|
||||||
|
Q_CHECK_PTR(m_node);
|
||||||
|
return m_node->getLastLocalBlockHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
QDateTime NodeAdapter::getLastLocalBlockTimestamp() const {
|
||||||
|
Q_CHECK_PTR(m_node);
|
||||||
|
return QDateTime::fromTime_t(m_node->getLastLocalBlockTimestamp(), Qt::UTC);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeAdapter::peerCountUpdated(Node& _node, size_t _count) {
|
||||||
|
Q_UNUSED(_node);
|
||||||
|
Q_EMIT peerCountUpdatedSignal(_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeAdapter::localBlockchainUpdated(Node& _node, uint64_t _height) {
|
||||||
|
Q_UNUSED(_node);
|
||||||
|
Q_EMIT localBlockchainUpdatedSignal(_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeAdapter::lastKnownBlockHeightUpdated(Node& _node, uint64_t _height) {
|
||||||
|
Q_UNUSED(_node);
|
||||||
|
Q_EMIT lastKnownBlockHeightUpdatedSignal(_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NodeAdapter::initInProcessNode() {
|
||||||
|
Q_ASSERT(m_node == nullptr);
|
||||||
|
m_nodeInitializerThread.start();
|
||||||
|
cryptonote::CoreConfig coreConfig = makeCoreConfig();
|
||||||
|
Q_EMIT initNodeSignal(&m_node, &CurrencyAdapter::instance().getCurrency(), this, coreConfig);
|
||||||
|
QEventLoop waitLoop;
|
||||||
|
connect(m_nodeInitializer, &InProcessNodeInitializer::nodeInitCompletedSignal, &waitLoop, &QEventLoop::quit);
|
||||||
|
connect(m_nodeInitializer, &InProcessNodeInitializer::nodeInitFailedSignal, &waitLoop, &QEventLoop::exit);
|
||||||
|
if (waitLoop.exec() != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_EMIT localBlockchainUpdatedSignal(getLastLocalBlockHeight());
|
||||||
|
Q_EMIT lastKnownBlockHeightUpdatedSignal(getLastKnownBlockHeight());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeAdapter::deinit() {
|
||||||
|
if (m_node != nullptr) {
|
||||||
|
if (m_nodeInitializerThread.isRunning()) {
|
||||||
|
m_nodeInitializer->stop(&m_node);
|
||||||
|
QEventLoop waitLoop;
|
||||||
|
connect(m_nodeInitializer, &InProcessNodeInitializer::nodeDeinitCompletedSignal, &waitLoop, &QEventLoop::quit, Qt::QueuedConnection);
|
||||||
|
waitLoop.exec();
|
||||||
|
m_nodeInitializerThread.quit();
|
||||||
|
m_nodeInitializerThread.wait();
|
||||||
|
} else {
|
||||||
|
delete m_node;
|
||||||
|
m_node = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cryptonote::CoreConfig NodeAdapter::makeCoreConfig() const {
|
||||||
|
cryptonote::CoreConfig config;
|
||||||
|
boost::program_options::variables_map options;
|
||||||
|
boost::any dataDir = Settings::instance().getDataDir().absolutePath().toStdString();
|
||||||
|
options.insert(std::make_pair("data-dir", boost::program_options::variable_value(dataDir, false)));
|
||||||
|
config.init(options);
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "NodeAdapter.moc"
|
67
src/NodeAdapter.h
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QThread>
|
||||||
|
|
||||||
|
#include <INode.h>
|
||||||
|
#include <IWallet.h>
|
||||||
|
|
||||||
|
#include "CryptoNote.h"
|
||||||
|
|
||||||
|
namespace cryptonote {
|
||||||
|
|
||||||
|
class Currency;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
class InProcessNodeInitializer;
|
||||||
|
|
||||||
|
class NodeAdapter : public QObject, public INodeCallback {
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY(NodeAdapter)
|
||||||
|
|
||||||
|
public:
|
||||||
|
static NodeAdapter& instance();
|
||||||
|
|
||||||
|
quintptr getPeerCount() const;
|
||||||
|
std::string convertPaymentId(const QString& _payment_id_string) const;
|
||||||
|
QString extractPaymentId(const std::string& _extra) const;
|
||||||
|
CryptoNote::IWallet* createWallet() const;
|
||||||
|
|
||||||
|
bool init();
|
||||||
|
void deinit();
|
||||||
|
quint64 getLastKnownBlockHeight() const;
|
||||||
|
quint64 getLastLocalBlockHeight() const;
|
||||||
|
QDateTime getLastLocalBlockTimestamp() const;
|
||||||
|
void peerCountUpdated(Node& _node, size_t _count) Q_DECL_OVERRIDE;
|
||||||
|
void localBlockchainUpdated(Node& _node, uint64_t _height) Q_DECL_OVERRIDE;
|
||||||
|
void lastKnownBlockHeightUpdated(Node& _node, uint64_t _height) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Node* m_node;
|
||||||
|
QThread m_nodeInitializerThread;
|
||||||
|
InProcessNodeInitializer* m_nodeInitializer;
|
||||||
|
|
||||||
|
NodeAdapter();
|
||||||
|
~NodeAdapter();
|
||||||
|
|
||||||
|
bool initInProcessNode();
|
||||||
|
cryptonote::CoreConfig makeCoreConfig() const;
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void localBlockchainUpdatedSignal(quint64 _height);
|
||||||
|
void lastKnownBlockHeightUpdatedSignal(quint64 _height);
|
||||||
|
void nodeInitCompletedSignal();
|
||||||
|
void peerCountUpdatedSignal(quintptr _count);
|
||||||
|
void initNodeSignal(Node** _node, const cryptonote::Currency* currency, INodeCallback* _callback, const cryptonote::CoreConfig& _core_config);
|
||||||
|
void deinitNodeSignal(Node** _node);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
225
src/Settings.cpp
Normal file
|
@ -0,0 +1,225 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QSettings>
|
||||||
|
#include <QStandardPaths>
|
||||||
|
#include <QTextCodec>
|
||||||
|
|
||||||
|
#include <common/util.h>
|
||||||
|
|
||||||
|
#include "CommandLineParser.h"
|
||||||
|
#include "CurrencyAdapter.h"
|
||||||
|
#include "Settings.h"
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
Settings& Settings::instance() {
|
||||||
|
static Settings inst;
|
||||||
|
return inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
Settings::Settings() : QObject(), m_cmdLineParser(nullptr) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Settings::~Settings() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void Settings::setCommandLineParser(CommandLineParser* _cmdLineParser) {
|
||||||
|
Q_CHECK_PTR(_cmdLineParser);
|
||||||
|
m_cmdLineParser = _cmdLineParser;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Settings::load() {
|
||||||
|
QFile cfgFile(getDataDir().absoluteFilePath(QCoreApplication::applicationName() + ".cfg"));
|
||||||
|
if (cfgFile.open(QIODevice::ReadOnly)) {
|
||||||
|
m_settings = QJsonDocument::fromJson(cfgFile.readAll()).object();
|
||||||
|
cfgFile.close();
|
||||||
|
if (!m_settings.contains("walletFile")) {
|
||||||
|
m_addressBookFile = getDataDir().absoluteFilePath(QCoreApplication::applicationName() + ".addressbook");
|
||||||
|
} else {
|
||||||
|
m_addressBookFile = m_settings.value("walletFile").toString();
|
||||||
|
m_addressBookFile.replace(m_addressBookFile.lastIndexOf(".wallet"), 7, ".addressbook");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m_addressBookFile = getDataDir().absoluteFilePath(QCoreApplication::applicationName() + ".addressbook");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QDir Settings::getDataDir() const {
|
||||||
|
Q_CHECK_PTR(m_cmdLineParser);
|
||||||
|
return QDir(m_cmdLineParser->getDataDir());
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Settings::getWalletFile() const {
|
||||||
|
return m_settings.contains("walletFile") ? m_settings.value("walletFile").toString() :
|
||||||
|
getDataDir().absoluteFilePath(QCoreApplication::applicationName() + ".wallet");
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Settings::getAddressBookFile() const {
|
||||||
|
return m_addressBookFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Settings::isEncrypted() const {
|
||||||
|
return m_settings.contains("encrypted") ? m_settings.value("encrypted").toBool() : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Settings::getVersion() const {
|
||||||
|
return GIT_REVISION;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Settings::isStartOnLoginEnabled() const {
|
||||||
|
bool res = false;
|
||||||
|
#ifdef Q_OS_MAC
|
||||||
|
QDir autorunDir = QDir::home();
|
||||||
|
if (!autorunDir.cd("Library") || !autorunDir.cd("LaunchAgents")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString autorunFilePath = autorunDir.absoluteFilePath(QCoreApplication::applicationName() + ".plist");
|
||||||
|
if (!QFile::exists(autorunFilePath)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSettings autorunSettings(autorunFilePath, QSettings::NativeFormat);
|
||||||
|
res = autorunSettings.value("RunAtLoad", false).toBool();
|
||||||
|
#elif defined(Q_OS_LINUX)
|
||||||
|
QString configPath = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation);
|
||||||
|
if (configPath.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDir autorunDir(configPath);
|
||||||
|
if (!autorunDir.cd("autostart")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString autorunFilePath = autorunDir.absoluteFilePath(QCoreApplication::applicationName() + ".desktop");
|
||||||
|
res = QFile::exists(autorunFilePath);
|
||||||
|
#elif defined(Q_OS_WIN)
|
||||||
|
QSettings autorunSettings("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::NativeFormat);
|
||||||
|
QString keyName = QString("%1Wallet").arg(CurrencyAdapter::instance().getCurrencyDisplayName());
|
||||||
|
res = autorunSettings.contains(keyName) &&
|
||||||
|
!QDir::fromNativeSeparators(autorunSettings.value(keyName).toString()).compare(QApplication::applicationFilePath());
|
||||||
|
#endif
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
bool Settings::isMinimizeToTrayEnabled() const {
|
||||||
|
return m_settings.contains("minimizeToTray") ? m_settings.value("minimizeToTray").toBool() : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Settings::isCloseToTrayEnabled() const {
|
||||||
|
return m_settings.contains("closeToTray") ? m_settings.value("closeToTray").toBool() : false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void Settings::setWalletFile(const QString& _file) {
|
||||||
|
if (_file.endsWith(".wallet") || _file.endsWith(".keys")) {
|
||||||
|
m_settings.insert("walletFile", _file);
|
||||||
|
} else {
|
||||||
|
m_settings.insert("walletFile", _file + ".wallet");
|
||||||
|
}
|
||||||
|
|
||||||
|
saveSettings();
|
||||||
|
m_addressBookFile = m_settings.value("walletFile").toString();
|
||||||
|
m_addressBookFile.replace(m_addressBookFile.lastIndexOf(".wallet"), 7, ".addressbook");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Settings::setEncrypted(bool _encrypted) {
|
||||||
|
if (isEncrypted() != _encrypted) {
|
||||||
|
m_settings.insert("encrypted", _encrypted);
|
||||||
|
saveSettings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Settings::setCurrentTheme(const QString& _theme) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void Settings::setStartOnLoginEnabled(bool _enable) {
|
||||||
|
#ifdef Q_OS_MAC
|
||||||
|
QDir autorunDir = QDir::home();
|
||||||
|
if (!autorunDir.cd("Library") || !autorunDir.cd("LaunchAgents")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString autorunFilePath = autorunDir.absoluteFilePath(QCoreApplication::applicationName() + ".plist");
|
||||||
|
QSettings autorunSettings(autorunFilePath, QSettings::NativeFormat);
|
||||||
|
autorunSettings.setValue("Label", "org." + QCoreApplication::applicationName());
|
||||||
|
autorunSettings.setValue("Program", QApplication::applicationFilePath());
|
||||||
|
autorunSettings.setValue("RunAtLoad", _enable);
|
||||||
|
autorunSettings.setValue("ProcessType", "InterActive");
|
||||||
|
#elif defined(Q_OS_LINUX)
|
||||||
|
QString configPath = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation);
|
||||||
|
if (configPath.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDir autorunDir(configPath);
|
||||||
|
if(!autorunDir.exists("autostart")) {
|
||||||
|
autorunDir.mkdir("autostart");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!autorunDir.cd("autostart")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString autorunFilePath = autorunDir.absoluteFilePath(QCoreApplication::applicationName() + ".desktop");
|
||||||
|
QFile autorunFile(autorunFilePath);
|
||||||
|
if (!autorunFile.open(QFile::WriteOnly | QFile::Truncate)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_enable) {
|
||||||
|
autorunFile.write("[Desktop Entry]\n");
|
||||||
|
autorunFile.write("Type=Application\n");
|
||||||
|
autorunFile.write(QString("Name=%1 Wallet\n").arg(CurrencyAdapter::instance().getCurrencyDisplayName()).toLocal8Bit());
|
||||||
|
autorunFile.write(QString("Exec=%1\n").arg(QApplication::applicationFilePath()).toLocal8Bit());
|
||||||
|
autorunFile.write("Terminal=false\n");
|
||||||
|
autorunFile.write("Hidden=false\n");
|
||||||
|
autorunFile.close();
|
||||||
|
} else {
|
||||||
|
QFile::remove(autorunFilePath);
|
||||||
|
}
|
||||||
|
#elif defined(Q_OS_WIN)
|
||||||
|
QSettings autorunSettings("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::NativeFormat);
|
||||||
|
QString keyName = QString("%1Wallet").arg(CurrencyAdapter::instance().getCurrencyDisplayName());
|
||||||
|
if (_enable) {
|
||||||
|
autorunSettings.setValue(keyName, QDir::toNativeSeparators(QApplication::applicationFilePath()));
|
||||||
|
} else {
|
||||||
|
autorunSettings.remove(keyName);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
void Settings::setMinimizeToTrayEnabled(bool _enable) {
|
||||||
|
if (isMinimizeToTrayEnabled() != _enable) {
|
||||||
|
m_settings.insert("minimizeToTray", _enable);
|
||||||
|
saveSettings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Settings::setCloseToTrayEnabled(bool _enable) {
|
||||||
|
if (isCloseToTrayEnabled() != _enable) {
|
||||||
|
m_settings.insert("closeToTray", _enable);
|
||||||
|
saveSettings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void Settings::saveSettings() const {
|
||||||
|
QFile cfgFile(getDataDir().absoluteFilePath(QCoreApplication::applicationName() + ".cfg"));
|
||||||
|
if (cfgFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
|
||||||
|
QJsonDocument cfg_doc(m_settings);
|
||||||
|
cfgFile.write(cfg_doc.toJson());
|
||||||
|
cfgFile.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
57
src/Settings.h
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QDir>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
class CommandLineParser;
|
||||||
|
|
||||||
|
class Settings : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY(Settings)
|
||||||
|
|
||||||
|
public:
|
||||||
|
static Settings& instance();
|
||||||
|
|
||||||
|
void setCommandLineParser(CommandLineParser* _cmd_line_parser);
|
||||||
|
void load();
|
||||||
|
|
||||||
|
QDir getDataDir() const;
|
||||||
|
QString getWalletFile() const;
|
||||||
|
QString getAddressBookFile() const;
|
||||||
|
bool isEncrypted() const;
|
||||||
|
QString getVersion() const;
|
||||||
|
bool isStartOnLoginEnabled() const;
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
bool isMinimizeToTrayEnabled() const;
|
||||||
|
bool isCloseToTrayEnabled() const;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void setWalletFile(const QString& _file);
|
||||||
|
void setEncrypted(bool _encrypted);
|
||||||
|
void setCurrentTheme(const QString& _theme);
|
||||||
|
void setStartOnLoginEnabled(bool _enable);
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
void setMinimizeToTrayEnabled(bool _enable);
|
||||||
|
void setCloseToTrayEnabled(bool _enable);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
QJsonObject m_settings;
|
||||||
|
QString m_addressBookFile;
|
||||||
|
CommandLineParser* m_cmdLineParser;
|
||||||
|
|
||||||
|
Settings();
|
||||||
|
~Settings();
|
||||||
|
|
||||||
|
void saveSettings() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
32
src/SignalHandler.cpp
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#include <csignal>
|
||||||
|
|
||||||
|
#include "SignalHandler.h"
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
SignalHandler& SignalHandler::instance() {
|
||||||
|
static SignalHandler inst;
|
||||||
|
return inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
SignalHandler::SignalHandler() : QObject() {
|
||||||
|
}
|
||||||
|
|
||||||
|
SignalHandler::~SignalHandler() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignalHandler::init() {
|
||||||
|
std::signal(SIGINT, SignalHandler::sigHandler);
|
||||||
|
std::signal(SIGTERM, SignalHandler::sigHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignalHandler::sigHandler(int _signal) {
|
||||||
|
Q_EMIT SignalHandler::instance().quitSignal();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
31
src/SignalHandler.h
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
class SignalHandler : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY(SignalHandler)
|
||||||
|
|
||||||
|
public:
|
||||||
|
static SignalHandler& instance();
|
||||||
|
|
||||||
|
void init();
|
||||||
|
|
||||||
|
private:
|
||||||
|
SignalHandler();
|
||||||
|
~SignalHandler();
|
||||||
|
|
||||||
|
static void sigHandler(int _signal);
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void quitSignal();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
432
src/WalletAdapter.cpp
Normal file
|
@ -0,0 +1,432 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QLocale>
|
||||||
|
#include <QVector>
|
||||||
|
|
||||||
|
#include <common/util.h>
|
||||||
|
#include <wallet/WalletErrors.h>
|
||||||
|
#include <wallet/LegacyKeysImporter.h>
|
||||||
|
|
||||||
|
#include "NodeAdapter.h"
|
||||||
|
#include "Settings.h"
|
||||||
|
#include "WalletAdapter.h"
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
const quint32 MSECS_IN_HOUR = 60 * 60 * 1000;
|
||||||
|
const quint32 MSECS_IN_MINUTE = 60 * 1000;
|
||||||
|
|
||||||
|
const quint32 LAST_BLOCK_INFO_UPDATING_INTERVAL = 1 * MSECS_IN_MINUTE;
|
||||||
|
const quint32 LAST_BLOCK_INFO_WARNING_INTERVAL = 1 * MSECS_IN_HOUR;
|
||||||
|
|
||||||
|
WalletAdapter& WalletAdapter::instance() {
|
||||||
|
static WalletAdapter inst;
|
||||||
|
return inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
WalletAdapter::WalletAdapter() : QObject(), m_wallet(nullptr), m_mutex(), m_isBackupInProgress(false),
|
||||||
|
m_isSynchronized(false), m_newTransactionsNotificationTimer(),
|
||||||
|
m_lastWalletTransactionId(std::numeric_limits<quint64>::max()) {
|
||||||
|
connect(this, &WalletAdapter::walletInitCompletedSignal, this, &WalletAdapter::onWalletInitCompleted, Qt::QueuedConnection);
|
||||||
|
connect(this, &WalletAdapter::walletSendTransactionCompletedSignal, this, &WalletAdapter::onWalletSendTransactionCompleted, Qt::QueuedConnection);
|
||||||
|
connect(this, &WalletAdapter::updateBlockStatusTextSignal, this, &WalletAdapter::updateBlockStatusText, Qt::QueuedConnection);
|
||||||
|
connect(this, &WalletAdapter::updateBlockStatusTextWithDelaySignal, this, &WalletAdapter::updateBlockStatusTextWithDelay, Qt::QueuedConnection);
|
||||||
|
connect(&m_newTransactionsNotificationTimer, &QTimer::timeout, this, &WalletAdapter::notifyAboutLastTransaction);
|
||||||
|
connect(this, &WalletAdapter::walletSynchronizationProgressUpdatedSignal, this, [&]() {
|
||||||
|
if (!m_newTransactionsNotificationTimer.isActive()) {
|
||||||
|
m_newTransactionsNotificationTimer.start();
|
||||||
|
}
|
||||||
|
}, Qt::QueuedConnection);
|
||||||
|
|
||||||
|
connect(this, &WalletAdapter::walletSynchronizationCompletedSignal, this, [&]() {
|
||||||
|
m_newTransactionsNotificationTimer.stop();
|
||||||
|
notifyAboutLastTransaction();
|
||||||
|
}, Qt::QueuedConnection);
|
||||||
|
|
||||||
|
m_newTransactionsNotificationTimer.setInterval(500);
|
||||||
|
}
|
||||||
|
|
||||||
|
WalletAdapter::~WalletAdapter() {
|
||||||
|
}
|
||||||
|
|
||||||
|
QString WalletAdapter::getAddress() const {
|
||||||
|
try {
|
||||||
|
return m_wallet == nullptr ? QString() : QString::fromStdString(m_wallet->getAddress());
|
||||||
|
} catch (std::system_error&) {
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
quint64 WalletAdapter::getActualBalance() const {
|
||||||
|
try {
|
||||||
|
return m_wallet == nullptr ? 0 : m_wallet->actualBalance();
|
||||||
|
} catch (std::system_error&) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
quint64 WalletAdapter::getPendingBalance() const {
|
||||||
|
try {
|
||||||
|
return m_wallet == nullptr ? 0 : m_wallet->pendingBalance();
|
||||||
|
} catch (std::system_error&) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletAdapter::open(const QString& _password) {
|
||||||
|
Q_ASSERT(m_wallet == nullptr);
|
||||||
|
Settings::instance().setEncrypted(!_password.isEmpty());
|
||||||
|
Q_EMIT walletStateChangedSignal(tr("Opening wallet"));
|
||||||
|
|
||||||
|
m_wallet = NodeAdapter::instance().createWallet();
|
||||||
|
m_wallet->addObserver(this);
|
||||||
|
|
||||||
|
if (QFile::exists(Settings::instance().getWalletFile())) {
|
||||||
|
if (Settings::instance().getWalletFile().endsWith(".keys")) {
|
||||||
|
if(!importLegacyWallet(_password)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (openFile(Settings::instance().getWalletFile(), true)) {
|
||||||
|
try {
|
||||||
|
m_wallet->initAndLoad(m_file, _password.toStdString());
|
||||||
|
} catch (std::system_error&) {
|
||||||
|
closeFile();
|
||||||
|
delete m_wallet;
|
||||||
|
m_wallet = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Settings::instance().setEncrypted(false);
|
||||||
|
try {
|
||||||
|
m_wallet->initAndGenerate("");
|
||||||
|
} catch (std::system_error&) {
|
||||||
|
delete m_wallet;
|
||||||
|
m_wallet = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WalletAdapter::isOpen() const {
|
||||||
|
return m_wallet != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WalletAdapter::importLegacyWallet(const QString &_password) {
|
||||||
|
QString fileName = Settings::instance().getWalletFile();
|
||||||
|
Settings::instance().setEncrypted(!_password.isEmpty());
|
||||||
|
try {
|
||||||
|
fileName.replace(fileName.lastIndexOf(".keys"), 5, ".wallet");
|
||||||
|
if (!openFile(fileName, false)) {
|
||||||
|
delete m_wallet;
|
||||||
|
m_wallet = nullptr;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
cryptonote::importLegacyKeys(Settings::instance().getWalletFile().toStdString(), _password.toStdString(), m_file);
|
||||||
|
closeFile();
|
||||||
|
Settings::instance().setWalletFile(fileName);
|
||||||
|
return true;
|
||||||
|
} catch (std::system_error& _err) {
|
||||||
|
closeFile();
|
||||||
|
if (_err.code().value() == cryptonote::error::WRONG_PASSWORD) {
|
||||||
|
Settings::instance().setEncrypted(true);
|
||||||
|
Q_EMIT openWalletWithPasswordSignal(!_password.isEmpty());
|
||||||
|
}
|
||||||
|
} catch (std::runtime_error& _err) {
|
||||||
|
closeFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
delete m_wallet;
|
||||||
|
m_wallet = nullptr;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletAdapter::close() {
|
||||||
|
Q_CHECK_PTR(m_wallet);
|
||||||
|
save(true, true);
|
||||||
|
lock();
|
||||||
|
m_wallet->removeObserver(this);
|
||||||
|
m_isSynchronized = false;
|
||||||
|
m_newTransactionsNotificationTimer.stop();
|
||||||
|
m_lastWalletTransactionId = std::numeric_limits<quint64>::max();
|
||||||
|
Q_EMIT walletCloseCompletedSignal();
|
||||||
|
QCoreApplication::processEvents();
|
||||||
|
delete m_wallet;
|
||||||
|
m_wallet = nullptr;
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WalletAdapter::save(bool _details, bool _cache) {
|
||||||
|
return save(Settings::instance().getWalletFile() + ".temp", _details, _cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WalletAdapter::save(const QString& _file, bool _details, bool _cache) {
|
||||||
|
Q_CHECK_PTR(m_wallet);
|
||||||
|
if (openFile(_file, false)) {
|
||||||
|
try {
|
||||||
|
m_wallet->save(m_file, _details, _cache);
|
||||||
|
} catch (std::system_error&) {
|
||||||
|
closeFile();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Q_EMIT walletStateChangedSignal(tr("Saving data"));
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletAdapter::backup(const QString& _file) {
|
||||||
|
if (save(_file.endsWith(".wallet") ? _file : _file + ".wallet", true, false)) {
|
||||||
|
m_isBackupInProgress = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
quint64 WalletAdapter::getTransactionCount() const {
|
||||||
|
Q_CHECK_PTR(m_wallet);
|
||||||
|
try {
|
||||||
|
return m_wallet->getTransactionCount();
|
||||||
|
} catch (std::system_error&) {
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
quint64 WalletAdapter::getTransferCount() const {
|
||||||
|
Q_CHECK_PTR(m_wallet);
|
||||||
|
try {
|
||||||
|
return m_wallet->getTransferCount();
|
||||||
|
} catch (std::system_error&) {
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WalletAdapter::getTransaction(CryptoNote::TransactionId& _id, CryptoNote::TransactionInfo& _transaction) {
|
||||||
|
Q_CHECK_PTR(m_wallet);
|
||||||
|
try {
|
||||||
|
return m_wallet->getTransaction(_id, _transaction);
|
||||||
|
} catch (std::system_error&) {
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WalletAdapter::getTransfer(CryptoNote::TransferId& _id, CryptoNote::Transfer& _transfer) {
|
||||||
|
Q_CHECK_PTR(m_wallet);
|
||||||
|
try {
|
||||||
|
return m_wallet->getTransfer(_id, _transfer);
|
||||||
|
} catch (std::system_error&) {
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletAdapter::sendTransaction(const QVector<CryptoNote::Transfer>& _transfers, quint64 _fee, const QString& _paymentId, quint64 _mixin) {
|
||||||
|
Q_CHECK_PTR(m_wallet);
|
||||||
|
try {
|
||||||
|
lock();
|
||||||
|
m_wallet->sendTransaction(_transfers.toStdVector(), _fee, NodeAdapter::instance().convertPaymentId(_paymentId), _mixin, 0);
|
||||||
|
Q_EMIT walletStateChangedSignal(tr("Sending transaction"));
|
||||||
|
} catch (std::system_error&) {
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WalletAdapter::changePassword(const QString& _oldPassword, const QString& _newPassword) {
|
||||||
|
Q_CHECK_PTR(m_wallet);
|
||||||
|
try {
|
||||||
|
if (m_wallet->changePassword(_oldPassword.toStdString(), _newPassword.toStdString()).value() == cryptonote::error::WRONG_PASSWORD) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (std::system_error&) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Settings::instance().setEncrypted(!_newPassword.isEmpty());
|
||||||
|
return save(true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletAdapter::setWalletFile(const QString& _path) {
|
||||||
|
Q_ASSERT(m_wallet == nullptr);
|
||||||
|
Settings::instance().setWalletFile(_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletAdapter::initCompleted(std::error_code _error) {
|
||||||
|
if (m_file.is_open()) {
|
||||||
|
closeFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_EMIT walletInitCompletedSignal(_error.value(), QString::fromStdString(_error.message()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletAdapter::onWalletInitCompleted(int _error, const QString& _errorText) {
|
||||||
|
switch(_error) {
|
||||||
|
case 0: {
|
||||||
|
Q_EMIT walletActualBalanceUpdatedSignal(m_wallet->actualBalance());
|
||||||
|
Q_EMIT walletPendingBalanceUpdatedSignal(m_wallet->pendingBalance());
|
||||||
|
Q_EMIT updateWalletAddressSignal(QString::fromStdString(m_wallet->getAddress()));
|
||||||
|
Q_EMIT reloadWalletTransactionsSignal();
|
||||||
|
Q_EMIT walletStateChangedSignal(tr("Ready"));
|
||||||
|
QTimer::singleShot(5000, this, SLOT(updateBlockStatusText()));
|
||||||
|
if (!QFile::exists(Settings::instance().getWalletFile())) {
|
||||||
|
save(true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case cryptonote::error::WRONG_PASSWORD:
|
||||||
|
Q_EMIT openWalletWithPasswordSignal(Settings::instance().isEncrypted());
|
||||||
|
Settings::instance().setEncrypted(true);
|
||||||
|
delete m_wallet;
|
||||||
|
m_wallet = nullptr;
|
||||||
|
break;
|
||||||
|
default: {
|
||||||
|
delete m_wallet;
|
||||||
|
m_wallet = nullptr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletAdapter::saveCompleted(std::error_code _error) {
|
||||||
|
if (!_error && !m_isBackupInProgress) {
|
||||||
|
closeFile();
|
||||||
|
renameFile(Settings::instance().getWalletFile() + ".temp", Settings::instance().getWalletFile());
|
||||||
|
Q_EMIT walletStateChangedSignal(tr("Ready"));
|
||||||
|
Q_EMIT updateBlockStatusTextWithDelaySignal();
|
||||||
|
} else if (m_isBackupInProgress) {
|
||||||
|
m_isBackupInProgress = false;
|
||||||
|
closeFile();
|
||||||
|
} else {
|
||||||
|
closeFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_EMIT walletSaveCompletedSignal(_error.value(), QString::fromStdString(_error.message()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletAdapter::synchronizationProgressUpdated(uint64_t _current, uint64_t _total) {
|
||||||
|
m_isSynchronized = false;
|
||||||
|
Q_EMIT walletStateChangedSignal(QString("%1 %2/%3").arg(tr("Synchronizing")).arg(_current).arg(_total));
|
||||||
|
Q_EMIT walletSynchronizationProgressUpdatedSignal(_current, _total);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletAdapter::synchronizationCompleted(std::error_code _error) {
|
||||||
|
if (!_error) {
|
||||||
|
m_isSynchronized = true;
|
||||||
|
Q_EMIT updateBlockStatusTextSignal();
|
||||||
|
Q_EMIT walletSynchronizationCompletedSignal(_error.value(), QString::fromStdString(_error.message()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletAdapter::actualBalanceUpdated(uint64_t _actual_balance) {
|
||||||
|
Q_EMIT walletActualBalanceUpdatedSignal(_actual_balance);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletAdapter::pendingBalanceUpdated(uint64_t _pending_balance) {
|
||||||
|
Q_EMIT walletPendingBalanceUpdatedSignal(_pending_balance);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletAdapter::externalTransactionCreated(CryptoNote::TransactionId _transactionId) {
|
||||||
|
if (!m_isSynchronized) {
|
||||||
|
m_lastWalletTransactionId = _transactionId;
|
||||||
|
} else {
|
||||||
|
Q_EMIT walletTransactionCreatedSignal(_transactionId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletAdapter::sendTransactionCompleted(CryptoNote::TransactionId _transaction_id, std::error_code _error) {
|
||||||
|
unlock();
|
||||||
|
Q_EMIT walletSendTransactionCompletedSignal(_transaction_id, _error.value(), QString::fromStdString(_error.message()));
|
||||||
|
Q_EMIT updateBlockStatusTextWithDelaySignal();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletAdapter::onWalletSendTransactionCompleted(CryptoNote::TransactionId _transactionId, int _error, const QString& _errorText) {
|
||||||
|
if (_error) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CryptoNote::TransactionInfo transaction;
|
||||||
|
if (!this->getTransaction(_transactionId, transaction)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (transaction.transferCount == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_EMIT walletTransactionCreatedSignal(_transactionId);
|
||||||
|
|
||||||
|
save(true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletAdapter::transactionUpdated(CryptoNote::TransactionId _transactionId) {
|
||||||
|
Q_EMIT walletTransactionUpdatedSignal(_transactionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletAdapter::lock() {
|
||||||
|
m_mutex.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletAdapter::unlock() {
|
||||||
|
m_mutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WalletAdapter::openFile(const QString& _file, bool _readOnly) {
|
||||||
|
lock();
|
||||||
|
m_file.open(_file.toStdString(), std::ios::binary | (_readOnly ? std::ios::in : (std::ios::out | std::ios::trunc)));
|
||||||
|
if (!m_file.is_open()) {
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_file.is_open();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletAdapter::closeFile() {
|
||||||
|
m_file.close();
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletAdapter::notifyAboutLastTransaction() {
|
||||||
|
if (m_lastWalletTransactionId != std::numeric_limits<quint64>::max()) {
|
||||||
|
Q_EMIT walletTransactionCreatedSignal(m_lastWalletTransactionId);
|
||||||
|
m_lastWalletTransactionId = std::numeric_limits<quint64>::max();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletAdapter::renameFile(const QString& _oldName, const QString& _newName) {
|
||||||
|
Q_ASSERT(QFile::exists(_oldName));
|
||||||
|
QFile::remove(_newName);
|
||||||
|
QFile::rename(_oldName, _newName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletAdapter::updateBlockStatusText() {
|
||||||
|
if (m_wallet == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QDateTime currentTime = QDateTime::currentDateTimeUtc();
|
||||||
|
const QDateTime blockTime = NodeAdapter::instance().getLastLocalBlockTimestamp();
|
||||||
|
quint64 blockAge = blockTime.msecsTo(currentTime);
|
||||||
|
const QString warningString = blockTime.msecsTo(currentTime) < LAST_BLOCK_INFO_WARNING_INTERVAL ? "" :
|
||||||
|
QString(" Warning: last block was received %1 hours %2 minutes ago").arg(blockAge / MSECS_IN_HOUR).arg(blockAge % MSECS_IN_HOUR / MSECS_IN_MINUTE);
|
||||||
|
Q_EMIT walletStateChangedSignal(QString(tr("Wallet synchronized. Height: %1 | Time (UTC): %2%3")).
|
||||||
|
arg(NodeAdapter::instance().getLastLocalBlockHeight()).
|
||||||
|
arg(QLocale(QLocale::English).toString(blockTime, "dd MMM yyyy, HH:mm:ss")).
|
||||||
|
arg(warningString));
|
||||||
|
|
||||||
|
QTimer::singleShot(LAST_BLOCK_INFO_UPDATING_INTERVAL, this, SLOT(updateBlockStatusText()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletAdapter::updateBlockStatusTextWithDelay() {
|
||||||
|
QTimer::singleShot(5000, this, SLOT(updateBlockStatusText()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
103
src/WalletAdapter.h
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QMutex>
|
||||||
|
#include <QObject>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
#include <IWallet.h>
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
class WalletAdapter : public QObject, public CryptoNote::IWalletObserver {
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY(WalletAdapter)
|
||||||
|
|
||||||
|
public:
|
||||||
|
static WalletAdapter& instance();
|
||||||
|
|
||||||
|
void open(const QString& _password);
|
||||||
|
void close();
|
||||||
|
bool save(bool _details, bool _cache);
|
||||||
|
void backup(const QString& _file);
|
||||||
|
|
||||||
|
QString getAddress() const;
|
||||||
|
quint64 getActualBalance() const;
|
||||||
|
quint64 getPendingBalance() const;
|
||||||
|
quint64 getTransactionCount() const;
|
||||||
|
quint64 getTransferCount() const;
|
||||||
|
bool getTransaction(CryptoNote::TransactionId& _id, CryptoNote::TransactionInfo& _transaction);
|
||||||
|
bool getTransfer(CryptoNote::TransferId& _id, CryptoNote::Transfer& _transfer);
|
||||||
|
bool isOpen() const;
|
||||||
|
void sendTransaction(const QVector<CryptoNote::Transfer>& _transfers, quint64 _fee, const QString& _payment_id, quint64 _mixin);
|
||||||
|
bool changePassword(const QString& _old_pass, const QString& _new_pass);
|
||||||
|
void setWalletFile(const QString& _path);
|
||||||
|
|
||||||
|
void initCompleted(std::error_code _result) Q_DECL_OVERRIDE;
|
||||||
|
void saveCompleted(std::error_code _result) Q_DECL_OVERRIDE;
|
||||||
|
void synchronizationProgressUpdated(uint64_t _current, uint64_t _total) Q_DECL_OVERRIDE;
|
||||||
|
void synchronizationCompleted(std::error_code _error) Q_DECL_OVERRIDE;
|
||||||
|
void actualBalanceUpdated(uint64_t _actual_balance) Q_DECL_OVERRIDE;
|
||||||
|
void pendingBalanceUpdated(uint64_t _pending_balance) Q_DECL_OVERRIDE;
|
||||||
|
void externalTransactionCreated(CryptoNote::TransactionId _transaction_id) Q_DECL_OVERRIDE;
|
||||||
|
void sendTransactionCompleted(CryptoNote::TransactionId _transaction_id, std::error_code _result) Q_DECL_OVERRIDE;
|
||||||
|
void transactionUpdated(CryptoNote::TransactionId _transaction_id) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::fstream m_file;
|
||||||
|
CryptoNote::IWallet* m_wallet;
|
||||||
|
QMutex m_mutex;
|
||||||
|
std::atomic<bool> m_isBackupInProgress;
|
||||||
|
std::atomic<bool> m_isSynchronized;
|
||||||
|
std::atomic<quint64> m_lastWalletTransactionId;
|
||||||
|
QTimer m_newTransactionsNotificationTimer;
|
||||||
|
|
||||||
|
WalletAdapter();
|
||||||
|
~WalletAdapter();
|
||||||
|
|
||||||
|
void onWalletInitCompleted(int _error, const QString& _error_text);
|
||||||
|
void onWalletSendTransactionCompleted(CryptoNote::TransactionId _transaction_id, int _error, const QString& _error_text);
|
||||||
|
|
||||||
|
bool importLegacyWallet(const QString &_password);
|
||||||
|
bool save(const QString& _file, bool _details, bool _cache);
|
||||||
|
void lock();
|
||||||
|
void unlock();
|
||||||
|
bool openFile(const QString& _file, bool _read_only);
|
||||||
|
void closeFile();
|
||||||
|
void notifyAboutLastTransaction();
|
||||||
|
|
||||||
|
static void renameFile(const QString& _old_name, const QString& _new_name);
|
||||||
|
Q_SLOT void updateBlockStatusText();
|
||||||
|
Q_SLOT void updateBlockStatusTextWithDelay();
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void walletInitCompletedSignal(int _error, const QString& _error_text);
|
||||||
|
void walletCloseCompletedSignal();
|
||||||
|
void walletSaveCompletedSignal(int _error, const QString& _error_text);
|
||||||
|
void walletSynchronizationProgressUpdatedSignal(quint64 _current, quint64 _total);
|
||||||
|
void walletSynchronizationCompletedSignal(int _error, const QString& _error_text);
|
||||||
|
void walletActualBalanceUpdatedSignal(quint64 _actual_balance);
|
||||||
|
void walletPendingBalanceUpdatedSignal(quint64 _pending_balance);
|
||||||
|
void walletTransactionCreatedSignal(CryptoNote::TransactionId _transaction_id);
|
||||||
|
void walletSendTransactionCompletedSignal(CryptoNote::TransactionId _transaction_id, int _error, const QString& _error_text);
|
||||||
|
void walletTransactionUpdatedSignal(CryptoNote::TransactionId _transaction_id);
|
||||||
|
void walletStateChangedSignal(const QString &_state_text);
|
||||||
|
|
||||||
|
void openWalletWithPasswordSignal(bool _error);
|
||||||
|
void changeWalletPasswordSignal();
|
||||||
|
void updateWalletAddressSignal(const QString& _address);
|
||||||
|
void reloadWalletTransactionsSignal();
|
||||||
|
void updateBlockStatusTextSignal();
|
||||||
|
void updateBlockStatusTextWithDelaySignal();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
1
src/cryptonotewallet.rc
Normal file
|
@ -0,0 +1 @@
|
||||||
|
IDI_ICON1 ICON "images\cryptonote.ico"
|
24
src/gui/AboutDialog.cpp
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#include "AboutDialog.h"
|
||||||
|
#include "CurrencyAdapter.h"
|
||||||
|
#include "Settings.h"
|
||||||
|
|
||||||
|
#include "ui_aboutdialog.h"
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
AboutDialog::AboutDialog(QWidget* _parent) : QDialog(_parent), m_ui(new Ui::AboutDialog) {
|
||||||
|
m_ui->setupUi(this);
|
||||||
|
setWindowTitle(QString(tr("About %1 Wallet")).arg(CurrencyAdapter::instance().getCurrencyDisplayName()));
|
||||||
|
QString aboutText = m_ui->m_aboutLabel->text();
|
||||||
|
m_ui->m_aboutLabel->setText(aboutText.arg(GIT_REVISION));
|
||||||
|
}
|
||||||
|
|
||||||
|
AboutDialog::~AboutDialog() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
28
src/gui/AboutDialog.h
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class AboutDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
class AboutDialog : public QDialog {
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY(AboutDialog)
|
||||||
|
|
||||||
|
public:
|
||||||
|
AboutDialog(QWidget* _parent);
|
||||||
|
~AboutDialog();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QScopedPointer<Ui::AboutDialog> m_ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
28
src/gui/AddressBookDialog.cpp
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#include "AddressBookDialog.h"
|
||||||
|
#include "AddressBookModel.h"
|
||||||
|
|
||||||
|
#include "ui_addressbookdialog.h"
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
AddressBookDialog::AddressBookDialog(QWidget* _parent) : QDialog(_parent), m_ui(new Ui::AddressBookDialog) {
|
||||||
|
m_ui->setupUi(this);
|
||||||
|
m_ui->m_addressBookView->setModel(&AddressBookModel::instance());
|
||||||
|
if (AddressBookModel::instance().rowCount() > 0) {
|
||||||
|
m_ui->m_addressBookView->setCurrentIndex(AddressBookModel::instance().index(0, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AddressBookDialog::~AddressBookDialog() {
|
||||||
|
}
|
||||||
|
|
||||||
|
QString AddressBookDialog::getAddress() const {
|
||||||
|
return m_ui->m_addressBookView->currentIndex().data(AddressBookModel::ROLE_ADDRESS).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
30
src/gui/AddressBookDialog.h
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class AddressBookDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
class AddressBookDialog : public QDialog {
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY(AddressBookDialog)
|
||||||
|
|
||||||
|
public:
|
||||||
|
AddressBookDialog(QWidget* _parent);
|
||||||
|
~AddressBookDialog();
|
||||||
|
|
||||||
|
QString getAddress() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QScopedPointer<Ui::AddressBookDialog> m_ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
58
src/gui/AddressBookFrame.cpp
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QClipboard>
|
||||||
|
|
||||||
|
#include "CurrencyAdapter.h"
|
||||||
|
#include "AddressBookModel.h"
|
||||||
|
#include "AddressBookFrame.h"
|
||||||
|
#include "MainWindow.h"
|
||||||
|
#include "NewAddressDialog.h"
|
||||||
|
#include "WalletEvents.h"
|
||||||
|
|
||||||
|
#include "ui_addressbookframe.h"
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
AddressBookFrame::AddressBookFrame(QWidget* _parent) : QFrame(_parent), m_ui(new Ui::AddressBookFrame) {
|
||||||
|
m_ui->setupUi(this);
|
||||||
|
m_ui->m_addressBookView->setModel(&AddressBookModel::instance());
|
||||||
|
|
||||||
|
connect(m_ui->m_addressBookView->selectionModel(), &QItemSelectionModel::currentChanged, this, &AddressBookFrame::currentAddressChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
AddressBookFrame::~AddressBookFrame() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddressBookFrame::addClicked() {
|
||||||
|
NewAddressDialog dlg(&MainWindow::instance());
|
||||||
|
if (dlg.exec() == QDialog::Accepted) {
|
||||||
|
QString label = dlg.getLabel();
|
||||||
|
QString address = dlg.getAddress();
|
||||||
|
if (!CurrencyAdapter::instance().validateAddress(address)) {
|
||||||
|
QCoreApplication::postEvent(&MainWindow::instance(), new ShowMessageEvent(tr("Invalid address"), QtCriticalMsg));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddressBookModel::instance().addAddress(label, address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddressBookFrame::copyClicked() {
|
||||||
|
QApplication::clipboard()->setText(m_ui->m_addressBookView->currentIndex().data(AddressBookModel::ROLE_ADDRESS).toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddressBookFrame::deleteClicked() {
|
||||||
|
int row = m_ui->m_addressBookView->currentIndex().row();
|
||||||
|
AddressBookModel::instance().removeAddress(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddressBookFrame::currentAddressChanged(const QModelIndex& _index) {
|
||||||
|
m_ui->m_copyAddressButton->setEnabled(_index.isValid());
|
||||||
|
m_ui->m_deleteAddressButton->setEnabled(_index.isValid());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
33
src/gui/AddressBookFrame.h
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QFrame>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class AddressBookFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
class AddressBookFrame : public QFrame {
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY(AddressBookFrame)
|
||||||
|
|
||||||
|
public:
|
||||||
|
AddressBookFrame(QWidget* _parent);
|
||||||
|
~AddressBookFrame();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QScopedPointer<Ui::AddressBookFrame> m_ui;
|
||||||
|
|
||||||
|
Q_SLOT void addClicked();
|
||||||
|
Q_SLOT void copyClicked();
|
||||||
|
Q_SLOT void deleteClicked();
|
||||||
|
Q_SLOT void currentAddressChanged(const QModelIndex& _index);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
155
src/gui/AddressBookModel.cpp
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#include <QFile>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonObject>
|
||||||
|
|
||||||
|
#include "WalletAdapter.h"
|
||||||
|
#include "AddressBookModel.h"
|
||||||
|
#include "Settings.h"
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
AddressBookModel& AddressBookModel::instance() {
|
||||||
|
static AddressBookModel inst;
|
||||||
|
return inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddressBookModel::AddressBookModel() : QAbstractItemModel() {
|
||||||
|
connect(&WalletAdapter::instance(), &WalletAdapter::walletInitCompletedSignal, this, &AddressBookModel::walletInitCompleted, Qt::QueuedConnection);
|
||||||
|
connect(&WalletAdapter::instance(), &WalletAdapter::walletCloseCompletedSignal, this, &AddressBookModel::reset, Qt::QueuedConnection);
|
||||||
|
}
|
||||||
|
|
||||||
|
AddressBookModel::~AddressBookModel() {
|
||||||
|
}
|
||||||
|
|
||||||
|
int AddressBookModel::columnCount(const QModelIndex& _parent) const {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant AddressBookModel::data(const QModelIndex& _index, int _role) const {
|
||||||
|
if (!_index.isValid()) {
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject address = m_addressBook.at(_index.row()).toObject();
|
||||||
|
|
||||||
|
switch (_role) {
|
||||||
|
case Qt::DisplayRole:
|
||||||
|
switch (_index.column()) {
|
||||||
|
case COLUMN_LABEL:
|
||||||
|
return _index.data(ROLE_LABEL);
|
||||||
|
case COLUMN_ADDRESS:
|
||||||
|
return _index.data(ROLE_ADDRESS);
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
case ROLE_LABEL:
|
||||||
|
return address.value("label");
|
||||||
|
case ROLE_ADDRESS:
|
||||||
|
return address.value("address");
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::ItemFlags AddressBookModel::flags(const QModelIndex& _index) const {
|
||||||
|
return (Qt::ItemIsEnabled | Qt::ItemNeverHasChildren | Qt::ItemIsSelectable);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant AddressBookModel::headerData(int _section, Qt::Orientation _orientation, int _role) const {
|
||||||
|
if (_orientation != Qt::Horizontal || _role != Qt::DisplayRole) {
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (_section) {
|
||||||
|
case COLUMN_LABEL:
|
||||||
|
return tr("Label");
|
||||||
|
case COLUMN_ADDRESS:
|
||||||
|
return tr("Address");
|
||||||
|
}
|
||||||
|
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex AddressBookModel::index(int _row, int _column, const QModelIndex& _parent) const {
|
||||||
|
if (_parent.isValid()) {
|
||||||
|
return QModelIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
return createIndex(_row, _column, _row);
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex AddressBookModel::parent(const QModelIndex& _index) const {
|
||||||
|
return QModelIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
int AddressBookModel::rowCount(const QModelIndex& _parent) const {
|
||||||
|
return m_addressBook.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddressBookModel::addAddress(const QString& _label, const QString& _address) {
|
||||||
|
beginInsertRows(QModelIndex(), m_addressBook.size(), m_addressBook.size());
|
||||||
|
QJsonObject newAddress;
|
||||||
|
newAddress.insert("label", _label);
|
||||||
|
newAddress.insert("address", _address);
|
||||||
|
m_addressBook.append(newAddress);
|
||||||
|
endInsertRows();
|
||||||
|
saveAddressBook();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddressBookModel::removeAddress(quint32 _row) {
|
||||||
|
if (_row > m_addressBook.size() - 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
beginRemoveRows(QModelIndex(), _row, _row);
|
||||||
|
m_addressBook.removeAt(_row);
|
||||||
|
endRemoveRows();
|
||||||
|
saveAddressBook();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddressBookModel::reset() {
|
||||||
|
beginResetModel();
|
||||||
|
while (!m_addressBook.empty()) {
|
||||||
|
m_addressBook.removeFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddressBookModel::saveAddressBook() {
|
||||||
|
QFile addressBookFile(Settings::instance().getAddressBookFile());
|
||||||
|
if (addressBookFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
|
||||||
|
QByteArray file_content = QJsonDocument(m_addressBook).toJson(QJsonDocument::Compact);
|
||||||
|
addressBookFile.write(file_content);
|
||||||
|
addressBookFile.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddressBookModel::walletInitCompleted(int _error, const QString& _error_text) {
|
||||||
|
if (!_error) {
|
||||||
|
QFile addressBookFile(Settings::instance().getAddressBookFile());
|
||||||
|
if (addressBookFile.open(QIODevice::ReadOnly)) {
|
||||||
|
QByteArray file_content = addressBookFile.readAll();
|
||||||
|
QJsonDocument doc = QJsonDocument::fromJson(file_content);
|
||||||
|
if (!doc.isNull()) {
|
||||||
|
m_addressBook = doc.array();
|
||||||
|
}
|
||||||
|
|
||||||
|
addressBookFile.close();
|
||||||
|
if (!m_addressBook.isEmpty()) {
|
||||||
|
beginInsertRows(QModelIndex(), 0, m_addressBook.size() - 1);
|
||||||
|
endInsertRows();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
45
src/gui/AddressBookModel.h
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QAbstractItemModel>
|
||||||
|
#include <QJsonArray>
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
class AddressBookModel : public QAbstractItemModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY(AddressBookModel)
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum Columns {COLUMN_LABEL = 0, COLUMN_ADDRESS};
|
||||||
|
enum Roles { ROLE_LABEL = Qt::UserRole, ROLE_ADDRESS };
|
||||||
|
|
||||||
|
static AddressBookModel& instance();
|
||||||
|
int columnCount(const QModelIndex& _parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
||||||
|
QVariant data(const QModelIndex& _index, int _role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
|
||||||
|
Qt::ItemFlags flags(const QModelIndex& _index) const Q_DECL_OVERRIDE;
|
||||||
|
QVariant headerData(int _section, Qt::Orientation _orientation, int _role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
|
||||||
|
QModelIndex index(int _row, int _column, const QModelIndex& _parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
||||||
|
QModelIndex parent(const QModelIndex& _index) const Q_DECL_OVERRIDE;
|
||||||
|
int rowCount(const QModelIndex& _parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
void addAddress(const QString& _label, const QString& _address);
|
||||||
|
void removeAddress(quint32 _row);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QJsonArray m_addressBook;
|
||||||
|
|
||||||
|
AddressBookModel();
|
||||||
|
~AddressBookModel();
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
void saveAddressBook();
|
||||||
|
void walletInitCompleted(int _error, const QString& _error_text);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
46
src/gui/AnimatedLabel.cpp
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#include "AnimatedLabel.h"
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
AnimatedLabel::AnimatedLabel(QWidget* _parent) : QLabel(_parent), m_spriteVerticalSpace(0) {
|
||||||
|
connect(&m_animationTimer, &QTimer::timeout, this, &AnimatedLabel::timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
AnimatedLabel::~AnimatedLabel() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimatedLabel::setSprite(const QPixmap& _spritePixmap, const QSize& _frameSize, quint32 _verticalSpace, quint32 _frequency) {
|
||||||
|
m_spritePixmap = _spritePixmap;
|
||||||
|
m_spriteFrameSize = _frameSize;
|
||||||
|
m_spriteVerticalSpace = _verticalSpace;
|
||||||
|
m_animationTimer.setInterval(1000 / _frequency);
|
||||||
|
m_frameRect.setTopLeft(QPoint(0, 0));
|
||||||
|
m_frameRect.setBottomRight(m_frameRect.topLeft() += QPoint(_frameSize.width(), _frameSize.height()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimatedLabel::startAnimation() {
|
||||||
|
if (m_animationTimer.isActive()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_animationTimer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimatedLabel::stopAnimation() {
|
||||||
|
m_animationTimer.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimatedLabel::timeout() {
|
||||||
|
setPixmap(m_spritePixmap.copy(m_frameRect));
|
||||||
|
m_frameRect.translate(QPoint(0, m_spriteVerticalSpace + m_spriteFrameSize.height()));
|
||||||
|
if (m_frameRect.bottom() >= m_spritePixmap.height()) {
|
||||||
|
m_frameRect.moveTop(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
35
src/gui/AnimatedLabel.h
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
class AnimatedLabel : public QLabel {
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY(AnimatedLabel)
|
||||||
|
|
||||||
|
public:
|
||||||
|
AnimatedLabel(QWidget* _parent);
|
||||||
|
~AnimatedLabel();
|
||||||
|
|
||||||
|
void setSprite(const QPixmap& _sprite_pixmap, const QSize& _frame_size, quint32 _vertical_space, quint32 _frequency);
|
||||||
|
void startAnimation();
|
||||||
|
void stopAnimation();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QPixmap m_spritePixmap;
|
||||||
|
QSize m_spriteFrameSize;
|
||||||
|
quint32 m_spriteVerticalSpace;
|
||||||
|
QTimer m_animationTimer;
|
||||||
|
QRect m_frameRect;
|
||||||
|
|
||||||
|
void timeout();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
36
src/gui/ChangePasswordDialog.cpp
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#include "ChangePasswordDialog.h"
|
||||||
|
|
||||||
|
#include "ui_changepassworddialog.h"
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
ChangePasswordDialog::ChangePasswordDialog(QWidget* _parent) : QDialog(_parent), m_ui(new Ui::ChangePasswordDialog) {
|
||||||
|
m_ui->setupUi(this);
|
||||||
|
m_ui->m_errorLabel->setText("");
|
||||||
|
}
|
||||||
|
|
||||||
|
ChangePasswordDialog::~ChangePasswordDialog() {
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ChangePasswordDialog::getNewPassword() const {
|
||||||
|
return m_ui->m_newPasswordEdit->text();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ChangePasswordDialog::getOldPassword() const {
|
||||||
|
return m_ui->m_oldPasswordEdit->text();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChangePasswordDialog::checkPassword(const QString& _password) {
|
||||||
|
bool passwordIsConfirmed = !(m_ui->m_newPasswordEdit->text().trimmed().isEmpty() ||
|
||||||
|
m_ui->m_newPasswordConfirmationEdit->text().trimmed().isEmpty() ||
|
||||||
|
m_ui->m_newPasswordEdit->text().compare(m_ui->m_newPasswordConfirmationEdit->text()));
|
||||||
|
m_ui->m_errorLabel->setText(passwordIsConfirmed ? "" : tr("Password not confirmed"));
|
||||||
|
m_ui->m_okButton->setEnabled(passwordIsConfirmed);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
33
src/gui/ChangePasswordDialog.h
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class ChangePasswordDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
class ChangePasswordDialog : public QDialog {
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY(ChangePasswordDialog)
|
||||||
|
|
||||||
|
public:
|
||||||
|
ChangePasswordDialog(QWidget* _parent);
|
||||||
|
~ChangePasswordDialog();
|
||||||
|
|
||||||
|
QString getNewPassword() const;
|
||||||
|
QString getOldPassword() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QScopedPointer<Ui::ChangePasswordDialog> m_ui;
|
||||||
|
|
||||||
|
Q_SLOT void checkPassword(const QString& _password);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
29
src/gui/ExitWidget.cpp
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#include <QMovie>
|
||||||
|
|
||||||
|
#include "CurrencyAdapter.h"
|
||||||
|
#include "ExitWidget.h"
|
||||||
|
|
||||||
|
#include "ui_exitwidget.h"
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
ExitWidget::ExitWidget(QWidget* _parent) : QWidget(_parent, Qt::Window), m_ui(new Ui::ExitWidget),
|
||||||
|
m_clockMovie(new QMovie(this)) {
|
||||||
|
m_ui->setupUi(this);
|
||||||
|
QString text = m_ui->m_label->text();
|
||||||
|
m_ui->m_label->setText(text.arg(CurrencyAdapter::instance().getCurrencyDisplayName()));
|
||||||
|
m_clockMovie->setFileName(":images/clock");
|
||||||
|
m_clockMovie->setScaledSize(QSize(48, 48));
|
||||||
|
m_ui->m_clockLabel->setMovie(m_clockMovie);
|
||||||
|
m_clockMovie->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
ExitWidget::~ExitWidget() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
31
src/gui/ExitWidget.h
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
class QMovie;
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class ExitWidget;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
class ExitWidget : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY(ExitWidget)
|
||||||
|
|
||||||
|
public:
|
||||||
|
ExitWidget(QWidget* _parent);
|
||||||
|
~ExitWidget();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QScopedPointer<Ui::ExitWidget> m_ui;
|
||||||
|
QMovie* m_clockMovie;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
413
src/gui/MainWindow.cpp
Normal file
|
@ -0,0 +1,413 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#include <QCloseEvent>
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QInputDialog>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QSystemTrayIcon>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
#include <common/util.h>
|
||||||
|
|
||||||
|
#include "AboutDialog.h"
|
||||||
|
#include "AnimatedLabel.h"
|
||||||
|
#include "ChangePasswordDialog.h"
|
||||||
|
#include "CurrencyAdapter.h"
|
||||||
|
#include "ExitWidget.h"
|
||||||
|
#include "MainWindow.h"
|
||||||
|
#include "NewPasswordDialog.h"
|
||||||
|
#include "NodeAdapter.h"
|
||||||
|
#include "PasswordDialog.h"
|
||||||
|
#include "Settings.h"
|
||||||
|
#include "WalletAdapter.h"
|
||||||
|
#include "WalletEvents.h"
|
||||||
|
|
||||||
|
#include "ui_mainwindow.h"
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
MainWindow* MainWindow::m_instance = nullptr;
|
||||||
|
|
||||||
|
MainWindow& MainWindow::instance() {
|
||||||
|
if (m_instance == nullptr) {
|
||||||
|
m_instance = new MainWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *m_instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
MainWindow::MainWindow() : QMainWindow(), m_ui(new Ui::MainWindow), m_trayIcon(nullptr), m_tabActionGroup(new QActionGroup(this)),
|
||||||
|
m_isAboutToQuit(false) {
|
||||||
|
m_ui->setupUi(this);
|
||||||
|
m_connectionStateIconLabel = new QLabel(this);
|
||||||
|
m_encryptionStateIconLabel = new QLabel(this);
|
||||||
|
m_synchronizationStateIconLabel = new AnimatedLabel(this);
|
||||||
|
|
||||||
|
connectToSignals();
|
||||||
|
initUi();
|
||||||
|
|
||||||
|
walletClosed();
|
||||||
|
}
|
||||||
|
|
||||||
|
MainWindow::~MainWindow() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::connectToSignals() {
|
||||||
|
connect(&WalletAdapter::instance(), &WalletAdapter::openWalletWithPasswordSignal, this, &MainWindow::askForWalletPassword, Qt::QueuedConnection);
|
||||||
|
connect(&WalletAdapter::instance(), &WalletAdapter::changeWalletPasswordSignal, this, &MainWindow::encryptWallet, Qt::QueuedConnection);
|
||||||
|
connect(&WalletAdapter::instance(), &WalletAdapter::walletSynchronizationProgressUpdatedSignal,
|
||||||
|
this, &MainWindow::walletSynchronizationInProgress, Qt::QueuedConnection);
|
||||||
|
connect(&WalletAdapter::instance(), &WalletAdapter::walletSynchronizationCompletedSignal, this, &MainWindow::walletSynchronized
|
||||||
|
, Qt::QueuedConnection);
|
||||||
|
connect(&WalletAdapter::instance(), &WalletAdapter::walletStateChangedSignal, this, &MainWindow::setStatusBarText);
|
||||||
|
connect(&WalletAdapter::instance(), &WalletAdapter::walletInitCompletedSignal, this, &MainWindow::walletOpened);
|
||||||
|
connect(&WalletAdapter::instance(), &WalletAdapter::walletCloseCompletedSignal, this, &MainWindow::walletClosed);
|
||||||
|
connect(&NodeAdapter::instance(), &NodeAdapter::peerCountUpdatedSignal, this, &MainWindow::peerCountUpdated, Qt::QueuedConnection);
|
||||||
|
connect(m_ui->m_exitAction, &QAction::triggered, qApp, &QApplication::quit);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::initUi() {
|
||||||
|
setWindowTitle(QString("%1 Wallet %2").arg(CurrencyAdapter::instance().getCurrencyDisplayName()).arg(Settings::instance().getVersion()));
|
||||||
|
#ifdef Q_OS_WIN32
|
||||||
|
if (QSystemTrayIcon::isSystemTrayAvailable()) {
|
||||||
|
m_trayIcon = new QSystemTrayIcon(QPixmap(":images/cryptonote"), this);
|
||||||
|
connect(m_trayIcon, &QSystemTrayIcon::activated, this, &MainWindow::trayActivated);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
m_ui->m_aboutCryptonoteAction->setText(QString(tr("About %1 Wallet")).arg(CurrencyAdapter::instance().getCurrencyDisplayName()));
|
||||||
|
|
||||||
|
m_ui->m_overviewFrame->hide();
|
||||||
|
m_ui->m_sendFrame->hide();
|
||||||
|
m_ui->m_receiveFrame->hide();
|
||||||
|
m_ui->m_transactionsFrame->hide();
|
||||||
|
m_ui->m_addressBookFrame->hide();
|
||||||
|
|
||||||
|
m_tabActionGroup->addAction(m_ui->m_overviewAction);
|
||||||
|
m_tabActionGroup->addAction(m_ui->m_sendAction);
|
||||||
|
m_tabActionGroup->addAction(m_ui->m_receiveAction);
|
||||||
|
m_tabActionGroup->addAction(m_ui->m_transactionsAction);
|
||||||
|
m_tabActionGroup->addAction(m_ui->m_addressBookAction);
|
||||||
|
|
||||||
|
m_ui->m_overviewAction->toggle();
|
||||||
|
encryptedFlagChanged(false);
|
||||||
|
statusBar()->addPermanentWidget(m_connectionStateIconLabel);
|
||||||
|
statusBar()->addPermanentWidget(m_encryptionStateIconLabel);
|
||||||
|
statusBar()->addPermanentWidget(m_synchronizationStateIconLabel);
|
||||||
|
qobject_cast<AnimatedLabel*>(m_synchronizationStateIconLabel)->setSprite(QPixmap(":icons/sync_sprite"), QSize(16, 16), 5, 24);
|
||||||
|
m_connectionStateIconLabel->setPixmap(QPixmap(":icons/disconnected").scaled(16, 16, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
||||||
|
|
||||||
|
#ifdef Q_OS_MAC
|
||||||
|
installDockHandler();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef Q_OS_WIN
|
||||||
|
m_ui->m_minimizeToTrayAction->deleteLater();
|
||||||
|
m_ui->m_closeToTrayAction->deleteLater();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
void MainWindow::minimizeToTray(bool _on) {
|
||||||
|
if (_on) {
|
||||||
|
hide();
|
||||||
|
m_trayIcon->show();
|
||||||
|
} else {
|
||||||
|
showNormal();
|
||||||
|
activateWindow();
|
||||||
|
m_trayIcon->hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void MainWindow::scrollToTransaction(const QModelIndex& _index) {
|
||||||
|
m_ui->m_transactionsAction->setChecked(true);
|
||||||
|
m_ui->m_transactionsFrame->scrollToTransaction(_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::quit() {
|
||||||
|
if (!m_isAboutToQuit) {
|
||||||
|
ExitWidget* exitWidget = new ExitWidget(nullptr);
|
||||||
|
exitWidget->show();
|
||||||
|
m_isAboutToQuit = true;
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef Q_OS_MAC
|
||||||
|
void MainWindow::restoreFromDock() {
|
||||||
|
if (m_isAboutToQuit) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
showNormal();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void MainWindow::closeEvent(QCloseEvent* _event) {
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
if (m_isAboutToQuit) {
|
||||||
|
QMainWindow::closeEvent(_event);
|
||||||
|
return;
|
||||||
|
} else if (Settings::instance().isCloseToTrayEnabled()) {
|
||||||
|
minimizeToTray(true);
|
||||||
|
_event->ignore();
|
||||||
|
} else {
|
||||||
|
QApplication::quit();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#elif defined(Q_OS_LINUX)
|
||||||
|
if (!m_isAboutToQuit) {
|
||||||
|
QApplication::quit();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
QMainWindow::closeEvent(_event);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
void MainWindow::changeEvent(QEvent* _event) {
|
||||||
|
QMainWindow::changeEvent(_event);
|
||||||
|
if (!QSystemTrayIcon::isSystemTrayAvailable()) {
|
||||||
|
QMainWindow::changeEvent(_event);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (_event->type()) {
|
||||||
|
case QEvent::WindowStateChange:
|
||||||
|
if(Settings::instance().isMinimizeToTrayEnabled()) {
|
||||||
|
minimizeToTray(isMinimized());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMainWindow::changeEvent(_event);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool MainWindow::event(QEvent* _event) {
|
||||||
|
switch (static_cast<WalletEventType>(_event->type())) {
|
||||||
|
case WalletEventType::ShowMessage:
|
||||||
|
showMessage(static_cast<ShowMessageEvent*>(_event)->messageText(), static_cast<ShowMessageEvent*>(_event)->messageType());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QMainWindow::event(_event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::createWallet() {
|
||||||
|
QString filePath = QFileDialog::getSaveFileName(this, tr("New wallet file"),
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
QApplication::applicationDirPath(),
|
||||||
|
#else
|
||||||
|
QDir::homePath(),
|
||||||
|
#endif
|
||||||
|
tr("Wallets (*.wallet)")
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!filePath.isEmpty() && !filePath.endsWith(".wallet")) {
|
||||||
|
filePath.append(".wallet");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!filePath.isEmpty() && !QFile::exists(filePath)) {
|
||||||
|
if (WalletAdapter::instance().isOpen()) {
|
||||||
|
WalletAdapter::instance().close();
|
||||||
|
}
|
||||||
|
|
||||||
|
WalletAdapter::instance().setWalletFile(filePath);
|
||||||
|
WalletAdapter::instance().open("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::openWallet() {
|
||||||
|
QString filePath = QFileDialog::getOpenFileName(this, tr("Open .wallet/.keys file"),
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
QApplication::applicationDirPath(),
|
||||||
|
#else
|
||||||
|
QDir::homePath(),
|
||||||
|
#endif
|
||||||
|
tr("Wallet (*.wallet *.keys)"));
|
||||||
|
|
||||||
|
if (!filePath.isEmpty()) {
|
||||||
|
if (WalletAdapter::instance().isOpen()) {
|
||||||
|
WalletAdapter::instance().close();
|
||||||
|
}
|
||||||
|
|
||||||
|
WalletAdapter::instance().setWalletFile(filePath);
|
||||||
|
WalletAdapter::instance().open("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::backupWallet() {
|
||||||
|
QString filePath = QFileDialog::getSaveFileName(this, tr("Backup wallet to..."),
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
QApplication::applicationDirPath(),
|
||||||
|
#else
|
||||||
|
QDir::homePath(),
|
||||||
|
#endif
|
||||||
|
tr("Wallets (*.wallet)")
|
||||||
|
);
|
||||||
|
if (!filePath.isEmpty() && !filePath.endsWith(".wallet")) {
|
||||||
|
filePath.append(".wallet");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!filePath.isEmpty() && !QFile::exists(filePath)) {
|
||||||
|
WalletAdapter::instance().backup(filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::encryptWallet() {
|
||||||
|
if (Settings::instance().isEncrypted()) {
|
||||||
|
bool error = false;
|
||||||
|
do {
|
||||||
|
ChangePasswordDialog dlg(this);
|
||||||
|
if (dlg.exec() == QDialog::Rejected) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString oldPassword = dlg.getOldPassword();
|
||||||
|
QString newPassword = dlg.getNewPassword();
|
||||||
|
error = !WalletAdapter::instance().changePassword(oldPassword, newPassword);
|
||||||
|
} while (error);
|
||||||
|
} else {
|
||||||
|
NewPasswordDialog dlg(this);
|
||||||
|
if (dlg.exec() == QDialog::Accepted) {
|
||||||
|
QString password = dlg.getPassword();
|
||||||
|
if (password.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
encryptedFlagChanged(WalletAdapter::instance().changePassword("", password));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::aboutQt() {
|
||||||
|
QMessageBox::aboutQt(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::setStartOnLogin(bool _on) {
|
||||||
|
Settings::instance().setStartOnLoginEnabled(_on);
|
||||||
|
m_ui->m_startOnLoginAction->setChecked(Settings::instance().isStartOnLoginEnabled());
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::setMinimizeToTray(bool _on) {
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
Settings::instance().setMinimizeToTrayEnabled(_on);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::setCloseToTray(bool _on) {
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
Settings::instance().setCloseToTrayEnabled(_on);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::about() {
|
||||||
|
AboutDialog dlg(this);
|
||||||
|
dlg.exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::setStatusBarText(const QString& _text) {
|
||||||
|
statusBar()->showMessage(_text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::showMessage(const QString& _text, QtMsgType _type) {
|
||||||
|
switch (_type) {
|
||||||
|
case QtCriticalMsg:
|
||||||
|
QMessageBox::critical(this, tr("Wallet error"), _text);
|
||||||
|
break;
|
||||||
|
case QtDebugMsg:
|
||||||
|
QMessageBox::information(this, tr("Wallet"), _text);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::askForWalletPassword(bool _error) {
|
||||||
|
PasswordDialog dlg(_error, this);
|
||||||
|
if (dlg.exec() == QDialog::Accepted) {
|
||||||
|
QString password = dlg.getPassword();
|
||||||
|
WalletAdapter::instance().open(password);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::encryptedFlagChanged(bool _encrypted) {
|
||||||
|
m_ui->m_encryptWalletAction->setEnabled(!_encrypted);
|
||||||
|
m_ui->m_changePasswordAction->setEnabled(_encrypted);
|
||||||
|
QString encryptionIconPath = _encrypted ? ":icons/encrypted" : ":icons/decrypted";
|
||||||
|
QPixmap encryptionIcon = QPixmap(encryptionIconPath).scaled(16, 16, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||||
|
m_encryptionStateIconLabel->setPixmap(encryptionIcon);
|
||||||
|
QString encryptionLabelTooltip = _encrypted ? tr("Encrypted") : tr("Not encrypted");
|
||||||
|
m_encryptionStateIconLabel->setToolTip(encryptionLabelTooltip);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::peerCountUpdated(quint64 _peerCount) {
|
||||||
|
QString connectionIconPath = _peerCount > 0 ? ":icons/connected" : ":icons/disconnected";
|
||||||
|
QPixmap connectionIcon = QPixmap(connectionIconPath).scaled(16, 16, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||||
|
m_connectionStateIconLabel->setPixmap(connectionIcon);
|
||||||
|
m_connectionStateIconLabel->setToolTip(QString(tr("%1 peers").arg(_peerCount)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::walletSynchronizationInProgress() {
|
||||||
|
qobject_cast<AnimatedLabel*>(m_synchronizationStateIconLabel)->startAnimation();
|
||||||
|
m_synchronizationStateIconLabel->setToolTip(tr("Synchronization in progress"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::walletSynchronized(int _error, const QString& _error_text) {
|
||||||
|
QPixmap syncIcon = QPixmap(":icons/synced").scaled(16, 16, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||||
|
qobject_cast<AnimatedLabel*>(m_synchronizationStateIconLabel)->stopAnimation();
|
||||||
|
m_synchronizationStateIconLabel->setPixmap(syncIcon);
|
||||||
|
QString syncLabelTooltip = _error > 0 ? tr("Not synchronized") : tr("Synchronized");
|
||||||
|
m_synchronizationStateIconLabel->setToolTip(syncLabelTooltip);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::walletOpened(bool _error, const QString& _error_text) {
|
||||||
|
if (!_error) {
|
||||||
|
m_encryptionStateIconLabel->show();
|
||||||
|
m_synchronizationStateIconLabel->show();
|
||||||
|
m_ui->m_backupWalletAction->setEnabled(true);
|
||||||
|
encryptedFlagChanged(Settings::instance().isEncrypted());
|
||||||
|
|
||||||
|
QList<QAction*> tabActions = m_tabActionGroup->actions();
|
||||||
|
Q_FOREACH(auto action, tabActions) {
|
||||||
|
action->setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_ui->m_overviewAction->trigger();
|
||||||
|
m_ui->m_overviewFrame->show();
|
||||||
|
} else {
|
||||||
|
walletClosed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::walletClosed() {
|
||||||
|
m_ui->m_backupWalletAction->setEnabled(false);
|
||||||
|
m_ui->m_encryptWalletAction->setEnabled(false);
|
||||||
|
m_ui->m_changePasswordAction->setEnabled(false);
|
||||||
|
m_ui->m_overviewFrame->hide();
|
||||||
|
m_ui->m_sendFrame->hide();
|
||||||
|
m_ui->m_transactionsFrame->hide();
|
||||||
|
m_ui->m_addressBookFrame->hide();
|
||||||
|
m_encryptionStateIconLabel->hide();
|
||||||
|
m_synchronizationStateIconLabel->hide();
|
||||||
|
QList<QAction*> tabActions = m_tabActionGroup->actions();
|
||||||
|
Q_FOREACH(auto action, tabActions) {
|
||||||
|
action->setEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
void MainWindow::trayActivated(QSystemTrayIcon::ActivationReason _reason) {
|
||||||
|
showNormal();
|
||||||
|
m_trayIcon->hide();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
87
src/gui/MainWindow.h
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QMainWindow>
|
||||||
|
#include <QSystemTrayIcon>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
class QActionGroup;
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class MainWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
class MainWindow : public QMainWindow {
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY(MainWindow)
|
||||||
|
|
||||||
|
public:
|
||||||
|
static MainWindow& instance();
|
||||||
|
void scrollToTransaction(const QModelIndex& _index);
|
||||||
|
void quit();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void closeEvent(QCloseEvent* _event) Q_DECL_OVERRIDE;
|
||||||
|
bool event(QEvent* _event) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QScopedPointer<Ui::MainWindow> m_ui;
|
||||||
|
QLabel* m_connectionStateIconLabel;
|
||||||
|
QLabel* m_encryptionStateIconLabel;
|
||||||
|
QLabel* m_synchronizationStateIconLabel;
|
||||||
|
QSystemTrayIcon* m_trayIcon;
|
||||||
|
QActionGroup* m_tabActionGroup;
|
||||||
|
bool m_isAboutToQuit;
|
||||||
|
|
||||||
|
static MainWindow* m_instance;
|
||||||
|
|
||||||
|
MainWindow();
|
||||||
|
~MainWindow();
|
||||||
|
|
||||||
|
void connectToSignals();
|
||||||
|
void initUi();
|
||||||
|
|
||||||
|
void minimizeToTray(bool _on);
|
||||||
|
void setStatusBarText(const QString& _text);
|
||||||
|
void showMessage(const QString& _text, QtMsgType _type);
|
||||||
|
void askForWalletPassword(bool _error);
|
||||||
|
void encryptedFlagChanged(bool _encrypted);
|
||||||
|
void peerCountUpdated(quint64 _peer_count);
|
||||||
|
void walletSynchronizationInProgress();
|
||||||
|
void walletSynchronized(int _error, const QString& _error_text);
|
||||||
|
void walletOpened(bool _error, const QString& _error_text);
|
||||||
|
void walletClosed();
|
||||||
|
|
||||||
|
Q_SLOT void createWallet();
|
||||||
|
Q_SLOT void openWallet();
|
||||||
|
Q_SLOT void backupWallet();
|
||||||
|
Q_SLOT void encryptWallet();
|
||||||
|
Q_SLOT void aboutQt();
|
||||||
|
Q_SLOT void about();
|
||||||
|
Q_SLOT void setStartOnLogin(bool _on);
|
||||||
|
Q_SLOT void setMinimizeToTray(bool _on);
|
||||||
|
Q_SLOT void setCloseToTray(bool _on);
|
||||||
|
|
||||||
|
#ifdef Q_OS_MAC
|
||||||
|
public:
|
||||||
|
void restoreFromDock();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void installDockHandler();
|
||||||
|
#elif defined(Q_OS_WIN)
|
||||||
|
protected:
|
||||||
|
void changeEvent(QEvent* _event) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void trayActivated(QSystemTrayIcon::ActivationReason _reason);
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
30
src/gui/MainWindow.mm
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#import <objc/runtime.h>
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
#include "mainwindow.h"
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
void dockClickHandler(id self, SEL _cmd) {
|
||||||
|
Q_UNUSED(self)
|
||||||
|
Q_UNUSED(_cmd)
|
||||||
|
MainWindow::instance().restoreFromDock();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::installDockHandler() {
|
||||||
|
Class cls = [[[NSApplication sharedApplication] delegate] class];
|
||||||
|
if (!class_replaceMethod(cls, @selector(applicationShouldHandleReopen:hasVisibleWindows:), (IMP) dockClickHandler, "v@:")) {
|
||||||
|
NSLog(@"MainWindow::installDockHandler() : class_addMethod failed!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
28
src/gui/NewAddressDialog.cpp
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#include "NewAddressDialog.h"
|
||||||
|
|
||||||
|
#include "ui_newaddressdialog.h"
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
NewAddressDialog::NewAddressDialog(QWidget* _parent) : QDialog(_parent), m_ui(new Ui::NewAddressDialog) {
|
||||||
|
m_ui->setupUi(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
NewAddressDialog::~NewAddressDialog() {
|
||||||
|
}
|
||||||
|
|
||||||
|
QString NewAddressDialog::getAddress() const {
|
||||||
|
return m_ui->m_addressEdit->text();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QString NewAddressDialog::getLabel() const {
|
||||||
|
return m_ui->m_labelEdit->text();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
31
src/gui/NewAddressDialog.h
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class NewAddressDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
class NewAddressDialog : public QDialog {
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY(NewAddressDialog)
|
||||||
|
|
||||||
|
public:
|
||||||
|
NewAddressDialog(QWidget* _parent);
|
||||||
|
~NewAddressDialog();
|
||||||
|
|
||||||
|
QString getAddress() const;
|
||||||
|
QString getLabel() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QScopedPointer<Ui::NewAddressDialog> m_ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
32
src/gui/NewPasswordDialog.cpp
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#include "NewPasswordDialog.h"
|
||||||
|
|
||||||
|
#include "ui_newpassworddialog.h"
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
NewPasswordDialog::NewPasswordDialog(QWidget* _parent) : QDialog(_parent), m_ui(new Ui::NewPasswordDialog) {
|
||||||
|
m_ui->setupUi(this);
|
||||||
|
m_ui->m_errorLabel->setText("");
|
||||||
|
}
|
||||||
|
|
||||||
|
NewPasswordDialog::~NewPasswordDialog() {
|
||||||
|
}
|
||||||
|
|
||||||
|
QString NewPasswordDialog::getPassword() const {
|
||||||
|
return m_ui->m_passwordEdit->text();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NewPasswordDialog::checkPassword(const QString& _password) {
|
||||||
|
bool passwordIsConfirmed = !(m_ui->m_passwordEdit->text().trimmed().isEmpty() ||
|
||||||
|
m_ui->m_passwordConfirmationEdit->text().trimmed().isEmpty() ||
|
||||||
|
m_ui->m_passwordEdit->text().compare(m_ui->m_passwordConfirmationEdit->text()));
|
||||||
|
m_ui->m_errorLabel->setText(passwordIsConfirmed ? "" : tr("Password not confirmed"));
|
||||||
|
m_ui->m_okButton->setEnabled(passwordIsConfirmed);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
32
src/gui/NewPasswordDialog.h
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class NewPasswordDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
class NewPasswordDialog : public QDialog {
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY(NewPasswordDialog)
|
||||||
|
|
||||||
|
public:
|
||||||
|
NewPasswordDialog(QWidget* _parent);
|
||||||
|
~NewPasswordDialog();
|
||||||
|
|
||||||
|
QString getPassword() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QScopedPointer<Ui::NewPasswordDialog> m_ui;
|
||||||
|
|
||||||
|
Q_SLOT void checkPassword(const QString& _password);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
95
src/gui/OverviewFrame.cpp
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#include "CurrencyAdapter.h"
|
||||||
|
#include "OverviewFrame.h"
|
||||||
|
#include "TransactionFrame.h"
|
||||||
|
#include "RecentTransactionsModel.h"
|
||||||
|
#include "WalletAdapter.h"
|
||||||
|
|
||||||
|
#include "ui_overviewframe.h"
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
class RecentTransactionsDelegate : public QStyledItemDelegate {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
RecentTransactionsDelegate(QObject* _parent) : QStyledItemDelegate(_parent) {
|
||||||
|
}
|
||||||
|
|
||||||
|
~RecentTransactionsDelegate() {
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget* createEditor(QWidget* _parent, const QStyleOptionViewItem& _option, const QModelIndex& _index) const Q_DECL_OVERRIDE {
|
||||||
|
if (!_index.isValid()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new TransactionFrame(_index, _parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize sizeHint(const QStyleOptionViewItem& _option, const QModelIndex& _index) const Q_DECL_OVERRIDE {
|
||||||
|
return QSize(346, 64);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
OverviewFrame::OverviewFrame(QWidget* _parent) : QFrame(_parent), m_ui(new Ui::OverviewFrame), m_transactionModel(new RecentTransactionsModel) {
|
||||||
|
m_ui->setupUi(this);
|
||||||
|
connect(&WalletAdapter::instance(), &WalletAdapter::walletActualBalanceUpdatedSignal, this, &OverviewFrame::updateActualBalance,
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
connect(&WalletAdapter::instance(), &WalletAdapter::walletPendingBalanceUpdatedSignal, this, &OverviewFrame::updatePendingBalance,
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
connect(&WalletAdapter::instance(), &WalletAdapter::walletCloseCompletedSignal, this, &OverviewFrame::reset,
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
connect(m_transactionModel.data(), &QAbstractItemModel::rowsInserted, this, &OverviewFrame::transactionsInserted);
|
||||||
|
connect(m_transactionModel.data(), &QAbstractItemModel::layoutChanged, this, &OverviewFrame::layoutChanged);
|
||||||
|
|
||||||
|
m_ui->m_tickerLabel1->setText(CurrencyAdapter::instance().getCurrencyTicker().toUpper());
|
||||||
|
m_ui->m_tickerLabel2->setText(CurrencyAdapter::instance().getCurrencyTicker().toUpper());
|
||||||
|
m_ui->m_tickerLabel3->setText(CurrencyAdapter::instance().getCurrencyTicker().toUpper());
|
||||||
|
|
||||||
|
m_ui->m_recentTransactionsView->setItemDelegate(new RecentTransactionsDelegate(this));
|
||||||
|
m_ui->m_recentTransactionsView->setModel(m_transactionModel.data());
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
OverviewFrame::~OverviewFrame() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void OverviewFrame::transactionsInserted(const QModelIndex& _parent, int _first, int _last) {
|
||||||
|
for (quint32 i = _first; i <= _last; ++i) {
|
||||||
|
QModelIndex recentModelIndex = m_transactionModel->index(i, 0);
|
||||||
|
m_ui->m_recentTransactionsView->openPersistentEditor(recentModelIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OverviewFrame::layoutChanged() {
|
||||||
|
for (quint32 i = 0; i <= m_transactionModel->rowCount(); ++i) {
|
||||||
|
QModelIndex recent_index = m_transactionModel->index(i, 0);
|
||||||
|
m_ui->m_recentTransactionsView->openPersistentEditor(recent_index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OverviewFrame::updateActualBalance(quint64 _balance) {
|
||||||
|
m_ui->m_actualBalanceLabel->setText(CurrencyAdapter::instance().formatAmount(_balance));
|
||||||
|
quint64 pendingBalance = WalletAdapter::instance().getPendingBalance();
|
||||||
|
m_ui->m_totalBalanceLabel->setText(CurrencyAdapter::instance().formatAmount(_balance + pendingBalance));
|
||||||
|
}
|
||||||
|
|
||||||
|
void OverviewFrame::updatePendingBalance(quint64 _balance) {
|
||||||
|
m_ui->m_pendingBalanceLabel->setText(CurrencyAdapter::instance().formatAmount(_balance));
|
||||||
|
quint64 actualBalance = WalletAdapter::instance().getActualBalance();
|
||||||
|
m_ui->m_totalBalanceLabel->setText(CurrencyAdapter::instance().formatAmount(_balance + actualBalance));
|
||||||
|
}
|
||||||
|
|
||||||
|
void OverviewFrame::reset() {
|
||||||
|
updateActualBalance(0);
|
||||||
|
updatePendingBalance(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "OverviewFrame.moc"
|
39
src/gui/OverviewFrame.h
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QFrame>
|
||||||
|
#include <QStyledItemDelegate>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class OverviewFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
class RecentTransactionsModel;
|
||||||
|
|
||||||
|
class OverviewFrame : public QFrame {
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY(OverviewFrame)
|
||||||
|
|
||||||
|
public:
|
||||||
|
OverviewFrame(QWidget* _parent);
|
||||||
|
~OverviewFrame();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QScopedPointer<Ui::OverviewFrame> m_ui;
|
||||||
|
QSharedPointer<RecentTransactionsModel> m_transactionModel;
|
||||||
|
|
||||||
|
void transactionsInserted(const QModelIndex& _parent, int _first, int _last);
|
||||||
|
void transactionsRemoved(const QModelIndex& _parent, int _first, int _last);
|
||||||
|
void layoutChanged();
|
||||||
|
void updateActualBalance(quint64 _balance);
|
||||||
|
void updatePendingBalance(quint64 _balance);
|
||||||
|
void reset();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
28
src/gui/PasswordDialog.cpp
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#include "PasswordDialog.h"
|
||||||
|
|
||||||
|
#include "ui_passworddialog.h"
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
PasswordDialog::PasswordDialog(bool _error, QWidget* _parent) : QDialog(_parent), m_ui(new Ui::PasswordDialog) {
|
||||||
|
m_ui->setupUi(this);
|
||||||
|
if (!_error) {
|
||||||
|
m_ui->m_errorLabel->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
adjustSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
PasswordDialog::~PasswordDialog() {
|
||||||
|
}
|
||||||
|
|
||||||
|
QString PasswordDialog::getPassword() const {
|
||||||
|
return m_ui->m_passwordEdit->text();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
30
src/gui/PasswordDialog.h
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class PasswordDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
class PasswordDialog : public QDialog {
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY(PasswordDialog)
|
||||||
|
|
||||||
|
public:
|
||||||
|
PasswordDialog(bool _error, QWidget* _parent);
|
||||||
|
~PasswordDialog();
|
||||||
|
|
||||||
|
QString getPassword() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QScopedPointer<Ui::PasswordDialog> m_ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
36
src/gui/ReceiveFrame.cpp
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#include <QClipboard>
|
||||||
|
|
||||||
|
#include "ReceiveFrame.h"
|
||||||
|
#include "WalletAdapter.h"
|
||||||
|
|
||||||
|
#include "ui_receiveframe.h"
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
ReceiveFrame::ReceiveFrame(QWidget* _parent) : QFrame(_parent), m_ui(new Ui::ReceiveFrame) {
|
||||||
|
m_ui->setupUi(this);
|
||||||
|
connect(&WalletAdapter::instance(), &WalletAdapter::updateWalletAddressSignal, this, &ReceiveFrame::updateWalletAddress);
|
||||||
|
connect(&WalletAdapter::instance(), &WalletAdapter::walletCloseCompletedSignal, this, &ReceiveFrame::reset);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReceiveFrame::~ReceiveFrame() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReceiveFrame::updateWalletAddress(const QString& _address) {
|
||||||
|
m_ui->m_addressEdit->setText(_address);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReceiveFrame::reset() {
|
||||||
|
m_ui->m_addressEdit->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReceiveFrame::copyAddress() {
|
||||||
|
QApplication::clipboard()->setText(m_ui->m_addressEdit->text());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
33
src/gui/ReceiveFrame.h
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QFrame>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class ReceiveFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
class ReceiveFrame : public QFrame {
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY(ReceiveFrame)
|
||||||
|
|
||||||
|
public:
|
||||||
|
ReceiveFrame(QWidget* _parent);
|
||||||
|
~ReceiveFrame();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QScopedPointer<Ui::ReceiveFrame> m_ui;
|
||||||
|
|
||||||
|
void updateWalletAddress(const QString& _address);
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
Q_SLOT void copyAddress();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
37
src/gui/RecentTransactionsModel.cpp
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#include "RecentTransactionsModel.h"
|
||||||
|
#include "SortedTransactionsModel.h"
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
RecentTransactionsModel::RecentTransactionsModel() : QSortFilterProxyModel() {
|
||||||
|
setSourceModel(&SortedTransactionsModel::instance());
|
||||||
|
setDynamicSortFilter(true);
|
||||||
|
connect(sourceModel(), &QAbstractItemModel::rowsInserted, this, &RecentTransactionsModel::invalidateFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
RecentTransactionsModel::~RecentTransactionsModel() {
|
||||||
|
}
|
||||||
|
|
||||||
|
int RecentTransactionsModel::columnCount(const QModelIndex& _parent) const {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant RecentTransactionsModel::data(const QModelIndex& _index, int _role) const {
|
||||||
|
if(_role == Qt::DecorationRole) {
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
return QSortFilterProxyModel::data(_index, _role);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RecentTransactionsModel::filterAcceptsRow(int _sourceRow, const QModelIndex& _sourceParent) const {
|
||||||
|
return _sourceRow < 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
25
src/gui/RecentTransactionsModel.h
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QSortFilterProxyModel>
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
class RecentTransactionsModel : public QSortFilterProxyModel {
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY(RecentTransactionsModel)
|
||||||
|
|
||||||
|
public:
|
||||||
|
RecentTransactionsModel();
|
||||||
|
~RecentTransactionsModel();
|
||||||
|
|
||||||
|
int columnCount(const QModelIndex& _parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
||||||
|
QVariant data(const QModelIndex& _index, int _role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
|
||||||
|
bool filterAcceptsRow(int _source_row, const QModelIndex& _source_parent) const Q_DECL_OVERRIDE;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
114
src/gui/SendFrame.cpp
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#include "AddressBookModel.h"
|
||||||
|
#include "CurrencyAdapter.h"
|
||||||
|
#include "MainWindow.h"
|
||||||
|
#include "NodeAdapter.h"
|
||||||
|
#include "SendFrame.h"
|
||||||
|
#include "TransferFrame.h"
|
||||||
|
#include "WalletAdapter.h"
|
||||||
|
#include "WalletEvents.h"
|
||||||
|
|
||||||
|
#include "ui_sendframe.h"
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
const quint64 MINIMAL_FEE = 1000000;
|
||||||
|
|
||||||
|
SendFrame::SendFrame(QWidget* _parent) : QFrame(_parent), m_ui(new Ui::SendFrame) {
|
||||||
|
m_ui->setupUi(this);
|
||||||
|
clearAllClicked();
|
||||||
|
mixinValueChanged(m_ui->m_mixinSlider->value());
|
||||||
|
|
||||||
|
connect(&WalletAdapter::instance(), &WalletAdapter::walletSendTransactionCompletedSignal, this, &SendFrame::sendTransactionCompleted,
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
connect(&WalletAdapter::instance(), &WalletAdapter::walletActualBalanceUpdatedSignal, this, &SendFrame::walletActualBalanceUpdated,
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
|
||||||
|
m_ui->m_tickerLabel->setText(CurrencyAdapter::instance().getCurrencyTicker().toUpper());
|
||||||
|
}
|
||||||
|
|
||||||
|
SendFrame::~SendFrame() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendFrame::addRecipientClicked() {
|
||||||
|
TransferFrame* newTransfer = new TransferFrame(m_ui->m_transfersScrollarea);
|
||||||
|
m_ui->m_send_frame_layout->insertWidget(m_transfers.size(), newTransfer);
|
||||||
|
m_transfers.append(newTransfer);
|
||||||
|
if (m_transfers.size() == 1) {
|
||||||
|
newTransfer->disableRemoveButton(true);
|
||||||
|
} else {
|
||||||
|
m_transfers[0]->disableRemoveButton(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(newTransfer, &TransferFrame::destroyed, [this](QObject* _obj) {
|
||||||
|
m_transfers.removeOne(static_cast<TransferFrame*>(_obj));
|
||||||
|
if (m_transfers.size() == 1) {
|
||||||
|
m_transfers[0]->disableRemoveButton(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendFrame::clearAllClicked() {
|
||||||
|
Q_FOREACH (TransferFrame* transfer, m_transfers) {
|
||||||
|
transfer->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_transfers.clear();
|
||||||
|
addRecipientClicked();
|
||||||
|
m_ui->m_paymentIdEdit->clear();
|
||||||
|
m_ui->m_mixinSlider->setValue(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendFrame::sendClicked() {
|
||||||
|
QVector<CryptoNote::Transfer> walletTransfers;
|
||||||
|
Q_FOREACH (TransferFrame * transfer, m_transfers) {
|
||||||
|
QString address = transfer->getAddress();
|
||||||
|
if (!CurrencyAdapter::instance().validateAddress(address)) {
|
||||||
|
QCoreApplication::postEvent(
|
||||||
|
&MainWindow::instance(),
|
||||||
|
new ShowMessageEvent(tr("Invalid recipient address"), QtCriticalMsg));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CryptoNote::Transfer walletTransfer;
|
||||||
|
walletTransfer.address = address.toStdString();
|
||||||
|
uint64_t amount = CurrencyAdapter::instance().parseAmount(transfer->getAmountString());
|
||||||
|
walletTransfer.amount = amount;
|
||||||
|
walletTransfers.push_back(walletTransfer);
|
||||||
|
QString label = transfer->getLabel();
|
||||||
|
if (!label.isEmpty()) {
|
||||||
|
AddressBookModel::instance().addAddress(label, address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
quint64 fee = MINIMAL_FEE;
|
||||||
|
if (fee < MINIMAL_FEE) {
|
||||||
|
QCoreApplication::postEvent(&MainWindow::instance(), new ShowMessageEvent(tr("Minimum allowed fee is 0.01"), QtCriticalMsg));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WalletAdapter::instance().isOpen()) {
|
||||||
|
WalletAdapter::instance().sendTransaction(walletTransfers, fee, m_ui->m_paymentIdEdit->text(), m_ui->m_mixinSlider->value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendFrame::mixinValueChanged(int _value) {
|
||||||
|
m_ui->m_mixinEdit->setText(QString::number(_value));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendFrame::sendTransactionCompleted(CryptoNote::TransactionId _id, bool _result, const QString& _errorText) {
|
||||||
|
Q_UNUSED(_id);
|
||||||
|
Q_UNUSED(_result);
|
||||||
|
Q_UNUSED(_errorText);
|
||||||
|
clearAllClicked();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendFrame::walletActualBalanceUpdated(quint64 _balance) {
|
||||||
|
m_ui->m_balanceLabel->setText(CurrencyAdapter::instance().formatAmount(_balance));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
41
src/gui/SendFrame.h
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QFrame>
|
||||||
|
|
||||||
|
#include <IWallet.h>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class SendFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
class TransferFrame;
|
||||||
|
|
||||||
|
class SendFrame : public QFrame {
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY(SendFrame)
|
||||||
|
|
||||||
|
public:
|
||||||
|
SendFrame(QWidget* _parent);
|
||||||
|
~SendFrame();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QScopedPointer<Ui::SendFrame> m_ui;
|
||||||
|
QList<TransferFrame*> m_transfers;
|
||||||
|
|
||||||
|
void sendTransactionCompleted(CryptoNote::TransactionId _id, bool _result, const QString& _error_text);
|
||||||
|
void walletActualBalanceUpdated(quint64 _balance);
|
||||||
|
|
||||||
|
Q_SLOT void addRecipientClicked();
|
||||||
|
Q_SLOT void clearAllClicked();
|
||||||
|
Q_SLOT void mixinValueChanged(int _value);
|
||||||
|
Q_SLOT void sendClicked();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
45
src/gui/SortedTransactionsModel.cpp
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#include <QDateTime>
|
||||||
|
|
||||||
|
#include "SortedTransactionsModel.h"
|
||||||
|
#include "TransactionsModel.h"
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
SortedTransactionsModel& SortedTransactionsModel::instance() {
|
||||||
|
static SortedTransactionsModel inst;
|
||||||
|
return inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
SortedTransactionsModel::SortedTransactionsModel() : QSortFilterProxyModel() {
|
||||||
|
setSourceModel(&TransactionsModel::instance());
|
||||||
|
setDynamicSortFilter(true);
|
||||||
|
sort(TransactionsModel::COLUMN_DATE, Qt::DescendingOrder);
|
||||||
|
}
|
||||||
|
|
||||||
|
SortedTransactionsModel::~SortedTransactionsModel() {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SortedTransactionsModel::lessThan(const QModelIndex& _left, const QModelIndex& _right) const {
|
||||||
|
QDateTime leftDate = _left.data(TransactionsModel::ROLE_DATE).toDateTime();
|
||||||
|
QDateTime rightDate = _right.data(TransactionsModel::ROLE_DATE).toDateTime();
|
||||||
|
if((rightDate.isNull() || !rightDate.isValid()) && (leftDate.isNull() || !leftDate.isValid())) {
|
||||||
|
return _left.row() < _right.row();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(leftDate.isNull() || !leftDate.isValid()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(rightDate.isNull() || !rightDate.isValid()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return leftDate < rightDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
29
src/gui/SortedTransactionsModel.h
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QSortFilterProxyModel>
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
class SortedTransactionsModel : public QSortFilterProxyModel {
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY(SortedTransactionsModel)
|
||||||
|
|
||||||
|
public:
|
||||||
|
static SortedTransactionsModel& instance();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool lessThan(const QModelIndex& _left, const QModelIndex& _right) const Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
private:
|
||||||
|
SortedTransactionsModel();
|
||||||
|
~SortedTransactionsModel();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
46
src/gui/TransactionDetailsDialog.cpp
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#include <QDateTime>
|
||||||
|
|
||||||
|
#include "CurrencyAdapter.h"
|
||||||
|
#include "TransactionDetailsDialog.h"
|
||||||
|
#include "TransactionsModel.h"
|
||||||
|
|
||||||
|
#include "ui_transactiondetailsdialog.h"
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
TransactionDetailsDialog::TransactionDetailsDialog(const QModelIndex& _index, QWidget* _parent) : QDialog(_parent),
|
||||||
|
m_ui(new Ui::TransactionDetailsDialog), m_detailsTemplate(
|
||||||
|
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
|
||||||
|
"</style></head><body style=\" font-family:'Cantarell'; font-size:11pt; font-weight:400; font-style:normal;\">\n"
|
||||||
|
"<span style=\" font-weight:600;\">Status: </span>%1</p><br>\n"
|
||||||
|
"<span style=\" font-weight:600;\">Date: </span>%2</p><br>\n"
|
||||||
|
"<span style=\" font-weight:600;\">To: </span>%4</p><br>\n"
|
||||||
|
"<span style=\" font-weight:600;\">Amount: </span>%5</p><br>\n"
|
||||||
|
"<span style=\" font-weight:600;\">Fee: </span>%6</p><br>\n"
|
||||||
|
"<span style=\" font-weight:600;\">Transaction hash: </span>%8</p></body></html>") {
|
||||||
|
m_ui->setupUi(this);
|
||||||
|
|
||||||
|
QModelIndex index = TransactionsModel::instance().index(_index.data(TransactionsModel::ROLE_ROW).toInt(),
|
||||||
|
_index.data(TransactionsModel::ROLE_ROW).toInt());
|
||||||
|
|
||||||
|
quint64 numberOfConfirmations = index.data(TransactionsModel::ROLE_NUMBER_OF_CONFIRMATIONS).value<quint64>();
|
||||||
|
QString amountText = index.sibling(index.row(), TransactionsModel::COLUMN_AMOUNT).data().toString() + " " +
|
||||||
|
CurrencyAdapter::instance().getCurrencyTicker().toUpper();
|
||||||
|
QString feeText = CurrencyAdapter::instance().formatAmount(index.data(TransactionsModel::ROLE_FEE).value<quint64>()) + " " +
|
||||||
|
CurrencyAdapter::instance().getCurrencyTicker().toUpper();
|
||||||
|
|
||||||
|
m_ui->m_detailsBrowser->setHtml(m_detailsTemplate.arg(QString("%1 confirmations").arg(numberOfConfirmations)).
|
||||||
|
arg(index.sibling(index.row(), TransactionsModel::COLUMN_DATE).data().toString()).arg(index.sibling(index.row(),
|
||||||
|
TransactionsModel::COLUMN_ADDRESS).data().toString()).arg(amountText).arg(feeText).
|
||||||
|
arg(index.sibling(index.row(), TransactionsModel::COLUMN_HASH).data().toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
TransactionDetailsDialog::~TransactionDetailsDialog() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
29
src/gui/TransactionDetailsDialog.h
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class TransactionDetailsDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
class TransactionDetailsDialog : public QDialog {
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY(TransactionDetailsDialog)
|
||||||
|
|
||||||
|
public:
|
||||||
|
TransactionDetailsDialog(const QModelIndex &_index, QWidget* _parent);
|
||||||
|
~TransactionDetailsDialog();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QScopedPointer<Ui::TransactionDetailsDialog> m_ui;
|
||||||
|
const QString m_detailsTemplate;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
68
src/gui/TransactionFrame.cpp
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#include <QFontDatabase>
|
||||||
|
|
||||||
|
#include "MainWindow.h"
|
||||||
|
#include "TransactionFrame.h"
|
||||||
|
#include "TransactionsModel.h"
|
||||||
|
|
||||||
|
#include "ui_transactionframe.h"
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
class RecentTransactionDelegate : public QStyledItemDelegate {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
RecentTransactionDelegate(QObject* _parent) : QStyledItemDelegate(_parent) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
~RecentTransactionDelegate() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void setEditorData(QWidget* _editor, const QModelIndex& _index) const Q_DECL_OVERRIDE {
|
||||||
|
switch(_index.column()) {
|
||||||
|
case TransactionsModel::COLUMN_AMOUNT:
|
||||||
|
case TransactionsModel::COLUMN_HASH:
|
||||||
|
case TransactionsModel::COLUMN_DATE:
|
||||||
|
static_cast<QLabel*>(_editor)->setText(_index.data().toString());
|
||||||
|
return;
|
||||||
|
case TransactionsModel::COLUMN_TYPE:
|
||||||
|
static_cast<QLabel*>(_editor)->setPixmap(_index.data(TransactionsModel::ROLE_ICON).value<QPixmap>());
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TransactionFrame::TransactionFrame(const QModelIndex& _index, QWidget* _parent) : QFrame(_parent),
|
||||||
|
m_ui(new Ui::TransactionFrame), m_dataMapper(this), m_index(_index) {
|
||||||
|
m_ui->setupUi(this);
|
||||||
|
QFont font = QFontDatabase::systemFont(QFontDatabase::FixedFont);
|
||||||
|
font.setPixelSize(11);
|
||||||
|
m_ui->m_hashLabel->setFont(font);
|
||||||
|
|
||||||
|
m_dataMapper.setModel(const_cast<QAbstractItemModel*>(m_index.model()));
|
||||||
|
m_dataMapper.setItemDelegate(new RecentTransactionDelegate(this));
|
||||||
|
m_dataMapper.addMapping(m_ui->m_iconLabel, TransactionsModel::COLUMN_TYPE);
|
||||||
|
m_dataMapper.addMapping(m_ui->m_amountLabel, TransactionsModel::COLUMN_AMOUNT);
|
||||||
|
m_dataMapper.addMapping(m_ui->m_timeLabel, TransactionsModel::COLUMN_DATE);
|
||||||
|
m_dataMapper.addMapping(m_ui->m_hashLabel, TransactionsModel::COLUMN_HASH);
|
||||||
|
m_dataMapper.setCurrentModelIndex(m_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
TransactionFrame::~TransactionFrame() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransactionFrame::mousePressEvent(QMouseEvent* _event) {
|
||||||
|
MainWindow::instance().scrollToTransaction(TransactionsModel::instance().index(m_index.data(TransactionsModel::ROLE_ROW).toInt(), 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "TransactionFrame.moc"
|
36
src/gui/TransactionFrame.h
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QDataWidgetMapper>
|
||||||
|
#include <QFrame>
|
||||||
|
#include <QModelIndex>
|
||||||
|
#include <QStyledItemDelegate>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class TransactionFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
class TransactionFrame : public QFrame {
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY(TransactionFrame)
|
||||||
|
|
||||||
|
public:
|
||||||
|
TransactionFrame(const QModelIndex &_index, QWidget* _parent);
|
||||||
|
~TransactionFrame();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void mousePressEvent(QMouseEvent* _event) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QScopedPointer<Ui::TransactionFrame> m_ui;
|
||||||
|
QDataWidgetMapper m_dataMapper;
|
||||||
|
QPersistentModelIndex m_index;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
62
src/gui/TransactionsFrame.cpp
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QLabel>
|
||||||
|
|
||||||
|
#include "MainWindow.h"
|
||||||
|
#include "SortedTransactionsModel.h"
|
||||||
|
#include "TransactionsFrame.h"
|
||||||
|
#include "TransactionDetailsDialog.h"
|
||||||
|
#include "TransactionsListModel.h"
|
||||||
|
#include "TransactionsModel.h"
|
||||||
|
|
||||||
|
#include "ui_transactionsframe.h"
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
TransactionsFrame::TransactionsFrame(QWidget* _parent) : QFrame(_parent), m_ui(new Ui::TransactionsFrame),
|
||||||
|
m_transactionsModel(new TransactionsListModel) {
|
||||||
|
m_ui->setupUi(this);
|
||||||
|
m_ui->m_transactionsView->setModel(m_transactionsModel.data());
|
||||||
|
m_ui->m_transactionsView->header()->setSectionResizeMode(TransactionsModel::COLUMN_STATE, QHeaderView::Fixed);
|
||||||
|
m_ui->m_transactionsView->header()->resizeSection(TransactionsModel::COLUMN_STATE, 25);
|
||||||
|
m_ui->m_transactionsView->header()->resizeSection(TransactionsModel::COLUMN_DATE, 140);
|
||||||
|
m_ui->m_transactionsView->header()->resizeSection(TransactionsModel::COLUMN_ADDRESS, 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
TransactionsFrame::~TransactionsFrame() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransactionsFrame::scrollToTransaction(const QModelIndex& _index) {
|
||||||
|
QModelIndex sortedModelIndex = SortedTransactionsModel::instance().mapFromSource(_index);
|
||||||
|
QModelIndex index = static_cast<QSortFilterProxyModel*>(m_ui->m_transactionsView->model())->mapFromSource(sortedModelIndex);
|
||||||
|
m_ui->m_transactionsView->scrollTo(index);
|
||||||
|
m_ui->m_transactionsView->setFocus();
|
||||||
|
m_ui->m_transactionsView->setCurrentIndex(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransactionsFrame::exportToCsv() {
|
||||||
|
QString file = QFileDialog::getSaveFileName(&MainWindow::instance(), tr("Select CSV file"), QDir::homePath(), "CSV (*.csv)");
|
||||||
|
if (!file.isEmpty()) {
|
||||||
|
QByteArray csv = TransactionsModel::instance().toCsv();
|
||||||
|
QFile f(file);
|
||||||
|
if (f.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
|
||||||
|
f.write(csv);
|
||||||
|
f.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransactionsFrame::showTransactionDetails(const QModelIndex& _index) {
|
||||||
|
if (!_index.isValid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TransactionDetailsDialog dlg(_index, &MainWindow::instance());
|
||||||
|
dlg.exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
37
src/gui/TransactionsFrame.h
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QFrame>
|
||||||
|
#include <QStyledItemDelegate>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class TransactionsFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
class TransactionsListModel;
|
||||||
|
|
||||||
|
class TransactionsFrame : public QFrame {
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY(TransactionsFrame)
|
||||||
|
|
||||||
|
public:
|
||||||
|
TransactionsFrame(QWidget* _parent);
|
||||||
|
~TransactionsFrame();
|
||||||
|
|
||||||
|
void scrollToTransaction(const QModelIndex& _index);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QScopedPointer<Ui::TransactionsFrame> m_ui;
|
||||||
|
QScopedPointer<TransactionsListModel> m_transactionsModel;
|
||||||
|
|
||||||
|
Q_SLOT void exportToCsv();
|
||||||
|
Q_SLOT void showTransactionDetails(const QModelIndex& _index);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
25
src/gui/TransactionsListModel.cpp
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#include "SortedTransactionsModel.h"
|
||||||
|
#include "TransactionsListModel.h"
|
||||||
|
#include "TransactionsModel.h"
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
TransactionsListModel::TransactionsListModel() : QSortFilterProxyModel() {
|
||||||
|
setSourceModel(&SortedTransactionsModel::instance());
|
||||||
|
}
|
||||||
|
|
||||||
|
TransactionsListModel::~TransactionsListModel() {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TransactionsListModel::filterAcceptsColumn(int _sourceColumn, const QModelIndex& _sourceParent) const {
|
||||||
|
quint32 column = sourceModel()->headerData(_sourceColumn, Qt::Horizontal, TransactionsModel::ROLE_COLUMN).toUInt();
|
||||||
|
return column != TransactionsModel::COLUMN_HASH && column != TransactionsModel::COLUMN_FEE && column != TransactionsModel::COLUMN_HEIGHT &&
|
||||||
|
column != TransactionsModel::COLUMN_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
23
src/gui/TransactionsListModel.h
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QSortFilterProxyModel>
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
class TransactionsListModel : public QSortFilterProxyModel {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
TransactionsListModel();
|
||||||
|
~TransactionsListModel();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool filterAcceptsColumn(int _sourceColumn, const QModelIndex& _sourceParent) const Q_DECL_OVERRIDE;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
394
src/gui/TransactionsModel.cpp
Normal file
|
@ -0,0 +1,394 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QFont>
|
||||||
|
#include <QMetaEnum>
|
||||||
|
#include <QPixmap>
|
||||||
|
|
||||||
|
#include "CurrencyAdapter.h"
|
||||||
|
#include "NodeAdapter.h"
|
||||||
|
#include "TransactionsModel.h"
|
||||||
|
#include "WalletAdapter.h"
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
enum class TransactionType : quint8 {MINED, INPUT, OUTPUT, INOUT};
|
||||||
|
|
||||||
|
const int TRANSACTIONS_MODEL_COLUMN_COUNT =
|
||||||
|
TransactionsModel::staticMetaObject.enumerator(TransactionsModel::staticMetaObject.indexOfEnumerator("Columns")).keyCount();
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
QPixmap getTransactionIcon(TransactionType _transactionType) {
|
||||||
|
switch (_transactionType) {
|
||||||
|
case TransactionType::MINED:
|
||||||
|
return QPixmap(":icons/tx-mined");
|
||||||
|
case TransactionType::INPUT:
|
||||||
|
return QPixmap(":icons/tx-input");
|
||||||
|
case TransactionType::OUTPUT:
|
||||||
|
return QPixmap(":icons/tx-output");
|
||||||
|
case TransactionType::INOUT:
|
||||||
|
return QPixmap(":icons/tx-inout");
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QPixmap();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
TransactionsModel& TransactionsModel::instance() {
|
||||||
|
static TransactionsModel inst;
|
||||||
|
return inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
TransactionsModel::TransactionsModel() : QAbstractItemModel() {
|
||||||
|
connect(&WalletAdapter::instance(), &WalletAdapter::reloadWalletTransactionsSignal, this, &TransactionsModel::reloadWalletTransactions,
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
connect(&WalletAdapter::instance(), &WalletAdapter::walletTransactionCreatedSignal, this,
|
||||||
|
static_cast<void(TransactionsModel::*)(CryptoNote::TransactionId)>(&TransactionsModel::appendTransaction), Qt::QueuedConnection);
|
||||||
|
connect(&WalletAdapter::instance(), &WalletAdapter::walletTransactionUpdatedSignal, this, &TransactionsModel::updateWalletTransaction,
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
connect(&NodeAdapter::instance(), &NodeAdapter::localBlockchainUpdatedSignal, this, &TransactionsModel::localBlockchainUpdated,
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
connect(&WalletAdapter::instance(), &WalletAdapter::walletCloseCompletedSignal, this, &TransactionsModel::reset,
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
}
|
||||||
|
|
||||||
|
TransactionsModel::~TransactionsModel() {
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::ItemFlags TransactionsModel::flags(const QModelIndex& _index) const {
|
||||||
|
Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemNeverHasChildren | Qt::ItemIsSelectable;
|
||||||
|
if(_index.column() == COLUMN_HASH) {
|
||||||
|
flags |= Qt::ItemIsEditable;
|
||||||
|
}
|
||||||
|
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TransactionsModel::columnCount(const QModelIndex& _parent) const {
|
||||||
|
return TRANSACTIONS_MODEL_COLUMN_COUNT;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TransactionsModel::rowCount(const QModelIndex& _parent) const {
|
||||||
|
return m_transfers.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant TransactionsModel::headerData(int _section, Qt::Orientation _orientation, int _role) const {
|
||||||
|
if(_orientation != Qt::Horizontal) {
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(_role) {
|
||||||
|
case Qt::DisplayRole:
|
||||||
|
switch(_section) {
|
||||||
|
case COLUMN_STATE:
|
||||||
|
return QVariant();
|
||||||
|
case COLUMN_DATE:
|
||||||
|
return tr("Date");
|
||||||
|
case COLUMN_TYPE:
|
||||||
|
return tr("Type");
|
||||||
|
case COLUMN_HASH:
|
||||||
|
return tr("Hash");
|
||||||
|
case COLUMN_ADDRESS:
|
||||||
|
return tr("Address");
|
||||||
|
case COLUMN_AMOUNT:
|
||||||
|
return tr("Amount");
|
||||||
|
case COLUMN_PAYMENT_ID:
|
||||||
|
return tr("PaymentID");
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Qt::TextAlignmentRole:
|
||||||
|
if (_section == COLUMN_AMOUNT) {
|
||||||
|
return static_cast<int>(Qt::AlignRight | Qt::AlignVCenter);
|
||||||
|
}
|
||||||
|
|
||||||
|
return QVariant();
|
||||||
|
|
||||||
|
case ROLE_COLUMN:
|
||||||
|
return _section;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant TransactionsModel::data(const QModelIndex& _index, int _role) const {
|
||||||
|
if(!_index.isValid()) {
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
CryptoNote::TransactionInfo transaction;
|
||||||
|
CryptoNote::Transfer transfer;
|
||||||
|
CryptoNote::TransactionId transactionId = m_transfers.value(_index.row()).first;
|
||||||
|
CryptoNote::TransferId transferId = m_transfers.value(_index.row()).second;
|
||||||
|
|
||||||
|
if(!WalletAdapter::instance().getTransaction(transactionId, transaction) ||
|
||||||
|
(m_transfers.value(_index.row()).second != CryptoNote::INVALID_TRANSFER_ID &&
|
||||||
|
!WalletAdapter::instance().getTransfer(transferId, transfer))) {
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(_role) {
|
||||||
|
case Qt::DisplayRole:
|
||||||
|
case Qt::EditRole:
|
||||||
|
return getDisplayRole(_index);
|
||||||
|
|
||||||
|
case Qt::DecorationRole:
|
||||||
|
return getDecorationRole(_index);
|
||||||
|
|
||||||
|
case Qt::TextAlignmentRole:
|
||||||
|
return getAlignmentRole(_index);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return getUserRole(_index, _role, transactionId, transaction, transferId, transfer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex TransactionsModel::index(int _row, int _column, const QModelIndex& _parent) const {
|
||||||
|
if(_parent.isValid()) {
|
||||||
|
return QModelIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
return createIndex(_row, _column, _row);
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex TransactionsModel::parent(const QModelIndex& _index) const {
|
||||||
|
return QModelIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray TransactionsModel::toCsv() const {
|
||||||
|
QByteArray res;
|
||||||
|
res.append("\"State\",\"Date\",\"Amount\",\"Fee\",\"Hash\",\"Height\",\"Address\",\"Payment ID\"\n");
|
||||||
|
for (quint32 row = 0; row < rowCount(); ++row) {
|
||||||
|
QModelIndex ind = index(row, 0);
|
||||||
|
res.append("\"").append(ind.data().toString().toUtf8()).append("\",");
|
||||||
|
res.append("\"").append(ind.sibling(row, COLUMN_DATE).data().toString().toUtf8()).append("\",");
|
||||||
|
res.append("\"").append(ind.sibling(row, COLUMN_AMOUNT).data().toString().toUtf8()).append("\",");
|
||||||
|
res.append("\"").append(ind.sibling(row, COLUMN_FEE).data().toString().toUtf8()).append("\",");
|
||||||
|
res.append("\"").append(ind.sibling(row, COLUMN_HASH).data().toString().toUtf8()).append("\",");
|
||||||
|
res.append("\"").append(ind.sibling(row, COLUMN_HEIGHT).data().toString().toUtf8()).append("\",");
|
||||||
|
res.append("\"").append(ind.sibling(row, COLUMN_ADDRESS).data().toString().toUtf8()).append("\",");
|
||||||
|
res.append("\"").append(ind.sibling(row, COLUMN_PAYMENT_ID).data().toString().toUtf8()).append("\"\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant TransactionsModel::getDisplayRole(const QModelIndex& _index) const {
|
||||||
|
switch(_index.column()) {
|
||||||
|
case COLUMN_DATE: {
|
||||||
|
QDateTime date = _index.data(ROLE_DATE).toDateTime();
|
||||||
|
return (date.isNull() || !date.isValid() ? "-" : date.toString("dd-MM-yy HH:mm"));
|
||||||
|
}
|
||||||
|
|
||||||
|
case COLUMN_HASH:
|
||||||
|
return _index.data(ROLE_HASH).toByteArray().toHex().toUpper();
|
||||||
|
|
||||||
|
case COLUMN_ADDRESS: {
|
||||||
|
TransactionType transactionType = static_cast<TransactionType>(_index.data(ROLE_TYPE).value<quint8>());
|
||||||
|
QString transactionAddress = _index.data(ROLE_ADDRESS).toString();
|
||||||
|
if (transactionType == TransactionType::INPUT || transactionType == TransactionType::MINED ||
|
||||||
|
transactionType == TransactionType::INOUT) {
|
||||||
|
return QString(tr("me (%1)").arg(WalletAdapter::instance().getAddress()));
|
||||||
|
} else if (transactionAddress.isEmpty()) {
|
||||||
|
return tr("(n/a)");
|
||||||
|
}
|
||||||
|
|
||||||
|
return transactionAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
case COLUMN_AMOUNT: {
|
||||||
|
qint64 amount = _index.data(ROLE_AMOUNT).value<qint64>();
|
||||||
|
QString amountStr = CurrencyAdapter::instance().formatAmount(qAbs(amount));
|
||||||
|
return (amount < 0 ? "-" + amountStr : amountStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
case COLUMN_PAYMENT_ID:
|
||||||
|
return _index.data(ROLE_PAYMENT_ID);
|
||||||
|
|
||||||
|
case COLUMN_FEE: {
|
||||||
|
qint64 fee = _index.data(ROLE_FEE).value<qint64>();
|
||||||
|
return CurrencyAdapter::instance().formatAmount(fee);
|
||||||
|
}
|
||||||
|
|
||||||
|
case COLUMN_HEIGHT:
|
||||||
|
return QString::number(_index.data(ROLE_HEIGHT).value<quint64>());
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant TransactionsModel::getDecorationRole(const QModelIndex& _index) const {
|
||||||
|
if(_index.column() == COLUMN_STATE) {
|
||||||
|
quint64 numberOfConfirmations = _index.data(ROLE_NUMBER_OF_CONFIRMATIONS).value<quint64>();
|
||||||
|
if(numberOfConfirmations == 0) {
|
||||||
|
return QPixmap(":icons/unconfirmed");
|
||||||
|
} else if(numberOfConfirmations < 2) {
|
||||||
|
return QPixmap(":icons/clock1");
|
||||||
|
} else if(numberOfConfirmations < 4) {
|
||||||
|
return QPixmap(":icons/clock2");
|
||||||
|
} else if(numberOfConfirmations < 6) {
|
||||||
|
return QPixmap(":icons/clock3");
|
||||||
|
} else if(numberOfConfirmations < 8) {
|
||||||
|
return QPixmap(":icons/clock4");
|
||||||
|
} else if(numberOfConfirmations < 10) {
|
||||||
|
return QPixmap(":icons/clock5");
|
||||||
|
} else {
|
||||||
|
return QPixmap(":icons/transaction");
|
||||||
|
}
|
||||||
|
} else if (_index.column() == COLUMN_ADDRESS) {
|
||||||
|
return _index.data(ROLE_ICON).value<QPixmap>().scaled(20, 20, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||||
|
}
|
||||||
|
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant TransactionsModel::getAlignmentRole(const QModelIndex& _index) const {
|
||||||
|
return headerData(_index.column(), Qt::Horizontal, Qt::TextAlignmentRole);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant TransactionsModel::getUserRole(const QModelIndex& _index, int _role, CryptoNote::TransactionId _transactionId,
|
||||||
|
CryptoNote::TransactionInfo& _transaction, CryptoNote::TransferId _transferId, CryptoNote::Transfer& _transfer) const {
|
||||||
|
switch(_role) {
|
||||||
|
case ROLE_DATE:
|
||||||
|
return (_transaction.timestamp > 0 ? QDateTime::fromTime_t(_transaction.timestamp) : QDateTime());
|
||||||
|
|
||||||
|
case ROLE_TYPE: {
|
||||||
|
QString transactionAddress = _index.data(ROLE_ADDRESS).toString();
|
||||||
|
if(_transaction.isCoinbase) {
|
||||||
|
return static_cast<quint8>(TransactionType::MINED);
|
||||||
|
} else if (!transactionAddress.compare(WalletAdapter::instance().getAddress())) {
|
||||||
|
return static_cast<quint8>(TransactionType::INOUT);
|
||||||
|
} else if(_transaction.totalAmount < 0) {
|
||||||
|
return static_cast<quint8>(TransactionType::OUTPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
return static_cast<quint8>(TransactionType::INPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
case ROLE_HASH:
|
||||||
|
return QByteArray(reinterpret_cast<char*>(&_transaction.hash.front()), _transaction.hash.size());
|
||||||
|
|
||||||
|
case ROLE_ADDRESS:
|
||||||
|
return QString::fromStdString(_transfer.address);
|
||||||
|
|
||||||
|
case ROLE_AMOUNT:
|
||||||
|
return static_cast<qint64>(_transferId == CryptoNote::INVALID_TRANSFER_ID ? _transaction.totalAmount : -_transfer.amount);
|
||||||
|
|
||||||
|
case ROLE_PAYMENT_ID:
|
||||||
|
return NodeAdapter::instance().extractPaymentId(_transaction.extra);
|
||||||
|
|
||||||
|
case ROLE_ICON: {
|
||||||
|
TransactionType transactionType = static_cast<TransactionType>(_index.data(ROLE_TYPE).value<quint8>());
|
||||||
|
return getTransactionIcon(transactionType);
|
||||||
|
}
|
||||||
|
|
||||||
|
case ROLE_TRANSACTION_ID:
|
||||||
|
return QVariant::fromValue(_transactionId);
|
||||||
|
|
||||||
|
case ROLE_HEIGHT:
|
||||||
|
return static_cast<quint64>(_transaction.blockHeight);
|
||||||
|
|
||||||
|
case ROLE_FEE:
|
||||||
|
return static_cast<quint64>(_transaction.fee);
|
||||||
|
|
||||||
|
case ROLE_NUMBER_OF_CONFIRMATIONS:
|
||||||
|
return (_transaction.blockHeight == CryptoNote::UNCONFIRMED_TRANSACTION_HEIGHT ? 0 :
|
||||||
|
NodeAdapter::instance().getLastKnownBlockHeight() - _transaction.blockHeight + 1);
|
||||||
|
|
||||||
|
case ROLE_COLUMN:
|
||||||
|
return headerData(_index.column(), Qt::Horizontal, ROLE_COLUMN);
|
||||||
|
|
||||||
|
case ROLE_ROW:
|
||||||
|
return _index.row();
|
||||||
|
}
|
||||||
|
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransactionsModel::reloadWalletTransactions() {
|
||||||
|
beginResetModel();
|
||||||
|
m_transfers.clear();
|
||||||
|
m_transactionRow.clear();
|
||||||
|
endResetModel();
|
||||||
|
|
||||||
|
quint32 row_count = 0;
|
||||||
|
for (CryptoNote::TransactionId transactionId = 0; transactionId < WalletAdapter::instance().getTransactionCount(); ++transactionId) {
|
||||||
|
appendTransaction(transactionId, row_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (row_count > 0) {
|
||||||
|
beginInsertRows(QModelIndex(), 0, row_count - 1);
|
||||||
|
endInsertRows();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransactionsModel::appendTransaction(CryptoNote::TransactionId _transactionId, quint32& _insertedRowCount) {
|
||||||
|
CryptoNote::TransactionInfo transaction;
|
||||||
|
if (!WalletAdapter::instance().getTransaction(_transactionId, transaction)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (transaction.transferCount) {
|
||||||
|
m_transactionRow[_transactionId] = qMakePair(m_transfers.size(), transaction.transferCount);
|
||||||
|
for (CryptoNote::TransferId transfer_id = transaction.firstTransferId;
|
||||||
|
transfer_id < transaction.firstTransferId + transaction.transferCount; ++transfer_id) {
|
||||||
|
m_transfers.append(TransactionTransferId(_transactionId, transfer_id));
|
||||||
|
++_insertedRowCount;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m_transfers.append(TransactionTransferId(_transactionId, CryptoNote::INVALID_TRANSFER_ID));
|
||||||
|
m_transactionRow[_transactionId] = qMakePair(m_transfers.size() - 1, 1);
|
||||||
|
++_insertedRowCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransactionsModel::appendTransaction(CryptoNote::TransactionId _transactionId) {
|
||||||
|
if (m_transactionRow.contains(_transactionId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
quint32 oldRowCount = rowCount();
|
||||||
|
quint32 insertedRowCount = 0;
|
||||||
|
for (quint64 transactionId = m_transactionRow.size(); transactionId <= _transactionId; ++transactionId) {
|
||||||
|
appendTransaction(transactionId, insertedRowCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (insertedRowCount > 0) {
|
||||||
|
beginInsertRows(QModelIndex(), oldRowCount, oldRowCount + insertedRowCount - 1);
|
||||||
|
endInsertRows();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransactionsModel::updateWalletTransaction(CryptoNote::TransactionId _id) {
|
||||||
|
quint32 firstRow = m_transactionRow.value(_id).first;
|
||||||
|
quint32 lastRow = firstRow + m_transactionRow.value(_id).second - 1;
|
||||||
|
Q_EMIT dataChanged(index(firstRow, COLUMN_DATE), index(lastRow, COLUMN_DATE));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransactionsModel::localBlockchainUpdated(quint64 _height) {
|
||||||
|
if(rowCount() > 0) {
|
||||||
|
Q_EMIT dataChanged(index(0, COLUMN_STATE), index(rowCount() - 1, COLUMN_STATE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransactionsModel::reset() {
|
||||||
|
beginResetModel();
|
||||||
|
m_transfers.clear();
|
||||||
|
m_transactionRow.clear();
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
67
src/gui/TransactionsModel.h
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QAbstractItemModel>
|
||||||
|
#include <QSortFilterProxyModel>
|
||||||
|
|
||||||
|
#include <IWallet.h>
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
typedef QPair<CryptoNote::TransactionId, CryptoNote::TransferId> TransactionTransferId;
|
||||||
|
|
||||||
|
class TransactionsModel : public QAbstractItemModel {
|
||||||
|
Q_OBJECT
|
||||||
|
Q_ENUMS(Columns)
|
||||||
|
Q_ENUMS(Roles)
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum Columns{
|
||||||
|
COLUMN_STATE = 0, COLUMN_DATE, COLUMN_AMOUNT, COLUMN_ADDRESS, COLUMN_PAYMENT_ID, COLUMN_HASH, COLUMN_FEE,
|
||||||
|
COLUMN_HEIGHT, COLUMN_TYPE
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Roles{
|
||||||
|
ROLE_DATE = Qt::UserRole, ROLE_TYPE, ROLE_HASH, ROLE_ADDRESS, ROLE_AMOUNT, ROLE_PAYMENT_ID, ROLE_ICON,
|
||||||
|
ROLE_TRANSACTION_ID, ROLE_HEIGHT, ROLE_FEE, ROLE_NUMBER_OF_CONFIRMATIONS, ROLE_COLUMN, ROLE_ROW
|
||||||
|
};
|
||||||
|
|
||||||
|
static TransactionsModel& instance();
|
||||||
|
|
||||||
|
Qt::ItemFlags flags(const QModelIndex& _index) const Q_DECL_OVERRIDE;
|
||||||
|
int columnCount(const QModelIndex& _parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
||||||
|
int rowCount(const QModelIndex& _parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
QVariant headerData(int _section, Qt::Orientation _orientation, int _role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
|
||||||
|
QVariant data(const QModelIndex& _index, int _role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
|
||||||
|
QModelIndex index(int _row, int _column, const QModelIndex& _parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
||||||
|
QModelIndex parent(const QModelIndex& _index) const Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
QByteArray toCsv() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QVector<TransactionTransferId> m_transfers;
|
||||||
|
QHash<CryptoNote::TransactionId, QPair<quint32, quint32> > m_transactionRow;
|
||||||
|
|
||||||
|
TransactionsModel();
|
||||||
|
~TransactionsModel();
|
||||||
|
|
||||||
|
QVariant getDisplayRole(const QModelIndex& _index) const;
|
||||||
|
QVariant getDecorationRole(const QModelIndex& _index) const;
|
||||||
|
QVariant getAlignmentRole(const QModelIndex& _index) const;
|
||||||
|
QVariant getUserRole(const QModelIndex& _index, int _role, CryptoNote::TransactionId _transactionId, CryptoNote::TransactionInfo& _transaction,
|
||||||
|
CryptoNote::TransferId _transferId, CryptoNote::Transfer& _transfer) const;
|
||||||
|
|
||||||
|
void reloadWalletTransactions();
|
||||||
|
void appendTransaction(CryptoNote::TransactionId _id, quint32& _row_count);
|
||||||
|
void appendTransaction(CryptoNote::TransactionId _id);
|
||||||
|
void updateWalletTransaction(CryptoNote::TransactionId _id);
|
||||||
|
void localBlockchainUpdated(quint64 _height);
|
||||||
|
void reset();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
58
src/gui/TransferFrame.cpp
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QClipboard>
|
||||||
|
|
||||||
|
#include "AddressBookDialog.h"
|
||||||
|
#include "MainWindow.h"
|
||||||
|
#include "CurrencyAdapter.h"
|
||||||
|
#include "TransferFrame.h"
|
||||||
|
|
||||||
|
#include "ui_transferframe.h"
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
TransferFrame::TransferFrame(QWidget* _parent) : QFrame(_parent), m_ui(new Ui::TransferFrame) {
|
||||||
|
m_ui->setupUi(this);
|
||||||
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
m_ui->m_amountSpin->setSuffix(" " + CurrencyAdapter::instance().getCurrencyTicker().toUpper());
|
||||||
|
}
|
||||||
|
|
||||||
|
TransferFrame::~TransferFrame() {
|
||||||
|
}
|
||||||
|
|
||||||
|
QString TransferFrame::getAddress() const {
|
||||||
|
return m_ui->m_addressEdit->text().trimmed();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString TransferFrame::getLabel() const {
|
||||||
|
return m_ui->m_labelEdit->text().trimmed();
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal TransferFrame::getAmount() const {
|
||||||
|
return m_ui->m_amountSpin->value();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString TransferFrame::getAmountString() const {
|
||||||
|
return m_ui->m_amountSpin->cleanText();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransferFrame::disableRemoveButton(bool _disable) {
|
||||||
|
m_ui->m_removeButton->setDisabled(_disable);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransferFrame::addressBookClicked() {
|
||||||
|
AddressBookDialog dlg(&MainWindow::instance());
|
||||||
|
if(dlg.exec() == QDialog::Accepted) {
|
||||||
|
m_ui->m_addressEdit->setText(dlg.getAddress());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransferFrame::pasteClicked() {
|
||||||
|
m_ui->m_addressEdit->setText(QApplication::clipboard()->text());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
38
src/gui/TransferFrame.h
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QFrame>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class TransferFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace WalletGui {
|
||||||
|
|
||||||
|
class TransferFrame : public QFrame {
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY(TransferFrame)
|
||||||
|
|
||||||
|
public:
|
||||||
|
TransferFrame(QWidget* _parent);
|
||||||
|
~TransferFrame();
|
||||||
|
|
||||||
|
QString getAddress() const;
|
||||||
|
QString getLabel() const;
|
||||||
|
qreal getAmount() const;
|
||||||
|
QString getAmountString() const;
|
||||||
|
|
||||||
|
void disableRemoveButton(bool _disable);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QScopedPointer<Ui::TransferFrame> m_ui;
|
||||||
|
|
||||||
|
Q_SLOT void addressBookClicked();
|
||||||
|
Q_SLOT void pasteClicked();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
37
src/gui/WalletEvents.h
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QEvent>
|
||||||
|
|
||||||
|
namespace WalletGui
|
||||||
|
{
|
||||||
|
enum class WalletEventType : quint32 {
|
||||||
|
ShowMessage = QEvent::User
|
||||||
|
};
|
||||||
|
|
||||||
|
class ShowMessageEvent : public QEvent {
|
||||||
|
Q_DISABLE_COPY(ShowMessageEvent)
|
||||||
|
|
||||||
|
public:
|
||||||
|
ShowMessageEvent(const QString &_messageText, QtMsgType _messageType) : QEvent(static_cast<QEvent::Type>(WalletEventType::ShowMessage)),
|
||||||
|
m_messageText(_messageText), m_messgaeType(_messageType) {
|
||||||
|
}
|
||||||
|
|
||||||
|
QString messageText() const {
|
||||||
|
return m_messageText;
|
||||||
|
}
|
||||||
|
|
||||||
|
QtMsgType messageType() const {
|
||||||
|
return m_messgaeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_messageText;
|
||||||
|
QtMsgType m_messgaeType;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
102
src/gui/ui/aboutdialog.ui
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>AboutDialog</class>
|
||||||
|
<widget class="QDialog" name="AboutDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>592</width>
|
||||||
|
<height>240</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>592</width>
|
||||||
|
<height>240</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>592</width>
|
||||||
|
<height>240</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>About %1</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,0">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="m_aboutLabel">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string><html><head/><body><p>CryptoNote coin version %1</p><p>CryptoNote coin is the next generation anonymous cryptocurrency based on CryptoNote.</p><p>Copyright (c) 2012-2015. CryptoNote Developers</p><p><a href="http://opensource.org/licenses/MIT"><span style=" text-decoration: underline; color:#0000ff;">http://opensource.org/licenses/MIT</span></a></p><p><a href="https://cryptonote.org/"><span style=" text-decoration: underline; color:#0000ff;">https://cryptonote.org/</span></a></p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="textFormat">
|
||||||
|
<enum>Qt::RichText</enum>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="openExternalLinks">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="m_closeButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Close</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>m_closeButton</sender>
|
||||||
|
<signal>clicked()</signal>
|
||||||
|
<receiver>AboutDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>538</x>
|
||||||
|
<y>285</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>294</x>
|
||||||
|
<y>156</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
81
src/gui/ui/addressbookdialog.ui
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>AddressBookDialog</class>
|
||||||
|
<widget class="QDialog" name="AddressBookDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>747</width>
|
||||||
|
<height>525</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Select address</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QTreeView" name="m_addressBookView"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="m_okButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Choose</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>m_okButton</sender>
|
||||||
|
<signal>clicked()</signal>
|
||||||
|
<receiver>AddressBookDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>694</x>
|
||||||
|
<y>499</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>373</x>
|
||||||
|
<y>262</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>m_addressBookView</sender>
|
||||||
|
<signal>doubleClicked(QModelIndex)</signal>
|
||||||
|
<receiver>AddressBookDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>373</x>
|
||||||
|
<y>242</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>373</x>
|
||||||
|
<y>262</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
142
src/gui/ui/addressbookframe.ui
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>AddressBookFrame</class>
|
||||||
|
<widget class="QFrame" name="AddressBookFrame">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>874</width>
|
||||||
|
<height>585</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Frame</string>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::StyledPanel</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Raised</enum>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QTreeView" name="m_addressBookView"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="m_addAddressButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>New address</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../resources.qrc">
|
||||||
|
<normaloff>:/icons/add</normaloff>:/icons/add</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="m_deleteAddressButton">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Delete address</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../resources.qrc">
|
||||||
|
<normaloff>:/icons/remove</normaloff>:/icons/remove</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="m_copyAddressButton">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Copy address</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../resources.qrc">
|
||||||
|
<normaloff>:/icons/copy</normaloff>:/icons/copy</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources>
|
||||||
|
<include location="../../resources.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>m_addAddressButton</sender>
|
||||||
|
<signal>clicked()</signal>
|
||||||
|
<receiver>AddressBookFrame</receiver>
|
||||||
|
<slot>addClicked()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>53</x>
|
||||||
|
<y>556</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>436</x>
|
||||||
|
<y>292</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>m_deleteAddressButton</sender>
|
||||||
|
<signal>clicked()</signal>
|
||||||
|
<receiver>AddressBookFrame</receiver>
|
||||||
|
<slot>deleteClicked()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>148</x>
|
||||||
|
<y>556</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>436</x>
|
||||||
|
<y>292</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>m_copyAddressButton</sender>
|
||||||
|
<signal>clicked()</signal>
|
||||||
|
<receiver>AddressBookFrame</receiver>
|
||||||
|
<slot>copyClicked()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>243</x>
|
||||||
|
<y>556</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>436</x>
|
||||||
|
<y>292</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
<slots>
|
||||||
|
<slot>addClicked()</slot>
|
||||||
|
<slot>deleteClicked()</slot>
|
||||||
|
<slot>copyClicked()</slot>
|
||||||
|
</slots>
|
||||||
|
</ui>
|
207
src/gui/ui/changepassworddialog.ui
Normal file
|
@ -0,0 +1,207 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>ChangePasswordDialog</class>
|
||||||
|
<widget class="QDialog" name="ChangePasswordDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>338</width>
|
||||||
|
<height>166</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>338</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>338</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Change password</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="4" column="1">
|
||||||
|
<widget class="QPushButton" name="m_okButton">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Ok</string>
|
||||||
|
</property>
|
||||||
|
<property name="default">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1" colspan="2">
|
||||||
|
<widget class="QLineEdit" name="m_newPasswordConfirmationEdit">
|
||||||
|
<property name="echoMode">
|
||||||
|
<enum>QLineEdit::Password</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="text">
|
||||||
|
<string>Old password:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1" colspan="2">
|
||||||
|
<widget class="QLineEdit" name="m_oldPasswordEdit">
|
||||||
|
<property name="echoMode">
|
||||||
|
<enum>QLineEdit::Password</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="2">
|
||||||
|
<widget class="QPushButton" name="m_cancelButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Cancel</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>New password:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1" colspan="2">
|
||||||
|
<widget class="QLineEdit" name="m_newPasswordEdit">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="echoMode">
|
||||||
|
<enum>QLineEdit::Password</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Confirm:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0" colspan="3">
|
||||||
|
<widget class="QLabel" name="m_errorLabel">
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">color: #ff0000; font: 11px;</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Password not confirmed</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<tabstops>
|
||||||
|
<tabstop>m_oldPasswordEdit</tabstop>
|
||||||
|
<tabstop>m_newPasswordEdit</tabstop>
|
||||||
|
<tabstop>m_newPasswordConfirmationEdit</tabstop>
|
||||||
|
<tabstop>m_okButton</tabstop>
|
||||||
|
<tabstop>m_cancelButton</tabstop>
|
||||||
|
</tabstops>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>m_newPasswordEdit</sender>
|
||||||
|
<signal>textChanged(QString)</signal>
|
||||||
|
<receiver>ChangePasswordDialog</receiver>
|
||||||
|
<slot>checkPassword(QString)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>223</x>
|
||||||
|
<y>64</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>168</x>
|
||||||
|
<y>82</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>m_newPasswordConfirmationEdit</sender>
|
||||||
|
<signal>textChanged(QString)</signal>
|
||||||
|
<receiver>ChangePasswordDialog</receiver>
|
||||||
|
<slot>checkPassword(QString)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>223</x>
|
||||||
|
<y>103</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>168</x>
|
||||||
|
<y>82</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>m_okButton</sender>
|
||||||
|
<signal>clicked()</signal>
|
||||||
|
<receiver>ChangePasswordDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>169</x>
|
||||||
|
<y>141</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>168</x>
|
||||||
|
<y>82</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>m_cancelButton</sender>
|
||||||
|
<signal>clicked()</signal>
|
||||||
|
<receiver>ChangePasswordDialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>277</x>
|
||||||
|
<y>141</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>168</x>
|
||||||
|
<y>82</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
<slots>
|
||||||
|
<slot>checkPassword(QString)</slot>
|
||||||
|
</slots>
|
||||||
|
</ui>
|
36
src/gui/ui/exitwidget.ui
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>ExitWidget</class>
|
||||||
|
<widget class="QWidget" name="ExitWidget">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>385</width>
|
||||||
|
<height>66</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Saving data</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,1">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="m_clockLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="m_label">
|
||||||
|
<property name="text">
|
||||||
|
<string>%1 wallet is saving data.
|
||||||
|
Please wait...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
628
src/gui/ui/mainwindow.ui
Normal file
|
@ -0,0 +1,628 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>MainWindow</class>
|
||||||
|
<widget class="QMainWindow" name="MainWindow">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>920</width>
|
||||||
|
<height>600</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16777215</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>MainWindow</string>
|
||||||
|
</property>
|
||||||
|
<property name="windowIcon">
|
||||||
|
<iconset resource="../../resources.qrc">
|
||||||
|
<normaloff>:/images/cryptonote</normaloff>:/images/cryptonote</iconset>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="centralwidget">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="WalletGui::OverviewFrame" name="m_overviewFrame">
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Raised</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="WalletGui::SendFrame" name="m_sendFrame">
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Raised</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="WalletGui::ReceiveFrame" name="m_receiveFrame">
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Raised</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="WalletGui::TransactionsFrame" name="m_transactionsFrame">
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Raised</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="WalletGui::AddressBookFrame" name="m_addressBookFrame">
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Raised</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QMenuBar" name="menubar">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>920</width>
|
||||||
|
<height>27</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<widget class="QMenu" name="menuFile">
|
||||||
|
<property name="title">
|
||||||
|
<string>File</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="m_createWalletAction"/>
|
||||||
|
<addaction name="m_openWalletAction"/>
|
||||||
|
<addaction name="m_backupWalletAction"/>
|
||||||
|
<addaction name="m_exitAction"/>
|
||||||
|
</widget>
|
||||||
|
<widget class="QMenu" name="menuSettings">
|
||||||
|
<property name="title">
|
||||||
|
<string>Settings</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="m_encryptWalletAction"/>
|
||||||
|
<addaction name="m_changePasswordAction"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
|
<addaction name="m_startOnLoginAction"/>
|
||||||
|
<addaction name="m_minimizeToTrayAction"/>
|
||||||
|
<addaction name="m_closeToTrayAction"/>
|
||||||
|
</widget>
|
||||||
|
<widget class="QMenu" name="menuHelp">
|
||||||
|
<property name="title">
|
||||||
|
<string>Help</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="m_aboutCryptonoteAction"/>
|
||||||
|
<addaction name="m_aboutQtAction"/>
|
||||||
|
</widget>
|
||||||
|
<addaction name="menuFile"/>
|
||||||
|
<addaction name="menuSettings"/>
|
||||||
|
<addaction name="menuHelp"/>
|
||||||
|
</widget>
|
||||||
|
<widget class="QToolBar" name="toolBar">
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>toolBar</string>
|
||||||
|
</property>
|
||||||
|
<property name="movable">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="toolButtonStyle">
|
||||||
|
<enum>Qt::ToolButtonTextBesideIcon</enum>
|
||||||
|
</property>
|
||||||
|
<attribute name="toolBarArea">
|
||||||
|
<enum>TopToolBarArea</enum>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="toolBarBreak">
|
||||||
|
<bool>false</bool>
|
||||||
|
</attribute>
|
||||||
|
<addaction name="m_overviewAction"/>
|
||||||
|
<addaction name="m_sendAction"/>
|
||||||
|
<addaction name="m_receiveAction"/>
|
||||||
|
<addaction name="m_transactionsAction"/>
|
||||||
|
<addaction name="m_addressBookAction"/>
|
||||||
|
</widget>
|
||||||
|
<widget class="QStatusBar" name="statusBar"/>
|
||||||
|
<action name="m_overviewAction">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../resources.qrc">
|
||||||
|
<normaloff>:/icons/overview</normaloff>:/icons/overview</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Overview</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="m_sendAction">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../resources.qrc">
|
||||||
|
<normaloff>:/icons/send</normaloff>:/icons/send</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Send</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="m_receiveAction">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../resources.qrc">
|
||||||
|
<normaloff>:/icons/receive</normaloff>:/icons/receive</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Receive</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="m_transactionsAction">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../resources.qrc">
|
||||||
|
<normaloff>:/icons/transactions</normaloff>:/icons/transactions</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Transactions</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="m_exitAction">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Exit</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+Q</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="m_addressBookAction">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../resources.qrc">
|
||||||
|
<normaloff>:/icons/address-book</normaloff>:/icons/address-book</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Address Book</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="m_createWalletAction">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Create wallet</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="m_openWalletAction">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Open wallet</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="m_encryptWalletAction">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Encrypt wallet</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="m_changePasswordAction">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Change password</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Change password</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="m_aboutCryptonoteAction">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>About</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="m_aboutQtAction">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>About Qt</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="m_backupWalletAction">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Backup wallet</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="m_startOnLoginAction">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Start on system login</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="m_minimizeToTrayAction">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Minimize to tray</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="m_closeToTrayAction">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Close to tray</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>WalletGui::OverviewFrame</class>
|
||||||
|
<extends>QFrame</extends>
|
||||||
|
<header>gui/OverviewFrame.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>WalletGui::SendFrame</class>
|
||||||
|
<extends>QFrame</extends>
|
||||||
|
<header>gui/SendFrame.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>WalletGui::ReceiveFrame</class>
|
||||||
|
<extends>QFrame</extends>
|
||||||
|
<header>gui/ReceiveFrame.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>WalletGui::TransactionsFrame</class>
|
||||||
|
<extends>QFrame</extends>
|
||||||
|
<header>gui/TransactionsFrame.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>WalletGui::AddressBookFrame</class>
|
||||||
|
<extends>QFrame</extends>
|
||||||
|
<header>gui/AddressBookFrame.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<resources>
|
||||||
|
<include location="../../resources.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>m_overviewAction</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>m_overviewFrame</receiver>
|
||||||
|
<slot>setVisible(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>-1</x>
|
||||||
|
<y>-1</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>112</x>
|
||||||
|
<y>333</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>m_sendAction</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>m_sendFrame</receiver>
|
||||||
|
<slot>setVisible(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>-1</x>
|
||||||
|
<y>-1</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>337</x>
|
||||||
|
<y>333</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>m_receiveAction</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>m_receiveFrame</receiver>
|
||||||
|
<slot>setVisible(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>-1</x>
|
||||||
|
<y>-1</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>562</x>
|
||||||
|
<y>333</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>m_transactionsAction</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>m_transactionsFrame</receiver>
|
||||||
|
<slot>setVisible(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>-1</x>
|
||||||
|
<y>-1</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>787</x>
|
||||||
|
<y>333</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>m_addressBookAction</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>m_addressBookFrame</receiver>
|
||||||
|
<slot>setVisible(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>-1</x>
|
||||||
|
<y>-1</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>809</x>
|
||||||
|
<y>320</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>m_createWalletAction</sender>
|
||||||
|
<signal>triggered()</signal>
|
||||||
|
<receiver>MainWindow</receiver>
|
||||||
|
<slot>createWallet()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>-1</x>
|
||||||
|
<y>-1</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>449</x>
|
||||||
|
<y>299</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>m_openWalletAction</sender>
|
||||||
|
<signal>triggered()</signal>
|
||||||
|
<receiver>MainWindow</receiver>
|
||||||
|
<slot>openWallet()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>-1</x>
|
||||||
|
<y>-1</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>449</x>
|
||||||
|
<y>299</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>m_encryptWalletAction</sender>
|
||||||
|
<signal>triggered()</signal>
|
||||||
|
<receiver>MainWindow</receiver>
|
||||||
|
<slot>encryptWallet()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>-1</x>
|
||||||
|
<y>-1</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>449</x>
|
||||||
|
<y>299</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>m_changePasswordAction</sender>
|
||||||
|
<signal>triggered()</signal>
|
||||||
|
<receiver>MainWindow</receiver>
|
||||||
|
<slot>encryptWallet()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>-1</x>
|
||||||
|
<y>-1</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>449</x>
|
||||||
|
<y>299</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>m_aboutQtAction</sender>
|
||||||
|
<signal>triggered()</signal>
|
||||||
|
<receiver>MainWindow</receiver>
|
||||||
|
<slot>aboutQt()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>-1</x>
|
||||||
|
<y>-1</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>449</x>
|
||||||
|
<y>299</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>m_backupWalletAction</sender>
|
||||||
|
<signal>triggered()</signal>
|
||||||
|
<receiver>MainWindow</receiver>
|
||||||
|
<slot>backupWallet()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>-1</x>
|
||||||
|
<y>-1</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>449</x>
|
||||||
|
<y>299</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>m_aboutCryptonoteAction</sender>
|
||||||
|
<signal>triggered()</signal>
|
||||||
|
<receiver>MainWindow</receiver>
|
||||||
|
<slot>about()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>-1</x>
|
||||||
|
<y>-1</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>459</x>
|
||||||
|
<y>299</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>m_startOnLoginAction</sender>
|
||||||
|
<signal>triggered(bool)</signal>
|
||||||
|
<receiver>MainWindow</receiver>
|
||||||
|
<slot>setStartOnLogin(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>-1</x>
|
||||||
|
<y>-1</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>459</x>
|
||||||
|
<y>299</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>m_minimizeToTrayAction</sender>
|
||||||
|
<signal>triggered(bool)</signal>
|
||||||
|
<receiver>MainWindow</receiver>
|
||||||
|
<slot>setMinimizeToTray(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>-1</x>
|
||||||
|
<y>-1</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>459</x>
|
||||||
|
<y>299</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>m_closeToTrayAction</sender>
|
||||||
|
<signal>triggered(bool)</signal>
|
||||||
|
<receiver>MainWindow</receiver>
|
||||||
|
<slot>setCloseToTray(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>-1</x>
|
||||||
|
<y>-1</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>459</x>
|
||||||
|
<y>299</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
<slots>
|
||||||
|
<slot>createWallet()</slot>
|
||||||
|
<slot>openWallet()</slot>
|
||||||
|
<slot>encryptWallet()</slot>
|
||||||
|
<slot>aboutQt()</slot>
|
||||||
|
<slot>backupWallet()</slot>
|
||||||
|
<slot>about()</slot>
|
||||||
|
<slot>setStartOnLogin(bool)</slot>
|
||||||
|
<slot>setMinimizeToTray(bool)</slot>
|
||||||
|
<slot>setCloseToTray(bool)</slot>
|
||||||
|
</slots>
|
||||||
|
</ui>
|
133
src/gui/ui/newaddressdialog.ui
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>NewAddressDialog</class>
|
||||||
|
<widget class="QDialog" name="NewAddressDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>590</width>
|
||||||
|
<height>127</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>New address</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Label:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1" colspan="3">
|
||||||
|
<widget class="QLineEdit" name="m_labelEdit">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="echoMode">
|
||||||
|
<enum>QLineEdit::Normal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Address:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1" colspan="3">
|
||||||
|
<widget class="QLineEdit" name="m_addressEdit">
|
||||||
|
<property name="echoMode">
|
||||||
|
<enum>QLineEdit::Normal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0" colspan="2">
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>338</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="2">
|
||||||
|
<widget class="QPushButton" name="m_okButton">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Ok</string>
|
||||||
|
</property>
|
||||||
|
<property name="default">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="3">
|
||||||
|
<widget class="QPushButton" name="m_cancelButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Cancel</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>m_okButton</sender>
|
||||||
|
<signal>clicked()</signal>
|
||||||
|
<receiver>NewAddressDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>410</x>
|
||||||
|
<y>102</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>294</x>
|
||||||
|
<y>63</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>m_cancelButton</sender>
|
||||||
|
<signal>clicked()</signal>
|
||||||
|
<receiver>NewAddressDialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>526</x>
|
||||||
|
<y>102</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>294</x>
|
||||||
|
<y>63</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
180
src/gui/ui/newpassworddialog.ui
Normal file
|
@ -0,0 +1,180 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>NewPasswordDialog</class>
|
||||||
|
<widget class="QDialog" name="NewPasswordDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>338</width>
|
||||||
|
<height>133</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Enter password</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QPushButton" name="m_okButton">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Ok</string>
|
||||||
|
</property>
|
||||||
|
<property name="default">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="2">
|
||||||
|
<widget class="QPushButton" name="m_cancelButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Cancel</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Password:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1" colspan="2">
|
||||||
|
<widget class="QLineEdit" name="m_passwordEdit">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="echoMode">
|
||||||
|
<enum>QLineEdit::Password</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1" colspan="2">
|
||||||
|
<widget class="QLineEdit" name="m_passwordConfirmationEdit">
|
||||||
|
<property name="echoMode">
|
||||||
|
<enum>QLineEdit::Password</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Confirm:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0" colspan="3">
|
||||||
|
<widget class="QLabel" name="m_errorLabel">
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">color: #ff0000; font: 11px;</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Password not confirmed</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<tabstops>
|
||||||
|
<tabstop>m_passwordEdit</tabstop>
|
||||||
|
<tabstop>m_passwordConfirmationEdit</tabstop>
|
||||||
|
<tabstop>m_okButton</tabstop>
|
||||||
|
<tabstop>m_cancelButton</tabstop>
|
||||||
|
</tabstops>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>m_okButton</sender>
|
||||||
|
<signal>clicked()</signal>
|
||||||
|
<receiver>NewPasswordDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>147</x>
|
||||||
|
<y>102</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>147</x>
|
||||||
|
<y>63</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>m_cancelButton</sender>
|
||||||
|
<signal>clicked()</signal>
|
||||||
|
<receiver>NewPasswordDialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>241</x>
|
||||||
|
<y>102</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>147</x>
|
||||||
|
<y>63</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>m_passwordEdit</sender>
|
||||||
|
<signal>textChanged(QString)</signal>
|
||||||
|
<receiver>NewPasswordDialog</receiver>
|
||||||
|
<slot>checkPassword(QString)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>206</x>
|
||||||
|
<y>25</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>168</x>
|
||||||
|
<y>64</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>m_passwordConfirmationEdit</sender>
|
||||||
|
<signal>textChanged(QString)</signal>
|
||||||
|
<receiver>NewPasswordDialog</receiver>
|
||||||
|
<slot>checkPassword(QString)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>206</x>
|
||||||
|
<y>64</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>168</x>
|
||||||
|
<y>64</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
<slots>
|
||||||
|
<slot>checkPassword(QString)</slot>
|
||||||
|
</slots>
|
||||||
|
</ui>
|
290
src/gui/ui/overviewframe.ui
Normal file
|
@ -0,0 +1,290 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>OverviewFrame</class>
|
||||||
|
<widget class="QFrame" name="OverviewFrame">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>866</width>
|
||||||
|
<height>590</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Frame</string>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::StyledPanel</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Raised</enum>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout" columnstretch="40,60">
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SetDefaultConstraint</enum>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="horizontalSpacing">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="verticalSpacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QFrame" name="m_overviewWalletFrame">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>160</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16777215</width>
|
||||||
|
<height>160</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Raised</enum>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
|
<item row="4" column="1">
|
||||||
|
<widget class="QLabel" name="m_totalBalanceLabel">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<weight>75</weight>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">0.00</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLabel" name="m_actualBalanceLabel">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<weight>75</weight>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">0.00</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QLabel" name="label_6">
|
||||||
|
<property name="text">
|
||||||
|
<string>Total:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="2">
|
||||||
|
<widget class="QLabel" name="m_tickerLabel1">
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<weight>75</weight>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Wallet</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>Unconfirmed:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Balance:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0" colspan="2">
|
||||||
|
<widget class="Line" name="line">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QLabel" name="m_pendingBalanceLabel">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<weight>75</weight>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">0.00</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="2">
|
||||||
|
<widget class="QLabel" name="m_tickerLabel3">
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="2">
|
||||||
|
<widget class="QLabel" name="m_tickerLabel2">
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="3">
|
||||||
|
<spacer name="horizontalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0" rowspan="2">
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeType">
|
||||||
|
<enum>QSizePolicy::Expanding</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>425</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1" rowspan="3">
|
||||||
|
<widget class="QFrame" name="frame_2">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16777215</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Raised</enum>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_8">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<weight>75</weight>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Recent transactions</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QTreeView" name="m_recentTransactionsView">
|
||||||
|
<property name="focusPolicy">
|
||||||
|
<enum>Qt::NoFocus</enum>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">background-color: transparent;</string>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="editTriggers">
|
||||||
|
<set>QAbstractItemView::NoEditTriggers</set>
|
||||||
|
</property>
|
||||||
|
<property name="selectionMode">
|
||||||
|
<enum>QAbstractItemView::NoSelection</enum>
|
||||||
|
</property>
|
||||||
|
<property name="rootIsDecorated">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="uniformRowHeights">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="itemsExpandable">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="headerHidden">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="expandsOnDoubleClick">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
131
src/gui/ui/passworddialog.ui
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>PasswordDialog</class>
|
||||||
|
<widget class="QDialog" name="PasswordDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>338</width>
|
||||||
|
<height>103</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>338</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>338</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Enter password</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="1" column="1" colspan="2">
|
||||||
|
<widget class="QLineEdit" name="m_passwordEdit">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="echoMode">
|
||||||
|
<enum>QLineEdit::Password</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="2">
|
||||||
|
<widget class="QPushButton" name="m_cancelButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Cancel</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Password:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QPushButton" name="m_okButton">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Ok</string>
|
||||||
|
</property>
|
||||||
|
<property name="default">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0" colspan="3">
|
||||||
|
<widget class="QLabel" name="m_errorLabel">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>122</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">color: #ff0000; font: 11px;</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Wrong password</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>m_okButton</sender>
|
||||||
|
<signal>clicked()</signal>
|
||||||
|
<receiver>PasswordDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>142</x>
|
||||||
|
<y>84</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>158</x>
|
||||||
|
<y>52</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>m_cancelButton</sender>
|
||||||
|
<signal>clicked()</signal>
|
||||||
|
<receiver>PasswordDialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>257</x>
|
||||||
|
<y>84</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>158</x>
|
||||||
|
<y>52</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
91
src/gui/ui/receiveframe.ui
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>ReceiveFrame</class>
|
||||||
|
<widget class="QFrame" name="ReceiveFrame">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>846</width>
|
||||||
|
<height>592</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Frame</string>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::StyledPanel</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Raised</enum>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Address:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="m_addressEdit">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="m_copyButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../resources.qrc">
|
||||||
|
<normaloff>:/icons/copy</normaloff>:/icons/copy</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources>
|
||||||
|
<include location="../../resources.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>m_copyButton</sender>
|
||||||
|
<signal>clicked()</signal>
|
||||||
|
<receiver>ReceiveFrame</receiver>
|
||||||
|
<slot>copyAddress()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>818</x>
|
||||||
|
<y>26</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>422</x>
|
||||||
|
<y>295</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
<slots>
|
||||||
|
<slot>copyAddress()</slot>
|
||||||
|
</slots>
|
||||||
|
</ui>
|
320
src/gui/ui/sendframe.ui
Normal file
|
@ -0,0 +1,320 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>SendFrame</class>
|
||||||
|
<widget class="QFrame" name="SendFrame">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>866</width>
|
||||||
|
<height>590</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Frame</string>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::StyledPanel</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Raised</enum>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="m_send_frame_main_layout">
|
||||||
|
<item>
|
||||||
|
<widget class="QScrollArea" name="m_transfersScrollarea">
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="widgetResizable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="scrollAreaWidgetContents">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>840</width>
|
||||||
|
<height>446</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="m_send_frame_layout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>445</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QSlider" name="m_mixinSlider">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>200</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>10</number>
|
||||||
|
</property>
|
||||||
|
<property name="pageStep">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="tracking">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="tickPosition">
|
||||||
|
<enum>QSlider::TicksBothSides</enum>
|
||||||
|
</property>
|
||||||
|
<property name="tickInterval">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="3">
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeType">
|
||||||
|
<enum>QSizePolicy::Expanding</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>298</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_6">
|
||||||
|
<property name="text">
|
||||||
|
<string>PaymentID:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="2">
|
||||||
|
<widget class="QLineEdit" name="m_mixinEdit">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>30</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
<property name="maxLength">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1" colspan="3">
|
||||||
|
<widget class="QLineEdit" name="m_paymentIdEdit"/>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Anonimity level:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="m_sendButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Send</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../resources.qrc">
|
||||||
|
<normaloff>:/icons/send</normaloff>:/icons/send</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="m_clearAllButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Clear All</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../resources.qrc">
|
||||||
|
<normaloff>:/icons/remove</normaloff>:/icons/remove</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="m_addRecipientButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Add Recipient</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../resources.qrc">
|
||||||
|
<normaloff>:/icons/add</normaloff>:/icons/add</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>Balance:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="m_balanceLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">0.00 </string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="m_tickerLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<tabstops>
|
||||||
|
<tabstop>m_paymentIdEdit</tabstop>
|
||||||
|
<tabstop>m_mixinSlider</tabstop>
|
||||||
|
<tabstop>m_sendButton</tabstop>
|
||||||
|
<tabstop>m_clearAllButton</tabstop>
|
||||||
|
<tabstop>m_addRecipientButton</tabstop>
|
||||||
|
<tabstop>m_transfersScrollarea</tabstop>
|
||||||
|
<tabstop>m_mixinEdit</tabstop>
|
||||||
|
</tabstops>
|
||||||
|
<resources>
|
||||||
|
<include location="../../resources.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>m_addRecipientButton</sender>
|
||||||
|
<signal>clicked()</signal>
|
||||||
|
<receiver>SendFrame</receiver>
|
||||||
|
<slot>addRecipientClicked()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>282</x>
|
||||||
|
<y>561</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>432</x>
|
||||||
|
<y>294</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>m_clearAllButton</sender>
|
||||||
|
<signal>clicked()</signal>
|
||||||
|
<receiver>SendFrame</receiver>
|
||||||
|
<slot>clearAllClicked()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>154</x>
|
||||||
|
<y>561</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>432</x>
|
||||||
|
<y>294</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>m_sendButton</sender>
|
||||||
|
<signal>clicked()</signal>
|
||||||
|
<receiver>SendFrame</receiver>
|
||||||
|
<slot>sendClicked()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>53</x>
|
||||||
|
<y>561</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>432</x>
|
||||||
|
<y>294</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>m_mixinSlider</sender>
|
||||||
|
<signal>valueChanged(int)</signal>
|
||||||
|
<receiver>SendFrame</receiver>
|
||||||
|
<slot>mixinValueChanged(int)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>221</x>
|
||||||
|
<y>520</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>432</x>
|
||||||
|
<y>294</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
<slots>
|
||||||
|
<slot>sendClicked()</slot>
|
||||||
|
<slot>clearAllClicked()</slot>
|
||||||
|
<slot>addRecipientClicked()</slot>
|
||||||
|
<slot>mixinValueChanged(int)</slot>
|
||||||
|
</slots>
|
||||||
|
</ui>
|
65
src/gui/ui/transactiondetailsdialog.ui
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>TransactionDetailsDialog</class>
|
||||||
|
<widget class="QDialog" name="TransactionDetailsDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>736</width>
|
||||||
|
<height>357</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Transaction details</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QTextBrowser" name="m_detailsBrowser"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="m_closeButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Close</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>m_closeButton</sender>
|
||||||
|
<signal>clicked()</signal>
|
||||||
|
<receiver>TransactionDetailsDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>619</x>
|
||||||
|
<y>331</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>335</x>
|
||||||
|
<y>178</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
156
src/gui/ui/transactionframe.ui
Normal file
|
@ -0,0 +1,156 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>TransactionFrame</class>
|
||||||
|
<widget class="QFrame" name="TransactionFrame">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>346</width>
|
||||||
|
<height>64</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>64</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>540</width>
|
||||||
|
<height>64</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Frame</string>
|
||||||
|
</property>
|
||||||
|
<property name="autoFillBackground">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Raised</enum>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="0,0,0">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="m_iconLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeType">
|
||||||
|
<enum>QSizePolicy::Fixed</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>10</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,1">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>20</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="m_timeLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>TextLabel</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="m_amountLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>TextLabel</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="m_hashLabel">
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>TextLabel</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
<property name="indent">
|
||||||
|
<number>-1</number>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::NoTextInteraction</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeType">
|
||||||
|
<enum>QSizePolicy::Fixed</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>10</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
125
src/gui/ui/transactionsframe.ui
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>TransactionsFrame</class>
|
||||||
|
<widget class="QFrame" name="TransactionsFrame">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>830</width>
|
||||||
|
<height>614</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Frame</string>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::StyledPanel</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Raised</enum>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QTreeView" name="m_transactionsView">
|
||||||
|
<property name="sizeAdjustPolicy">
|
||||||
|
<enum>QAbstractScrollArea::AdjustIgnored</enum>
|
||||||
|
</property>
|
||||||
|
<property name="editTriggers">
|
||||||
|
<set>QAbstractItemView::AnyKeyPressed|QAbstractItemView::CurrentChanged|QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked</set>
|
||||||
|
</property>
|
||||||
|
<property name="alternatingRowColors">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="rootIsDecorated">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="uniformRowHeights">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="itemsExpandable">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="sortingEnabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<attribute name="headerCascadingSectionResizes">
|
||||||
|
<bool>true</bool>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="headerShowSortIndicator" stdset="0">
|
||||||
|
<bool>false</bool>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="m_csvButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Export</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../resources.qrc">
|
||||||
|
<normaloff>:/icons/export</normaloff>:/icons/export</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources>
|
||||||
|
<include location="../../resources.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>m_csvButton</sender>
|
||||||
|
<signal>clicked()</signal>
|
||||||
|
<receiver>TransactionsFrame</receiver>
|
||||||
|
<slot>exportToCsv()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>761</x>
|
||||||
|
<y>587</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>414</x>
|
||||||
|
<y>306</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>m_transactionsView</sender>
|
||||||
|
<signal>doubleClicked(QModelIndex)</signal>
|
||||||
|
<receiver>TransactionsFrame</receiver>
|
||||||
|
<slot>showTransactionDetails(QModelIndex)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>414</x>
|
||||||
|
<y>287</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>414</x>
|
||||||
|
<y>306</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
<slots>
|
||||||
|
<slot>exportToCsv()</slot>
|
||||||
|
<slot>showTransactionDetails(QModelIndex)</slot>
|
||||||
|
</slots>
|
||||||
|
</ui>
|
195
src/gui/ui/transferframe.ui
Normal file
|
@ -0,0 +1,195 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>TransferFrame</class>
|
||||||
|
<widget class="QFrame" name="TransferFrame">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>885</width>
|
||||||
|
<height>121</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Frame</string>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::Box</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Sunken</enum>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Pay To:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="3">
|
||||||
|
<widget class="QToolButton" name="m_addressBookButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../resources.qrc">
|
||||||
|
<normaloff>:/icons/address-book</normaloff>:/icons/address-book</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="4">
|
||||||
|
<widget class="QToolButton" name="m_pasteButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../resources.qrc">
|
||||||
|
<normaloff>:/icons/paste</normaloff>:/icons/paste</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1" colspan="5">
|
||||||
|
<widget class="QLineEdit" name="m_labelEdit">
|
||||||
|
<property name="placeholderText">
|
||||||
|
<string>Enter a label for this address to add it to your address book</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="text">
|
||||||
|
<string>Amount:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="5">
|
||||||
|
<widget class="QToolButton" name="m_removeButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../resources.qrc">
|
||||||
|
<normaloff>:/icons/remove</normaloff>:/icons/remove</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="2" colspan="4">
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>558</width>
|
||||||
|
<height>17</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Label:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QDoubleSpinBox" name="m_amountSpin">
|
||||||
|
<property name="layoutDirection">
|
||||||
|
<enum>Qt::LeftToRight</enum>
|
||||||
|
</property>
|
||||||
|
<property name="suffix">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
<property name="decimals">
|
||||||
|
<number>8</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>999999999.999999046325684</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1" colspan="2">
|
||||||
|
<widget class="QLineEdit" name="m_addressEdit"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<tabstops>
|
||||||
|
<tabstop>m_addressEdit</tabstop>
|
||||||
|
<tabstop>m_labelEdit</tabstop>
|
||||||
|
<tabstop>m_amountSpin</tabstop>
|
||||||
|
<tabstop>m_addressBookButton</tabstop>
|
||||||
|
<tabstop>m_pasteButton</tabstop>
|
||||||
|
<tabstop>m_removeButton</tabstop>
|
||||||
|
</tabstops>
|
||||||
|
<resources>
|
||||||
|
<include location="../../resources.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>m_removeButton</sender>
|
||||||
|
<signal>clicked()</signal>
|
||||||
|
<receiver>TransferFrame</receiver>
|
||||||
|
<slot>close()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>862</x>
|
||||||
|
<y>21</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>442</x>
|
||||||
|
<y>60</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>m_addressBookButton</sender>
|
||||||
|
<signal>clicked()</signal>
|
||||||
|
<receiver>TransferFrame</receiver>
|
||||||
|
<slot>addressBookClicked()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>786</x>
|
||||||
|
<y>21</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>442</x>
|
||||||
|
<y>60</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>m_pasteButton</sender>
|
||||||
|
<signal>clicked()</signal>
|
||||||
|
<receiver>TransferFrame</receiver>
|
||||||
|
<slot>pasteClicked()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>824</x>
|
||||||
|
<y>21</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>442</x>
|
||||||
|
<y>60</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
<slots>
|
||||||
|
<slot>addressBookClicked()</slot>
|
||||||
|
<slot>pasteClicked()</slot>
|
||||||
|
</slots>
|
||||||
|
</ui>
|
BIN
src/icons/add.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
src/icons/address-book.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
src/icons/clock1.png
Normal file
After Width: | Height: | Size: 864 B |
BIN
src/icons/clock2.png
Normal file
After Width: | Height: | Size: 863 B |
BIN
src/icons/clock3.png
Normal file
After Width: | Height: | Size: 856 B |
BIN
src/icons/clock4.png
Normal file
After Width: | Height: | Size: 869 B |
BIN
src/icons/clock5.png
Normal file
After Width: | Height: | Size: 858 B |
BIN
src/icons/connected.png
Normal file
After Width: | Height: | Size: 762 B |
BIN
src/icons/disconnected.png
Normal file
After Width: | Height: | Size: 538 B |
BIN
src/icons/editcopy.png
Normal file
After Width: | Height: | Size: 600 B |
BIN
src/icons/editpaste.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
src/icons/export.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
src/icons/lock_closed.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
src/icons/lock_open.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
src/icons/overview.png
Normal file
After Width: | Height: | Size: 6.2 KiB |
BIN
src/icons/receive.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
src/icons/remove.png
Normal file
After Width: | Height: | Size: 649 B |
BIN
src/icons/send.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
src/icons/sync_sprite.png
Normal file
After Width: | Height: | Size: 42 KiB |