Compare commits

..

85 Commits

Author SHA1 Message Date
luigi1111
43f378b7d2 Merge pull request #2644
3c6a1e4 wizard: fix mode selection back button (selsta)
2019-12-23 09:30:21 -05:00
luigi1111
b73551d6ab Merge pull request #2643
3528bcd main: show wizard init screen when no wallet is found (selsta)
2019-12-23 09:29:15 -05:00
luigi1111
632d82ac95 Merge pull request #2640
c5785ed main: fix wallet lock is unlocked without password (selsta)
2019-12-23 09:28:21 -05:00
luigi1111
3fb775de28 Merge pull request #2680
6d0593a build: fix build on Ubuntu 16.04 GCC 5.4 (missing includes) (xiphon)
2019-12-23 09:06:27 -05:00
luigi1111
82affff63f Merge pull request #2679
13ea403 FutureScheduler: drop moveToThread, setParent might silently fail (xiphon)
2019-12-23 09:05:09 -05:00
xiphon
6d0593a26b build: fix build on Ubuntu 16.04 GCC 5.4 (missing includes) 2019-12-23 12:01:41 +00:00
xiphon
13ea4035b5 FutureScheduler: drop moveToThread, setParent might silently fail 2019-12-23 11:35:47 +00:00
luigi1111
1c97e9796d Merge pull request #2601
4a86a1c remove colored dots (tobtoht)
2019-12-21 18:43:06 -05:00
luigi1111
4eca4194b7 Merge pull request #2675
3f4f6f0 misc: remove unused components (tobtoht)
2019-12-21 18:16:01 -05:00
luigi1111
5c801ec2ad Merge pull request #2674
ded0a4d Scrollbar: don't autohide if enabled (except on Mac) (tobtoht)
2019-12-21 18:15:09 -05:00
luigi1111
7f324fb3e6 Merge pull request #2673
6a5de80 Add *.autosave (tobtoht)
2019-12-21 18:14:17 -05:00
luigi1111
710159a236 Merge pull request #2670
1fef418 main: enable high DPI scaling (selsta)
2019-12-21 18:12:46 -05:00
luigi1111
7afbcc9855 Merge pull request #2665
c6c094b SettingsWallet: cleanup on wallet close (xiphon)
2019-12-21 18:10:59 -05:00
luigi1111
8d0647d677 Merge pull request #2650
10dea60 Settings: fix page height (tobtoht)
2019-12-21 18:09:53 -05:00
luigi1111
9a5296f00e Merge pull request #2648
beeddea build: add application icon on Windows (xiphon)
2019-12-21 18:07:53 -05:00
luigi1111
6f53cc4dda Merge pull request #2645
66f6b95 Account: update balance card label (selsta)
2019-12-21 18:07:07 -05:00
luigi1111
86f573f02c Merge pull request #2642
f8262b0 misc: cleanup unused variables and comments (selsta)
2019-12-21 18:06:17 -05:00
thotbot
ded0a4da48 Scrollbar: don't autohide if enabled (except on Mac) 2019-12-21 18:33:36 +00:00
thotbot
3f4f6f01dc misc: remove unused components 2019-12-21 15:13:23 +00:00
thotbot
6a5de80bd9 Add *.autosave 2019-12-21 11:16:43 +00:00
selsta
1fef418adb main: enable high DPI scaling 2019-12-21 06:31:25 +01:00
xiphon
c6c094bbd5 SettingsWallet: cleanup on wallet close 2019-12-20 19:28:17 +00:00
thotbot
10dea6073b Settings: fix page height 2019-12-20 16:15:36 +00:00
xiphon
beeddea678 build: add application icon on Windows 2019-12-20 13:27:47 +00:00
selsta
66f6b95b5c Account: update balance card label 2019-12-20 07:29:19 +01:00
selsta
3c6a1e45d7 wizard: fix mode selection back button 2019-12-20 06:32:42 +01:00
selsta
3528bcd6b5 main: show wizard init screen when no wallet is found 2019-12-20 03:49:31 +01:00
selsta
f8262b0d27 misc: cleanup unused variables and comments 2019-12-20 03:37:52 +01:00
selsta
c5785ed195 main: fix wallet lock is unlocked without password 2019-12-20 02:20:12 +01:00
luigi1111
500c7ec82e Merge pull request #2591
3e07eca main: blur on PasswordDialog, InputDialog or ProcessingSplash (xiphon)
2019-12-19 20:06:42 -05:00
xiphon
3e07ecabf9 main: blur on PasswordDialog, InputDialog or ProcessingSplash 2019-12-20 01:04:36 +00:00
luigi1111
98279f54fb Merge pull request #2635
aa96e2f build: define QT_NO_DEBUG for non--debug targets (xiphon)
2019-12-19 19:51:05 -05:00
luigi1111
a6818cd274 Merge pull request #2632
d6ccae3 Transfer: cleanup payment id code (tobtoht)
2019-12-19 19:50:11 -05:00
luigi1111
4c7d402eaf Merge pull request #2631
ec83dea build: support DEV_MODE env var to override default value (xiphon)
2019-12-19 19:49:06 -05:00
luigi1111
3984f8d1e8 Merge pull request #2630
3ea329e FutureScheduler: fix possible race, connect before setFuture (xiphon)
2019-12-19 19:48:10 -05:00
luigi1111
f2424ddeaa Merge pull request #2627
8c51172 Subaddress: fix use-after-free on accessing stale Wallet API data (xiphon)
2019-12-19 19:46:45 -05:00
luigi1111
b963028f10 Merge pull request #2626
a83adb7 Transfer: improve warning flow (tobtoht)
2019-12-19 19:45:33 -05:00
luigi1111
4aac66a024 Merge pull request #2625
131769f fix dropdown closure behavior (tobtoht)
2019-12-19 19:43:32 -05:00
luigi1111
598de0f03f Merge pull request #2623
c9900c0 SubaddressAccount: drop useless getAll 'update' default argument (xiphon)
e0ab9aa SubaddressAccount: fix use-after-free bug (xiphon)
2019-12-19 19:37:27 -05:00
luigi1111
bd3b26c33d Merge pull request #2604
50cb726 do not ask to start daemon if in remote node mode (tobtoht)
2019-12-19 19:36:17 -05:00
luigi1111
66f5b7310f Merge pull request #2622
94561ed fix clunky scrolling behavior on flickables (tobtoht)
2019-12-19 19:35:22 -05:00
luigi1111
5ff030783a Merge pull request #2616
5dccde2 History: don't hide 'Export all history' if there ain't any txes (xiphon)
2019-12-19 19:34:08 -05:00
luigi1111
7c11ac4d98 Merge pull request #2614
4e1f734 TransactionHistory: fix use-after-free bugs (xiphon)
2019-12-19 19:32:37 -05:00
luigi1111
05a0d21f4c Merge pull request #2590
cc86795 WizardController: always close and re-open newly created wallet (xiphon)
2019-12-19 19:30:32 -05:00
luigi1111
d0c2740a51 Merge pull request #2588
a113670 History: don't show empty paymentId in tx details (xiphon)
2019-12-19 19:29:36 -05:00
luigi1111
118752e775 Merge pull request #2587
1661c82 TransactionInfo: parse Wallet API provided data on initialization (xiphon)
2019-12-19 19:23:06 -05:00
luigi1111
1ed02f7d7a Merge pull request #2581
872b49f CMakeLists: remove duplicated x11 (selsta)
2019-12-19 19:21:55 -05:00
luigi1111
4042186fac Merge pull request #2580
ba24fd7 SettingsInfo: open containing folder on wallet log path click (xiphon)
088d32e OSHelper: file preselection support (Windows and Mac) (xiphon)
2019-12-19 19:20:53 -05:00
luigi1111
abd98b95f6 Merge pull request #2578
38d412a components: handle enter and return (selsta)
2019-12-19 19:19:32 -05:00
thotbot
d6ccae342d Transfer: cleanup payment id code 2019-12-20 00:18:52 +00:00
luigi1111
78f8cb2595 Merge pull request #2576
b940ad7 InputDialog: pre-populate input text (selsta)
2019-12-19 19:18:03 -05:00
xiphon
aa96e2ff3e build: define QT_NO_DEBUG for non--debug targets 2019-12-19 15:13:10 +00:00
xiphon
ec83dea3c3 build: support DEV_MODE env var to override default value 2019-12-19 00:52:26 +00:00
xiphon
3ea329e45f FutureScheduler: fix possible race, connect before setFuture 2019-12-19 00:37:00 +00:00
thotbot
a83adb70ad Transfer: improve warning flow 2019-12-19 00:16:00 +00:00
thotbot
94561ed2a6 fix clunky scrolling behavior on flickables 2019-12-17 23:11:11 +00:00
xiphon
8c511722e0 Subaddress: fix use-after-free on accessing stale Wallet API data 2019-12-17 21:51:04 +00:00
thotbot
131769f175 fix dropdown closure behavior 2019-12-17 20:21:04 +00:00
thotbot
4a86a1cf76 remove colored dots 2019-12-17 15:04:23 +00:00
xiphon
e0ab9aa898 SubaddressAccount: fix use-after-free bug 2019-12-17 14:18:54 +00:00
xiphon
cc86795fa3 WizardController: always close and re-open newly created wallet 2019-12-17 01:08:08 +00:00
thotbot
50cb72656a do not ask to start daemon if in remote node mode 2019-12-16 22:48:35 +00:00
xiphon
c9900c05b2 SubaddressAccount: drop useless getAll 'update' default argument 2019-12-16 14:35:50 +00:00
xiphon
4e1f7349c4 TransactionHistory: fix use-after-free bugs 2019-12-16 13:31:31 +00:00
xiphon
5dccde25f4 History: don't hide 'Export all history' if there ain't any txes 2019-12-16 09:30:23 +00:00
xiphon
a113670905 History: don't show empty paymentId in tx details 2019-12-13 10:42:47 +00:00
xiphon
1661c82449 TransactionInfo: parse Wallet API provided data on initialization 2019-12-12 21:26:18 +00:00
xiphon
088d32e712 OSHelper: file preselection support (Windows and Mac)
Co-authored-by: selsta <selsta@sent.at>
2019-12-12 01:28:49 +00:00
xiphon
ba24fd79bb SettingsInfo: open containing folder on wallet log path click 2019-12-12 00:10:22 +00:00
luigi1111
46227bdad0 Merge pull request #2531
2833fdb cmake: use appropriate compiler flags (xiphon)
17ea26e build: fix monero-wallet-gui.pro source paths, rm qml.qrc duplicate (xiphon)
2019-12-09 22:05:22 -06:00
selsta
872b49f29a CMakeLists: remove duplicated x11 2019-12-10 03:01:02 +01:00
selsta
38d412a3fa components: handle enter and return 2019-12-10 02:52:15 +01:00
xiphon
2833fdb907 cmake: use appropriate compiler flags 2019-12-09 22:49:42 +00:00
selsta
b940ad72be InputDialog: pre-populate input text 2019-12-09 17:38:09 +01:00
xiphon
17ea26e02a build: fix monero-wallet-gui.pro source paths, rm qml.qrc duplicate 2019-12-09 14:03:24 +00:00
luigi1111
1cee81b996 Merge pull request #2404
8dd2a20 e04db92 d06ae80 c83c74d 1723d04 52182ef 97a9ac9 2d23917 91aff7c (TheCharlatan)
2019-12-09 07:52:41 -06:00
xiphon
97a9ac9bf8 cmake: don't force LINUX=ON, DEBUG=ON, CMAKE_BUILD_TYPE=Release 2019-11-27 22:59:27 +01:00
xiphon
2d23917afb cmake: MinGW - set WIN32 executable property 2019-11-27 22:59:27 +01:00
xiphon
52182ef9b1 cmake: fix MinGW static builds, add 'release-static-win64' target 2019-11-27 22:59:27 +01:00
xiphon
91aff7c0e4 cmake: put monero-gui executable into 'bin' directory 2019-11-27 22:59:27 +01:00
xiphon
1723d04902 cmake: inherit ARCH_WIDTH from 'monero' subdirectory 2019-11-27 22:59:27 +01:00
TheCharlatan
c83c74d3c2 Add Apple support 2019-11-27 22:59:27 +01:00
TheCharlatan
d06ae80e0a Add support for msys/mingw32 2019-11-27 22:59:27 +01:00
TheCharlatan
8dd2a20ff8 Migrate build system to cmake
The content in this commit is not split in order to preserve working
compilation. Once this is added to master, the old build script will no
longer work and all existing build toolings will require changes.

Monero's cmake directory's files need to be copied to this project's cmake
directory in order for the linking and function definitions to work correctly.

Monero-gui has its own version check and generate file in order to not
conflict with monero's destination version files.

Most of the source files that are currently in monero-gui's root
directory are now moved to subdirectories. This is done to preserve
compilation order properly and to give some content structure.

The original CMakeList file included all headers it found in
subdirectories. Make sure that they are set manually to evade linking
errors.

The current build script always checks out latest master of the monero
submodule. The submodule rules in the current CMakeLists.txt file do not
enforce. An override to compile master nevertheless can still be given
with `-D DEV_MODE`.

To enable the linux X11 xcb linking the libraries had to be hardcoded. There
does not seem to be good support for this in pkgconfig, or in
existing cmake checks.
2019-11-27 22:59:27 +01:00
TheCharlatan
e04db9299d Add dsc's CMakeLists.txt file 2019-11-27 22:59:27 +01:00
108 changed files with 4574 additions and 938 deletions

1
.gitignore vendored
View File

@@ -28,6 +28,7 @@ Session.vim
# Temporary
.netrwhist
*~
*.autosave
# Auto-generated tag files
tags
# Persistent undo

412
CMakeLists.txt Normal file
View File

@@ -0,0 +1,412 @@
cmake_minimum_required(VERSION 3.10)
project(monero-gui)
message(STATUS "Initiating compile using CMake ${CMAKE_VERSION}")
set(VERSION_MAJOR "14")
set(VERSION_MINOR "0")
set(VERSION_REVISION "3")
set(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION}")
# libwallet requires a static build, so we only allow static compilation
set(STATIC ON)
option(USE_DEVICE_TREZOR ON)
option(ENABLE_PASS_STRENGTH_METER "Disable zxcvbn" OFF)
option(WITH_SCANNER "Enable webcam QR scanner" OFF)
option(DEV_MODE "Checkout latest monero master on build" OFF)
list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_SOURCE_DIR}/cmake")
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
if(DEBUG)
set(CMAKE_VERBOSE_MAKEFILE ON)
endif()
set(BUILD_GUI_DEPS ON)
set(ARCH "x86-64")
set(BUILD_64 ON)
set(INSTALL_VENDORED_LIBUNBOUND=ON)
function (add_c_flag_if_supported flag var)
string(REPLACE "-" "_" supported ${flag}_c)
check_c_compiler_flag(${flag} ${supported})
if(${${supported}})
set(${var} "${${var}} ${flag}" PARENT_SCOPE)
endif()
endfunction()
function (add_cxx_flag_if_supported flag var)
string(REPLACE "-" "_" supported ${flag}_cxx)
check_cxx_compiler_flag(${flag} ${supported})
if(${${supported}})
set(${var} "${${var}} ${flag}" PARENT_SCOPE)
endif()
endfunction()
function (add_linker_flag_if_supported flag var)
string(REPLACE "-" "_" supported ${flag}_ld)
string(REPLACE "," "_" supported ${flag}_ld)
check_linker_flag(${flag} ${supported})
if(${${supported}})
set(${var} "${${var}} ${flag}" PARENT_SCOPE)
endif()
endfunction()
find_package(Git)
if(GIT_FOUND)
if(NOT DEV_MODE)
find_package(Git)
function (check_submodule relative_path)
execute_process(COMMAND git rev-parse "HEAD" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${relative_path} OUTPUT_VARIABLE localHead)
execute_process(COMMAND git rev-parse "HEAD:${relative_path}" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} OUTPUT_VARIABLE checkedHead)
string(COMPARE EQUAL "${localHead}" "${checkedHead}" upToDate)
if (upToDate)
message(STATUS "Submodule '${relative_path}' is up-to-date")
else()
message(FATAL_ERROR "Submodule '${relative_path}' is not using the checked head. Please update all submodules with\ngit submodule update --init --force\nor run cmake with -DMANUAL_SUBMODULES=1,\n or if you want to build from latest master run cmake with -DEV_MODE,\n or run make devmode")
endif()
endfunction ()
message(STATUS "Checking submodules")
check_submodule(monero)
else()
execute_process(COMMAND cd monero && git checkout origin/master)
endif()
endif()
add_subdirectory(monero)
set_property(TARGET wallet_merged PROPERTY FOLDER "monero")
get_directory_property(ARCH_WIDTH DIRECTORY "monero" DEFINITION ARCH_WIDTH)
if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
add_definitions(-DQT_NO_DEBUG)
endif()
if(STATIC)
message(STATUS "Initiating static build")
set(Boost_USE_STATIC_LIBS ON)
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
add_definitions(-DMONERO_GUI_STATIC)
endif()
# Include password strength library
if(ENABLE_PASS_STRENGTH_METER)
message(STATUS "Buildin with pass strength meter support.")
else()
add_definitions(-DDISABLE_PASS_STRENGTH_METER)
endif()
include(CheckTrezor) # Trezor support check
include(CMakePackageConfigHelpers)
# force version update
function (monero_gui_add_library_with_deps)
cmake_parse_arguments(MONERO_ADD_LIBRARY "" "NAME" "DEPENDS;SOURCES" ${ARGN})
source_group("${MONERO_ADD_LIBRARY_NAME}" FILES ${MONERO_ADD_LIBRARY_SOURCES})
# Define a ("virtual") object library and an actual library that links those
# objects together. The virtual libraries can be arbitrarily combined to link
# any subset of objects into one library archive. This is used for releasing
# libwallet, which combines multiple components.
set(objlib obj_${MONERO_ADD_LIBRARY_NAME})
add_library(${objlib} OBJECT ${MONERO_ADD_LIBRARY_SOURCES})
add_library("${MONERO_ADD_LIBRARY_NAME}" $<TARGET_OBJECTS:${objlib}>)
if (MONERO_ADD_LIBRARY_DEPENDS)
add_dependencies(${objlib} ${MONERO_ADD_LIBRARY_DEPENDS})
endif()
set_property(TARGET "${MONERO_ADD_LIBRARY_NAME}" PROPERTY FOLDER "libs")
target_compile_definitions(${objlib}
PRIVATE $<TARGET_PROPERTY:${MONERO_ADD_LIBRARY_NAME},INTERFACE_COMPILE_DEFINITIONS>)
endfunction ()
function (monero_gui_add_library name)
monero_gui_add_library_with_deps(NAME "${name}" SOURCES ${ARGN})
endfunction()
include_directories(${EASYLOGGING_INCLUDE})
link_directories(${EASYLOGGING_LIBRARY_DIRS})
include(VersionGui)
monero_gui_add_library(gui_version SOURCES version.js DEPENDS genversiongui)
message(STATUS "${CMAKE_MODULE_PATH}")
# OpenSSL
find_package(OpenSSL REQUIRED)
message(STATUS "OpenSSL: Version ${OPENSSL_VERSION}")
message(STATUS "OpenSSL: include dir at ${OPENSSL_INCLUDE_DIR}")
message(STATUS "OpenSSL: libraries at ${OPENSSL_LIBRARIES} ${OPENSSL_SSL_LIBRARIES}")
# Zbar (for QR scanner)
if(WITH_SCANNER)
add_definitions(-DWITH_SCANNER)
find_package(ZBar0)
message(STATUS "libzbar: include dir at ${ZBAR_INCLUDE_DIR}")
message(STATUS "libzbar: libraries at ${ZBAR_LIBRARIES}")
endif()
# Sodium
find_library(SODIUM_LIBRARY sodium)
message(STATUS "libsodium: libraries at ${SODIUM_LIBRARY}")
# LibUSB
find_package(LibUSB)
message(STATUS "libusb: include dir at ${LibUSB_INCLUDE_DIRS}")
message(STATUS "libusb: libraries at ${LibUSB_LIBRARIES}")
# HIDApi
find_package(HIDAPI REQUIRED)
message(STATUS "libhidapi: include dir at ${HIDAPI_INCLUDE_DIRS}")
message(STATUS "libhidapi: libraries at ${HIDAPI_LIBRARIES}")
# Boost
if(DEBUG)
set(Boost_DEBUG ON)
endif()
find_package(Boost 1.62 REQUIRED COMPONENTS
system
filesystem
thread
date_time
chrono
regex
serialization
program_options
locale)
if(LINUX)
find_package(X11 REQUIRED)
message(STATUS "X11_FOUND = ${X11_FOUND}")
message(STATUS "X11_INCLUDE_DIR = ${X11_INCLUDE_DIR}")
message(STATUS "X11_LIBRARIES = ${X11_LIBRARIES}")
include_directories(${X11_INCLUDE_DIR})
link_directories(${X11_LIBRARIES})
if(STATIC)
find_library(XCB_LIBRARY xcb)
message(STATUS "Found xcb library: ${XCB_LIBRARY}")
endif()
endif()
if(MINGW)
string(REGEX MATCH "^[^/]:/[^/]*" msys2_install_path "${CMAKE_C_COMPILER}")
message(STATUS "MSYS location: ${msys2_install_path}")
set(CMAKE_INCLUDE_PATH "${msys2_install_path}/mingw${ARCH_WIDTH}/include")
link_directories("${msys2_install_path}/mingw${ARCH_WIDTH}/qml/Qt/labs/folderlistmodel")
link_directories("${msys2_install_path}/mingw${ARCH_WIDTH}/qml/Qt/labs/settings")
link_directories("${msys2_install_path}/mingw${ARCH_WIDTH}/qml/QtGraphicalEffects")
link_directories("${msys2_install_path}/mingw${ARCH_WIDTH}/qml/QtGraphicalEffects/private")
link_directories("${msys2_install_path}/mingw${ARCH_WIDTH}/qml/QtMultimedia")
link_directories("${msys2_install_path}/mingw${ARCH_WIDTH}/qml/QtQuick.2")
link_directories("${msys2_install_path}/mingw${ARCH_WIDTH}/qml/QtQuick/Controls")
link_directories("${msys2_install_path}/mingw${ARCH_WIDTH}/qml/QtQuick/Controls.2")
link_directories("${msys2_install_path}/mingw${ARCH_WIDTH}/qml/QtQuick/Dialogs")
link_directories("${msys2_install_path}/mingw${ARCH_WIDTH}/qml/QtQuick/Dialogs/Private")
link_directories("${msys2_install_path}/mingw${ARCH_WIDTH}/qml/QtQuick/Layouts")
link_directories("${msys2_install_path}/mingw${ARCH_WIDTH}/qml/QtQuick/PrivateWidgets")
link_directories("${msys2_install_path}/mingw${ARCH_WIDTH}/qml/QtQuick/Templates.2")
link_directories("${msys2_install_path}/mingw${ARCH_WIDTH}/qml/QtQuick/Window.2")
link_directories("${msys2_install_path}/mingw${ARCH_WIDTH}/qml/QtQuick/XmlListModel")
# This is necessary because otherwise CMake will make Boost libraries -lfoo
# rather than a full path. Unfortunately, this makes the shared libraries get
# linked due to a bug in CMake which misses putting -static flags around the
# -lfoo arguments.
set(DEFLIB ${msys2_install_path}/mingw${ARCH_WIDTH}/lib)
list(REMOVE_ITEM CMAKE_C_IMPLICIT_LINK_DIRECTORIES ${DEFLIB})
list(REMOVE_ITEM CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES ${DEFLIB})
endif()
set(QT5_LIBRARIES
Qt5Core
Qt5Quick
Qt5QuickControls2
Qt5Widgets
Qt5Gui
Qt5Network
Qt5Qml
Qt5Multimedia
Qt5Xml
Qt5XmlPatterns
Qt5Svg
)
foreach(QT5_MODULE ${QT5_LIBRARIES})
find_package(${QT5_MODULE} REQUIRED)
endforeach()
find_package(PkgConfig)
if(PKGCONFIG_FOUND)
pkg_check_modules(QT5_PKG_CONFIG ${QT5_LIBRARIES})
if(QT5_PKG_CONFIG_FOUND)
set(QT5_PKG_CONFIG "QT5_PKG_CONFIG")
if(STATIC)
set(QT5_PKG_CONFIG "${QT5_PKG_CONFIG}_STATIC")
endif()
set(QT5_LIBRARIES ${${QT5_PKG_CONFIG}_LIBRARIES} ${${QT5_PKG_CONFIG}_LDFLAGS_OTHER})
include_directories(${${QT5_PKG_CONFIG}_INCLUDE_DIRS})
link_directories(${${QT5_PKG_CONFIG}_LIBRARY_DIRS})
endif()
endif()
list(APPEND QT5_LIBRARIES
${Qt5Gui_PLUGINS}
${Qt5Svg_PLUGINS}
${Qt5Qml_PLUGINS}
${Qt5Network_PLUGINS}
)
if(STATIC)
set(QT5_LIBRARIES
qtquickcontrols2plugin # has to be the first one, depends on Qt5QuickControls2
${QT5_LIBRARIES}
declarative_multimedia
dialogplugin
dialogsprivateplugin
qmlfolderlistmodelplugin
qmlsettingsplugin
qmlxmllistmodelplugin
qquicklayoutsplugin
Qt5EventDispatcherSupport
Qt5FontDatabaseSupport
Qt5MultimediaQuick_p
Qt5PacketProtocol
Qt5ThemeSupport
qtgraphicaleffectsplugin
qtgraphicaleffectsprivate
qtquick2plugin
qtquickcontrolsplugin
qtquicktemplates2plugin
widgetsplugin
windowplugin
)
if(MINGW)
list(APPEND QT5_LIBRARIES qtfreetype)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
list(APPEND QT5_LIBRARIES D3D11 Dwrite D2d1)
endif()
endif()
endif()
message(STATUS "Using Boost include dir at ${Boost_INCLUDE_DIRS}")
message(STATUS "Using Boost libraries at ${Boost_LIBRARIES}")
include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
if(MINGW)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wa,-mbig-obj")
set(EXTRA_LIBRARIES mswsock;ws2_32;iphlpapi;crypt32;bcrypt)
if(DEPENDS)
set(ICU_LIBRARIES icuio icui18n icuuc icudata icutu iconv)
else()
set(ICU_LIBRARIES icuio icuin icuuc icudt icutu iconv)
endif()
elseif(APPLE OR OPENBSD OR ANDROID)
set(EXTRA_LIBRARIES "")
elseif(FREEBSD)
set(EXTRA_LIBRARIES execinfo)
elseif(DRAGONFLY)
find_library(COMPAT compat)
set(EXTRA_LIBRARIES execinfo ${COMPAT})
elseif(CMAKE_SYSTEM_NAME MATCHES "(SunOS|Solaris)")
set(EXTRA_LIBRARIES socket nsl resolv)
elseif(NOT MSVC AND NOT DEPENDS)
find_library(RT rt)
set(EXTRA_LIBRARIES ${RT})
endif()
list(APPEND EXTRA_LIBRARIES ${CMAKE_DL_LIBS})
if(APPLE)
include_directories(SYSTEM /usr/include/malloc)
if(POLICY CMP0042)
cmake_policy(SET CMP0042 NEW)
endif()
endif()
if (APPLE AND NOT IOS)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=x86-64 -fvisibility=default -std=c++11")
endif()
if(APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=default -DGTEST_HAS_TR1_TUPLE=0")
endif()
# warnings
add_c_flag_if_supported(-Wformat C_SECURITY_FLAGS)
add_cxx_flag_if_supported(-Wformat CXX_SECURITY_FLAGS)
add_c_flag_if_supported(-Wformat-security C_SECURITY_FLAGS)
add_cxx_flag_if_supported(-Wformat-security CXX_SECURITY_FLAGS)
# -fstack-protector
if (NOT OPENBSD AND NOT (WIN32 AND (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_LESS 9.1)))
add_c_flag_if_supported(-fstack-protector C_SECURITY_FLAGS)
add_cxx_flag_if_supported(-fstack-protector CXX_SECURITY_FLAGS)
add_c_flag_if_supported(-fstack-protector-strong C_SECURITY_FLAGS)
add_cxx_flag_if_supported(-fstack-protector-strong CXX_SECURITY_FLAGS)
endif()
# New in GCC 8.2
if (NOT OPENBSD AND NOT (WIN32 AND (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_LESS 9.1)))
add_c_flag_if_supported(-fcf-protection=full C_SECURITY_FLAGS)
add_cxx_flag_if_supported(-fcf-protection=full CXX_SECURITY_FLAGS)
endif()
if (NOT WIN32 AND NOT OPENBSD)
add_c_flag_if_supported(-fstack-clash-protection C_SECURITY_FLAGS)
add_cxx_flag_if_supported(-fstack-clash-protection CXX_SECURITY_FLAGS)
endif()
# Removed in GCC 9.1 (or before ?), but still accepted, so spams the output
if (NOT (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 9.1))
add_c_flag_if_supported(-mmitigate-rop C_SECURITY_FLAGS)
add_cxx_flag_if_supported(-mmitigate-rop CXX_SECURITY_FLAGS)
endif()
# linker
if (NOT (WIN32 AND CMAKE_C_COMPILER_ID STREQUAL "GNU"))
# Windows binaries die on startup with PIE when compiled with GCC
add_linker_flag_if_supported(-pie LD_SECURITY_FLAGS)
endif()
add_linker_flag_if_supported(-Wl,-z,relro LD_SECURITY_FLAGS)
add_linker_flag_if_supported(-Wl,-z,now LD_SECURITY_FLAGS)
add_linker_flag_if_supported(-Wl,-z,noexecstack noexecstack_SUPPORTED)
if (noexecstack_SUPPORTED)
set(LD_SECURITY_FLAGS "${LD_SECURITY_FLAGS} -Wl,-z,noexecstack")
endif()
add_linker_flag_if_supported(-Wl,-z,noexecheap noexecheap_SUPPORTED)
if (noexecheap_SUPPORTED)
set(LD_SECURITY_FLAGS "${LD_SECURITY_FLAGS} -Wl,-z,noexecheap")
endif()
message(STATUS "Using C security hardening flags: ${C_SECURITY_FLAGS}")
message(STATUS "Using C++ security hardening flags: ${CXX_SECURITY_FLAGS}")
message(STATUS "Using linker security hardening flags: ${LD_SECURITY_FLAGS}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_SECURITY_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_SECURITY_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${LD_SECURITY_FLAGS}")
if (HIDAPI_FOUND OR LibUSB_COMPILE_TEST_PASSED)
if (APPLE)
if(DEPENDS)
list(APPEND EXTRA_LIBRARIES "-framework Foundation -framework IOKit")
else()
find_library(COREFOUNDATION CoreFoundation)
find_library(IOKIT IOKit)
list(APPEND EXTRA_LIBRARIES ${IOKIT})
list(APPEND EXTRA_LIBRARIES ${COREFOUNDATION})
endif()
endif()
if (WIN32)
list(APPEND EXTRA_LIBRARIES setupapi Version)
endif()
endif()
add_subdirectory(src)
# Required to make wallet_merged build before the gui
add_dependencies(monero-gui wallet_merged)

View File

@@ -350,6 +350,7 @@ Rectangle {
anchors.top: parent.top
anchors.bottom: networkStatus.top
width: parent.width
boundsBehavior: isMac ? Flickable.DragAndOvershootBounds : Flickable.StopAtBounds
clip: true
Column {
@@ -364,7 +365,7 @@ Rectangle {
MoneroComponents.MenuButtonDivider {
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 16
anchors.leftMargin: 20
}
// ------------- Account tab ---------------
@@ -374,7 +375,6 @@ Rectangle {
anchors.right: parent.right
text: qsTr("Account") + translationManager.emptyString
symbol: qsTr("T") + translationManager.emptyString
dotColor: "#44AAFF"
onClicked: {
parent.previousButton.checked = false
parent.previousButton = accountButton
@@ -386,7 +386,7 @@ Rectangle {
visible: accountButton.present
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 16
anchors.leftMargin: 20
}
// ------------- Transfer tab ---------------
@@ -396,7 +396,6 @@ Rectangle {
anchors.right: parent.right
text: qsTr("Send") + translationManager.emptyString
symbol: qsTr("S") + translationManager.emptyString
dotColor: "#FF6C3C"
onClicked: {
parent.previousButton.checked = false
parent.previousButton = transferButton
@@ -408,7 +407,7 @@ Rectangle {
visible: transferButton.present
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 16
anchors.leftMargin: 20
}
// ------------- AddressBook tab ---------------
@@ -419,7 +418,6 @@ Rectangle {
anchors.right: parent.right
text: qsTr("Address book") + translationManager.emptyString
symbol: qsTr("B") + translationManager.emptyString
dotColor: "#FF4F41"
under: transferButton
onClicked: {
parent.previousButton.checked = false
@@ -432,7 +430,7 @@ Rectangle {
visible: addressBookButton.present
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 16
anchors.leftMargin: 20
}
// ------------- Receive tab ---------------
@@ -442,7 +440,6 @@ Rectangle {
anchors.right: parent.right
text: qsTr("Receive") + translationManager.emptyString
symbol: qsTr("R") + translationManager.emptyString
dotColor: "#AAFFBB"
onClicked: {
parent.previousButton.checked = false
parent.previousButton = receiveButton
@@ -454,7 +451,7 @@ Rectangle {
visible: receiveButton.present
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 16
anchors.leftMargin: 20
}
// ------------- Merchant tab ---------------
@@ -466,7 +463,6 @@ Rectangle {
anchors.right: parent.right
text: qsTr("Merchant") + translationManager.emptyString
symbol: qsTr("U") + translationManager.emptyString
dotColor: "#FF4F41"
under: receiveButton
onClicked: {
parent.previousButton.checked = false
@@ -479,7 +475,7 @@ Rectangle {
visible: merchantButton.present && appWindow.walletMode >= 2
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 16
anchors.leftMargin: 20
}
// ------------- History tab ---------------
@@ -490,7 +486,6 @@ Rectangle {
anchors.right: parent.right
text: qsTr("Transactions") + translationManager.emptyString
symbol: qsTr("H") + translationManager.emptyString
dotColor: "#6B0072"
onClicked: {
parent.previousButton.checked = false
parent.previousButton = historyButton
@@ -502,7 +497,7 @@ Rectangle {
visible: historyButton.present
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 16
anchors.leftMargin: 20
}
// ------------- Advanced tab ---------------
@@ -513,7 +508,6 @@ Rectangle {
anchors.right: parent.right
text: qsTr("Advanced") + translationManager.emptyString
symbol: qsTr("D") + translationManager.emptyString
dotColor: "#FFD781"
onClicked: {
parent.previousButton.checked = false
parent.previousButton = advancedButton
@@ -524,7 +518,7 @@ Rectangle {
visible: advancedButton.present && appWindow.walletMode >= 2
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 16
anchors.leftMargin: 20
}
// ------------- Mining tab ---------------
@@ -535,7 +529,6 @@ Rectangle {
anchors.right: parent.right
text: qsTr("Mining") + translationManager.emptyString
symbol: qsTr("M") + translationManager.emptyString
dotColor: "#FFD781"
under: advancedButton
onClicked: {
parent.previousButton.checked = false
@@ -548,7 +541,7 @@ Rectangle {
visible: miningButton.present && appWindow.walletMode >= 2
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 16
anchors.leftMargin: 20
}
// ------------- TxKey tab ---------------
@@ -559,7 +552,6 @@ Rectangle {
anchors.right: parent.right
text: qsTr("Prove/check") + translationManager.emptyString
symbol: qsTr("K") + translationManager.emptyString
dotColor: "#FFD781"
under: advancedButton
onClicked: {
parent.previousButton.checked = false
@@ -572,7 +564,7 @@ Rectangle {
visible: txkeyButton.present && appWindow.walletMode >= 2
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 16
anchors.leftMargin: 20
}
// ------------- Shared RingDB tab ---------------
@@ -583,7 +575,6 @@ Rectangle {
anchors.right: parent.right
text: qsTr("Shared RingDB") + translationManager.emptyString
symbol: qsTr("G") + translationManager.emptyString
dotColor: "#FFD781"
under: advancedButton
onClicked: {
parent.previousButton.checked = false
@@ -596,7 +587,7 @@ Rectangle {
visible: sharedringdbButton.present && appWindow.walletMode >= 2
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 16
anchors.leftMargin: 20
}
// ------------- Sign/verify tab ---------------
@@ -607,7 +598,6 @@ Rectangle {
anchors.right: parent.right
text: qsTr("Sign/verify") + translationManager.emptyString
symbol: qsTr("I") + translationManager.emptyString
dotColor: "#FFD781"
under: advancedButton
onClicked: {
parent.previousButton.checked = false
@@ -620,7 +610,7 @@ Rectangle {
visible: signButton.present && appWindow.walletMode >= 2
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 16
anchors.leftMargin: 20
}
// ------------- Settings tab ---------------
@@ -630,7 +620,6 @@ Rectangle {
anchors.right: parent.right
text: qsTr("Settings") + translationManager.emptyString
symbol: qsTr("E") + translationManager.emptyString
dotColor: "#36B25C"
onClicked: {
parent.previousButton.checked = false
parent.previousButton = settingsButton
@@ -642,7 +631,7 @@ Rectangle {
visible: settingsButton.present
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 16
anchors.leftMargin: 20
}
} // Column

40
Makefile Normal file
View File

@@ -0,0 +1,40 @@
ANDROID_STANDALONE_TOOLCHAIN_PATH ?= /usr/local/toolchain
dotgit=$(shell ls -d .git/config)
ifneq ($(dotgit), .git/config)
USE_SINGLE_BUILDDIR=1
endif
subbuilddir:=$(shell echo `uname | sed -e 's|[:/\\ \(\)]|_|g'`/`git branch | grep '\* ' | cut -f2- -d' '| sed -e 's|[:/\\ \(\)]|_|g'`)
ifeq ($(USE_SINGLE_BUILDDIR),)
builddir := build/"$(subbuilddir)"
topdir := ../../../..
deldirs := $(builddir)
else
builddir := build
topdir := ../..
deldirs := $(builddir)/debug $(builddir)/release $(builddir)/fuzz
endif
default:
mkdir -p build && cd build && cmake -D ARCH="x86-64" -D DEV_MODE=$(or ${DEV_MODE},OFF) -D BUILD_64=ON -D CMAKE_BUILD_TYPE=Release .. && $(MAKE)
debug:
mkdir -p build && cd build && cmake -D DEV_MODE=$(or ${DEV_MODE},ON) .. && $(MAKE) VERBOSE=1
devmode:
mkdir -p build && cd build && cmake -D ARCH="x86-64" -D DEV_MODE=$(or ${DEV_MODE},ON) -D BUILD_64=ON -D CMAKE_BUILD_TYPE=Release .. && $(MAKE)
clean:
mkdir -p build && cd build && rm -rf *
scanner:
mkdir -p build && cd build && cmake -D ARCH="x86-64" -D DEV_MODE=$(or ${DEV_MODE},ON) -D WITH_SCANNER=ON -D BUILD_64=ON -D CMAKE_BUILD_TYPE=Release .. && $(MAKE)
debug-static-win64:
mkdir -p $(builddir)/debug && cd $(builddir)/debug && cmake -D STATIC=ON -G "MSYS Makefiles" -D DEV_MODE=$(or ${DEV_MODE},ON) -D ARCH="x86-64" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=Debug -D BUILD_TAG="win-x64" -D CMAKE_TOOLCHAIN_FILE=$(topdir)/cmake/64-bit-toolchain.cmake -D MSYS2_FOLDER=c:/msys64 -D MINGW=ON $(topdir) && $(MAKE)
debug-static-mac64:
mkdir -p $(builddir)/debug
cd $(builddir)/debug && cmake -D STATIC=ON -D DEV_MODE=$(or ${DEV_MODE},ON) -D ARCH="x86-64" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=release -D BUILD_TAG="mac-x64" $(topdir) && $(MAKE)
release-static-win64:
mkdir -p $(builddir)/release && cd $(builddir)/release && cmake -D STATIC=ON -G "MSYS Makefiles" -D DEV_MODE=$(or ${DEV_MODE},OFF) -D ARCH="x86-64" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=Release -D BUILD_TAG="win-x64" -D CMAKE_TOOLCHAIN_FILE=$(topdir)/cmake/64-bit-toolchain.cmake -D MSYS2_FOLDER=c:/msys64 -D MINGW=ON $(topdir) && $(MAKE)

View File

@@ -186,6 +186,7 @@ Rectangle {
Layout.fillWidth: true
Layout.fillHeight: true
clip: true
boundsBehavior: isMac ? Flickable.DragAndOvershootBounds : Flickable.StopAtBounds
ScrollBar.vertical: ScrollBar {
parent: root
@@ -195,6 +196,7 @@ Rectangle {
anchors.topMargin: persistentSettings.customDecorations ? 60 : 10
anchors.bottom: parent.bottom
anchors.bottomMargin: persistentSettings.customDecorations ? 15 : 10
onActiveChanged: if (!active && !isMac) active = true
}
onFlickingChanged: {

View File

@@ -0,0 +1,50 @@
# Copyright (c) 2014-2019, The Monero Project
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification, are
# permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of
# conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
# of conditions and the following disclaimer in the documentation and/or other
# materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be
# used to endorse or promote products derived from this software without specific
# prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
# THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if (NOT CMAKE_HOST_WIN32)
set (CMAKE_SYSTEM_NAME Windows)
endif()
set (GCC_PREFIX i686-w64-mingw32)
set (CMAKE_C_COMPILER ${GCC_PREFIX}-gcc)
set (CMAKE_CXX_COMPILER ${GCC_PREFIX}-g++)
set (CMAKE_AR ar CACHE FILEPATH "" FORCE)
set (CMAKE_NM nm CACHE FILEPATH "" FORCE)
set (CMAKE_LINKER ld CACHE FILEPATH "" FORCE)
#set (CMAKE_RANLIB ${GCC_PREFIX}-gcc-ranlib CACHE FILEPATH "" FORCE)
set (CMAKE_RC_COMPILER windres)
set (CMAKE_FIND_ROOT_PATH "${MSYS2_FOLDER}/mingw32")
# Ensure cmake doesn't find things in the wrong places
set (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) # Find programs on host
set (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) # Find libs in target
set (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) # Find includes in target
set (MINGW_FLAG "-m32")
set (USE_LTO_DEFAULT false)

View File

@@ -0,0 +1,50 @@
# Copyright (c) 2014-2019, The Monero Project
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification, are
# permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of
# conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
# of conditions and the following disclaimer in the documentation and/or other
# materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be
# used to endorse or promote products derived from this software without specific
# prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
# THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if (NOT CMAKE_HOST_WIN32)
set (CMAKE_SYSTEM_NAME Windows)
endif()
set (GCC_PREFIX x86_64-w64-mingw32)
set (CMAKE_C_COMPILER ${GCC_PREFIX}-gcc)
set (CMAKE_CXX_COMPILER ${GCC_PREFIX}-g++)
set (CMAKE_AR ar CACHE FILEPATH "" FORCE)
set (CMAKE_NM nm CACHE FILEPATH "" FORCE)
set (CMAKE_LINKER ld CACHE FILEPATH "" FORCE)
#set (CMAKE_RANLIB ${GCC_PREFIX}-gcc-ranlib CACHE FILEPATH "" FORCE)
set (CMAKE_RC_COMPILER windres)
set (CMAKE_FIND_ROOT_PATH "${MSYS2_FOLDER}/mingw64")
# Ensure cmake doesn't find things in the wrong places
set (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) # Find programs on host
set (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) # Find libs in target
set (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) # Find includes in target
set (MINGW_FLAG "-m64")
set (USE_LTO_DEFAULT false)

14
cmake/CheckLinkerFlag.c Normal file
View File

@@ -0,0 +1,14 @@
#ifdef __CLASSIC_C__
int main()
{
int ac;
char* av[];
#else
int main(int ac, char* av[])
{
#endif
if (ac > 1000) {
return *av[0];
}
return 0;
}

View File

@@ -0,0 +1,47 @@
include(CheckCCompilerFlag)
macro(CHECK_LINKER_FLAG flag VARIABLE)
if(NOT DEFINED "${VARIABLE}")
if(NOT CMAKE_REQUIRED_QUIET)
message(STATUS "Looking for ${flag} linker flag")
endif()
set(_cle_source ${CMAKE_SOURCE_DIR}/cmake/CheckLinkerFlag.c)
set(saved_CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
set(CMAKE_C_FLAGS "${flag}")
try_compile(${VARIABLE}
${CMAKE_BINARY_DIR}
${_cle_source}
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} ${flag}
CMAKE_FLAGS
OUTPUT_VARIABLE OUTPUT)
unset(_cle_source)
set(CMAKE_C_FLAGS ${saved_CMAKE_C_FLAGS})
unset(saved_CMAKE_C_FLAGS)
if ("${OUTPUT}" MATCHES "warning.*ignored")
set(${VARIABLE} 0)
endif()
if(${VARIABLE})
if(NOT CMAKE_REQUIRED_QUIET)
message(STATUS "Looking for ${flag} linker flag - found")
endif()
set(${VARIABLE} 1 CACHE INTERNAL "Have linker flag ${flag}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the ${flag} linker flag is supported "
"passed with the following output:\n"
"${OUTPUT}\n\n")
else()
if(NOT CMAKE_REQUIRED_QUIET)
message(STATUS "Looking for ${flag} linker flag - not found")
endif()
set(${VARIABLE} "" CACHE INTERNAL "Have linker flag ${flag}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the ${flag} linker flag is supported "
"failed with the following output:\n"
"${OUTPUT}\n\n")
endif()
endif()
endmacro()

181
cmake/CheckTrezor.cmake Normal file
View File

@@ -0,0 +1,181 @@
OPTION(USE_DEVICE_TREZOR "Trezor support compilation" ON)
OPTION(USE_DEVICE_TREZOR_LIBUSB "Trezor LibUSB compilation" ON)
OPTION(USE_DEVICE_TREZOR_UDP_RELEASE "Trezor UdpTransport in release mode" OFF)
OPTION(USE_DEVICE_TREZOR_DEBUG "Trezor Debugging enabled" OFF)
OPTION(TREZOR_DEBUG "Main trezor debugging switch" OFF)
# Helper function to fix cmake < 3.6.0 FindProtobuf variables
function(_trezor_protobuf_fix_vars)
if(${CMAKE_VERSION} VERSION_LESS "3.6.0")
foreach(UPPER
PROTOBUF_SRC_ROOT_FOLDER
PROTOBUF_IMPORT_DIRS
PROTOBUF_DEBUG
PROTOBUF_LIBRARY
PROTOBUF_PROTOC_LIBRARY
PROTOBUF_INCLUDE_DIR
PROTOBUF_PROTOC_EXECUTABLE
PROTOBUF_LIBRARY_DEBUG
PROTOBUF_PROTOC_LIBRARY_DEBUG
PROTOBUF_LITE_LIBRARY
PROTOBUF_LITE_LIBRARY_DEBUG
)
if (DEFINED ${UPPER})
string(REPLACE "PROTOBUF_" "Protobuf_" Camel ${UPPER})
if (NOT DEFINED ${Camel})
set(${Camel} ${${UPPER}} PARENT_SCOPE)
endif()
endif()
endforeach()
endif()
endfunction()
# Use Trezor master switch
if (USE_DEVICE_TREZOR)
# Protobuf is required to build protobuf messages for Trezor
include(FindProtobuf OPTIONAL)
find_package(Protobuf)
_trezor_protobuf_fix_vars()
# Protobuf handling the cache variables set in docker.
if(NOT Protobuf_FOUND AND NOT Protobuf_LIBRARY AND NOT Protobuf_PROTOC_EXECUTABLE AND NOT Protobuf_INCLUDE_DIR)
message(STATUS "Could not find Protobuf")
elseif(NOT Protobuf_LIBRARY OR NOT EXISTS "${Protobuf_LIBRARY}")
message(STATUS "Protobuf library not found: ${Protobuf_LIBRARY}")
unset(Protobuf_FOUND)
elseif(NOT Protobuf_PROTOC_EXECUTABLE OR NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}")
message(STATUS "Protobuf executable not found: ${Protobuf_PROTOC_EXECUTABLE}")
unset(Protobuf_FOUND)
elseif(NOT Protobuf_INCLUDE_DIR OR NOT EXISTS "${Protobuf_INCLUDE_DIR}")
message(STATUS "Protobuf include dir not found: ${Protobuf_INCLUDE_DIR}")
unset(Protobuf_FOUND)
else()
message(STATUS "Protobuf lib: ${Protobuf_LIBRARY}, inc: ${Protobuf_INCLUDE_DIR}, protoc: ${Protobuf_PROTOC_EXECUTABLE}")
set(Protobuf_INCLUDE_DIRS ${Protobuf_INCLUDE_DIR})
set(Protobuf_FOUND 1) # override found if all rquired info was provided by variables
endif()
if(TREZOR_DEBUG)
set(USE_DEVICE_TREZOR_DEBUG 1)
endif()
# Compile debugging support (for tests)
if (USE_DEVICE_TREZOR_DEBUG)
add_definitions(-DWITH_TREZOR_DEBUGGING=1)
endif()
else()
message(STATUS "Trezor support disabled by USE_DEVICE_TREZOR")
endif()
if(Protobuf_FOUND AND USE_DEVICE_TREZOR)
if (NOT "$ENV{TREZOR_PYTHON}" STREQUAL "")
set(TREZOR_PYTHON "$ENV{TREZOR_PYTHON}" CACHE INTERNAL "Copied from environment variable TREZOR_PYTHON")
else()
find_package(Python QUIET COMPONENTS Interpreter) # cmake 3.12+
if(Python_Interpreter_FOUND)
set(TREZOR_PYTHON "${Python_EXECUTABLE}")
endif()
endif()
if(NOT TREZOR_PYTHON)
find_package(PythonInterp)
if(PYTHONINTERP_FOUND AND PYTHON_EXECUTABLE)
set(TREZOR_PYTHON "${PYTHON_EXECUTABLE}")
endif()
endif()
if(NOT TREZOR_PYTHON)
message(STATUS "Trezor: Python not found")
endif()
endif()
# Protobuf compilation test
if(Protobuf_FOUND AND USE_DEVICE_TREZOR AND TREZOR_PYTHON)
execute_process(COMMAND ${Protobuf_PROTOC_EXECUTABLE} -I "${CMAKE_SOURCE_DIR}/cmake" -I "${Protobuf_INCLUDE_DIR}" "${CMAKE_SOURCE_DIR}/cmake/test-protobuf.proto" --cpp_out ${CMAKE_BINARY_DIR} RESULT_VARIABLE RET OUTPUT_VARIABLE OUT ERROR_VARIABLE ERR)
if(RET)
message(STATUS "Protobuf test generation failed: ${OUT} ${ERR}")
endif()
try_compile(Protobuf_COMPILE_TEST_PASSED
"${CMAKE_BINARY_DIR}"
SOURCES
"${CMAKE_BINARY_DIR}/test-protobuf.pb.cc"
"${CMAKE_SOURCE_DIR}/cmake/test-protobuf.cpp"
CMAKE_FLAGS
"-DINCLUDE_DIRECTORIES=${Protobuf_INCLUDE_DIR};${CMAKE_BINARY_DIR}"
"-DCMAKE_CXX_STANDARD=11"
LINK_LIBRARIES ${Protobuf_LIBRARY}
OUTPUT_VARIABLE OUTPUT
)
if(NOT Protobuf_COMPILE_TEST_PASSED)
message(STATUS "Protobuf Compilation test failed: ${OUTPUT}.")
endif()
endif()
# Try to build protobuf messages
if(Protobuf_FOUND AND USE_DEVICE_TREZOR AND TREZOR_PYTHON AND Protobuf_COMPILE_TEST_PASSED)
set(ENV{PROTOBUF_INCLUDE_DIRS} "${Protobuf_INCLUDE_DIR}")
set(ENV{PROTOBUF_PROTOC_EXECUTABLE} "${Protobuf_PROTOC_EXECUTABLE}")
set(TREZOR_PROTOBUF_PARAMS "")
if (USE_DEVICE_TREZOR_DEBUG)
set(TREZOR_PROTOBUF_PARAMS "--debug")
endif()
execute_process(COMMAND ${TREZOR_PYTHON} tools/build_protob.py ${TREZOR_PROTOBUF_PARAMS} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/monero/src/device_trezor/trezor RESULT_VARIABLE RET OUTPUT_VARIABLE OUT ERROR_VARIABLE ERR)
if(RET)
message(WARNING "Trezor protobuf messages could not be regenerated (err=${RET}, python ${PYTHON})."
"OUT: ${OUT}, ERR: ${ERR}."
"Please read src/device_trezor/trezor/tools/README.md")
else()
message(STATUS "Trezor protobuf messages regenerated out: \"${OUT}.\"")
set(DEVICE_TREZOR_READY 1)
add_definitions(-DDEVICE_TREZOR_READY=1)
add_definitions(-DPROTOBUF_INLINE_NOT_IN_HEADERS=0)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
add_definitions(-DTREZOR_DEBUG=1)
endif()
if(USE_DEVICE_TREZOR_UDP_RELEASE)
add_definitions(-DUSE_DEVICE_TREZOR_UDP_RELEASE=1)
endif()
if (Protobuf_INCLUDE_DIR)
include_directories(${Protobuf_INCLUDE_DIR})
endif()
# LibUSB support, check for particular version
# Include support only if compilation test passes
if (USE_DEVICE_TREZOR_LIBUSB)
find_package(LibUSB)
endif()
if (LibUSB_COMPILE_TEST_PASSED)
add_definitions(-DHAVE_TREZOR_LIBUSB=1)
if(LibUSB_INCLUDE_DIRS)
include_directories(${LibUSB_INCLUDE_DIRS})
endif()
endif()
set(TREZOR_LIBUSB_LIBRARIES "")
if(LibUSB_COMPILE_TEST_PASSED)
list(APPEND TREZOR_LIBUSB_LIBRARIES ${LibUSB_LIBRARIES})
message(STATUS "Trezor compatible LibUSB found at: ${LibUSB_INCLUDE_DIRS}")
endif()
if (BUILD_GUI_DEPS)
set(TREZOR_DEP_LIBS "")
set(TREZOR_DEP_LINKER "")
if (Protobuf_LIBRARY)
list(APPEND TREZOR_DEP_LIBS ${Protobuf_LIBRARY})
string(APPEND TREZOR_DEP_LINKER " -lprotobuf")
endif()
if (TREZOR_LIBUSB_LIBRARIES)
list(APPEND TREZOR_DEP_LIBS ${TREZOR_LIBUSB_LIBRARIES})
string(APPEND TREZOR_DEP_LINKER " -lusb-1.0")
endif()
endif()
endif()
endif()

1803
cmake/Doxyfile.in Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,14 @@
/* increase vertical space */
#titlearea, #nav-path {
display: none;
height: 0px;
}
/* uncomment these lines for some extra vertical space */
/*
.tablist li {
line-height: 26px;
}
*/

98
cmake/FindBacktrace.cmake Normal file
View File

@@ -0,0 +1,98 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
#.rst:
# FindBacktrace
# -------------
#
# Find provider for backtrace(3).
#
# Checks if OS supports backtrace(3) via either libc or custom library.
# This module defines the following variables:
#
# ``Backtrace_HEADER``
# The header file needed for backtrace(3). Cached.
# Could be forcibly set by user.
# ``Backtrace_INCLUDE_DIRS``
# The include directories needed to use backtrace(3) header.
# ``Backtrace_LIBRARIES``
# The libraries (linker flags) needed to use backtrace(3), if any.
# ``Backtrace_FOUND``
# Is set if and only if backtrace(3) support detected.
#
# The following cache variables are also available to set or use:
#
# ``Backtrace_LIBRARY``
# The external library providing backtrace, if any.
# ``Backtrace_INCLUDE_DIR``
# The directory holding the backtrace(3) header.
#
# Typical usage is to generate of header file using configure_file() with the
# contents like the following::
#
# #cmakedefine01 Backtrace_FOUND
# #if Backtrace_FOUND
# # include <${Backtrace_HEADER}>
# #endif
#
# And then reference that generated header file in actual source.
include(CMakePushCheckState)
include(CheckSymbolExists)
include(FindPackageHandleStandardArgs)
# List of variables to be provided to find_package_handle_standard_args()
set(_Backtrace_STD_ARGS Backtrace_INCLUDE_DIR)
if(Backtrace_HEADER)
set(_Backtrace_HEADER_TRY "${Backtrace_HEADER}")
else(Backtrace_HEADER)
set(_Backtrace_HEADER_TRY "execinfo.h")
endif(Backtrace_HEADER)
find_path(Backtrace_INCLUDE_DIR "${_Backtrace_HEADER_TRY}")
set(Backtrace_INCLUDE_DIRS ${Backtrace_INCLUDE_DIR})
if (NOT DEFINED Backtrace_LIBRARY)
# First, check if we already have backtrace(), e.g., in libc
cmake_push_check_state(RESET)
set(CMAKE_REQUIRED_INCLUDES ${Backtrace_INCLUDE_DIRS})
set(CMAKE_REQUIRED_QUIET ${Backtrace_FIND_QUIETLY})
check_symbol_exists("backtrace" "${_Backtrace_HEADER_TRY}" _Backtrace_SYM_FOUND)
cmake_pop_check_state()
endif()
if(_Backtrace_SYM_FOUND)
# Avoid repeating the message() call below each time CMake is run.
if(NOT Backtrace_FIND_QUIETLY AND NOT DEFINED Backtrace_LIBRARY)
message(STATUS "backtrace facility detected in default set of libraries")
endif()
set(Backtrace_LIBRARY "" CACHE FILEPATH "Library providing backtrace(3), empty for default set of libraries")
else()
# Check for external library, for non-glibc systems
if(Backtrace_INCLUDE_DIR)
# OpenBSD has libbacktrace renamed to libexecinfo
find_library(Backtrace_LIBRARY "execinfo")
elseif() # respect user wishes
set(_Backtrace_HEADER_TRY "backtrace.h")
find_path(Backtrace_INCLUDE_DIR ${_Backtrace_HEADER_TRY})
find_library(Backtrace_LIBRARY "backtrace")
endif()
# Prepend list with library path as it's more common practice
set(_Backtrace_STD_ARGS Backtrace_LIBRARY ${_Backtrace_STD_ARGS})
endif()
message(STATUS "Backtrace_LIBRARY: ${Backtrace_LIBRARY}")
if(Backtrace_LIBRARY STREQUAL "NOTFOUND")
set(Backtrace_LIBRARY "")
endif()
if(Backtrace_LIBRARY STREQUAL "Backtrace_LIBRARY-NOTFOUND")
set(Backtrace_LIBRARY "")
endif()
set(Backtrace_LIBRARIES ${Backtrace_LIBRARY})
set(Backtrace_HEADER "${_Backtrace_HEADER_TRY}" CACHE STRING "Header providing backtrace(3) facility")
find_package_handle_standard_args(Backtrace FOUND_VAR Backtrace_FOUND REQUIRED_VARS ${_Backtrace_STD_ARGS})
mark_as_advanced(Backtrace_HEADER Backtrace_INCLUDE_DIR Backtrace_LIBRARY)

View File

@@ -0,0 +1,25 @@
# - Try to find Berkeley DB
# Once done this will define
#
# BERKELEY_DB_FOUND - system has Berkeley DB
# BERKELEY_DB_INCLUDE_DIR - the Berkeley DB include directory
# BERKELEY_DB_LIBRARIES - Link these to use Berkeley DB
# BERKELEY_DB_DEFINITIONS - Compiler switches required for using Berkeley DB
# Copyright (c) 2006, Alexander Dymo, <adymo@kdevelop.org>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
find_path(BERKELEY_DB_INCLUDE_DIR db_cxx.h
/usr/include/db4
/usr/local/include/db4
)
find_library(BERKELEY_DB_LIBRARIES NAMES db_cxx )
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Berkeley "Could not find Berkeley DB >= 4.1" BERKELEY_DB_INCLUDE_DIR BERKELEY_DB_LIBRARIES)
# show the BERKELEY_DB_INCLUDE_DIR and BERKELEY_DB_LIBRARIES variables only in the advanced view
mark_as_advanced(BERKELEY_DB_INCLUDE_DIR BERKELEY_DB_LIBRARIES )

60
cmake/FindHIDAPI.cmake Normal file
View File

@@ -0,0 +1,60 @@
# - try to find HIDAPI library
# from http://www.signal11.us/oss/hidapi/
#
# Cache Variables: (probably not for direct use in your scripts)
# HIDAPI_INCLUDE_DIR
# HIDAPI_LIBRARY
#
# Non-cache variables you might use in your CMakeLists.txt:
# HIDAPI_FOUND
# HIDAPI_INCLUDE_DIRS
# HIDAPI_LIBRARIES
#
# Requires these CMake modules:
# FindPackageHandleStandardArgs (known included with CMake >=2.6.2)
#
# Original Author:
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
#
# Copyright Iowa State University 2009-2010.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
find_library(HIDAPI_LIBRARY
NAMES hidapi hidapi-libusb)
find_path(HIDAPI_INCLUDE_DIR
NAMES hidapi.h
PATH_SUFFIXES
hidapi)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(HIDAPI
DEFAULT_MSG
HIDAPI_LIBRARY
HIDAPI_INCLUDE_DIR)
if(HIDAPI_FOUND)
set(HIDAPI_LIBRARIES "${HIDAPI_LIBRARY}")
if((STATIC AND UNIX AND NOT APPLE) OR (DEPENDS AND CMAKE_SYSTEM_NAME STREQUAL "Linux"))
find_library(LIBUSB-1.0_LIBRARY usb-1.0)
find_library(LIBUDEV_LIBRARY udev)
if(LIBUSB-1.0_LIBRARY)
set(HIDAPI_LIBRARIES "${HIDAPI_LIBRARIES};${LIBUSB-1.0_LIBRARY}")
if(LIBUDEV_LIBRARY)
set(HIDAPI_LIBRARIES "${HIDAPI_LIBRARIES};${LIBUDEV_LIBRARY}")
else()
message(WARNING "libudev library not found, binaries may fail to link.")
endif()
else()
message(WARNING "libusb-1.0 library not found, binaries may fail to link.")
endif()
endif()
set(HIDAPI_INCLUDE_DIRS "${HIDAPI_INCLUDE_DIR}")
endif()
mark_as_advanced(HIDAPI_INCLUDE_DIR HIDAPI_LIBRARY)

149
cmake/FindLibUSB.cmake Normal file
View File

@@ -0,0 +1,149 @@
# - Find libusb for portable USB support
# This module will find libusb as published by
# http://libusb.sf.net and
# http://libusb-win32.sf.net
#
# It will use PkgConfig if present and supported, else search
# it on its own. If the LibUSB_ROOT_DIR environment variable
# is defined, it will be used as base path.
# The following standard variables get defined:
# LibUSB_FOUND: true if LibUSB was found
# LibUSB_HEADER_FILE: the location of the C header file
# LibUSB_INCLUDE_DIRS: the directory that contains the include file
# LibUSB_LIBRARIES: the library
# source: https://github.com/IntelRealSense/librealsense
include ( CheckLibraryExists )
include ( CheckIncludeFile )
find_package ( PkgConfig )
if ( PKG_CONFIG_FOUND )
pkg_check_modules ( PKGCONFIG_LIBUSB libusb-1.0 )
if ( NOT PKGCONFIG_LIBUSB_FOUND )
pkg_check_modules ( PKGCONFIG_LIBUSB libusb )
endif ( NOT PKGCONFIG_LIBUSB_FOUND )
endif ( PKG_CONFIG_FOUND )
if ( PKGCONFIG_LIBUSB_FOUND )
set ( LibUSB_INCLUDE_DIRS ${PKGCONFIG_LIBUSB_INCLUDE_DIRS} )
foreach ( i ${PKGCONFIG_LIBUSB_LIBRARIES} )
string ( REGEX MATCH "[^-]*" ibase "${i}" )
find_library ( ${ibase}_LIBRARY
NAMES ${i}
PATHS ${PKGCONFIG_LIBUSB_LIBRARY_DIRS}
)
if ( ${ibase}_LIBRARY )
list ( APPEND LibUSB_LIBRARIES ${${ibase}_LIBRARY} )
endif ( ${ibase}_LIBRARY )
mark_as_advanced ( ${ibase}_LIBRARY )
endforeach ( i )
else ( PKGCONFIG_LIBUSB_FOUND )
find_file ( LibUSB_HEADER_FILE
NAMES
libusb.h usb.h
PATHS
$ENV{ProgramFiles}/LibUSB-Win32
$ENV{LibUSB_ROOT_DIR}
PATH_SUFFIXES
include
libusb-1.0
include/libusb-1.0
)
mark_as_advanced ( LibUSB_HEADER_FILE )
get_filename_component ( LibUSB_INCLUDE_DIRS "${LibUSB_HEADER_FILE}" PATH )
if ( ${CMAKE_SYSTEM_NAME} STREQUAL "Windows" )
# LibUSB-Win32 binary distribution contains several libs.
# Use the lib that got compiled with the same compiler.
if ( MSVC )
if ( WIN32 )
set ( LibUSB_LIBRARY_PATH_SUFFIX lib/msvc )
else ( WIN32 )
set ( LibUSB_LIBRARY_PATH_SUFFIX lib/msvc_x64 )
endif ( WIN32 )
elseif ( BORLAND )
set ( LibUSB_LIBRARY_PATH_SUFFIX lib/bcc )
elseif ( CMAKE_COMPILER_IS_GNUCC )
set ( LibUSB_LIBRARY_PATH_SUFFIX lib/gcc )
endif ( MSVC )
endif ( ${CMAKE_SYSTEM_NAME} STREQUAL "Windows" )
find_library ( usb_LIBRARY
NAMES
usb-1.0 libusb usb
PATHS
$ENV{ProgramFiles}/LibUSB-Win32
$ENV{LibUSB_ROOT_DIR}
PATH_SUFFIXES
${LibUSB_LIBRARY_PATH_SUFFIX}
)
mark_as_advanced ( usb_LIBRARY )
if ( usb_LIBRARY )
set ( LibUSB_LIBRARIES ${usb_LIBRARY} )
endif ( usb_LIBRARY )
endif ( PKGCONFIG_LIBUSB_FOUND )
if ( LibUSB_INCLUDE_DIRS AND LibUSB_LIBRARIES )
set ( LibUSB_FOUND true )
endif ( LibUSB_INCLUDE_DIRS AND LibUSB_LIBRARIES )
if ( LibUSB_FOUND )
set ( CMAKE_REQUIRED_INCLUDES "${LibUSB_INCLUDE_DIRS}" )
check_include_file ( "${LibUSB_HEADER_FILE}" LibUSB_FOUND )
endif ( LibUSB_FOUND )
if ( LibUSB_FOUND )
check_library_exists ( "${LibUSB_LIBRARIES}" usb_open "" LibUSB_FOUND )
check_library_exists ( "${LibUSB_LIBRARIES}" libusb_get_device_list "" LibUSB_VERSION_1.0 )
check_library_exists ( "${LibUSB_LIBRARIES}" libusb_get_port_numbers "" LibUSB_VERSION_1.0.16 )
if((STATIC AND UNIX AND NOT APPLE) OR (DEPENDS AND CMAKE_SYSTEM_NAME STREQUAL "Linux"))
find_library(LIBUDEV_LIBRARY udev)
if(LIBUDEV_LIBRARY)
set(LibUSB_LIBRARIES "${LibUSB_LIBRARIES};${LIBUDEV_LIBRARY}")
else()
message(WARNING "libudev library not found, binaries may fail to link.")
endif()
endif()
# Library 1.0.16+ compilation test.
# The check_library_exists does not work well on Apple with shared libs.
if (APPLE OR LibUSB_VERSION_1.0.16 OR STATIC)
if (APPLE)
if(DEPENDS)
list(APPEND TEST_COMPILE_EXTRA_LIBRARIES "-framework Foundation -framework IOKit")
else()
find_library(COREFOUNDATION CoreFoundation)
find_library(IOKIT IOKit)
list(APPEND TEST_COMPILE_EXTRA_LIBRARIES ${IOKIT})
list(APPEND TEST_COMPILE_EXTRA_LIBRARIES ${COREFOUNDATION})
endif()
endif()
if (WIN32)
list(APPEND TEST_COMPILE_EXTRA_LIBRARIES setupapi)
endif()
list(APPEND TEST_COMPILE_EXTRA_LIBRARIES ${LibUSB_LIBRARIES})
try_compile(LibUSB_COMPILE_TEST_PASSED
${CMAKE_BINARY_DIR}
"${CMAKE_SOURCE_DIR}/cmake/test-libusb-version.c"
CMAKE_FLAGS
"-DINCLUDE_DIRECTORIES=${LibUSB_INCLUDE_DIRS}"
"-DLINK_DIRECTORIES=${LibUSB_LIBRARIES}"
LINK_LIBRARIES ${TEST_COMPILE_EXTRA_LIBRARIES}
OUTPUT_VARIABLE OUTPUT)
unset(TEST_COMPILE_EXTRA_LIBRARIES)
message(STATUS "LibUSB Compilation test: ${LibUSB_COMPILE_TEST_PASSED}")
endif()
endif ( LibUSB_FOUND )
if ( NOT LibUSB_FOUND )
if ( NOT LibUSB_FIND_QUIETLY )
message ( STATUS "LibUSB not found, try setting LibUSB_ROOT_DIR environment variable." )
endif ( NOT LibUSB_FIND_QUIETLY )
if ( LibUSB_FIND_REQUIRED )
message ( FATAL_ERROR "" )
endif ( LibUSB_FIND_REQUIRED )
endif ( NOT LibUSB_FOUND )

41
cmake/FindLibunwind.cmake Normal file
View File

@@ -0,0 +1,41 @@
# - Try to find libunwind
# Once done this will define
#
# LIBUNWIND_FOUND - system has libunwind
# LIBUNWIND_INCLUDE_DIR - the libunwind include directory
# LIBUNWIND_LIBRARIES - Link these to use libunwind
# LIBUNWIND_DEFINITIONS - Compiler switches required for using libunwind
# Copyright (c) 2006, Alexander Dymo, <adymo@kdevelop.org>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
find_path(LIBUNWIND_INCLUDE_DIR libunwind.h
/usr/include
/usr/local/include
)
find_library(LIBUNWIND_LIBRARIES NAMES unwind )
if(NOT LIBUNWIND_LIBRARIES STREQUAL "LIBUNWIND_LIBRARIES-NOTFOUND")
if (CMAKE_COMPILER_IS_GNUCC)
set(LIBUNWIND_LIBRARIES "gcc_eh;${LIBUNWIND_LIBRARIES}")
endif()
endif()
# some versions of libunwind need liblzma, and we don't use pkg-config
# so we just look whether liblzma is installed, and add it if it is.
# It might not be actually needed, but doesn't hurt if it is not.
# We don't need any headers, just the lib, as it's privately needed.
message(STATUS "looking for liblzma")
find_library(LIBLZMA_LIBRARIES lzma )
if(NOT LIBLZMA_LIBRARIES STREQUAL "LIBLZMA_LIBRARIES-NOTFOUND")
message(STATUS "liblzma found")
set(LIBUNWIND_LIBRARIES "${LIBUNWIND_LIBRARIES};${LIBLZMA_LIBRARIES}")
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Libunwind "Could not find libunwind" LIBUNWIND_INCLUDE_DIR LIBUNWIND_LIBRARIES)
# show the LIBUNWIND_INCLUDE_DIR and LIBUNWIND_LIBRARIES variables only in the advanced view
mark_as_advanced(LIBUNWIND_INCLUDE_DIR LIBUNWIND_LIBRARIES )

59
cmake/FindMiniupnpc.cmake Normal file
View File

@@ -0,0 +1,59 @@
# --------------------------------- FindMiniupnpc Start ---------------------------------
# Locate miniupnp library
# This module defines
# MINIUPNP_FOUND, if false, do not try to link to miniupnp
# MINIUPNP_LIBRARY, the miniupnp variant
# MINIUPNP_INCLUDE_DIR, where to find miniupnpc.h and family)
# MINIUPNPC_VERSION_1_7_OR_HIGHER, set if we detect the version of miniupnpc is 1.7 or higher
#
# Note that the expected include convention is
# #include "miniupnpc.h"
# and not
# #include <miniupnpc/miniupnpc.h>
# This is because, the miniupnpc location is not standardized and may exist
# in locations other than miniupnpc/
if (MINIUPNP_INCLUDE_DIR AND MINIUPNP_LIBRARY)
# Already in cache, be silent
set(MINIUPNP_FIND_QUIETLY TRUE)
endif ()
find_path(MINIUPNP_INCLUDE_DIR miniupnpc.h
HINTS $ENV{MINIUPNP_INCLUDE_DIR}
PATH_SUFFIXES miniupnpc
)
find_library(MINIUPNP_LIBRARY miniupnpc
HINTS $ENV{MINIUPNP_LIBRARY}
)
find_library(MINIUPNP_STATIC_LIBRARY libminiupnpc.a
HINTS $ENV{MINIUPNP_STATIC_LIBRARY}
)
set(MINIUPNP_INCLUDE_DIRS ${MINIUPNP_INCLUDE_DIR})
set(MINIUPNP_LIBRARIES ${MINIUPNP_LIBRARY})
set(MINIUPNP_STATIC_LIBRARIES ${MINIUPNP_STATIC_LIBRARY})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(
MiniUPnPc DEFAULT_MSG
MINIUPNP_INCLUDE_DIR
MINIUPNP_LIBRARY
)
IF(MINIUPNPC_FOUND)
file(STRINGS "${MINIUPNP_INCLUDE_DIR}/miniupnpc.h" MINIUPNPC_API_VERSION_STR REGEX "^#define[\t ]+MINIUPNPC_API_VERSION[\t ]+[0-9]+")
if(MINIUPNPC_API_VERSION_STR MATCHES "^#define[\t ]+MINIUPNPC_API_VERSION[\t ]+([0-9]+)")
set(MINIUPNPC_API_VERSION "${CMAKE_MATCH_1}")
if (${MINIUPNPC_API_VERSION} GREATER "10" OR ${MINIUPNPC_API_VERSION} EQUAL "10")
message(STATUS "Found miniupnpc API version " ${MINIUPNPC_API_VERSION})
set(MINIUPNP_FOUND true)
set(MINIUPNPC_VERSION_1_7_OR_HIGHER true)
endif()
endif()
ENDIF()
mark_as_advanced(MINIUPNP_INCLUDE_DIR MINIUPNP_LIBRARY MINIUPNP_STATIC_LIBRARY)
# --------------------------------- FindMiniupnpc End ---------------------------------

91
cmake/FindReadline.cmake Normal file
View File

@@ -0,0 +1,91 @@
# - Try to find readline include dirs and libraries
#
# Usage of this module as follows:
#
# find_package(Readline)
#
# Variables used by this module, they can change the default behaviour and need
# to be set before calling find_package:
#
# Readline_ROOT_DIR Set this variable to the root installation of
# readline if the module has problems finding the
# proper installation path.
#
# Variables defined by this module:
#
# READLINE_FOUND System has readline, include and lib dirs found
# GNU_READLINE_FOUND Version of readline found is GNU readline, not libedit!
# LIBEDIT_FOUND Version of readline found is libedit, not GNU readline!
# Readline_INCLUDE_DIR The readline include directories.
# Readline_LIBRARY The readline library.
# GNU_READLINE_LIBRARY The GNU readline library or empty string.
# LIBEDIT_LIBRARY The libedit library or empty string.
find_path(Readline_ROOT_DIR
NAMES include/readline/readline.h
PATHS /usr/local/opt/readline/ /opt/local/ /usr/local/ /usr/
NO_DEFAULT_PATH
)
find_path(Readline_INCLUDE_DIR
NAMES readline/readline.h
PATHS ${Readline_ROOT_DIR}/include
NO_DEFAULT_PATH
)
find_library(Readline_LIBRARY
NAMES readline
PATHS ${Readline_ROOT_DIR}/lib
NO_DEFAULT_PATH
)
find_library(Termcap_LIBRARY
NAMES tinfo termcap ncursesw ncurses cursesw curses
)
if(Readline_INCLUDE_DIR AND Readline_LIBRARY)
set(READLINE_FOUND TRUE)
else(Readline_INCLUDE_DIR AND Readline_LIBRARY)
FIND_LIBRARY(Readline_LIBRARY NAMES readline PATHS Readline_ROOT_DIR)
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Readline DEFAULT_MSG Readline_INCLUDE_DIR Readline_LIBRARY )
MARK_AS_ADVANCED(Readline_INCLUDE_DIR Readline_LIBRARY)
endif(Readline_INCLUDE_DIR AND Readline_LIBRARY)
mark_as_advanced(
Readline_ROOT_DIR
Readline_INCLUDE_DIR
Readline_LIBRARY
)
set(CMAKE_REQUIRED_INCLUDES ${Readline_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${Readline_LIBRARY})
include(CheckFunctionExists)
check_function_exists(rl_copy_text HAVE_COPY_TEXT)
check_function_exists(rl_filename_completion_function HAVE_COMPLETION_FUNCTION)
if(NOT HAVE_COMPLETION_FUNCTION)
if (Readline_LIBRARY)
set(CMAKE_REQUIRED_LIBRARIES ${Readline_LIBRARY} ${Termcap_LIBRARY})
endif(Readline_LIBRARY)
check_function_exists(rl_copy_text HAVE_COPY_TEXT_TC)
check_function_exists(rl_filename_completion_function HAVE_COMPLETION_FUNCTION_TC)
set(HAVE_COMPLETION_FUNCTION ${HAVE_COMPLETION_FUNCTION_TC})
set(HAVE_COPY_TEXT ${HAVE_COPY_TEXT_TC})
if(HAVE_COMPLETION_FUNCTION)
set(Readline_LIBRARY ${Readline_LIBRARY} ${Termcap_LIBRARY})
endif(HAVE_COMPLETION_FUNCTION)
endif(NOT HAVE_COMPLETION_FUNCTION)
set(LIBEDIT_LIBRARY "")
set(GNU_READLINE_LIBRARY "")
if(HAVE_COMPLETION_FUNCTION AND HAVE_COPY_TEXT)
set(GNU_READLINE_FOUND TRUE)
set(GNU_READLINE_LIBRARY ${Readline_LIBRARY})
elseif(READLINE_FOUND AND NOT HAVE_COPY_TEXT)
set(LIBEDIT_FOUND TRUE)
set(LIBEDIT_LIBRARY ${Readline_LIBRARY})
endif(HAVE_COMPLETION_FUNCTION AND HAVE_COPY_TEXT)

40
cmake/FindUnbound.cmake Normal file
View File

@@ -0,0 +1,40 @@
# Copyright (c) 2014-2019, The Monero Project
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification, are
# permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of
# conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
# of conditions and the following disclaimer in the documentation and/or other
# materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be
# used to endorse or promote products derived from this software without specific
# prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
# THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
MESSAGE(STATUS "Looking for libunbound")
FIND_PATH(UNBOUND_INCLUDE_DIR
NAMES unbound.h
PATH_SUFFIXES include/ include/unbound/
PATHS "${PROJECT_SOURCE_DIR}"
${UNBOUND_ROOT}
$ENV{UNBOUND_ROOT}
/usr/local/
/usr/
)
find_library(UNBOUND_LIBRARIES unbound)

22
cmake/FindZBar0.cmake Normal file
View File

@@ -0,0 +1,22 @@
# from http://code.google.com/p/low-cost-vision-2012/source/browse/CMakeModules/FindZBar0.cmake?name=2-helium-1&r=d61f248bd5565b3c086bf4769a04bfd98f7079df
# - Try to find ZBar
# This will define
#
# ZBAR_FOUND -
# ZBAR_LIBRARY_DIR -
# ZBAR_INCLUDE_DIR -
# ZBAR_LIBRARIES -
#
find_package(PkgConfig)
pkg_check_modules(PC_ZBAR QUIET zbar)
set(ZBAR_DEFINITIONS ${PC_ZBAR_CFLAGS_OTHER})
find_library(ZBAR_LIBRARIES NAMES zbar
HINTS ${PC_ZBAR_LIBDIR} ${PC_ZBAR_LIBRARY_DIRS} )
find_path(ZBAR_INCLUDE_DIR Decoder.h
HINTS ${PC_ZBAR_INCLUDEDIR} ${PC_ZBAR_INCLUDE_DIRS}
PATH_SUFFIXES zbar )
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(ZBAR DEFAULT_MSG ZBAR_LIBRARIES ZBAR_INCLUDE_DIR)
message(STATUS "Found zbar libraries ${ZBAR_LIBRARIES}")

68
cmake/GenVersion.cmake Normal file
View File

@@ -0,0 +1,68 @@
# Copyright (c) 2014-2019, The Monero Project
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification, are
# permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of
# conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
# of conditions and the following disclaimer in the documentation and/or other
# materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be
# used to endorse or promote products derived from this software without specific
# prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
# THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
# Check what commit we're on
execute_process(COMMAND "${GIT}" rev-parse --short=9 HEAD RESULT_VARIABLE RET OUTPUT_VARIABLE COMMIT OUTPUT_STRIP_TRAILING_WHITESPACE)
if(RET)
# Something went wrong, set the version tag to -unknown
message(WARNING "Cannot determine current commit. Make sure that you are building either from a Git working tree or from a source archive.")
set(VERSIONTAG "unknown")
set(VERSION_IS_RELEASE "false")
configure_file("monero/src/version.cpp.in" "${TO}")
else()
string(SUBSTRING ${COMMIT} 0 9 COMMIT)
message(STATUS "You are currently on commit ${COMMIT}")
# Get all the tags
execute_process(COMMAND "${GIT}" rev-list --tags --max-count=1 --abbrev-commit RESULT_VARIABLE RET OUTPUT_VARIABLE TAGGEDCOMMIT OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT TAGGEDCOMMIT)
message(WARNING "Cannot determine most recent tag. Make sure that you are building either from a Git working tree or from a source archive.")
set(VERSIONTAG "${COMMIT}")
set(VERSION_IS_RELEASE "false")
else()
message(STATUS "The most recent tag was at ${TAGGEDCOMMIT}")
# Check if we're building that tagged commit or a different one
if(COMMIT STREQUAL TAGGEDCOMMIT)
message(STATUS "You are building a tagged release")
set(VERSIONTAG "release")
set(VERSION_IS_RELEASE "true")
else()
message(STATUS "You are ahead of or behind a tagged release")
set(VERSIONTAG "${COMMIT}")
set(VERSION_IS_RELEASE "false")
endif()
endif()
configure_file("monero/src/version.cpp.in" "${TO}")
endif()

64
cmake/GenVersionGui.cmake Normal file
View File

@@ -0,0 +1,64 @@
# Copyright (c) 2014-2019, The Monero Project
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification, are
# permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of
# conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
# of conditions and the following disclaimer in the documentation and/or other
# materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be
# used to endorse or promote products derived from this software without specific
# prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
# THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
# Check what commit we're on
execute_process(COMMAND "${GIT}" rev-parse --short=9 HEAD RESULT_VARIABLE RET OUTPUT_VARIABLE COMMIT OUTPUT_STRIP_TRAILING_WHITESPACE)
if(RET)
# Something went wrong, set the version tag to -unknown
message(WARNING "Cannot determine current commit. Make sure that you are building either from a Git working tree or from a source archive.")
set(VERSIONTAG "unknown")
configure_file("src/version.js.in" "${TO}")
else()
string(SUBSTRING ${COMMIT} 0 9 COMMIT)
message(STATUS "You are currently on commit ${COMMIT}")
# Get all the tags
execute_process(COMMAND "${GIT}" rev-list --tags --max-count=1 --abbrev-commit RESULT_VARIABLE RET OUTPUT_VARIABLE TAGGEDCOMMIT OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT TAGGEDCOMMIT)
message(WARNING "Cannot determine most recent tag. Make sure that you are building either from a Git working tree or from a source archive.")
set(VERSIONTAG "${COMMIT}")
else()
message(STATUS "The most recent tag was at ${TAGGEDCOMMIT}")
# Check if we're building that tagged commit or a different one
if(COMMIT STREQUAL TAGGEDCOMMIT)
message(STATUS "You are building a tagged release")
set(VERSIONTAG "release")
else()
message(STATUS "You are ahead of or behind a tagged release")
set(VERSIONTAG "${COMMIT}")
endif()
endif()
configure_file("src/version.js.in" "${TO}")
endif()

81
cmake/Version.cmake Normal file
View File

@@ -0,0 +1,81 @@
# Copyright (c) 2014-2017, The Monero Project
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification, are
# permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of
# conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
# of conditions and the following disclaimer in the documentation and/or other
# materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be
# used to endorse or promote products derived from this software without specific
# prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
# THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
function (write_static_version_header hash)
set(VERSIONTAG "${hash}")
configure_file("${CMAKE_SOURCE_DIR}/monero/src/version.cpp.in" "${CMAKE_BINARY_DIR}/version.cpp")
endfunction ()
find_package(Git QUIET)
if ("$Format:$" STREQUAL "")
# We're in a tarball; use hard-coded variables.
write_static_version_header("release")
elseif (GIT_FOUND OR Git_FOUND)
add_custom_command(
OUTPUT "${CMAKE_BINARY_DIR}/version.cpp"
COMMAND "${CMAKE_COMMAND}"
"-D" "GIT=${GIT_EXECUTABLE}"
"-D" "TO=${CMAKE_BINARY_DIR}/version.cpp"
"-P" "cmake/GenVersion.cmake"
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}")
#message(STATUS "Found Git: ${GIT_EXECUTABLE}")
# COMMAND "${CMAKE_COMMAND}"
# "-D" "GIT=${GIT_EXECUTABLE}"
# "-D" "TO=${CMAKE_BINARY_DIR}/monero/version.cpp"
# "-P" "cmake/GenVersion.cmake"
# BYPRODUCTS "${CMAKE_BINARY_DIR}/monero/version.cpp"
# WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}")
else()
message(STATUS "WARNING: Git was not found!")
write_static_version_header("unknown")
endif ()
add_custom_target(genversion ALL
DEPENDS "${CMAKE_BINARY_DIR}/version.cpp")
#find_package(Git QUIET)
#if ("$Format:$" STREQUAL "")
# # We're in a tarball; use hard-coded variables.
# write_static_version_header("release")
#elseif (GIT_FOUND OR Git_FOUND)
# message(STATUS "Found Git: ${GIT_EXECUTABLE}")
# add_custom_command(
# OUTPUT "${CMAKE_BINARY_DIR}/version.cpp"
# COMMAND "${CMAKE_COMMAND}"
# "-D" "GIT=${GIT_EXECUTABLE}"
# "-D" "TO=${CMAKE_BINARY_DIR}/version.cpp"
# "-P" "cmake/GenVersion.cmake"
# WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}")
#else()
# message(STATUS "WARNING: Git was not found!")
# write_static_version_header("unknown")
#endif ()
#add_custom_target(genversion ALL
# DEPENDS "${CMAKE_BINARY_DIR}/version.cpp")

52
cmake/VersionGui.cmake Normal file
View File

@@ -0,0 +1,52 @@
# Copyright (c) 2014-2019, The Monero Project
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification, are
# permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of
# conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
# of conditions and the following disclaimer in the documentation and/or other
# materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be
# used to endorse or promote products derived from this software without specific
# prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
# THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
function (write_static_version_header hash)
set(VERSIONTAG "${hash}")
configure_file("${CMAKE_SOURCE_DIR}/version.js.in" "${CMAKE_SOURCE_DIR}/version.js")
endfunction ()
find_package(Git QUIET)
if ("$Format:$" STREQUAL "")
# We're in a tarball; use hard-coded variables.
write_static_version_header("release")
elseif (GIT_FOUND OR Git_FOUND)
message(STATUS "Found Git: ${GIT_EXECUTABLE}")
add_custom_command(
OUTPUT "${CMAKE_SOURCE_DIR}/version.js"
COMMAND "${CMAKE_COMMAND}"
"-D" "GIT=${GIT_EXECUTABLE}"
"-D" "TO=${CMAKE_SOURCE_DIR}/version.js"
"-P" "cmake/GenVersionGui.cmake"
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}")
else()
message(STATUS "WARNING: Git was not found!")
write_static_version_header("unknown")
endif ()
add_custom_target(genversiongui ALL
DEPENDS "${CMAKE_SOURCE_DIR}/version.js")

View File

@@ -0,0 +1,52 @@
// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <libusb.h>
#define UNUSED(expr) (void)(expr)
int main(int argc, char *argv[]) {
libusb_device **devs;
libusb_context *ctx = NULL;
int r = libusb_init(&ctx); UNUSED(r);
ssize_t cnt = libusb_get_device_list(ctx, &devs); UNUSED(cnt);
struct libusb_device_descriptor desc;
r = libusb_get_device_descriptor(devs[0], &desc); UNUSED(r);
uint8_t bus_id = libusb_get_bus_number(devs[0]); UNUSED(bus_id);
uint8_t addr = libusb_get_device_address(devs[0]); UNUSED(addr);
uint8_t tmp_path[16];
r = libusb_get_port_numbers(devs[0], tmp_path, sizeof(tmp_path));
UNUSED(r);
UNUSED(tmp_path);
libusb_free_device_list(devs, 1);
libusb_exit(ctx);
}

43
cmake/test-protobuf.cpp Normal file
View File

@@ -0,0 +1,43 @@
// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string>
#include <iostream>
#include <google/protobuf/message.h>
#include <google/protobuf/unknown_field_set.h>
#include "test-protobuf.pb.h"
int main(int argc, char *argv[]) {
google::protobuf::UnknownFieldSet ufs;
ufs.ClearAndFreeMemory();
Success sc;
sc.set_message("test");
sc.SerializeToOstream(&std::cerr);
return 0;
}

View File

@@ -0,0 +1,7 @@
syntax = "proto2";
import "google/protobuf/descriptor.proto";
message Success {
optional string message = 1;
}

View File

@@ -0,0 +1,34 @@
// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assert.h>
static_assert(1, "FAIL");
int main(int argc, char *argv[]) {
return 0;
}

View File

@@ -0,0 +1,34 @@
// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assert.h>
static_assert(1, "FAIL");
int main(int argc, char *argv[]) {
return 0;
}

47
components/CMakeLists.txt Normal file
View File

@@ -0,0 +1,47 @@
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
###
#configure_file(${CMAKE_CURRENT_SOURCE_DIR}/defines.h.cmake
# ${CMAKE_CURRENT_BINARY_DIR}/defines.h)
file(GLOB_RECURSE UI_FILES *.ui)
file(GLOB_RECURSE CODE_FILES *.cpp)
qt5_wrap_ui(UI_HEADERS ${UI_FILES})
#qt5_add_resources(RESOURCE_FILES ../resources/resources.qrc)
# Windows application icon
if (WIN32)
set(WINDOWS_RES_FILE ${CMAKE_CURRENT_BINARY_DIR}/resources.obj)
if (MSVC)
add_custom_command(OUTPUT ${WINDOWS_RES_FILE}
COMMAND rc.exe /fo ${WINDOWS_RES_FILE} resources.rc
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/win
)
else()
add_custom_command(OUTPUT ${WINDOWS_RES_FILE}
COMMAND windres.exe resources.rc ${WINDOWS_RES_FILE}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/win
)
endif()
endif()
add_executable(${CMAKE_PROJECT_NAME} WIN32
${UI_HEADERS}
${CODE_FILES}
${RESOURCE_FILES}
${WINDOWS_RES_FILE}
)
target_link_libraries(${CMAKE_PROJECT_NAME}
Qt5::Widgets
)
if (UNIX)
install(TARGETS ${CMAKE_PROJECT_NAME}
RUNTIME DESTINATION bin)
elseif (WIN32)
install(TARGETS ${CMAKE_PROJECT_NAME}
DESTINATION .)
endif()

View File

@@ -1,220 +0,0 @@
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import QtQuick 2.9
import QtQuick.Controls 2.0
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.1
import QtQuick.Controls.Styles 1.4
import QtQuick.Window 2.2
import "." as MoneroComponents
import "effects/" as MoneroEffects
import "../js/Windows.js" as Windows
import "../js/Utils.js" as Utils
Window {
id: root
modality: Qt.ApplicationModal
color: "black"
flags: Windows.flags
property alias text: dialogContent.text
property alias content: root.text
property alias textArea: dialogContent
property var icon
// same signals as Dialog has
signal accepted()
signal rejected()
onClosing: {
inactiveOverlay.visible = false;
}
function open() {
inactiveOverlay.visible = true;
show();
}
// TODO: implement without hardcoding sizes
width: 480
height: 280
// background
MoneroEffects.GradientBackground {
anchors.fill: parent
fallBackColor: MoneroComponents.Style.middlePanelBackgroundColor
initialStartColor: MoneroComponents.Style.middlePanelBackgroundGradientStart
initialStopColor: MoneroComponents.Style.middlePanelBackgroundGradientStop
blackColorStart: MoneroComponents.Style._b_middlePanelBackgroundGradientStart
blackColorStop: MoneroComponents.Style._b_middlePanelBackgroundGradientStop
whiteColorStart: MoneroComponents.Style._w_middlePanelBackgroundGradientStart
whiteColorStop: MoneroComponents.Style._w_middlePanelBackgroundGradientStop
start: Qt.point(0, 0)
end: Qt.point(height, width)
}
// Make window draggable
MouseArea {
anchors.fill: parent
property point lastMousePos: Qt.point(0, 0)
onPressed: { lastMousePos = Qt.point(mouseX, mouseY); }
onMouseXChanged: root.x += (mouseX - lastMousePos.x)
onMouseYChanged: root.y += (mouseY - lastMousePos.y)
}
ColumnLayout {
id: mainLayout
anchors.fill: parent
anchors.topMargin: 20
anchors.margins: 35
spacing: 20
Item {
Layout.fillHeight: true
Layout.fillWidth: true
Rectangle {
anchors.fill: parent
color: "transparent"
border.color: MoneroComponents.Style.inputBorderColorActive
border.width: 1
radius: 4
}
Flickable {
id: flickable
anchors.fill: parent
TextArea.flickable: TextArea {
id : dialogContent
textFormat: TextEdit.RichText
selectByMouse: true
selectByKeyboard: true
font.family: MoneroComponents.Style.defaultFontColor
font.pixelSize: 14
color: MoneroComponents.Style.defaultFontColor
selectionColor: MoneroComponents.Style.textSelectionColor
wrapMode: TextEdit.Wrap
readOnly: true
function logCommand(msg){
msg = log_color(msg, MoneroComponents.Style.blackTheme ? "lime" : "#009100");
textArea.append(msg);
}
function logMessage(msg){
msg = msg.trim();
var color = MoneroComponents.Style.defaultFontColor;
if(msg.toLowerCase().indexOf('error') >= 0){
color = MoneroComponents.Style.errorColor;
} else if (msg.toLowerCase().indexOf('warning') >= 0){
color = MoneroComponents.Style.warningColor;
}
// format multi-lines
if(msg.split("\n").length >= 2){
msg = msg.split("\n").join('<br>');
}
log(msg, color);
}
function log_color(msg, color){
return "<span style='color: " + color + ";' >" + msg + "</span>";
}
function log(msg, color){
var timestamp = Utils.formatDate(new Date(), {
weekday: undefined,
month: "numeric",
timeZoneName: undefined
});
var _timestamp = log_color("[" + timestamp + "]", "#FFFFFF");
var _msg = log_color(msg, color);
textArea.append(_timestamp + " " + _msg);
// scroll to bottom
//if(flickable.contentHeight > content.height){
// flickable.contentY = flickable.contentHeight + 20;
//}
}
}
ScrollBar.vertical: ScrollBar {}
}
}
RowLayout {
Layout.fillWidth: true
MoneroComponents.LineEdit {
id: sendCommandText
Layout.fillWidth: true
placeholderText: qsTr("command + enter (e.g help)") + translationManager.emptyString
onAccepted: {
if(text.length > 0) {
textArea.logCommand(">>> " + text)
daemonManager.sendCommandAsync(text.split(" "), currentWallet.nettype, function(result) {
if (!result) {
appWindow.showStatusMessage(qsTr("Failed to send command"), 3);
}
});
}
text = ""
}
}
}
}
// window borders
Rectangle {
anchors.bottom: parent.bottom
anchors.top: parent.top
anchors.left: parent.left
width:1
color: "#2F2F2F"
z: 2
}
Rectangle {
anchors.bottom: parent.bottom
anchors.top: parent.top
anchors.right: parent.right
width:1
color: "#2F2F2F"
z: 2
}
Rectangle {
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.left: parent.left
height:1
color: "#2F2F2F"
z: 2
}
}

View File

@@ -251,6 +251,7 @@ Item {
QtQuickControls2.Popup {
id: popup
padding: 0
closePolicy: QtQuickControls2.Popup.CloseOnEscape | QtQuickControls2.Popup.CloseOnPressOutsideParent
Rectangle {
id: calendarRect

View File

@@ -125,6 +125,8 @@ Item {
source: rect
}
Keys.enabled: inlineButton.visible
Keys.onSpacePressed: doClick()
Keys.onEnterPressed: Keys.onReturnPressed(event)
Keys.onReturnPressed: doClick()
}

View File

@@ -45,18 +45,16 @@ Item {
signal accepted()
signal rejected()
function open() {
inactiveOverlay.visible = true
function open(prepopulate) {
leftPanel.enabled = false
middlePanel.enabled = false
titleBar.state = "essentials"
root.visible = true;
input.focus = true;
input.text = "";
input.text = prepopulate ? prepopulate : "";
}
function close() {
inactiveOverlay.visible = false
leftPanel.enabled = true
middlePanel.enabled = true
titleBar.state = "default"
@@ -110,6 +108,8 @@ Item {
color: MoneroComponents.Style.blackTheme ? "black" : "#A9FFFFFF"
}
Keys.enabled: root.visible
Keys.onEnterPressed: Keys.onReturnPressed(event)
Keys.onReturnPressed: {
root.close()
root.accepted()

View File

@@ -36,7 +36,6 @@ Rectangle {
id: button
property alias text: label.text
property bool checked: false
property alias dotColor: dot.color
property alias symbol: symbolText.text
property int numSelectedChildren: 0
property var under: null
@@ -63,7 +62,7 @@ Rectangle {
height: present ? ((appWindow.height >= 800) ? 44 : 38 ) : 0
LinearGradient {
visible: isOpenGL && button.checked
visible: isOpenGL && button.checked || numSelectedChildren > 0
height: parent.height
width: 260
anchors.verticalCenter: parent.verticalCenter
@@ -88,27 +87,10 @@ Rectangle {
// button decorations that are subject to leftMargin offsets
Rectangle {
anchors.left: parent.left
anchors.leftMargin: parent.getOffset() + 20
anchors.leftMargin: 20
height: parent.height
width: button.checked ? 20: 10
color: "transparent"
// dot if unchecked
Rectangle {
id: dot
anchors.centerIn: parent
width: button.checked ? 20 : 8
height: button.checked ? 20 : 8
radius: button.checked ? 20 : 4
color: button.dotColor
// arrow if checked
Image {
anchors.centerIn: parent
anchors.left: parent.left
source: MoneroComponents.Style.menuButtonImageDotArrowSource
visible: button.checked
}
}
width: 2
color: button.checked ? MoneroComponents.Style.buttonBackgroundColor : "transparent"
// button text
MoneroComponents.TextPlain {
@@ -118,7 +100,7 @@ Rectangle {
themeTransitionWhiteColor: MoneroComponents.Style._w_menuButtonTextColor
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.right
anchors.leftMargin: 8
anchors.leftMargin: button.getOffset() + 8
font.bold: true
font.pixelSize: 14
}
@@ -144,7 +126,7 @@ Rectangle {
anchors.verticalCenter: parent.verticalCenter
font.pixelSize: 12
font.bold: true
color: button.checked || buttonArea.containsMouse ? MoneroComponents.Style.menuButtonTextColor : dot.color
color: MoneroComponents.Style.menuButtonTextColor
visible: appWindow.ctrlPressed
themeTransition: false
}

View File

@@ -68,7 +68,6 @@ Item {
passwordInput1.text = ""
passwordInput2.text = ""
passwordInput1.forceActiveFocus();
inactiveOverlay.visible = true // draw appwindow inactive
root.walletName = walletName ? walletName : ""
errorTextLabel.text = errorText ? errorText : "";
leftPanel.enabled = false
@@ -106,7 +105,6 @@ Item {
}
function close() {
inactiveOverlay.visible = false
leftPanel.enabled = true
middlePanel.enabled = true
wizard.enabled = true
@@ -125,7 +123,6 @@ Item {
}
ColumnLayout {
z: inactiveOverlay.z + 1
id: mainLayout
spacing: 10
anchors { fill: parent; margins: 35 }
@@ -254,6 +251,7 @@ Item {
}
Keys.enabled: root.visible
Keys.onEnterPressed: Keys.onReturnPressed(event)
Keys.onReturnPressed: {
root.close()
if (passwordDialogMode) {
@@ -352,6 +350,8 @@ Item {
}
}
Keys.enabled: root.visible
Keys.onEnterPressed: Keys.onReturnPressed(event)
Keys.onReturnPressed: {
if (passwordInput1.text === passwordInput2.text) {
root.close()

View File

@@ -1,89 +0,0 @@
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import QtQuick 2.9
import "." as MoneroComponents
Item {
id: scrollItem
property var flickable
property alias scrollColor: scroll.color
property alias scrollWidth: scroll.width
property alias scrollRadius: scroll.radius
width: 15
z: 1
function flickableContentYChanged() {
if(flickable === undefined)
return
var t = flickable.height - scroll.height
scroll.y = (flickable.contentY / (flickable.contentHeight - flickable.height)) * t
}
MouseArea {
id: scrollArea
anchors.fill: parent
hoverEnabled: true
}
Rectangle {
id: scroll
width: 4
radius: width / 2
height: {
var t = (flickable.height * flickable.height) / flickable.contentHeight
return t < 50 ? 50 : t
}
y: 0; x: 0
color: MoneroComponents.Style.orange
opacity: flickable.moving || handleArea.pressed || scrollArea.containsMouse ? 0.8 : 0
visible: flickable.contentHeight > flickable.height
Behavior on opacity {
NumberAnimation { duration: 200; easing.type: Easing.InQuad }
}
MouseArea {
id: handleArea
anchors.fill: parent
drag.target: scroll
drag.axis: Drag.YAxis
drag.minimumY: 0
drag.maximumY: flickable.height - height
propagateComposedEvents: true
onPositionChanged: {
if(!pressed) return
var dy = scroll.y / (flickable.height - scroll.height)
flickable.contentY = (flickable.contentHeight - flickable.height) * dy
}
}
}
}

View File

@@ -146,6 +146,8 @@ Item {
cursorShape: Qt.PointingHandCursor
}
Keys.enabled: button.visible
Keys.onSpacePressed: doClick()
Keys.onEnterPressed: Keys.onReturnPressed(event)
Keys.onReturnPressed: doClick()
}

View File

@@ -124,7 +124,10 @@ Rectangle {
Flickable {
id: flickable
anchors.fill: parent
ScrollBar.vertical: ScrollBar { }
ScrollBar.vertical: ScrollBar {
onActiveChanged: if (!active && !isMac) active = true
}
boundsBehavior: isMac ? Flickable.DragAndOvershootBounds : Flickable.StopAtBounds
TextArea.flickable: TextArea {
id: dialogContent

View File

@@ -126,6 +126,7 @@ Item {
Popup {
id: popup
padding: 0
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
Rectangle {
id: droplist

1
fonts/CMakeLists.txt Normal file
View File

@@ -0,0 +1 @@
qt5_add_resources(RESOURCE_FILES *.otf)

1
images/CMakeLists.txt Normal file
View File

@@ -0,0 +1 @@
qt5_add_resources(RESOURCE_FILES *.png)

1
js/CMakeLists.txt Normal file
View File

@@ -0,0 +1 @@
qt5_add_resources(RESOURCE_FILES *.js)

View File

@@ -19,10 +19,8 @@ function setCustomWindowDecorations(custom) {
if (custom) {
appWindow.flags = flagsCustomDecorations;
daemonConsolePopup.flags = flagsCustomDecorations;
} else {
appWindow.flags = flags;
daemonConsolePopup.flags = flags;
}
// Reset window

314
main.qml
View File

@@ -31,6 +31,7 @@ import QtQuick.Window 2.0
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1
import QtQuick.Dialogs 1.2
import QtGraphicalEffects 1.0
import moneroComponents.Wallet 1.0
import moneroComponents.PendingTransaction 1.0
@@ -57,7 +58,6 @@ ApplicationWindow {
property var transaction;
property var transactionDescription;
property var walletPassword
property bool isNewWallet: false
property int restoreHeight:0
property bool daemonSynced: false
property bool walletSynced: false
@@ -201,8 +201,20 @@ ApplicationWindow {
leftPanel.selectItem(page);
}
function openWallet(prevState) {
passwordDialog.onAcceptedCallback = function() {
walletPassword = passwordDialog.password;
initialize();
}
passwordDialog.onRejectedCallback = function() {
if (prevState) {
appWindow.viewState = prevState;
}
};
passwordDialog.open(usefulName(walletPath()));
}
function initialize() {
appWindow.viewState = "normal";
console.log("initializing..")
// Use stored log level
@@ -238,30 +250,18 @@ ApplicationWindow {
simpleModeConnectionTimer.running = true;
// wallet already opened with wizard, we just need to initialize it
if (typeof wizard.m_wallet !== 'undefined') {
console.log("using wizard wallet")
//Set restoreHeight
if(persistentSettings.restore_height > 0){
// We store restore height in own variable for performance reasons.
restoreHeight = persistentSettings.restore_height
}
var wallet_path = walletPath();
if(isIOS)
wallet_path = moneroAccountsDir + wallet_path;
// console.log("opening wallet at: ", wallet_path, "with password: ", appWindow.walletPassword);
console.log("opening wallet at: ", wallet_path, ", network type: ", persistentSettings.nettype == NetworkType.MAINNET ? "mainnet" : persistentSettings.nettype == NetworkType.TESTNET ? "testnet" : "stagenet");
connectWallet(wizard.m_wallet)
isNewWallet = true
// We don't need the wizard wallet any more - delete to avoid conflict with daemon adress change
delete wizard.m_wallet
} else {
var wallet_path = walletPath();
if(isIOS)
wallet_path = moneroAccountsDir + wallet_path;
// console.log("opening wallet at: ", wallet_path, "with password: ", appWindow.walletPassword);
console.log("opening wallet at: ", wallet_path, ", network type: ", persistentSettings.nettype == NetworkType.MAINNET ? "mainnet" : persistentSettings.nettype == NetworkType.TESTNET ? "testnet" : "stagenet");
this.onWalletOpening();
walletManager.openWalletAsync(wallet_path, walletPassword,
persistentSettings.nettype, persistentSettings.kdfRounds);
}
this.onWalletOpening();
walletManager.openWalletAsync(
wallet_path,
walletPassword,
persistentSettings.nettype,
persistentSettings.kdfRounds);
// Hide titlebar based on persistentSettings.customDecorations
titleBar.visible = persistentSettings.customDecorations;
@@ -401,6 +401,13 @@ ApplicationWindow {
return path.replace(/.*[\/\\]/, '').replace(/\.keys$/, '')
}
function getUnlockedBalance() {
if(!currentWallet){
return 0
}
return currentWallet.unlockedBalance()
}
function updateBalance() {
if (!currentWallet)
return;
@@ -408,8 +415,8 @@ ApplicationWindow {
var balance = "?.??";
var balanceU = "?.??";
if(!hideBalanceForced && !persistentSettings.hideBalance){
balance = walletManager.displayAmount(currentWallet.balance(currentWallet.currentSubaddressAccount));
balanceU = walletManager.displayAmount(currentWallet.unlockedBalance(currentWallet.currentSubaddressAccount));
balance = walletManager.displayAmount(currentWallet.balance());
balanceU = walletManager.displayAmount(currentWallet.unlockedBalance());
}
if (persistentSettings.fiatPriceEnabled) {
@@ -467,7 +474,7 @@ ApplicationWindow {
// update local daemon status.
const isDisconnected = status === Wallet.ConnectionStatus_Disconnected;
if (walletManager.isDaemonLocal(currentDaemonAddress)) {
if (!persistentSettings.useRemoteNode) {
daemonRunning = !isDisconnected;
} else {
daemonRunning = false;
@@ -477,7 +484,7 @@ ApplicationWindow {
middlePanel.transferView.updatePriorityDropdown();
// If wallet isnt connected, advanced wallet mode and no daemon is running - Ask
if (appWindow.walletMode >= 2 && walletManager.isDaemonLocal(currentDaemonAddress) && !walletInitialized && isDisconnected) {
if (appWindow.walletMode >= 2 && !persistentSettings.useRemoteNode && !walletInitialized && isDisconnected) {
daemonManager.runningAsync(persistentSettings.nettype, function(running) {
if (!running) {
daemonManagerDialog.open();
@@ -517,16 +524,6 @@ ApplicationWindow {
walletName = usefulName(wallet.path)
console.log(">>> wallet opened: " + wallet)
if (wallet.status !== Wallet.Status_Ok) {
passwordDialog.onAcceptedCallback = function() {
walletPassword = passwordDialog.password;
appWindow.initialize();
}
passwordDialog.onRejectedCallback = function() {
walletPassword = "";
//appWindow.enableUI(false)
wizard.wizardState = "wizardHome";
rootItem.state = "wizard";
}
// try to resolve common wallet cache errors automatically
switch (wallet.errorString) {
case "basic_string::_M_replace_aux":
@@ -649,17 +646,6 @@ ApplicationWindow {
// Refresh is succesfull if blockchain height > 1
if (bcHeight > 1){
// Save new wallet after first refresh
// Wallet is nomrmally saved to disk on app exit. This prevents rescan from block 0 after app crash
if(isNewWallet){
console.log("Saving wallet after first refresh");
currentWallet.store()
isNewWallet = false
// Update History
currentWallet.history.refresh(currentWallet.currentSubaddressAccount);
}
// recovering from seed is finished after first refresh
if(persistentSettings.is_recovering) {
persistentSettings.is_recovering = false
@@ -858,24 +844,24 @@ ApplicationWindow {
if (amount !== "(all)") {
var amountxmr = walletManager.amountFromString(amount);
console.log("integer amount: ", amountxmr);
console.log("integer unlocked",currentWallet.unlockedBalance)
console.log("integer unlocked", currentWallet.unlockedBalance())
if (amountxmr <= 0) {
hideProcessingSplash()
informationPopup.title = qsTr("Error") + translationManager.emptyString;
informationPopup.text = qsTr("Amount is wrong: expected number from %1 to %2")
.arg(walletManager.displayAmount(0))
.arg(walletManager.maximumAllowedAmountAsSting())
.arg(walletManager.displayAmount(currentWallet.unlockedBalance()))
+ translationManager.emptyString
informationPopup.icon = StandardIcon.Critical
informationPopup.onCloseCallback = null
informationPopup.open()
return;
} else if (amountxmr > currentWallet.unlockedBalance) {
} else if (amountxmr > currentWallet.unlockedBalance()) {
hideProcessingSplash()
informationPopup.title = qsTr("Error") + translationManager.emptyString;
informationPopup.text = qsTr("Insufficient funds. Unlocked balance: %1")
.arg(walletManager.displayAmount(currentWallet.unlockedBalance))
.arg(walletManager.displayAmount(currentWallet.unlockedBalance()))
+ translationManager.emptyString
informationPopup.icon = StandardIcon.Critical
@@ -1104,7 +1090,6 @@ ApplicationWindow {
leftPanel.enabled = false;
middlePanel.enabled = false;
titleBar.enabled = false;
inactiveOverlay.visible = true;
splash.show();
}
@@ -1116,7 +1101,6 @@ ApplicationWindow {
leftPanel.enabled = true
middlePanel.enabled = true
titleBar.enabled = true
inactiveOverlay.visible = false;
}
}
@@ -1129,6 +1113,9 @@ ApplicationWindow {
rootItem.state = "wizard"
// reset balance
clearMoneroCardLabelText();
middlePanel.addressBookView.clearFields();
middlePanel.transferView.clearFields();
middlePanel.receiveView.clearFields();
// disable timers
userInActivityTimer.running = false;
simpleModeConnectionTimer.running = false;
@@ -1330,18 +1317,12 @@ ApplicationWindow {
} else console.log("qrScannerEnabled disabled");
if(!walletsFound()) {
wizard.wizardState = "wizardLanguage";
rootItem.state = "wizard"
} else {
wizard.wizardState = "wizardHome";
rootItem.state = "normal"
passwordDialog.onAcceptedCallback = function() {
walletPassword = passwordDialog.password;
initialize(persistentSettings);
}
passwordDialog.onRejectedCallback = function() {
wizard.wizardState = "wizardHome";
rootItem.state = "wizard"
}
passwordDialog.open(usefulName(walletPath()))
openWallet("wizard");
}
checkUpdates();
@@ -1364,12 +1345,9 @@ ApplicationWindow {
property string locale
property string account_name
property string wallet_path
property bool auto_donations_enabled : false
property int auto_donations_amount : 50
property bool allow_background_mining : false
property bool miningIgnoreBattery : true
property var nettype: NetworkType.MAINNET
property string payment_id
property int restore_height : 0
property bool is_trusted_daemon : false
property bool is_recovering : false
@@ -1607,96 +1585,108 @@ ApplicationWindow {
}
]
LeftPanel {
id: leftPanel
anchors.top: parent.top
anchors.left: parent.left
anchors.bottom: parent.bottom
visible: rootItem.state == "normal" && middlePanel.state != "Merchant"
currentAccountIndex: currentWallet ? currentWallet.currentSubaddressAccount : 0
currentAccountLabel: {
if (currentWallet) {
return currentWallet.getSubaddressLabel(currentWallet.currentSubaddressAccount, 0);
Item {
id: blurredArea
anchors.fill: parent
LeftPanel {
id: leftPanel
anchors.top: parent.top
anchors.left: parent.left
anchors.bottom: parent.bottom
visible: rootItem.state == "normal" && middlePanel.state != "Merchant"
currentAccountIndex: currentWallet ? currentWallet.currentSubaddressAccount : 0
currentAccountLabel: {
if (currentWallet) {
return currentWallet.getSubaddressLabel(currentWallet.currentSubaddressAccount, 0);
}
return qsTr("Primary account") + translationManager.emptyString;
}
onTransferClicked: {
middlePanel.state = "Transfer";
middlePanel.flickable.contentY = 0;
updateBalance();
}
onReceiveClicked: {
middlePanel.state = "Receive";
middlePanel.flickable.contentY = 0;
updateBalance();
}
onMerchantClicked: {
middlePanel.state = "Merchant";
middlePanel.flickable.contentY = 0;
updateBalance();
}
onTxkeyClicked: {
middlePanel.state = "TxKey";
middlePanel.flickable.contentY = 0;
updateBalance();
}
onSharedringdbClicked: {
middlePanel.state = "SharedRingDB";
middlePanel.flickable.contentY = 0;
updateBalance();
}
onHistoryClicked: {
middlePanel.state = "History";
middlePanel.flickable.contentY = 0;
updateBalance();
}
onAddressBookClicked: {
middlePanel.state = "AddressBook";
middlePanel.flickable.contentY = 0;
updateBalance();
}
onMiningClicked: {
middlePanel.state = "Mining";
middlePanel.flickable.contentY = 0;
updateBalance();
}
onSignClicked: {
middlePanel.state = "Sign";
middlePanel.flickable.contentY = 0;
updateBalance();
}
onSettingsClicked: {
middlePanel.state = "Settings";
middlePanel.flickable.contentY = 0;
updateBalance();
}
onAccountClicked: {
middlePanel.state = "Account";
middlePanel.flickable.contentY = 0;
updateBalance();
}
return qsTr("Primary account") + translationManager.emptyString;
}
onTransferClicked: {
middlePanel.state = "Transfer";
middlePanel.flickable.contentY = 0;
updateBalance();
}
onReceiveClicked: {
middlePanel.state = "Receive";
middlePanel.flickable.contentY = 0;
updateBalance();
}
onMerchantClicked: {
middlePanel.state = "Merchant";
middlePanel.flickable.contentY = 0;
updateBalance();
}
onTxkeyClicked: {
middlePanel.state = "TxKey";
middlePanel.flickable.contentY = 0;
updateBalance();
}
onSharedringdbClicked: {
middlePanel.state = "SharedRingDB";
middlePanel.flickable.contentY = 0;
updateBalance();
}
onHistoryClicked: {
middlePanel.state = "History";
middlePanel.flickable.contentY = 0;
updateBalance();
}
onAddressBookClicked: {
middlePanel.state = "AddressBook";
middlePanel.flickable.contentY = 0;
updateBalance();
}
onMiningClicked: {
middlePanel.state = "Mining";
middlePanel.flickable.contentY = 0;
updateBalance();
}
onSignClicked: {
middlePanel.state = "Sign";
middlePanel.flickable.contentY = 0;
updateBalance();
}
onSettingsClicked: {
middlePanel.state = "Settings";
middlePanel.flickable.contentY = 0;
updateBalance();
}
onAccountClicked: {
middlePanel.state = "Account";
middlePanel.flickable.contentY = 0;
updateBalance();
MiddlePanel {
id: middlePanel
accountView.currentAccountIndex: currentWallet ? currentWallet.currentSubaddressAccount : 0
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left: leftPanel.visible ? leftPanel.right : parent.left
anchors.right: parent.right
state: "Transfer"
}
}
MiddlePanel {
id: middlePanel
accountView.currentAccountIndex: currentWallet ? currentWallet.currentSubaddressAccount : 0
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left: leftPanel.visible ? leftPanel.right : parent.left
anchors.right: parent.right
state: "Transfer"
FastBlur {
id: blur
anchors.fill: blurredArea
source: blurredArea
radius: 64
visible: passwordDialog.visible || inputDialog.visible || splash.visible
}
WizardController {
@@ -1704,7 +1694,7 @@ ApplicationWindow {
anchors.fill: parent
onUseMoneroClicked: {
rootItem.state = "normal";
appWindow.initialize();
appWindow.openWallet("wizard");
}
}
@@ -2055,6 +2045,7 @@ ApplicationWindow {
if(rootItem.state !== "normal") return;
if(!persistentSettings.lockOnUserInActivity) return;
if(passwordDialog.visible) return;
var inputDialogVisible = inputDialog && inputDialog.visible
// prompt password after X seconds of inactivity
var epoch = Math.floor((new Date).getTime() / 1000);
@@ -2067,9 +2058,11 @@ ApplicationWindow {
} else {
passwordDialog.showError(qsTr("Wrong password"));
}
if (inputDialogVisible) inputDialog.open(inputDialog.inputText)
}
passwordDialog.onRejectedCallback = function() { appWindow.showWizard(); }
if (inputDialogVisible) inputDialog.close()
passwordDialog.open();
}
@@ -2103,24 +2096,13 @@ ApplicationWindow {
console.log("walletMode: " + (mode === 0 ? "simple": mode === 1 ? "simple (bootstrap)" : "Advanced"));
}
// Daemon console
DaemonConsole {
id: daemonConsolePopup
height:500
width:800
title: qsTr("Daemon log") + translationManager.emptyString
onAccepted: {
close();
}
}
Rectangle {
id: inactiveOverlay
visible: false
visible: blur.visible
anchors.fill: parent
anchors.topMargin: titleBar.height
color: MoneroComponents.Style.blackTheme ? "black" : "white"
opacity: MoneroComponents.Style.blackTheme ? 0.8 : 0.9
opacity: isOpenGL ? 0.3 : inputDialog.visible || splash.visible ? 0.7 : 1.0
MoneroEffects.ColorTransition {
targetObj: parent

View File

@@ -46,9 +46,9 @@ INCLUDEPATH += $$WALLET_ROOT/include \
$$WALLET_ROOT/src
HEADERS += \
filter.h \
clipboardAdapter.h \
oscursor.h \
src/main/filter.h \
src/main/clipboardAdapter.h \
src/main/oscursor.h \
src/libwalletqt/WalletManager.h \
src/libwalletqt/Wallet.h \
src/libwalletqt/PendingTransaction.h \
@@ -57,8 +57,8 @@ HEADERS += \
src/libwalletqt/QRCodeImageProvider.h \
src/libwalletqt/Transfer.h \
src/NetworkType.h \
oshelper.h \
TranslationManager.h \
src/main/oshelper.h \
src/TranslationManager.h \
src/model/TransactionHistoryModel.h \
src/model/TransactionHistorySortFilterModel.h \
src/QR-Code-generator/BitBuffer.hpp \
@@ -72,8 +72,8 @@ HEADERS += \
src/libwalletqt/SubaddressAccount.h \
src/zxcvbn-c/zxcvbn.h \
src/libwalletqt/UnsignedTransaction.h \
Logger.h \
MainApp.h \
src/main/Logger.h \
src/main/MainApp.h \
src/qt/FutureScheduler.h \
src/qt/ipc.h \
src/qt/KeysFiles.h \
@@ -83,18 +83,18 @@ HEADERS += \
src/qt/MoneroSettings.h \
src/qt/TailsOS.h
SOURCES += main.cpp \
filter.cpp \
clipboardAdapter.cpp \
oscursor.cpp \
SOURCES += src/main/main.cpp \
src/main/filter.cpp \
src/main/clipboardAdapter.cpp \
src/main/oscursor.cpp \
src/libwalletqt/WalletManager.cpp \
src/libwalletqt/Wallet.cpp \
src/libwalletqt/PendingTransaction.cpp \
src/libwalletqt/TransactionHistory.cpp \
src/libwalletqt/TransactionInfo.cpp \
src/libwalletqt/QRCodeImageProvider.cpp \
oshelper.cpp \
TranslationManager.cpp \
src/main/oshelper.cpp \
src/TranslationManager.cpp \
src/model/TransactionHistoryModel.cpp \
src/model/TransactionHistorySortFilterModel.cpp \
src/QR-Code-generator/BitBuffer.cpp \
@@ -108,8 +108,8 @@ SOURCES += main.cpp \
src/libwalletqt/SubaddressAccount.cpp \
src/zxcvbn-c/zxcvbn.c \
src/libwalletqt/UnsignedTransaction.cpp \
Logger.cpp \
MainApp.cpp \
src/main/Logger.cpp \
src/main/MainApp.cpp \
src/qt/FutureScheduler.cpp \
src/qt/ipc.cpp \
src/qt/KeysFiles.cpp \

View File

@@ -53,12 +53,11 @@ Rectangle {
function renameSubaddressAccountLabel(_index){
inputDialog.labelText = qsTr("Set the label of the selected account:") + translationManager.emptyString;
inputDialog.inputText = appWindow.currentWallet.getSubaddressLabel(_index, 0);
inputDialog.onAcceptedCallback = function() {
appWindow.currentWallet.subaddressAccount.setLabel(_index, inputDialog.inputText)
appWindow.currentWallet.setSubaddressLabel(_index, 0, inputDialog.inputText)
}
inputDialog.onRejectedCallback = null;
inputDialog.open()
inputDialog.open(appWindow.currentWallet.getSubaddressLabel(_index, 0))
}
Clipboard { id: clipboard }
@@ -354,7 +353,6 @@ Rectangle {
text: qsTr("Create new account") + translationManager.emptyString;
onClicked: {
inputDialog.labelText = qsTr("Set the label of the new account:") + translationManager.emptyString
inputDialog.inputText = qsTr("(Untitled)") + translationManager.emptyString
inputDialog.onAcceptedCallback = function() {
appWindow.currentWallet.subaddressAccount.addRow(inputDialog.inputText)
appWindow.currentWallet.switchSubaddressAccount(appWindow.currentWallet.numSubaddressAccounts() - 1)

1
pages/CMakeLists.txt Normal file
View File

@@ -0,0 +1 @@
qt5_add_resources(RESOURCE_FILES *.qrc)

View File

@@ -477,7 +477,6 @@ Rectangle {
return;
inputDialog.labelText = qsTr("Jump to page (1-%1)").arg(pages) + translationManager.emptyString;
inputDialog.inputText = "1";
inputDialog.onAcceptedCallback = function() {
var pageNumber = parseInt(inputDialog.inputText);
if (!isNaN(pageNumber) && pageNumber >= 1 && pageNumber <= pages) {
@@ -1195,7 +1194,7 @@ Rectangle {
if(res[i].state === 'copyable' && res[i].parent.hasOwnProperty('text')) toClipboard(res[i].parent.text);
if(res[i].state === 'copyable_address') root.toClipboard(address);
if(res[i].state === 'copyable_txkey') root.getTxKey(hash, res[i]);
if(res[i].state === 'set_tx_note') root.editDescription(hash);
if(res[i].state === 'set_tx_note') root.editDescription(hash, tx_note);
if(res[i].state === 'details') root.showTxDetails(hash, paymentId, destinations, subaddrAccount, subaddrIndex, dateTime, displayAmount, isout);
if(res[i].state === 'proof') root.showTxProof(hash, paymentId, destinations, subaddrAccount, subaddrIndex);
doCollapse = false;
@@ -1315,7 +1314,7 @@ Rectangle {
}
MoneroComponents.StandardButton {
visible: !isIOS && root.txCount > 0
visible: !isIOS
small: true
text: qsTr("Export all history") + translationManager.emptyString
onClicked: {
@@ -1533,7 +1532,7 @@ Rectangle {
root.updateFilter();
}
function editDescription(_hash){
function editDescription(_hash, _tx_note){
inputDialog.labelText = qsTr("Set description:") + translationManager.emptyString;
inputDialog.onAcceptedCallback = function() {
appWindow.currentWallet.setUserNote(_hash, inputDialog.inputText);
@@ -1541,7 +1540,7 @@ Rectangle {
root.update();
}
inputDialog.onRejectedCallback = null;
inputDialog.open();
inputDialog.open(_tx_note);
}
function paginationPrevClicked(){
@@ -1599,7 +1598,7 @@ Rectangle {
currentWallet.getTxKeyAsync(hash, function(hash, tx_key) {
informationPopup.title = qsTr("Transaction details") + translationManager.emptyString;
informationPopup.content = buildTxDetailsString(hash, paymentId, tx_key, tx_note, destinations, rings, address, address_label, integratedAddress, dateTime, amount);
informationPopup.content = buildTxDetailsString(hash, hasPaymentId ? paymentId : null, tx_key, tx_note, destinations, rings, address, address_label, integratedAddress, dateTime, amount);
informationPopup.onCloseCallback = null
informationPopup.open();
});

View File

@@ -57,13 +57,13 @@ Rectangle {
MoneroComponents.WarningBox {
Layout.bottomMargin: 8
text: qsTr("Mining is only available on local daemons.") + translationManager.emptyString
visible: !walletManager.isDaemonLocal(appWindow.currentDaemonAddress)
visible: persistentSettings.useRemoteNode
}
MoneroComponents.WarningBox {
Layout.bottomMargin: 8
text: qsTr("Your daemon must be synchronized before you can start mining") + translationManager.emptyString
visible: walletManager.isDaemonLocal(appWindow.currentDaemonAddress) && !appWindow.daemonSynced
visible: !persistentSettings.useRemoteNode && !appWindow.daemonSynced
}
MoneroComponents.TextPlain {
@@ -199,7 +199,7 @@ Rectangle {
} else {
errorPopup.title = qsTr("Error starting mining") + translationManager.emptyString;
errorPopup.text = qsTr("Couldn't start mining.<br>") + translationManager.emptyString
if (!walletManager.isDaemonLocal(appWindow.currentDaemonAddress))
if (persistentSettings.useRemoteNode)
errorPopup.text += qsTr("Mining is only available on local daemons. Run a local daemon to be able to mine.<br>") + translationManager.emptyString
errorPopup.icon = StandardIcon.Critical
errorPopup.open()
@@ -259,7 +259,7 @@ Rectangle {
}
function onMiningStatus(isMining) {
var daemonReady = walletManager.isDaemonLocal(appWindow.currentDaemonAddress) && appWindow.daemonSynced
var daemonReady = !persistentSettings.useRemoteNode && appWindow.daemonSynced
appWindow.isMining = isMining;
updateStatusText()
startSoloMinerButton.enabled = !appWindow.isMining && daemonReady
@@ -284,7 +284,7 @@ Rectangle {
function onPageCompleted() {
console.log("Mining page loaded");
update()
timer.running = walletManager.isDaemonLocal(appWindow.currentDaemonAddress)
timer.running = !persistentSettings.useRemoteNode
}
function onPageClosed() {

View File

@@ -53,12 +53,11 @@ Rectangle {
function renameSubaddressLabel(_index){
inputDialog.labelText = qsTr("Set the label of the selected address:") + translationManager.emptyString;
inputDialog.inputText = appWindow.currentWallet.getSubaddressLabel(appWindow.currentWallet.currentSubaddressAccount, _index);
inputDialog.onAcceptedCallback = function() {
appWindow.currentWallet.subaddress.setLabel(appWindow.currentWallet.currentSubaddressAccount, _index, inputDialog.inputText);
}
inputDialog.onRejectedCallback = null;
inputDialog.open()
inputDialog.open(appWindow.currentWallet.getSubaddressLabel(appWindow.currentWallet.currentSubaddressAccount, _index))
}
Clipboard { id: clipboard }
@@ -74,10 +73,6 @@ Rectangle {
anchors.right: parent.right
spacing: 20
property int labelWidth: 120
property int editWidth: 400
property int lineEditFontSize: 12
property int qrCodeSize: 220
ColumnLayout {
id: addressRow
@@ -254,7 +249,6 @@ Rectangle {
text: qsTr("Create new address") + translationManager.emptyString;
onClicked: {
inputDialog.labelText = qsTr("Set the label of the new address:") + translationManager.emptyString
inputDialog.inputText = qsTr("(Untitled)") + translationManager.emptyString
inputDialog.onAcceptedCallback = function() {
appWindow.currentWallet.subaddress.addRow(appWindow.currentWallet.currentSubaddressAccount, inputDialog.inputText)
current_subaddress_table_index = appWindow.currentWallet.numSubaddresses(appWindow.currentWallet.currentSubaddressAccount) - 1

View File

@@ -53,9 +53,6 @@ Rectangle {
property string warningContent: ""
property string sendButtonWarning: ""
property string startLinkText: qsTr("<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style><font size='2'> (</font><a href='#'>Start daemon</a><font size='2'>)</font>") + translationManager.emptyString
property bool showAdvanced: false
// @TODO: remove after pid removal hardfork
property bool warningLongPidTransfer: false
property bool warningLongPidDescription: descriptionLine.text.match(/^[0-9a-f]{64}$/i)
Clipboard { id: clipboard }
@@ -87,17 +84,6 @@ Rectangle {
paymentIdCheckbox.checked = paymentIdLine.text != "";
}
function isLongPidService(text) {
// @TODO: remove after pid removal hardfork
return text.length == 95 &&
[ "44tLjmXrQNrWJ5NBsEj2R77ZBEgDa3fEe9GLpSf2FRmhexPvfYDUAB7EXX1Hdb3aMQ9FLqdJ56yaAhiXoRsceGJCRS3Jxkn", // Binance
"4AQ3ZREb53FMYKBmpPn7BD7hphPk6G1ceinQX6gefAvhFJsNbeFsGwebZWCNxoJAbZhD9cjetBAqmLhfXmcNLBpPMsBL6yM", // KuCoin
"47YzEcMrU2S42UitURo7ukUDaSaL485Z1QbmFgq1vSs5g3JesL4rChwWf2uWk1va99JAaRxt65jhX9uAqQnjeFM44ckgZtp", // AnycoinDirect
"4BCeEPhodgPMbPWFN1dPwhWXdRX8q4mhhdZdA1dtSMLTLCEYvAj9QXjXAfF7CugEbmfBhgkqHbdgK9b2wKA6nqRZQCgvCDm", // Bitfinex
"463tWEBn5XZJSxLU6uLQnQ2iY9xuNcDbjLSjkn3XAXHCbLrTTErJrBWYgHJQyrCwkNgYvyV3z8zctJLPCZy24jvb3NiTcTJ" // Bittrex
].indexOf(text) > -1
}
function clearFields() {
addressLine.text = ""
setPaymentId("");
@@ -193,6 +179,7 @@ Rectangle {
amountLine.cursorPosition = 1;
}
}
amountLine.error = walletManager.amountFromString(amountLine.text) > appWindow.getUnlockedBalance()
}
validator: RegExpValidator {
@@ -277,7 +264,6 @@ Rectangle {
amountLine.text = parsed.amount;
setDescription(parsed.tx_description);
}
warningLongPidTransfer = isLongPidService(text);
}
inlineButton.text: FontAwesome.qrcode
inlineButton.fontPixelSize: 22
@@ -375,7 +361,6 @@ Rectangle {
ColumnLayout {
visible: paymentIdCheckbox.checked
// @TODO: remove after pid removal hardfork
CheckBox {
id: paymentIdCheckbox
border: false
@@ -403,17 +388,17 @@ Rectangle {
wrapMode: Text.WrapAnywhere
addressValidation: false
visible: paymentIdCheckbox.checked
error: paymentIdCheckbox.checked
}
}
}
MoneroComponents.WarningBox {
// @TODO: remove after pid removal hardfork
id: paymentIdWarningBox
text: qsTr("Long payment IDs are obsolete. \
Long payment IDs were not encrypted on the blockchain and would harm your privacy. \
If the party you're sending to still requires a long payment ID, please notify them.") + translationManager.emptyString;
visible: warningLongPidTransfer || paymentIdCheckbox.checked
visible: paymentIdCheckbox.checked || warningLongPidDescription
}
MoneroComponents.WarningBox {
@@ -444,22 +429,8 @@ Rectangle {
}
}
function checkInformation(amount, address, payment_id, nettype) {
address = address.trim()
payment_id = payment_id.trim()
var amount_ok = amount.length > 0
var address_ok = walletManager.addressValid(address, nettype)
var payment_id_ok = payment_id.length == 0 || (payment_id.length == 64 && walletManager.paymentIdValid(payment_id))
var ipid = walletManager.paymentIdFromAddress(address, nettype)
if (ipid.length > 0 && payment_id.length > 0)
payment_id_ok = false
addressLine.error = !address_ok
amountLine.error = !amount_ok
paymentIdLine.error = !payment_id_ok
return amount_ok && address_ok && payment_id_ok
function checkInformation(amount, address, nettype) {
return amount.length > 0 && walletManager.amountFromString(amountLine.text) <= appWindow.getUnlockedBalance() && TxUtils.checkAddress(address, nettype)
}
} // pageRoot
@@ -505,7 +476,7 @@ Rectangle {
id: saveTxButton
text: qsTr("Create tx file") + translationManager.emptyString
visible: appWindow.viewOnly
enabled: pageRoot.checkInformation(amountLine.text, addressLine.text, paymentIdLine.text, appWindow.persistentSettings.nettype)
enabled: pageRoot.checkInformation(amountLine.text, addressLine.text, appWindow.persistentSettings.nettype)
small: true
onClicked: {
console.log("Transfer: saveTx Clicked")
@@ -558,7 +529,7 @@ Rectangle {
id: importKeyImagesButton
text: qsTr("Import key images") + translationManager.emptyString
small: true
visible: appWindow.viewOnly && walletManager.isDaemonLocal(appWindow.currentDaemonAddress)
visible: appWindow.viewOnly && !persistentSettings.useRemoteNode
enabled: pageRoot.enabled
onClicked: {
console.log("Transfer: import key images clicked")
@@ -710,7 +681,7 @@ Rectangle {
function updateStatus() {
var messageNotConnected = qsTr("Wallet is not connected to daemon.");
if(appWindow.walletMode >= 2) messageNotConnected += root.startLinkText;
if(appWindow.walletMode >= 2 && !persistentSettings.useRemoteNode) messageNotConnected += root.startLinkText;
pageRoot.enabled = true;
if(typeof currentWallet === "undefined") {
root.warningContent = messageNotConnected;
@@ -772,7 +743,7 @@ Rectangle {
}
// There are sufficient unlocked funds available
if(parseFloat(amountLine.text) > parseFloat(middlePanel.unlockedBalanceText)){
if(walletManager.amountFromString(amountLine.text) > appWindow.getUnlockedBalance()){
root.sendButtonWarning = qsTr("Amount is more than unlocked balance.") + translationManager.emptyString;
return false;
}
@@ -782,10 +753,19 @@ Rectangle {
return false;
}
// The transactional information is correct
if(!pageRoot.checkInformation(amountLine.text, addressLine.text, paymentIdLine.text, appWindow.persistentSettings.nettype)){
if(amountLine.text && addressLine.text)
root.sendButtonWarning = qsTr("Transaction information is incorrect.") + translationManager.emptyString;
if (addressLine.text == "") {
return false;
}
// Address is valid
if(!TxUtils.checkAddress(addressLine.text, appWindow.persistentSettings.nettype)){
root.sendButtonWarning = qsTr("Address is invalid.") + translationManager.emptyString;
return false;
}
// Amount is nonzero
if (!amountLine.text || parseFloat(amountLine.text) <= 0) {
root.sendButtonWarning = qsTr("Enter an amount.") + translationManager.emptyString;
return false;
}

View File

@@ -83,18 +83,23 @@ ColumnLayout {
State {
name: "Wallet"
PropertyChanges { target: settingsStateView; currentView: settingsStateView.settingsWalletView }
PropertyChanges { target: settingsPage; settingsHeight: settingsStateView.settingsWalletView.settingsHeight + 140 }
}, State {
name: "UI"
PropertyChanges { target: settingsStateView; currentView: settingsStateView.settingsLayoutView }
PropertyChanges { target: settingsPage; settingsHeight: settingsStateView.settingsLayoutView.layoutHeight + 140 }
}, State {
name: "Node"
PropertyChanges { target: settingsStateView; currentView: settingsStateView.settingsNodeView }
PropertyChanges { target: settingsPage; settingsHeight: settingsStateView.settingsNodeView.nodeHeight + 140 }
}, State {
name: "Log"
PropertyChanges { target: settingsStateView; currentView: settingsStateView.settingsLogView }
PropertyChanges { target: settingsPage; settingsHeight: settingsStateView.settingsLogView.logHeight + 140 }
}, State {
name: "Info"
PropertyChanges { target: settingsStateView; currentView: settingsStateView.settingsInfoView }
PropertyChanges { target: settingsPage; settingsHeight: settingsStateView.settingsInfoView.infoHeight + 140 }
}
]

View File

@@ -39,8 +39,8 @@ import "../../components" as MoneroComponents
Rectangle {
color: "transparent"
height: 1400
Layout.fillWidth: true
property alias infoHeight: infoLayout.height
property string walletModeString: {
if(appWindow.walletMode === 0){
return qsTr("Simple mode") + translationManager.emptyString;
@@ -132,14 +132,21 @@ Rectangle {
MoneroComponents.TextBlock {
Layout.fillWidth: true
Layout.maximumWidth: 360
color: MoneroComponents.Style.dimmedFontColor
font.pixelSize: 14
text: {
var wallet_path = walletPath();
if(isIOS)
wallet_path = moneroAccountsDir + wallet_path;
return wallet_path;
property string walletPath: (isIOS ? moneroAccountsDir : "") + appWindow.walletPath()
text: "\
<style type='text/css'>\
a {cursor:pointer;text-decoration: none; color: #FF6C3C}\
</style>\
<a href='#'>%1</a>".arg(walletPath)
textFormat: Text.RichText
onLinkActivated: oshelper.openContainingFolder(walletPath)
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.NoButton
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
}
}
@@ -178,7 +185,6 @@ Rectangle {
text: (currentWallet ? currentWallet.walletCreationHeight : "") + style + qsTr(" <a href='#'> (Click to change)</a>") + translationManager.emptyString
onLinkActivated: {
inputDialog.labelText = qsTr("Set a new restore height.\nYou can enter a block height or a date (YYYY-MM-DD):") + translationManager.emptyString;
inputDialog.inputText = currentWallet ? currentWallet.walletCreationHeight : "0";
inputDialog.onAcceptedCallback = function() {
var _restoreHeight;
if (inputDialog.inputText) {
@@ -224,7 +230,7 @@ Rectangle {
appWindow.showStatusMessage(qsTr("Invalid restore height specified. Must be a number or a date formatted YYYY-MM-DD"),3);
}
inputDialog.onRejectedCallback = null;
inputDialog.open()
inputDialog.open(currentWallet ? currentWallet.walletCreationHeight : "0")
}
MouseArea {
@@ -262,7 +268,19 @@ Rectangle {
Layout.fillWidth: true
color: MoneroComponents.Style.dimmedFontColor
font.pixelSize: 14
text: walletLogPath
text: "\
<style type='text/css'>\
a {cursor:pointer;text-decoration: none; color: #FF6C3C}\
</style>\
<a href='#'>%1</a>".arg(walletLogPath)
textFormat: Text.RichText
onLinkActivated: oshelper.openContainingFolder(walletLogPath)
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.NoButton
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
}
}
Rectangle {

View File

@@ -37,8 +37,8 @@ import "../../components" as MoneroComponents
Rectangle {
color: "transparent"
height: 1400
Layout.fillWidth: true
property alias layoutHeight: settingsUI.height
ColumnLayout {
id: settingsUI

View File

@@ -37,8 +37,8 @@ import "../../components" as MoneroComponents
Rectangle {
property alias consoleArea: consoleArea
color: "transparent"
height: 1400
Layout.fillWidth: true
property alias logHeight: settingsLog.height
ColumnLayout {
id: settingsLog
@@ -150,6 +150,7 @@ Rectangle {
Flickable {
id: flickable
anchors.fill: parent
boundsBehavior: isMac ? Flickable.DragAndOvershootBounds : Flickable.StopAtBounds
TextArea.flickable: TextArea {
id : consoleArea
@@ -203,7 +204,9 @@ Rectangle {
}
}
ScrollBar.vertical: ScrollBar {}
ScrollBar.vertical: ScrollBar {
onActiveChanged: if (!active && !isMac) active = true
}
}
}

View File

@@ -36,8 +36,8 @@ import "../../components/effects" as MoneroEffects
Rectangle{
color: "transparent"
height: 1400
Layout.fillWidth: true
property alias nodeHeight: root.height
/* main layout */
ColumnLayout {
@@ -50,10 +50,6 @@ Rectangle{
anchors.right: parent.right
spacing: 0
property int labelWidth: 120
property int editWidth: 400
property int lineEditFontSize: 14
property int buttonWidth: 110
Rectangle {
Layout.fillWidth: true

View File

@@ -36,8 +36,8 @@ import "../../components" as MoneroComponents
Rectangle {
color: "transparent"
height: 1400
Layout.fillWidth: true
property alias settingsHeight: settingsWallet.height
ColumnLayout {
id: settingsWallet
@@ -54,12 +54,7 @@ Rectangle {
description: qsTr("Logs out of this wallet.") + translationManager.emptyString
title: qsTr("Close this wallet") + translationManager.emptyString
onClicked: {
middlePanel.addressBookView.clearFields();
middlePanel.transferView.clearFields();
middlePanel.receiveView.clearFields();
appWindow.showWizard();
}
onClicked: appWindow.showWizard()
}
MoneroComponents.SettingsListItem {

View File

@@ -26,7 +26,6 @@
<file>components/LineEdit.qml</file>
<file>components/TipItem.qml</file>
<file>images/tip.png</file>
<file>components/Scroll.qml</file>
<file>components/MenuButtonDivider.qml</file>
<file>images/moneroIcon.png</file>
<file>components/StandardDropdown.qml</file>
@@ -103,7 +102,6 @@
<file>pages/Sign.qml</file>
<file>components/DaemonManagerDialog.qml</file>
<file>version.js</file>
<file>components/DaemonConsole.qml</file>
<file>components/QRCodeScanner.qml</file>
<file>components/Notifier.qml</file>
<file>components/TextBlock.qml</file>

164
src/CMakeLists.txt Normal file
View File

@@ -0,0 +1,164 @@
add_subdirectory(QR-Code-generator)
add_subdirectory(QR-Code-scanner)
add_subdirectory(daemon)
add_subdirectory(libwalletqt)
add_subdirectory(model)
add_subdirectory(zxcvbn-c)
qt5_add_resources(RESOURCES ../qml.qrc)
# Compile source files (.h/.cpp)
file(GLOB SOURCE_FILES
"*.h"
"*.cpp"
"main/*.h"
"main/*.cpp"
"libwalletqt/WalletManager.cpp"
"libwalletqt/Wallet.cpp"
"libwalletqt/PendingTransaction.cpp"
"libwalletqt/TransactionHistory.cpp"
"libwalletqt/TransactionInfo.cpp"
"libwalletqt/QRCodeImageProvider.cpp" QR
"QR-Code-generator/BitBuffer.cpp"
"QR-Code-generator/QrCode.cpp"
"QR-Code-generator/QrSegment.cpp"
"libwalletqt/AddressBook.cpp"
"libwalletqt/Subaddress.cpp"
"libwalletqt/SubaddressAccount.cpp"
"libwalletqt/UnsignedTransaction.cpp"
"libwalletqt/WalletManager.h"
"libwalletqt/Wallet.h"
"libwalletqt/PendingTransaction.h"
"libwalletqt/TransactionHistory.h"
"libwalletqt/TransactionInfo.h"
"libwalletqt/QRCodeImageProvider.h"
"QR-Code-generator/BitBuffer.h"
"QR-Code-generator/QrCode.h"
"QR-Code-generator/QrSegment.h"
"libwalletqt/Transfer.h"
"libwalletqt/AddressBook.h"
"libwalletqt/Subaddress.h"
"libwalletqt/SubaddressAccount.h"
"libwalletqt/UnsignedTransaction.h"
"daemon/*.h"
"daemon/*.cpp"
"model/*.h"
"model/*.cpp"
"qt/*.h"
"qt/*.cpp"
)
if(ENABLE_PASS_STRENGTH_METER)
file(GLOB PASS_STRENGTH_FILES
"zxcvbn-c/zxcvbn.h"
"zxcvbn-c/zxcvbn.c"
)
endif()
if(WITH_SCANNER)
file(GLOB QR_CODE_FILES
"QR-Code-generator/*.h"
"QR-Code-generator/*.cpp"
"QR-Code-scanner/*.h"
"QR-Code-scanner/*.cpp"
)
endif()
set(EXECUTABLE_FLAG)
if(MINGW)
set(EXECUTABLE_FLAG WIN32)
set(ICON ${PROJECT_SOURCE_DIR}/images/appicon.ico)
set(ICON_RC ${CMAKE_CURRENT_BINARY_DIR}/icon.rc)
set(ICON_RES ${CMAKE_CURRENT_BINARY_DIR}/icon.o)
file(WRITE ${ICON_RC} "IDI_ICON1 ICON DISCARDABLE \"${ICON}\"")
add_custom_command(OUTPUT ${ICON_RES} COMMAND windres ${ICON_RC} ${ICON_RES} MAIN_DEPENDENCY ${ICON_RC})
list(APPEND RESOURCES ${ICON_RES})
endif()
add_executable(monero-gui ${EXECUTABLE_FLAG} main/main.cpp
${SOURCE_FILES}
${PASS_STRENGTH_FILES}
${QR_CODE_FILES}
${RESOURCES}
)
set_property(TARGET monero-gui PROPERTY RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
# OpenGL
target_include_directories(monero-gui PUBLIC ${OPENGL_INCLUDE_DIR})
message(STATUS "OpenGL: include dir at ${OPENGL_INCLUDE_DIR}")
message(STATUS "OpenGL: libraries at ${OPENGL_LIBRARIES}")
target_include_directories(monero-gui PUBLIC ${Qt5Gui_PRIVATE_INCLUDE_DIRS})
file(GLOB_RECURSE SRC_SOURCES *.cpp)
file(GLOB_RECURSE SRC_HEADERS *.h)
target_include_directories(monero-gui PUBLIC
${CMAKE_SOURCE_DIR}/monero/include
${CMAKE_SOURCE_DIR}/monero/src
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/daemon
${CMAKE_CURRENT_SOURCE_DIR}/libwalletqt
${CMAKE_CURRENT_SOURCE_DIR}/model
${CMAKE_CURRENT_SOURCE_DIR}/QR-Code-generator
${CMAKE_CURRENT_SOURCE_DIR}/QR-Code-scanner
${CMAKE_CURRENT_SOURCE_DIR}/zxcvbn-c
${LibUSB_INCLUDE_DIRS}
${HIDAPI_INCLUDE_DIRS}
${X11_INCLUDE_DIR}
${Boost_INCLUDE_DIRS}
${OPENSSL_INCLUDE_DIR}
${ZBAR_INCLUDE_DIR}
)
target_compile_definitions(monero-gui
PUBLIC
${Qt5Widgets_DEFINITIONS}
${Qt5Qml_DEFINITIONS}
)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
if(X11_FOUND)
target_link_libraries(monero-gui ${X11_LIBRARIES} pthread dl Xt xcb X11)
endif()
if(DEVICE_TREZOR_READY)
target_link_libraries(monero-gui ${TREZOR_DEP_LIBS})
endif()
target_link_libraries(monero-gui
${CMAKE_BINARY_DIR}/lib/libwallet_merged.a
${LMDB_LIBRARY}
${CMAKE_BINARY_DIR}/monero/contrib/epee/src/libepee.a
${CMAKE_BINARY_DIR}/monero/external/unbound/libunbound.a
${SODIUM_LIBRARY}
${CMAKE_BINARY_DIR}/monero/external/easylogging++/libeasylogging.a
${CMAKE_BINARY_DIR}/monero/src/blockchain_db/libblockchain_db.a
${CMAKE_BINARY_DIR}/monero/external/randomx/librandomx.a
${CMAKE_BINARY_DIR}/monero/src/hardforks/libhardforks.a
${Boost_LIBRARIES}
${OPENSSL_LIBRARIES}
${CMAKE_DL_LIBS}
${LibUSB_LIBRARIES}
${HIDAPI_LIBRARIES}
${QT5_LIBRARIES}
${EXTRA_LIBRARIES}
${ICU_LIBRARIES}
)
if(WITH_SCANNER)
target_link_libraries(monero-gui
${ZBAR_LIBRARIES}
jpeg
v4l2
v4lconvert
rt
)
endif()
install(TARGETS monero-gui
DESTINATION ${CMAKE_INSTALL_PREFIX}
)

View File

@@ -0,0 +1,4 @@
file(GLOB_RECURSE SRC_SOURCES *.cpp)
file(GLOB_RECURSE SRC_HEADERS *.h)

View File

@@ -0,0 +1,4 @@
file(GLOB_RECURSE SRC_SOURCES *.cpp)
file(GLOB_RECURSE SRC_HEADERS *.h)

View File

@@ -0,0 +1,4 @@
file(GLOB_RECURSE SRC_SOURCES *.cpp)
file(GLOB_RECURSE SRC_HEADERS *.h)

View File

@@ -0,0 +1,4 @@
file(GLOB_RECURSE SRC_SOURCES *.cpp)
file(GLOB_RECURSE SRC_HEADERS *.h)

View File

@@ -36,49 +36,58 @@ Subaddress::Subaddress(Monero::Subaddress *subaddressImpl, QObject *parent)
getAll();
}
QList<Monero::SubaddressRow*> Subaddress::getAll(bool update) const
void Subaddress::getAll() const
{
qDebug(__FUNCTION__);
emit refreshStarted();
if(update)
m_rows.clear();
{
QWriteLocker locker(&m_lock);
if (m_rows.empty()){
m_rows.clear();
for (auto &row: m_subaddressImpl->getAll()) {
m_rows.append(row);
}
}
emit refreshFinished();
return m_rows;
}
Monero::SubaddressRow * Subaddress::getRow(int index) const
bool Subaddress::getRow(int index, std::function<void (Monero::SubaddressRow &row)> callback) const
{
return m_rows.at(index);
QReadLocker locker(&m_lock);
if (index < 0 || index >= m_rows.size())
{
return false;
}
callback(*m_rows.value(index));
return true;
}
void Subaddress::addRow(quint32 accountIndex, const QString &label) const
{
m_subaddressImpl->addRow(accountIndex, label.toStdString());
getAll(true);
getAll();
}
void Subaddress::setLabel(quint32 accountIndex, quint32 addressIndex, const QString &label) const
{
m_subaddressImpl->setLabel(accountIndex, addressIndex, label.toStdString());
getAll(true);
getAll();
}
void Subaddress::refresh(quint32 accountIndex) const
{
m_subaddressImpl->refresh(accountIndex);
getAll(true);
getAll();
}
quint64 Subaddress::count() const
{
QReadLocker locker(&m_lock);
return m_rows.size();
}

View File

@@ -29,7 +29,10 @@
#ifndef SUBADDRESS_H
#define SUBADDRESS_H
#include <functional>
#include <wallet/api/wallet2_api.h>
#include <QReadWriteLock>
#include <QObject>
#include <QList>
#include <QDateTime>
@@ -38,8 +41,8 @@ class Subaddress : public QObject
{
Q_OBJECT
public:
Q_INVOKABLE QList<Monero::SubaddressRow*> getAll(bool update = false) const;
Q_INVOKABLE Monero::SubaddressRow * getRow(int index) const;
Q_INVOKABLE void getAll() const;
Q_INVOKABLE bool getRow(int index, std::function<void (Monero::SubaddressRow &row)> callback) const;
Q_INVOKABLE void addRow(quint32 accountIndex, const QString &label) const;
Q_INVOKABLE void setLabel(quint32 accountIndex, quint32 addressIndex, const QString &label) const;
Q_INVOKABLE void refresh(quint32 accountIndex) const;
@@ -54,6 +57,7 @@ public slots:
private:
explicit Subaddress(Monero::Subaddress * subaddressImpl, QObject *parent);
friend class Wallet;
mutable QReadWriteLock m_lock;
Monero::Subaddress * m_subaddressImpl;
mutable QList<Monero::SubaddressRow*> m_rows;
};

View File

@@ -36,49 +36,57 @@ SubaddressAccount::SubaddressAccount(Monero::SubaddressAccount *subaddressAccoun
getAll();
}
QList<Monero::SubaddressAccountRow*> SubaddressAccount::getAll(bool update) const
void SubaddressAccount::getAll() const
{
qDebug(__FUNCTION__);
emit refreshStarted();
if(update)
{
QWriteLocker locker(&m_lock);
m_rows.clear();
if (m_rows.empty()){
for (auto &row: m_subaddressAccountImpl->getAll()) {
m_rows.append(row);
}
}
emit refreshFinished();
return m_rows;
}
Monero::SubaddressAccountRow * SubaddressAccount::getRow(int index) const
bool SubaddressAccount::getRow(int index, std::function<void (Monero::SubaddressAccountRow &)> callback) const
{
return m_rows.at(index);
QReadLocker locker(&m_lock);
if (index < 0 || index >= m_rows.size())
{
return false;
}
callback(*m_rows.value(index));
return true;
}
void SubaddressAccount::addRow(const QString &label) const
{
m_subaddressAccountImpl->addRow(label.toStdString());
getAll(true);
getAll();
}
void SubaddressAccount::setLabel(quint32 accountIndex, const QString &label) const
{
m_subaddressAccountImpl->setLabel(accountIndex, label.toStdString());
getAll(true);
getAll();
}
void SubaddressAccount::refresh() const
{
m_subaddressAccountImpl->refresh();
getAll(true);
getAll();
}
quint64 SubaddressAccount::count() const
{
QReadLocker locker(&m_lock);
return m_rows.size();
}

View File

@@ -29,8 +29,11 @@
#ifndef SUBADDRESSACCOUNT_H
#define SUBADDRESSACCOUNT_H
#include <functional>
#include <wallet/api/wallet2_api.h>
#include <QObject>
#include <QReadWriteLock>
#include <QList>
#include <QDateTime>
@@ -38,8 +41,8 @@ class SubaddressAccount : public QObject
{
Q_OBJECT
public:
Q_INVOKABLE QList<Monero::SubaddressAccountRow*> getAll(bool update = false) const;
Q_INVOKABLE Monero::SubaddressAccountRow * getRow(int index) const;
Q_INVOKABLE void getAll() const;
Q_INVOKABLE bool getRow(int index, std::function<void (Monero::SubaddressAccountRow &)> callback) const;
Q_INVOKABLE void addRow(const QString &label) const;
Q_INVOKABLE void setLabel(quint32 accountIndex, const QString &label) const;
Q_INVOKABLE void refresh() const;
@@ -54,6 +57,7 @@ public slots:
private:
explicit SubaddressAccount(Monero::SubaddressAccount * subaddressAccountImpl, QObject *parent);
friend class Wallet;
mutable QReadWriteLock m_lock;
Monero::SubaddressAccount * m_subaddressAccountImpl;
mutable QList<Monero::SubaddressAccountRow*> m_rows;
};

View File

@@ -36,16 +36,18 @@
#include <QWriteLocker>
TransactionInfo *TransactionHistory::transaction(int index)
bool TransactionHistory::transaction(int index, std::function<void (TransactionInfo &)> callback)
{
QReadLocker locker(&m_tinfoLock);
QReadLocker locker(&m_lock);
if (index < 0 || index >= m_tinfo.size()) {
qCritical("%s: no transaction info for index %d", __FUNCTION__, index);
qCritical("%s: there's %d transactions in backend", __FUNCTION__, m_pimpl->count());
return nullptr;
return false;
}
return m_tinfo.at(index);
callback(*m_tinfo.value(index));
return true;
}
//// XXX: not sure if this method really needed;
@@ -54,7 +56,7 @@ TransactionInfo *TransactionHistory::transaction(int index)
// return nullptr;
//}
QList<TransactionInfo *> TransactionHistory::getAll(quint32 accountIndex) const
void TransactionHistory::refresh(quint32 accountIndex)
{
QDateTime firstDateTime = QDateTime(QDate(2014, 4, 18)); // the genesis block
QDateTime lastDateTime = QDateTime::currentDateTime().addDays(1); // tomorrow (guard against jitter and timezones)
@@ -62,23 +64,24 @@ QList<TransactionInfo *> TransactionHistory::getAll(quint32 accountIndex) const
emit refreshStarted();
{
QWriteLocker locker(&m_tinfoLock);
QWriteLocker locker(&m_lock);
// XXX this invalidates previously saved history that might be used by model
qDeleteAll(m_tinfo);
m_tinfo.clear();
quint64 lastTxHeight = 0;
m_locked = false;
m_minutesToUnlock = 0;
TransactionHistory * parent = const_cast<TransactionHistory*>(this);
m_pimpl->refresh();
for (const auto i : m_pimpl->getAll()) {
TransactionInfo * ti = new TransactionInfo(i, parent);
if (ti->subaddrAccount() != accountIndex) {
delete ti;
if (i->subaddrAccount() != accountIndex) {
continue;
}
m_tinfo.append(ti);
m_tinfo.append(new TransactionInfo(i, this));
const TransactionInfo *ti = m_tinfo.back();
// looking for transactions timestamp scope
if (ti->timestamp() >= lastDateTime) {
lastDateTime = ti->timestamp();
@@ -94,7 +97,6 @@ QList<TransactionInfo *> TransactionHistory::getAll(quint32 accountIndex) const
m_minutesToUnlock = (requiredConfirmations - ti->confirmations()) * 2;
m_locked = true;
}
}
}
@@ -108,21 +110,11 @@ QList<TransactionInfo *> TransactionHistory::getAll(quint32 accountIndex) const
m_lastDateTime = lastDateTime;
emit lastDateTimeChanged();
}
return m_tinfo;
}
void TransactionHistory::refresh(quint32 accountIndex)
{
// rebuilding transaction list in wallet_api;
m_pimpl->refresh();
// copying list here and keep track on every item to avoid memleaks
getAll(accountIndex);
}
quint64 TransactionHistory::count() const
{
QReadLocker locker(&m_tinfoLock);
QReadLocker locker(&m_lock);
return m_tinfo.count();
}
@@ -157,11 +149,6 @@ TransactionHistory::TransactionHistory(Monero::TransactionHistory *pimpl, QObjec
QString TransactionHistory::writeCSV(quint32 accountIndex, QString out)
{
QList<TransactionInfo *> history = this->getAll(accountIndex);
if(history.count() < 1){
return QString("");
}
// construct filename
qint64 now = QDateTime::currentDateTime().currentMSecsSinceEpoch();
QString fn = QString(QString("%1/monero-txs_%2.csv").arg(out, QString::number(now / 1000)));
@@ -176,15 +163,21 @@ QString TransactionHistory::writeCSV(quint32 accountIndex, QString out)
QTextStream output(&data);
output << "blockHeight,epoch,date,direction,amount,atomicAmount,fee,txid,label,subaddrAccount,paymentId\n";
foreach(const TransactionInfo *info, history)
{
QReadLocker locker(&m_lock);
for (const auto &tx : m_pimpl->getAll()) {
if (tx->subaddrAccount() != accountIndex) {
continue;
}
TransactionInfo info(tx, this);
// collect column data
double amount = info->amount();
quint64 atomicAmount = info->atomicAmount();
quint32 subaddrAccount = info->subaddrAccount();
QString fee = info->fee();
double amount = info.amount();
quint64 atomicAmount = info.atomicAmount();
quint32 subaddrAccount = info.subaddrAccount();
QString fee = info.fee();
QString direction = QString("");
TransactionInfo::Direction _direction = info->direction();
TransactionInfo::Direction _direction = info.direction();
if(_direction == TransactionInfo::Direction_In)
{
direction = QString("in");
@@ -195,14 +188,14 @@ QString TransactionHistory::writeCSV(quint32 accountIndex, QString out)
else {
continue; // skip TransactionInfo::Direction_Both
}
QString label = info->label();
QString label = info.label();
label.remove(QChar('"')); // reserved
quint64 blockHeight = info->blockHeight();
QDateTime timeStamp = info->timestamp();
QString date = info->date() + " " + info->time();
quint64 blockHeight = info.blockHeight();
QDateTime timeStamp = info.timestamp();
QString date = info.date() + " " + info.time();
uint epoch = timeStamp.toTime_t();
QString displayAmount = info->displayAmount();
QString paymentId = info->paymentId();
QString displayAmount = info.displayAmount();
QString paymentId = info.paymentId();
if(paymentId == "0000000000000000"){
paymentId = "";
}
@@ -211,7 +204,7 @@ QString TransactionHistory::writeCSV(quint32 accountIndex, QString out)
QString line = QString("%1,%2,%3,%4,%5,%6,%7,%8,\"%9\",%10,%11\n")
.arg(QString::number(blockHeight), QString::number(epoch), date)
.arg(direction, QString::number(amount), QString::number(atomicAmount))
.arg(info->fee(), info->hash(), label, QString::number(subaddrAccount))
.arg(info.fee(), info.hash(), label, QString::number(subaddrAccount))
.arg(paymentId);
output << line;
}

View File

@@ -29,6 +29,8 @@
#ifndef TRANSACTIONHISTORY_H
#define TRANSACTIONHISTORY_H
#include <functional>
#include <QObject>
#include <QList>
#include <QReadWriteLock>
@@ -50,9 +52,8 @@ class TransactionHistory : public QObject
Q_PROPERTY(bool locked READ locked)
public:
Q_INVOKABLE TransactionInfo *transaction(int index);
Q_INVOKABLE bool transaction(int index, std::function<void (TransactionInfo &)> callback);
// Q_INVOKABLE TransactionInfo * transaction(const QString &id);
Q_INVOKABLE QList<TransactionInfo*> getAll(quint32 accountIndex) const;
Q_INVOKABLE void refresh(quint32 accountIndex);
Q_INVOKABLE QString writeCSV(quint32 accountIndex, QString out);
quint64 count() const;
@@ -75,9 +76,9 @@ private:
private:
friend class Wallet;
mutable QReadWriteLock m_lock;
Monero::TransactionHistory * m_pimpl;
mutable QList<TransactionInfo*> m_tinfo;
mutable QReadWriteLock m_tinfoLock;
mutable QDateTime m_firstDateTime;
mutable QDateTime m_lastDateTime;
mutable int m_minutesToUnlock;

View File

@@ -34,85 +34,81 @@
TransactionInfo::Direction TransactionInfo::direction() const
{
return static_cast<Direction>(m_pimpl->direction());
return m_direction;
}
bool TransactionInfo::isPending() const
{
return m_pimpl->isPending();
return m_pending;
}
bool TransactionInfo::isFailed() const
{
return m_pimpl->isFailed();
return m_failed;
}
double TransactionInfo::amount() const
{
// there's no unsigned uint64 for JS, so better use double
return WalletManager::instance()->displayAmount(m_pimpl->amount()).toDouble();
return displayAmount().toDouble();
}
quint64 TransactionInfo::atomicAmount() const
{
return m_pimpl->amount();
return m_amount;
}
QString TransactionInfo::displayAmount() const
{
return WalletManager::instance()->displayAmount(m_pimpl->amount());
return WalletManager::instance()->displayAmount(m_amount);
}
QString TransactionInfo::fee() const
{
if(m_pimpl->fee() == 0)
if(m_fee == 0)
return "";
return WalletManager::instance()->displayAmount(m_pimpl->fee());
return WalletManager::instance()->displayAmount(m_fee);
}
quint64 TransactionInfo::blockHeight() const
{
return m_pimpl->blockHeight();
return m_blockHeight;
}
QSet<quint32> TransactionInfo::subaddrIndex() const
{
QSet<quint32> result;
for (uint32_t i : m_pimpl->subaddrIndex())
result.insert(i);
return result;
return m_subaddrIndex;
}
quint32 TransactionInfo::subaddrAccount() const
{
return m_pimpl->subaddrAccount();
return m_subaddrAccount;
}
QString TransactionInfo::label() const
{
return QString::fromStdString(m_pimpl->label());
return m_label;
}
quint64 TransactionInfo::confirmations() const
{
return m_pimpl->confirmations();
return m_confirmations;
}
quint64 TransactionInfo::unlockTime() const
{
return m_pimpl->unlockTime();
return m_unlockTime;
}
QString TransactionInfo::hash() const
{
return QString::fromStdString(m_pimpl->hash());
return m_hash;
}
QDateTime TransactionInfo::timestamp() const
{
QDateTime result = QDateTime::fromTime_t(m_pimpl->timestamp());
return result;
return m_timestamp;
}
QString TransactionInfo::date() const
@@ -127,13 +123,13 @@ QString TransactionInfo::time() const
QString TransactionInfo::paymentId() const
{
return QString::fromStdString(m_pimpl->paymentId());
return m_paymentId;
}
QString TransactionInfo::destinations_formatted() const
{
QString destinations;
for (auto const& t: transfers()) {
for (auto const& t: m_transfers) {
if (!destinations.isEmpty())
destinations += "<br> ";
destinations += WalletManager::instance()->displayAmount(t->amount()) + ": " + t->address();
@@ -141,22 +137,29 @@ QString TransactionInfo::destinations_formatted() const
return destinations;
}
QList<Transfer*> TransactionInfo::transfers() const
TransactionInfo::TransactionInfo(const Monero::TransactionInfo *pimpl, QObject *parent)
: QObject(parent)
, m_amount(pimpl->amount())
, m_blockHeight(pimpl->blockHeight())
, m_confirmations(pimpl->confirmations())
, m_direction(static_cast<Direction>(pimpl->direction()))
, m_failed(pimpl->isFailed())
, m_fee(pimpl->fee())
, m_hash(QString::fromStdString(pimpl->hash()))
, m_label(QString::fromStdString(pimpl->label()))
, m_paymentId(QString::fromStdString(pimpl->paymentId()))
, m_pending(pimpl->isPending())
, m_subaddrAccount(pimpl->subaddrAccount())
, m_timestamp(QDateTime::fromTime_t(pimpl->timestamp()))
, m_unlockTime(pimpl->unlockTime())
{
if (!m_transfers.isEmpty()) {
return m_transfers;
}
for(auto const& t: m_pimpl->transfers()) {
TransactionInfo * parent = const_cast<TransactionInfo*>(this);
Transfer * transfer = new Transfer(t.amount, QString::fromStdString(t.address), parent);
for (auto const &t: pimpl->transfers())
{
Transfer *transfer = new Transfer(t.amount, QString::fromStdString(t.address), this);
m_transfers.append(transfer);
}
return m_transfers;
}
TransactionInfo::TransactionInfo(Monero::TransactionInfo *pimpl, QObject *parent)
: QObject(parent), m_pimpl(pimpl)
{
for (uint32_t i : pimpl->subaddrIndex())
{
m_subaddrIndex.insert(i);
}
}

View File

@@ -90,18 +90,25 @@ public:
//! only applicable for output transactions
//! used in tx details popup
QString destinations_formatted() const;
//! Could be useful later when addressbook is implemented
Q_INVOKABLE QList<Transfer*> transfers() const;
private:
explicit TransactionInfo(Monero::TransactionInfo * pimpl, QObject *parent = 0);
explicit TransactionInfo(const Monero::TransactionInfo *pimpl, QObject *parent = 0);
private:
friend class TransactionHistory;
Monero::TransactionInfo * m_pimpl;
mutable QList<Transfer*> m_transfers;
quint64 m_amount;
quint64 m_blockHeight;
quint64 m_confirmations;
Direction m_direction;
bool m_failed;
quint64 m_fee;
QString m_hash;
QString m_label;
QString m_paymentId;
bool m_pending;
quint32 m_subaddrAccount;
QSet<quint32> m_subaddrIndex;
QDateTime m_timestamp;
quint64 m_unlockTime;
};
// in order to wrap it to QVariant
Q_DECLARE_METATYPE(TransactionInfo*)
#endif // TRANSACTIONINFO_H

View File

@@ -289,6 +289,11 @@ bool Wallet::viewOnly() const
return m_walletImpl->watchOnly();
}
quint64 Wallet::balance() const
{
return balance(m_currentSubaddressAccount);
}
quint64 Wallet::balance(quint32 accountIndex) const
{
return m_walletImpl->balance(accountIndex);
@@ -299,6 +304,11 @@ quint64 Wallet::balanceAll() const
return m_walletImpl->balanceAll();
}
quint64 Wallet::unlockedBalance() const
{
return unlockedBalance(m_currentSubaddressAccount);
}
quint64 Wallet::unlockedBalance(quint32 accountIndex) const
{
return m_walletImpl->unlockedBalance(accountIndex);
@@ -351,6 +361,7 @@ QString Wallet::getSubaddressLabel(quint32 accountIndex, quint32 addressIndex) c
void Wallet::setSubaddressLabel(quint32 accountIndex, quint32 addressIndex, const QString &label)
{
m_walletImpl->setSubaddressLabel(accountIndex, addressIndex, label.toStdString());
emit currentSubaddressAccountChanged();
}
void Wallet::deviceShowAddressAsync(quint32 accountIndex, quint32 addressIndex, const QString &paymentId)
{
@@ -438,7 +449,7 @@ bool Wallet::refresh()
bool result = m_walletImpl->refresh();
m_history->refresh(currentSubaddressAccount());
m_subaddress->refresh(currentSubaddressAccount());
m_subaddressAccount->getAll(true);
m_subaddressAccount->getAll();
if (result)
emit updated();
return result;

View File

@@ -160,10 +160,12 @@ public:
Q_INVOKABLE void setTrustedDaemon(bool arg);
//! returns balance
Q_INVOKABLE quint64 balance() const;
Q_INVOKABLE quint64 balance(quint32 accountIndex) const;
Q_INVOKABLE quint64 balanceAll() const;
//! returns unlocked balance
Q_INVOKABLE quint64 unlockedBalance() const;
Q_INVOKABLE quint64 unlockedBalance(quint32 accountIndex) const;
Q_INVOKABLE quint64 unlockedBalanceAll() const;

View File

@@ -260,7 +260,7 @@ quint64 WalletManager::maximumAllowedAmount() const
return Monero::Wallet::maximumAllowedAmount();
}
QString WalletManager::maximumAllowedAmountAsSting() const
QString WalletManager::maximumAllowedAmountAsString() const
{
return WalletManager::displayAmount(WalletManager::maximumAllowedAmount());
}
@@ -458,7 +458,6 @@ double WalletManager::getPasswordStrength(const QString &password) const
bool WalletManager::saveQrCode(const QString &code, const QString &path) const
{
QSize size;
// 240 <=> mainLayout.qrCodeSize (Receive.qml)
return QRCodeImageProvider::genQrImage(code, &size).scaled(size.expandedTo(QSize(240, 240)), Qt::KeepAspectRatio).save(path, "PNG", 100);
}

View File

@@ -135,7 +135,7 @@ public:
Q_INVOKABLE quint64 maximumAllowedAmount() const;
// QML JS engine doesn't support unsigned integers
Q_INVOKABLE QString maximumAllowedAmountAsSting() const;
Q_INVOKABLE QString maximumAllowedAmountAsString() const;
Q_INVOKABLE bool paymentIdValid(const QString &payment_id) const;
Q_INVOKABLE bool addressValid(const QString &address, NetworkType::Type nettype) const;

View File

@@ -34,7 +34,7 @@
#include <QDebug>
#include "Logger.h"
#include "src/qt/TailsOS.h"
#include "qt/TailsOS.h"
#include "wallet/api/wallet2_api.h"
// default log path by OS (should be writable)

View File

@@ -1,21 +1,21 @@
// Copyright (c) 2014-2018, The Monero Project
//
//
// All rights reserved.
//
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
@@ -64,9 +64,9 @@
#include "MainApp.h"
#include "qt/ipc.h"
#include "qt/utils.h"
#include "src/qt/TailsOS.h"
#include "src/qt/KeysFiles.h"
#include "src/qt/MoneroSettings.h"
#include "qt/TailsOS.h"
#include "qt/KeysFiles.h"
#include "qt/MoneroSettings.h"
#include "qt/prices.h"
// IOS exclusions
@@ -75,7 +75,58 @@
#endif
#ifdef WITH_SCANNER
#include "QrCodeScanner.h"
#include "QR-Code-scanner/QrCodeScanner.h"
#endif
#ifdef MONERO_GUI_STATIC
#include <QtPlugin>
#if defined(Q_OS_OSX)
Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin);
#elif defined(Q_OS_WIN)
Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin);
#elif defined(Q_OS_LINUX)
Q_IMPORT_PLUGIN(QXcbIntegrationPlugin);
#endif
Q_IMPORT_PLUGIN(QSvgIconPlugin)
Q_IMPORT_PLUGIN(QGifPlugin)
Q_IMPORT_PLUGIN(QICNSPlugin)
Q_IMPORT_PLUGIN(QICOPlugin)
Q_IMPORT_PLUGIN(QJpegPlugin)
Q_IMPORT_PLUGIN(QMngPlugin)
Q_IMPORT_PLUGIN(QSvgPlugin)
Q_IMPORT_PLUGIN(QTgaPlugin)
Q_IMPORT_PLUGIN(QTiffPlugin)
Q_IMPORT_PLUGIN(QWbmpPlugin)
Q_IMPORT_PLUGIN(QWebpPlugin)
Q_IMPORT_PLUGIN(QQmlDebuggerServiceFactory)
Q_IMPORT_PLUGIN(QQmlInspectorServiceFactory)
Q_IMPORT_PLUGIN(QLocalClientConnectionFactory)
Q_IMPORT_PLUGIN(QDebugMessageServiceFactory)
Q_IMPORT_PLUGIN(QQmlNativeDebugConnectorFactory)
Q_IMPORT_PLUGIN(QQmlNativeDebugServiceFactory)
Q_IMPORT_PLUGIN(QQmlProfilerServiceFactory)
Q_IMPORT_PLUGIN(QQuickProfilerAdapterFactory)
Q_IMPORT_PLUGIN(QQmlDebugServerFactory)
Q_IMPORT_PLUGIN(QTcpServerConnectionFactory)
Q_IMPORT_PLUGIN(QGenericEnginePlugin)
Q_IMPORT_PLUGIN(QtQuick2Plugin)
Q_IMPORT_PLUGIN(QtQuickLayoutsPlugin)
Q_IMPORT_PLUGIN(QtGraphicalEffectsPlugin)
Q_IMPORT_PLUGIN(QtGraphicalEffectsPrivatePlugin)
Q_IMPORT_PLUGIN(QtQuick2WindowPlugin)
Q_IMPORT_PLUGIN(QtQuickControls1Plugin)
Q_IMPORT_PLUGIN(QtQuick2DialogsPlugin)
Q_IMPORT_PLUGIN(QmlFolderListModelPlugin)
Q_IMPORT_PLUGIN(QmlSettingsPlugin)
Q_IMPORT_PLUGIN(QtQuick2DialogsPrivatePlugin)
Q_IMPORT_PLUGIN(QtQuick2PrivateWidgetsPlugin)
Q_IMPORT_PLUGIN(QtQuickControls2Plugin)
Q_IMPORT_PLUGIN(QtQuickTemplates2Plugin)
Q_IMPORT_PLUGIN(QmlXmlListModelPlugin)
Q_IMPORT_PLUGIN(QMultimediaDeclarativeModule)
#endif
bool isIOS = false;
@@ -119,11 +170,8 @@ int main(int argc, char *argv[])
if (isDesktop) putenv((char*)"QT_QPA_PLATFORM=xcb");
#endif
// // Enable high DPI scaling on windows & linux
//#if !defined(Q_OS_ANDROID) && QT_VERSION >= 0x050600
// QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
// qDebug() << "High DPI auto scaling - enabled";
//#endif
// enable High DPI scaling
qputenv("QT_ENABLE_HIGHDPI_SCALING", "1");
// Turn off colors in monerod log output.
qputenv("TERM", "goaway");

View File

@@ -30,11 +30,15 @@
#include <QTemporaryFile>
#include <QDir>
#include <QDebug>
#include <QDesktopServices>
#include <QFileInfo>
#include <QString>
#include <QUrl>
#ifdef Q_OS_MAC
#include "qt/macoshelper.h"
#endif
#ifdef Q_OS_WIN32
#ifdef Q_OS_WIN
#include <Shlobj.h>
#include <windows.h>
#endif
#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)
@@ -46,11 +50,61 @@
// #undef those Xlib #defines that conflict with QEvent::Type enum
#endif
#if defined(Q_OS_WIN)
bool openFolderAndSelectItem(const QString &filePath)
{
struct scope {
~scope() { ::CoTaskMemFree(pidl); }
PIDLIST_ABSOLUTE pidl = nullptr;
} scope;
SFGAOF flags;
HRESULT result = ::SHParseDisplayName(filePath.toStdWString().c_str(), nullptr, &scope.pidl, 0, &flags);
if (result != S_OK)
{
qWarning() << "SHParseDisplayName failed" << result << "file path" << filePath;
return false;
}
result = ::SHOpenFolderAndSelectItems(scope.pidl, 0, nullptr, 0);
if (result != S_OK)
{
qWarning() << "SHOpenFolderAndSelectItems failed" << result << "file path" << filePath;
return false;
}
return true;
}
#endif
OSHelper::OSHelper(QObject *parent) : QObject(parent)
{
}
bool OSHelper::openContainingFolder(const QString &filePath) const
{
#if defined(Q_OS_WIN)
if (openFolderAndSelectItem(QDir::toNativeSeparators(filePath)))
{
return true;
}
#elif defined(Q_OS_MAC)
if (MacOSHelper::openFolderAndSelectItem(QUrl::fromLocalFile(filePath)))
{
return true;
}
#endif
QUrl url = QUrl::fromLocalFile(QFileInfo(filePath).absolutePath());
if (!url.isValid())
{
qWarning() << "Malformed file path" << filePath << url.errorString();
return false;
}
return QDesktopServices::openUrl(url);
}
QString OSHelper::temporaryFilename() const
{
QString tempFileName;
@@ -76,7 +130,7 @@ bool OSHelper::removeTemporaryWallet(const QString &fileName) const
bool OSHelper::isCapsLock() const
{
// platform dependent method of determining if CAPS LOCK is on
#if defined(Q_OS_WIN32) // MS Windows version
#if defined(Q_OS_WIN) // MS Windows version
return GetKeyState(VK_CAPITAL) == 1;
#elif defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) // X11 version
Display * d = XOpenDisplay((char*)0);

View File

@@ -39,6 +39,7 @@ class OSHelper : public QObject
public:
explicit OSHelper(QObject *parent = 0);
Q_INVOKABLE bool openContainingFolder(const QString &filePath) const;
Q_INVOKABLE QString temporaryFilename() const;
Q_INVOKABLE QString temporaryPath() const;
Q_INVOKABLE bool removeTemporaryWallet(const QString &walletName) const;

4
src/model/CMakeLists.txt Normal file
View File

@@ -0,0 +1,4 @@
file(GLOB_RECURSE SRC_SOURCES *.cpp)
file(GLOB_RECURSE SRC_HEADERS *.h)

View File

@@ -59,22 +59,28 @@ QVariant SubaddressAccountModel::data(const QModelIndex &index, int role) const
if (!index.isValid() || index.row() < 0 || (unsigned)index.row() >= m_subaddressAccount->count())
return {};
Monero::SubaddressAccountRow * sr = m_subaddressAccount->getRow(index.row());
QVariant result;
QVariant result = "";
switch (role) {
case SubaddressAccountAddressRole:
result = QString::fromStdString(sr->getAddress());
break;
case SubaddressAccountLabelRole:
result = QString::fromStdString(sr->getLabel());
break;
case SubaddressAccountBalanceRole:
result = QString::fromStdString(sr->getBalance());
break;
case SubaddressAccountUnlockedBalanceRole:
result = QString::fromStdString(sr->getUnlockedBalance());
break;
bool found = m_subaddressAccount->getRow(index.row(), [&result, &role](const Monero::SubaddressAccountRow &row) {
switch (role) {
case SubaddressAccountAddressRole:
result = QString::fromStdString(row.getAddress());
break;
case SubaddressAccountLabelRole:
result = QString::fromStdString(row.getLabel());
break;
case SubaddressAccountBalanceRole:
result = QString::fromStdString(row.getBalance());
break;
case SubaddressAccountUnlockedBalanceRole:
result = QString::fromStdString(row.getUnlockedBalance());
break;
default:
qCritical() << "Unimplemented role" << role;
}
});
if (!found) {
qCritical("%s: internal error: invalid index %d", __FUNCTION__, index.row());
}
return result;

View File

@@ -60,18 +60,23 @@ QVariant SubaddressModel::data(const QModelIndex &index, int role) const
if (!index.isValid() || index.row() < 0 || (unsigned)index.row() >= m_subaddress->count())
return {};
Monero::SubaddressRow * sr = m_subaddress->getRow(index.row());
if (!sr)
return {};
QVariant result;
QVariant result = "";
switch (role) {
case SubaddressAddressRole:
result = QString::fromStdString(sr->getAddress());
break;
case SubaddressLabelRole:
result = index.row() == 0 ? tr("Primary address") : QString::fromStdString(sr->getLabel());
break;
bool found = m_subaddress->getRow(index.row(), [&index, &result, &role](const Monero::SubaddressRow &subaddress) {
switch (role) {
case SubaddressAddressRole:
result = QString::fromStdString(subaddress.getAddress());
break;
case SubaddressLabelRole:
result = index.row() == 0 ? tr("Primary address") : QString::fromStdString(subaddress.getLabel());
break;
default:
qCritical() << "Unimplemented role" << role;
}
});
if (!found)
{
qCritical("%s: internal error: invalid index %d", __FUNCTION__, index.row());
}
return result;

View File

@@ -59,106 +59,90 @@ TransactionHistory *TransactionHistoryModel::transactionHistory() const
return m_transactionHistory;
}
QVariant TransactionHistoryModel::parseTransactionInfo(const TransactionInfo &tInfo, int role) const
{
switch (role)
{
case TransactionDirectionRole:
return QVariant::fromValue(tInfo.direction());
case TransactionPendingRole:
return tInfo.isPending();
case TransactionFailedRole:
return tInfo.isFailed();
case TransactionAmountRole:
return tInfo.amount();
case TransactionDisplayAmountRole:
return tInfo.displayAmount();
case TransactionAtomicAmountRole:
return tInfo.atomicAmount();
case TransactionFeeRole:
return tInfo.fee();
case TransactionBlockHeightRole:
{
// Use NULL QVariant for transactions without height.
// Forces them to be displayed at top when sorted by blockHeight.
if (tInfo.blockHeight() != 0)
{
return tInfo.blockHeight();
}
return QVariant();
}
case TransactionSubaddrIndexRole:
{
QString str = QString{""};
bool first = true;
for (quint32 i : tInfo.subaddrIndex())
{
if (!first)
str += QString{","};
first = false;
str += QString::number(i);
}
return str;
}
case TransactionSubaddrAccountRole:
return tInfo.subaddrAccount();
case TransactionLabelRole:
return tInfo.subaddrIndex().size() == 1 && *tInfo.subaddrIndex().begin() == 0 ? tr("Primary address") : tInfo.label();
case TransactionConfirmationsRole:
return tInfo.confirmations();
case TransactionConfirmationsRequiredRole:
return (tInfo.blockHeight() < tInfo.unlockTime()) ? tInfo.unlockTime() - tInfo.blockHeight() : 10;
case TransactionHashRole:
return tInfo.hash();
case TransactionTimeStampRole:
return tInfo.timestamp();
case TransactionPaymentIdRole:
return tInfo.paymentId();
case TransactionIsOutRole:
return tInfo.direction() == TransactionInfo::Direction_Out;
case TransactionDateRole:
return tInfo.date();
case TransactionTimeRole:
return tInfo.time();
case TransactionDestinationsRole:
return tInfo.destinations_formatted();
default:
{
qCritical() << "Unimplemented role" << role;
return QVariant();
}
}
}
QVariant TransactionHistoryModel::data(const QModelIndex &index, int role) const
{
if (!m_transactionHistory) {
return QVariant();
}
if (index.row() < 0 || (unsigned)index.row() >= m_transactionHistory->count()) {
return QVariant();
}
TransactionInfo * tInfo = m_transactionHistory->transaction(index.row());
Q_ASSERT(tInfo);
if (!tInfo) {
qCritical("%s: internal error: no transaction info for index %d", __FUNCTION__, index.row());
return QVariant();
}
QVariant result;
switch (role) {
case TransactionRole:
result = QVariant::fromValue(tInfo);
break;
case TransactionDirectionRole:
result = QVariant::fromValue(tInfo->direction());
break;
case TransactionPendingRole:
result = tInfo->isPending();
break;
case TransactionFailedRole:
result = tInfo->isFailed();
break;
case TransactionAmountRole:
result = tInfo->amount();
break;
case TransactionDisplayAmountRole:
result = tInfo->displayAmount();
break;
case TransactionAtomicAmountRole:
result = tInfo->atomicAmount();
break;
case TransactionFeeRole:
result = tInfo->fee();
break;
case TransactionBlockHeightRole:
// Use NULL QVariant for transactions without height.
// Forces them to be displayed at top when sorted by blockHeight.
if (tInfo->blockHeight() != 0) {
result = tInfo->blockHeight();
}
break;
case TransactionSubaddrIndexRole:
{
QString str = QString{""};
bool first = true;
for (quint32 i : tInfo->subaddrIndex()) {
if (!first)
str += QString{","};
first = false;
str += QString::number(i);
}
result = str;
}
break;
case TransactionSubaddrAccountRole:
result = tInfo->subaddrAccount();
break;
case TransactionLabelRole:
result = tInfo->subaddrIndex().size() == 1 && *tInfo->subaddrIndex().begin() == 0 ? tr("Primary address") : tInfo->label();
break;
case TransactionConfirmationsRole:
result = tInfo->confirmations();
break;
case TransactionConfirmationsRequiredRole:
result = (tInfo->blockHeight() < tInfo->unlockTime()) ? tInfo->unlockTime() - tInfo->blockHeight() : 10;
break;
case TransactionHashRole:
result = tInfo->hash();
break;
case TransactionTimeStampRole:
result = tInfo->timestamp();
break;
case TransactionPaymentIdRole:
result = tInfo->paymentId();
break;
case TransactionIsOutRole:
result = tInfo->direction() == TransactionInfo::Direction_Out;
break;
case TransactionDateRole:
result = tInfo->date();
break;
case TransactionTimeRole:
result = tInfo->time();
break;
case TransactionDestinationsRole:
result = tInfo->destinations_formatted();
break;
bool found = m_transactionHistory->transaction(index.row(), [this, &result, &role](const TransactionInfo &tInfo) {
result = parseTransactionInfo(tInfo, role);
});
if (!found) {
qCritical("%s: internal error: no transaction info for index %d", __FUNCTION__, index.row());
}
return result;
}
@@ -171,7 +155,6 @@ int TransactionHistoryModel::rowCount(const QModelIndex &parent) const
QHash<int, QByteArray> TransactionHistoryModel::roleNames() const
{
QHash<int, QByteArray> roleNames = QAbstractListModel::roleNames();
roleNames.insert(TransactionRole, "transaction");
roleNames.insert(TransactionDirectionRole, "direction");
roleNames.insert(TransactionPendingRole, "isPending");
roleNames.insert(TransactionFailedRole, "isFailed");

View File

@@ -45,8 +45,7 @@ class TransactionHistoryModel : public QAbstractListModel
public:
enum TransactionInfoRole {
TransactionRole = Qt::UserRole + 1, // for the TransactionInfo object;
TransactionDirectionRole,
TransactionDirectionRole = Qt::UserRole + 1,
TransactionPendingRole,
TransactionFailedRole,
TransactionAmountRole,
@@ -97,6 +96,9 @@ public:
signals:
void transactionHistoryChanged();
private:
QVariant parseTransactionInfo(const TransactionInfo &tInfo, int role) const;
private:
TransactionHistory * m_transactionHistory;
};

View File

@@ -32,12 +32,6 @@ private:
QFutureWatcher<T> *newWatcher()
{
QFutureWatcher<T> *watcher = new QFutureWatcher<T>();
QThread *schedulerThread = this->thread();
if (watcher->thread() != schedulerThread)
{
watcher->moveToThread(schedulerThread);
}
watcher->setParent(this);
return watcher;
}
@@ -50,10 +44,10 @@ private:
try
{
auto *watcher = newWatcher<T>();
watcher->setFuture(makeFuture(watcher));
connect(watcher, &QFutureWatcher<T>::finished, [this, watcher] {
watcher->deleteLater();
});
watcher->setFuture(makeFuture(watcher));
return qMakePair(true, watcher->future());
}
catch (const std::exception &exception)

View File

@@ -35,6 +35,7 @@ class MacOSHelper
public:
static bool isCapsLock();
static bool openFolderAndSelectItem(const QUrl &path);
};
#endif //MACOSHELPER_H

View File

@@ -47,3 +47,11 @@ bool MacOSHelper::isCapsLock()
return (flags & NSAlphaShiftKeyMask);
#endif
}
bool MacOSHelper::openFolderAndSelectItem(const QUrl &path)
{
NSURL *nspath = path.toNSURL();
NSArray *fileURLs = [NSArray arrayWithObjects:nspath, nil];
[[NSWorkspace sharedWorkspace] activateFileViewerSelectingURLs:fileURLs];
return true;
}

Some files were not shown because too many files have changed in this diff Show More