Compare commits

..
54 Commits
Author SHA1 Message Date
tobtoht 8c197f26ea Merge pull request 'build: prepare beta-2' (#224) from tobtoht/feather:beta-2 into master
Reviewed-on: https://git.wownero.com/feather/feather/pulls/224
2020-12-14 23:06:10 +00:00
tobtoht 6f17a1dfaa Merge pull request 'Update OpenSSL to 1.1.1i' (#223) from tobtoht/feather:openssl_1.1.1i into master
Reviewed-on: https://git.wownero.com/feather/feather/pulls/223
2020-12-14 23:04:58 +00:00
tobtoht 2217ae602a Merge pull request 'Allow resending failed transactions' (#212) from tobtoht/feather:black_holed_no_more into master
Reviewed-on: https://git.wownero.com/feather/feather/pulls/212
2020-12-14 22:27:12 +00:00
tobtoht 75743e8897 build: prepare beta-2 2020-12-14 23:10:54 +01:00
tobtoht 169d14ab3a Allow resending failed transactions 2020-12-14 23:07:50 +01:00
tobtoht 710556a580 Update OpenSSL to 1.1.1i 2020-12-14 21:55:52 +01:00
tobtoht 15211ce5fa Merge pull request 'Menu: add rescan spent' (#221) from tobtoht/feather:rescan_spent into master
Reviewed-on: https://git.wownero.com/feather/feather/pulls/221
2020-12-14 19:45:26 +00:00
tobtoht 66f53d865e Menu: add rescan spent 2020-12-14 20:44:37 +01:00
tobtoht ea81b308f7 Merge pull request 'TxInfoDialog: set blockheight to unconfirmed for mempool txs' (#220) from tobtoht/feather:tx_info_blockheight into master
Reviewed-on: https://git.wownero.com/feather/feather/pulls/220
2020-12-14 19:31:01 +00:00
tobtoht 9016fa13dc TxInfoDialog: set blockheight to unconfirmed for mempool txs 2020-12-14 20:30:15 +01:00
tobtoht cee70a997d Merge pull request 'TickerWidget: don't show percentage on balance' (#219) from tobtoht/feather:ticker_widget_no_perc into master
Reviewed-on: https://git.wownero.com/feather/feather/pulls/219
2020-12-14 19:19:40 +00:00
tobtoht 041c11f618 TickerWidget: don't show percentage on balance 2020-12-14 20:17:22 +01:00
tobtoht c5f0962e40 Merge pull request 'Replace showMessageBox with Qt builtin' (#218) from tobtoht/feather:messagebox_cleanup into master
Reviewed-on: https://git.wownero.com/feather/feather/pulls/218
2020-12-14 02:25:11 +00:00
tobtoht 85a06007a1 Replace showMessageBox with Qt builtin 2020-12-14 03:23:19 +01:00
tobtoht b6459d1b64 Merge pull request 'Remove user_agents.txt' (#217) from tobtoht/feather:remove_user_agents into master
Reviewed-on: https://git.wownero.com/feather/feather/pulls/217
2020-12-14 01:49:06 +00:00
tobtoht 653e59f5ec Remove user_agents.txt 2020-12-14 02:47:51 +01:00
tobtoht 71e28831d8 Merge pull request 'Coins: copy label' (#216) from tobtoht/feather:coins_copy_label into master
Reviewed-on: https://git.wownero.com/feather/feather/pulls/216
2020-12-14 01:33:29 +00:00
tobtoht 874748ea7f Coins: copy label 2020-12-14 02:30:30 +01:00
tobtoht d3e55c4510 Merge pull request 'Store wallet immediately after sending tx' (#215) from tobtoht/feather:store_on_send into master
Reviewed-on: https://git.wownero.com/feather/feather/pulls/215
2020-12-14 01:18:08 +00:00
tobtoht 147ee8ef8b Store wallet immediately after sending tx 2020-12-14 02:15:56 +01:00
tobtoht 5ec641bc6f Merge pull request 'Update fiat conversion label on donate' (#214) from tobtoht/feather:donation_fix into master
Reviewed-on: https://git.wownero.com/feather/feather/pulls/214
2020-12-14 01:01:00 +00:00
tobtoht 4a37be1ce7 Update fiat conversion label on donate 2020-12-14 01:59:32 +01:00
tobtoht d1b4db2be4 Merge pull request 'Core: rebase to v0.17.1.7' (#213) from tobtoht/feather:v0.17.1.7 into master
Reviewed-on: https://git.wownero.com/feather/feather/pulls/213
2020-12-13 13:21:29 +00:00
tobtoht 1e2fa51b98 Core: rebase to v0.17.1.7 2020-12-13 14:19:17 +01:00
tobtoht 743c5fa9a4 Merge pull request 'DebugInfoDialog: improve Tor status on Tails' (#211) from tobtoht/feather:tails_debug_info into master
Reviewed-on: https://git.wownero.com/feather/feather/pulls/211
2020-12-12 16:34:58 +00:00
tobtoht ae1d6a2d1c DebugInfoDialog: improve Tor status on Tails 2020-12-12 17:33:33 +01:00
tobtoht 5e246519c2 Merge pull request 'SeedDialog: improve UI' (#210) from tobtoht/feather:seed_dialog_height into master
Reviewed-on: https://git.wownero.com/feather/feather/pulls/210
2020-12-12 16:23:24 +00:00
tobtoht 8b5cb8ba2c SeedDialog: improve UI 2020-12-12 17:19:37 +01:00
tobtoht 3ea7e5932e Merge pull request 'Menu: remove disabled open wallet item' (#209) from tobtoht/feather:remove_open_wallet into master
Reviewed-on: https://git.wownero.com/feather/feather/pulls/209
2020-12-12 16:07:29 +00:00
tobtoht 97b4fcb958 Menu: remove disable open wallet item 2020-12-12 16:59:44 +01:00
tobtoht 80c1c66bea Merge pull request 'MorphToken: add statustext for missing states' (#208) from tobtoht/feather:morphtoken_processing_delay into master
Reviewed-on: https://git.wownero.com/feather/feather/pulls/208
2020-12-12 15:37:26 +00:00
tobtoht be61c803bf MorphToken: add statustext for missing states 2020-12-12 16:35:44 +01:00
tobtoht a0a307f3bd Merge pull request 'Remove sorry()' (#207) from tobtoht/feather:no_sorry into master
Reviewed-on: https://git.wownero.com/feather/feather/pulls/207
2020-12-12 14:56:18 +00:00
tobtoht 1d8f4f0bfd Remove sorry() 2020-12-12 15:54:43 +01:00
tobtoht 7c288570b1 Merge pull request 'Update calc icon' (#206) from tobtoht/feather:calc_icon into master
Reviewed-on: https://git.wownero.com/feather/feather/pulls/206
2020-12-12 14:48:57 +00:00
tobtoht 02d71ebf02 Update calc icon 2020-12-12 15:46:41 +01:00
tobtoht 6ef4eaa39f Merge pull request 'Rename XMRig tab to Mining' (#205) from tobtoht/feather:xmrig_mining into master
Reviewed-on: https://git.wownero.com/feather/feather/pulls/205
2020-12-12 14:29:30 +00:00
tobtoht d3ee2744d4 Merge pull request 'XMRig: squish settings UI' (#204) from tobtoht/feather:xmrig_cleanup into master
Reviewed-on: https://git.wownero.com/feather/feather/pulls/204
2020-12-12 14:24:02 +00:00
tobtoht 61b54efb97 Rename XMRig tab to Mining 2020-12-12 15:22:31 +01:00
tobtoht 91b00da4af XMRig: squish settings UI 2020-12-12 14:39:13 +01:00
tobtoht 2b72624ec0 Merge pull request 'Consolidate exchanges to exchange tab' (#203) from tobtoht/feather:consolidate_exchanges into master
Reviewed-on: https://git.wownero.com/feather/feather/pulls/203
2020-12-12 13:03:06 +00:00
tobtoht 55bb304dc2 Merge pull request 'Drone: optimize builds' (#202) from tobtoht/feather:drone_optimize_builds into master
Reviewed-on: https://git.wownero.com/feather/feather/pulls/202
2020-12-12 12:18:18 +00:00
tobtoht 8ffd2293f4 Consolidate exchanges to exchange tab 2020-12-12 02:49:33 +01:00
tobtoht 3df2e591fe Drone: optimize builds 2020-12-12 01:54:04 +01:00
tobtoht 785771cb90 Merge pull request 'Do not bundle XMRig' (#201) from tobtoht/feather:xmrip into master
Reviewed-on: https://git.wownero.com/feather/feather/pulls/201
2020-12-12 00:51:55 +00:00
tobtoht aa14a2dcbb Do not bundle XMRig binary 2020-12-12 01:18:09 +01:00
tobtoht c9e2ce3770 Merge pull request 'Spell it backwards' (#200) from tobtoht/feather:tobtoht into master
Reviewed-on: https://git.wownero.com/feather/feather/pulls/200
2020-12-11 19:50:08 +00:00
tobtoht 835e4aaca3 Spell it backwards 2020-12-11 20:46:24 +01:00
tobtoht 97900bcbe6 Merge pull request 'Home: add tabs for home widgets' (#199) from tobtoht/feather:main_tab into master
Reviewed-on: https://git.wownero.com/feather/feather/pulls/199
2020-12-11 13:33:32 +00:00
tobtoht a9ec69afd0 Home: add tabs for home widgets 2020-12-11 14:32:14 +01:00
tobtoht a008f1f45f Merge pull request 'Add reproducible build instructions' (#198) from tobtoht/feather:update_building into master
Reviewed-on: https://git.wownero.com/feather/feather/pulls/198
2020-12-10 17:16:54 +00:00
tobtoht fbd6b8eb53 Add reproducible build instructions 2020-12-10 18:13:21 +01:00
tobtoht 855755fea3 Merge pull request 'Add release signing key' (#197) from tobtoht/feather:signing_key into master
Reviewed-on: https://git.wownero.com/feather/feather/pulls/197
2020-12-09 21:14:31 +00:00
tobtoht 302e585af4 Add release signing key 2020-12-09 22:12:55 +01:00
64 changed files with 606 additions and 8231 deletions
+4 -4
View File
@@ -16,8 +16,8 @@ steps:
- git config --global url."http://gitea:3000/".insteadOf https://github.com/
- git config --global url."http://gitea:3000/".insteadOf https://git.wownero.com/
- git submodule update --init monero
- git submodule update --init --recursive monero
- TOR="/usr/local/tor/bin/tor" XMRIG="/xmrig/xmrig" make -j8 release-static
- git submodule update --init --depth 1 --recursive monero
- TOR_BIN="/usr/local/tor/bin/tor" make -j8 release-static
environment:
OPENSSL_ROOT_DIR: /usr/local/openssl/
CMAKEFLAGS_EXTRA: -DFETCH_DEPS=Off
@@ -97,8 +97,8 @@ steps:
- git config --global url."http://gitea:3000/".insteadOf https://github.com/
- git config --global url."http://gitea:3000/".insteadOf https://git.wownero.com/
- git submodule update --init monero
- git submodule update --init --recursive monero
- PATH="/mxe/usr/bin/:$PATH" TOR="/mxe/usr/x86_64-w64-mingw32.static/bin/tor.exe" XMRIG="/xmrig/xmrig.exe" make -j8 windows-mxe-release
- git submodule update --init --depth 1 --recursive monero
- PATH="/mxe/usr/bin/:$PATH" TOR_BIN="/mxe/usr/x86_64-w64-mingw32.static/bin/tor.exe" make -j8 windows-mxe-release
environment:
CMAKEFLAGS_EXTRA: -DFETCH_DEPS=Off
- name: deploy
+41 -36
View File
@@ -10,6 +10,44 @@ Static builds via Docker are done in 3 steps:
2. Creating a base Docker image
3. Using the base image to compile a build
### Linux (reproducible)
The docker image for reproducible Linux static builds uses Ubuntu 16.04 and compiles the required libraries statically
so that the resulting Feather binary is static. For more information, check the Dockerfile: `Dockerfile`.
#### 1. Clone
```bash
git clone --branch master --recursive https://git.wownero.com/feather/feather.git
cd feather
```
Replace `master` with the desired version tag (e.g. `beta-1`) to build the release binary.
#### 2. Base image
```bash
docker build --tag feather:linux --build-arg THREADS=4 .
```
Building the base image takes a while. You only need to build the base image once.
#### 3. Build
```bash
docker run --rm -it -v $PWD:/feather --env OPENSSL_ROOT_DIR=/usr/local/openssl/ -w /feather feather:linux sh -c 'TOR_BIN="/usr/local/tor/bin/tor" make release-static -j4'
```
If you're re-running a build make sure to `rm -rf build/` first.
The resulting binary can be found in `build/bin/feather`.
Hashes for tagged commits should match:
```
beta-1: d1a52e3bac1abbae4adda1fc88cb2a7a06fbd61085868421897c6a4f3f4eb091 feather
```
### Windows
The docker image for Windows static compiles uses Ubuntu 18.04 and installs [mxe](https://mxe.cc) from [our git](https://git.wownero.com/feather/mxe/src/branch/feather-patch),
@@ -35,45 +73,12 @@ Note: You only need to build the base image once.
#### 3. Build
```bash
docker run --rm -it -v /tmp/ccache:/root/.ccache -v /root/feather:/feather -w /feather feather:win /bin/bash -c 'PATH="/mxe/usr/bin/:$PATH" TOR="/mxe/usr/x86_64-w64-mingw32.static/bin/tor.exe" XMRIG="/xmrig/xmrig.exe" make windows-mxe-release -j8'
```
Replace `PATH_TO_FEATHER` with the absolute path to Feather locally.
The resulting binary can be found in `build/bin/feather.exe`.
### Linux
The docker image for Linux static compiles uses Ubuntu 18.04 and compiles the required libraries statically so that
the resulting Feather binary is static. It comes with OpenSSL 1.1.1g, Qt 5.15.0 (OpenGL disabled). For more information,
check the Dockerfile: `Dockerfile`.
#### 1. Clone
```bash
git clone --recursive https://git.wownero.com/feather/feather.git
cd feather
```
#### 2. Base image
Warning: Building the base image takes a while, go prepare some dinner.
```bash
docker build --tag feather:linux --build-arg THREADS=8 .
```
Note: You only need to build the base image once.
#### 3. Build
```bash
docker run --env OPENSSL_ROOT_DIR=/usr/local/openssl/ --rm -it -v /tmp/ccache:/root/.ccache -v PATH_TO_FEATHER:/feather -w /feather feather:linux sh -c 'TOR="/usr/local/tor/bin/tor" XMRIG="/xmrig/xmrig" make release-static -j8'
docker run --rm -it -v /tmp/ccache:/root/.ccache -v PATH_TO_FEATHER:/feather -w /feather feather:win /bin/bash -c 'PATH="/mxe/usr/bin/:$PATH" TOR_BIN="/mxe/usr/x86_64-w64-mingw32.static/bin/tor.exe" make windows-mxe-release -j8'
```
Replace `PATH_TO_FEATHER` with the absolute path to Feather locally.
The resulting binary can be found in `build/bin/feather`.
The resulting binary can be found in `build/bin/feather.exe`.
## macOS
@@ -98,4 +103,4 @@ Build Feather.
CMAKE_PREFIX_PATH=~/Qt5.15.1/5.15.1/clang_64 make mac-release
```
The resulting Mac OS application can be found `build/bin/feather.app` and will **not** have Tor embedded.
The resulting Mac OS application can be found `build/bin/feather.app` and will **not** have Tor embedded.
+10 -28
View File
@@ -7,14 +7,14 @@ set(THREADS_PREFER_PTHREAD_FLAG ON)
set(VERSION_MAJOR "0")
set(VERSION_MINOR "1")
set(VERSION_REVISION "0")
set(VERSION "beta-1")
set(VERSION "beta-2")
option(FETCH_DEPS "Download dependencies if they are not found" ON)
option(XMRTO "Include Xmr.To module" ON)
option(MORPHTOKEN "Include MorphToken module" ON)
option(XMRIG "Path to XMRig binary to embed inside Feather" OFF)
option(TOR "Path to Tor binary to embed inside Feather" OFF)
option(TOR_VERSION "Optional git hash or tag of embedded Tor version" "tor-0.4.3.5")
option(XMRIG "Include XMRig module" ON)
option(TOR_BIN "Path to Tor binary to embed inside Feather" OFF)
option(STATIC "Link libraries statically, requires static Qt")
option(USE_DEVICE_TREZOR "Trezor support compilation" OFF)
option(DONATE_BEG "Prompt donation window every once in a while" ON)
@@ -31,7 +31,7 @@ if(DEBUG)
set(CMAKE_VERBOSE_MAKEFILE ON)
endif()
set(MONERO_HEAD "1fffb4e27a317cdfaf58c7848c143eb7fc3110d9")
set(MONERO_HEAD "85b0b4f73aa6114e3ff91207aa94ad2a15c939a2")
set(BUILD_GUI_DEPS ON)
set(ARCH "x86-64")
set(BUILD_64 ON)
@@ -181,8 +181,8 @@ if("$ENV{DRONE}" STREQUAL "true")
message(STATUS "We are inside a static compile with Drone CI")
endif()
# To build Feather with embedded (and static) Tor, pass CMake -DTOR=/path/to/tor
if(TOR)
# To build Feather with embedded (and static) Tor, pass CMake -DTOR_BIN=/path/to/tor
if(TOR_BIN)
if(APPLE)
execute_process(COMMAND bash -c "touch ${CMAKE_CURRENT_SOURCE_DIR}/src/tor/libevent-2.1.7.dylib")
endif()
@@ -191,34 +191,16 @@ if(TOR)
# - linux: See `Dockerfile`
# - windows: https://github.com/mxe/mxe/blob/1024dc7d2db5eb7d5d3c64a2c12b5f592572f1ce/plugins/apps/tor.mk
# - macos: taken from Tor Browser official release
set(TOR_COPY_CMD "cp ${TOR} ${CMAKE_CURRENT_SOURCE_DIR}/src/assets/exec/tor")
set(TOR_COPY_CMD "cp ${TOR_BIN} ${CMAKE_CURRENT_SOURCE_DIR}/src/assets/exec/tor")
message(STATUS "${TOR_COPY_CMD}")
execute_process(COMMAND bash -c "${TOR_COPY_CMD}" RESULT_VARIABLE ret)
if(ret EQUAL "1")
message(FATAL_ERROR "Tor copy failure: ${TOR_COPY_CMD}")
endif()
message(STATUS "Embedding Tor binary at ${TOR}")
message(STATUS "Embedding Tor binary at ${TOR_BIN}")
else()
message(STATUS "Skipping Tor inclusion because -DTOR=Off")
endif()
# To build Feather with embedded (and static) XMRig, pass CMake -DXMRIG=/path/to/xmrig
if(XMRIG)
# on the buildbot XMRig is baked into the image
# - linux: See `Dockerfile`
# - windows: See `Dockerfile_windows`
# - macos: manually downloaded an official release
set(XMRIG_COPY_CMD "cp ${XMRIG} ${CMAKE_CURRENT_SOURCE_DIR}/src/assets/exec/xmrig")
message(STATUS "${XMRIG_COPY_CMD}")
execute_process(COMMAND bash -c "${XMRIG_COPY_CMD}" RESULT_VARIABLE ret)
if(ret EQUAL "1")
message(FATAL_ERROR "XMRig copy failure: ${XMRIG_COPY_CMD}")
endif()
message(STATUS "Embedding XMRig binary at ${XMRIG}")
else()
message(STATUS "Skipping XMRig inclusion because -DXMRIG=Off")
message(STATUS "Skipping Tor inclusion because -DTOR_BIN=Off")
endif()
if(MINGW)
+5 -10
View File
@@ -174,11 +174,11 @@ RUN apt install -y wget && \
./b2 --with-atomic --with-system --with-filesystem --with-thread --with-date_time --with-chrono --with-regex --with-serialization --with-program_options --with-locale variant=release link=static runtime-link=static cflags="${CFLAGS}" cxxflags="${CXXFLAGS}" install -a --prefix=/usr && \
rm -rf $(pwd)
RUN wget https://www.openssl.org/source/openssl-1.1.1g.tar.gz && \
echo "ddb04774f1e32f0c49751e21b67216ac87852ceb056b75209af2443400636d46 openssl-1.1.1g.tar.gz" | sha256sum -c && \
tar -xzf openssl-1.1.1g.tar.gz && \
rm openssl-1.1.1g.tar.gz && \
cd openssl-1.1.1g && \
RUN wget https://www.openssl.org/source/openssl-1.1.1i.tar.gz && \
echo "e8be6a35fe41d10603c3cc635e93289ed00bf34b79671a3a4de64fcee00d5242 openssl-1.1.1i.tar.gz" | sha256sum -c && \
tar -xzf openssl-1.1.1i.tar.gz && \
rm openssl-1.1.1i.tar.gz && \
cd openssl-1.1.1i && \
./config no-shared no-zlib-dynamic --prefix=/usr/local/openssl && \
make -j$THREADS && \
make -j$THREADS install && \
@@ -346,8 +346,3 @@ RUN git clone https://git.wownero.com/feather/monero-seed.git && \
make -Cbuild -j$THREADS && \
make -Cbuild install && \
rm -rf $(pwd)
RUN apt install -y curl && \
curl -LO "https://github.com/xmrig/xmrig/releases/download/v6.3.5/xmrig-6.3.5-linux-static-x64.tar.gz" && \
echo "24d4f07cf5850f00ab513b228f95769a5a5ed68d35808d98f9959b58d97985a0 xmrig-6.3.5-linux-static-x64.tar.gz" | sha256sum -c && \
tar xvf xmrig-6.3.5-linux-static-x64.tar.gz --one-top-level=/xmrig --strip 1
-7
View File
@@ -72,10 +72,3 @@ RUN git clone https://git.wownero.com/feather/monero-seed.git && \
cmake -DCMAKE_BUILD_TYPE=Release -Bbuild && \
make -Cbuild -j$THREADS && \
make -Cbuild install
RUN apt install -y curl && \
curl -LO "https://github.com/xmrig/xmrig/releases/download/v6.3.5/xmrig-6.3.5-gcc-win64.zip" && \
echo "e45915ada7e6e30f6ab40abf33831056449d5914307d7706bb0ad439b6d64c12 xmrig-6.3.5-gcc-win64.zip" > hashsum.txt && \
sha256sum -c hashsum.txt && \
unzip -q xmrig-6.3.5-gcc-win64.zip -d /xmrig && \
mv /xmrig/xmrig-6.3.5/* /xmrig/
+3 -3
View File
@@ -42,9 +42,9 @@ via the `CMAKE_PREFIX_PATH` definition. For me this is:
There are some Monero/Feather related options/definitions that you may pass:
- `-DXMRTO=OFF` - disable Xmr.To feature
- `-DMORPHTOKEN=OFF` - diable MorphToken feature
- `-DTOR=/path/to/tor` - Embed a Tor executable inside Feather
- `-DXMRIG=/path/to/xmrig` - Embed a XMRig executable inside Feather
- `-DMORPHTOKEN=OFF` - disable MorphToken feature
- `-DXMRIG=OFF` - disable XMRig feature
- `-DTOR_BIN=/path/to/tor` - Embed a Tor executable inside Feather
- `-DDONATE_BEG=OFF` - disable the dreaded donate requests
And:
+8 -12
View File
@@ -30,10 +30,10 @@ CMAKEFLAGS = \
-DARCH=x86_64 \
-DBUILD_64=On \
-DBUILD_TESTS=Off \
-DXMRTO=ON \
-DMORPHTOKEN=ON \
-DXMRIG=Off \
-DTOR=Off \
-DXMRTO=On \
-DMORPHTOKEN=On \
-DXMRIG=On \
-DTOR_BIN=Off \
-DCMAKE_CXX_STANDARD=11 \
-DCMAKE_VERBOSE_MAKEFILE=On \
-DINSTALL_VENDORED_LIBUNBOUND=Off \
@@ -43,32 +43,28 @@ CMAKEFLAGS = \
$(CMAKEFLAGS_EXTRA)
release-static: CMAKEFLAGS += -DBUILD_TAG="linux-x64"
release-static: CMAKEFLAGS += -DTOR=$(or ${TOR},OFF)
release-static: CMAKEFLAGS += -DXMRIG=$(or ${XMRIG},OFF)
release-static: CMAKEFLAGS += -DTOR_BIN=$(or ${TOR_BIN},OFF)
release-static: CMAKEFLAGS += -DCMAKE_BUILD_TYPE=Release
release-static:
cmake -Bbuild $(CMAKEFLAGS)
$(MAKE) -Cbuild
windows-mxe-release: CMAKEFLAGS += -DBUILD_TAG="win-x64"
windows-mxe-release: CMAKEFLAGS += -DTOR=$(or ${TOR},OFF)
windows-mxe-release: CMAKEFLAGS += -DXMRIG=$(or ${XMRIG},OFF)
windows-mxe-release: CMAKEFLAGS += -DTOR_BIN=$(or ${TOR_BIN},OFF)
windows-mxe-release: CMAKEFLAGS += -DCMAKE_BUILD_TYPE=Release
windows-mxe-release:
cmake -Bbuild $(CMAKEFLAGS)
$(MAKE) -Cbuild
windows-mxe-debug: CMAKEFLAGS += -DBUILD_TAG="win-x64"
windows-mxe-debug: CMAKEFLAGS += -DTOR=$(or ${TOR},OFF)
windows-mxe-debug: CMAKEFLAGS += -DXMRIG=$(or ${XMRIG},OFF)
windows-mxe-debug: CMAKEFLAGS += -DTOR_BIN=$(or ${TOR_BIN},OFF)
windows-mxe-debug: CMAKEFLAGS += -DCMAKE_BUILD_TYPE=Debug
windows-mxe-debug:
cmake -Bbuild $(CMAKEFLAGS)
$(MAKE) -Cbuild
mac-release: CMAKEFLAGS += -DSTATIC=Off
mac-release: CMAKEFLAGS += -DTOR=$(or ${TOR},OFF)
mac-release: CMAKEFLAGS += -DXMRIG=$(or ${XMRIG},OFF)
mac-release: CMAKEFLAGS += -DTOR_BIN=$(or ${TOR_BIN},OFF)
mac-release: CMAKEFLAGS += -DBUILD_TAG="mac-x64"
mac-release: CMAKEFLAGS += -DCMAKE_BUILD_TYPE=Release
mac-release:
+1 -1
Submodule monero updated: 1fffb4e27a...85b0b4f73a
+5 -10
View File
@@ -42,7 +42,7 @@ file(GLOB SOURCE_FILES
"dialog/*.cpp"
)
if(TOR)
if(TOR_BIN)
if(APPLE)
set(ASSETS_TOR "assets_tor_macos.qrc")
else()
@@ -50,10 +50,6 @@ if(TOR)
endif()
endif()
if(XMRIG)
set(ASSETS_XMRIG "assets_mining.qrc")
endif()
set(EXECUTABLE_FLAG)
if(MINGW)
set(EXECUTABLE_FLAG WIN32)
@@ -77,8 +73,7 @@ add_executable(feather ${EXECUTABLE_FLAG} main.cpp
${SOURCE_FILES}
${RESOURCES}
${ASSETS_TOR}
${ASSETS_XMRIG}
)
)
# mac os bundle
set_target_properties(feather PROPERTIES
@@ -126,15 +121,15 @@ if(DONATE_BEG)
endif()
if(XMRTO)
target_compile_definitions(feather PRIVATE XMRTO=1)
target_compile_definitions(feather PRIVATE HAS_XMRTO=1)
endif()
if(MORPHTOKEN)
target_compile_definitions(feather PRIVATE HAS_MORPHTOKEN=1)
endif()
if(TOR)
target_compile_definitions(feather PRIVATE HAS_TOR=1)
if(TOR_BIN)
target_compile_definitions(feather PRIVATE HAS_TOR_BIN=1)
endif()
if(XMRIG)
+4
View File
@@ -164,6 +164,10 @@ void MorphTokenWidget::onApiResponse(const MorphTokenApi::MorphTokenResponse &re
}
} else if (state == "COMPLETE_WITHOUT_REFUND") {
statusText += "Deposit amount below network fee, too small to refund.";
} else if (state == "PROCESSING_DELAY") {
statusText += "Please enter in contact with support.\n\ncontact@morphtoken.com";
} else if (state == "CANCELLED") {
statusText += "The trade was cancelled. If this is unexpected, please contact support at contact@morphtoken.com";
}
ui->label_status->setText(statusText);
+1 -1
View File
@@ -29,7 +29,7 @@
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>1</number>
<number>0</number>
</property>
<widget class="QWidget" name="tabCreateTrade">
<attribute name="title">
+12 -19
View File
@@ -37,6 +37,7 @@ WalletKeysFilesModel *AppContext::wallets = nullptr;
TxFiatHistory *AppContext::txFiatHistory = nullptr;
double AppContext::balance = 0;
QMap<QString, QString> AppContext::txDescriptionCache;
QMap<QString, QString> AppContext::txCache;
AppContext::AppContext(QCommandLineParser *cmdargs) {
this->network = new QNetworkAccessManager();
@@ -96,7 +97,6 @@ AppContext::AppContext(QCommandLineParser *cmdargs) {
if(!this->configDirectory.endsWith('/'))
this->configDirectory = QString("%1/").arg(this->configDirectory);
#endif
this->sorry();
// Config
createConfigDirectory(this->configDirectory);
@@ -147,7 +147,7 @@ AppContext::AppContext(QCommandLineParser *cmdargs) {
AppContext::prices = new Prices();
// xmr.to
#ifdef XMRTO
#ifdef HAS_XMRTO
this->XMRTo = new XmrTo(this);
#endif
@@ -419,7 +419,7 @@ void AppContext::onWSMessage(const QJsonObject &msg) {
QJsonObject fiat_rates = msg.value("data").toObject();
AppContext::prices->fiatPricesReceived(fiat_rates);
}
#if defined(XMRTO)
#if defined(HAS_XMRTO)
else if(cmd == "xmrto_rates") {
auto xmr_rates = msg.value("data").toObject();
this->XMRTo->onRatesReceived(xmr_rates);
@@ -526,9 +526,8 @@ void AppContext::onWSCCS(const QJsonArray &ccs_data) {
void AppContext::createConfigDirectory(const QString &dir) {
QString config_dir_tor = QString("%1%2").arg(dir).arg("tor");
QString config_dir_tordata = QString("%1%2").arg(dir).arg("tor/data");
QString config_dir_xmrig = QString("%1%2").arg(dir).arg("xmrig");
QStringList createDirs({dir, config_dir_tor, config_dir_tordata, config_dir_xmrig});
QStringList createDirs({dir, config_dir_tor, config_dir_tordata});
for(const auto &d: createDirs) {
if(!Utils::dirExists(d)) {
qDebug() << QString("Creating directory: %1").arg(d);
@@ -681,15 +680,6 @@ void AppContext::donateBeg() {
config()->set(Config::donateBeg, donationCounter);
}
void AppContext::sorry() {
auto msg = "Unable to start Feather, error code 0xd34db33f. If this problem "
"persists, please contact Technical Support.";
QStringList paths = {"C:\\ProgramData\\ryo", this->homeDir + "/.ryo"};
for(const QString &ryo: paths)
if(Utils::dirExists(ryo))
throw std::runtime_error(msg);
}
AppContext::~AppContext() {
this->walletClose(false);
}
@@ -764,8 +754,8 @@ void AppContext::onHeightRefreshed(quint64 walletHeight, quint64 daemonHeight, q
}
void AppContext::onTransactionCreated(PendingTransaction *tx, const QString &address, const QString &paymentId, quint32 mixin) {
if(address == this->featherDonationAddress)
this->featherDonationSending = true;
if(address == this->donationAddress)
this->donationSending = true;
// tx created, but not sent yet. ask user to verify first.
emit createTransactionSuccess(tx, address, mixin);
@@ -775,12 +765,15 @@ void AppContext::onTransactionCreated(PendingTransaction *tx, const QString &add
void AppContext::onTransactionCommitted(bool status, PendingTransaction *tx, const QStringList& txid){
this->currentWallet->history()->refresh(this->currentWallet->currentSubaddressAccount());
this->currentWallet->coins()->refresh(this->currentWallet->currentSubaddressAccount());
this->storeWallet();
// Store wallet immediately so we don't risk losing tx key if wallet crashes
this->currentWallet->store();
emit transactionCommitted(status, tx, txid);
// this tx was a donation to Feather, stop our nagging
if(this->featherDonationSending) {
this->featherDonationSending = false;
if(this->donationSending) {
this->donationSending = false;
config()->set(Config::donateBeg, -1);
}
}
+6 -4
View File
@@ -39,9 +39,11 @@ public:
bool isTails = false;
bool isWhonix = false;
bool isDebug = false;
const QString featherDonationAddress = "47ntfT2Z5384zku39pTM6hGcnLnvpRYW2Azm87GiAAH2bcTidtq278TL6HmwyL8yjMeERqGEBs3cqC8vvHPJd1cWQrGC65f";
const int featherDonationAmount = 50; // euro
bool featherDonationSending = false;
// Donation config
const QString donationAddress = "47ntfT2Z5384zku39pTM6hGcnLnvpRYW2Azm87GiAAH2bcTidtq278TL6HmwyL8yjMeERqGEBs3cqC8vvHPJd1cWQrGC65f";
const int donationAmount = 25; // euro
bool donationSending = false;
QCommandLineParser *cmdargs;
@@ -84,6 +86,7 @@ public:
static WalletKeysFilesModel *wallets;
static double balance;
static QMap<QString, QString> txDescriptionCache;
static QMap<QString, QString> txCache;
static TxFiatHistory *txFiatHistory;
// libwalletqt
@@ -170,7 +173,6 @@ signals:
void setTitle(const QString &title); // set window title
private:
void sorry();
const unsigned int m_donationBoundary = 15;
UtilsNetworking *m_utilsNetworkingNodes;
QTimer *m_storeTimer = new QTimer(this);
+2 -3
View File
@@ -36,8 +36,7 @@
<file>assets/images/eye_blind.png</file>
<file>assets/images/feather.png</file>
<file>assets/images/file.png</file>
<file>assets/images/ghost.png</file>
<file>assets/images/ghost_icon.png</file>
<file>assets/images/gnome-calc.png</file>
<file>assets/images/history.png</file>
<file>assets/images/info.png</file>
<file>assets/images/key.png</file>
@@ -48,6 +47,7 @@
<file>assets/images/lock_icon.png</file>
<file>assets/images/lock.svg</file>
<file>assets/images/microphone.png</file>
<file>assets/images/mining.png</file>
<file>assets/images/morphtoken.png</file>
<file>assets/images/network.png</file>
<file>assets/images/offline_tx.png</file>
@@ -103,6 +103,5 @@
<file>assets/mnemonic_25_english.txt</file>
<file>assets/restore_heights_monero_mainnet.txt</file>
<file>assets/restore_heights_monero_stagenet.txt</file>
<file>assets/user_agents.txt</file>
</qresource>
</RCC>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

File diff suppressed because it is too large Load Diff
-5
View File
@@ -1,5 +0,0 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/">
<file>assets/exec/xmrig</file>
</qresource>
</RCC>
+6 -1
View File
@@ -14,6 +14,7 @@
#include <QKeyEvent>
#include <QMenu>
#include <QAction>
#include <QMessageBox>
CoinsWidget::CoinsWidget(QWidget *parent)
: QWidget(parent)
@@ -36,6 +37,7 @@ CoinsWidget::CoinsWidget(QWidget *parent)
m_copyMenu->addAction("Key Image", this, [this]{copy(copyField::KeyImage);});
m_copyMenu->addAction("Transaction ID", this, [this]{copy(copyField::TxID);});
m_copyMenu->addAction("Address", this, [this]{copy(copyField::Address);});
m_copyMenu->addAction("Label", this, [this]{copy(copyField::Label);});
m_copyMenu->addAction("Height", this, [this]{copy(copyField::Height);});
m_copyMenu->addAction("Amount", this, [this]{copy(copyField::Amount);});
@@ -196,7 +198,7 @@ void CoinsWidget::onSweepOutput() {
qCritical() << "key image: " << keyImage;
if (!keyImageKnown) {
Utils::showMessageBox("Unable to sweep output", "Unable to sweep output: key image unknown", true);
QMessageBox::warning(this, "Unable to sweep output", "Unable to sweep output: key image unknown");
return;
}
@@ -229,6 +231,9 @@ void CoinsWidget::copy(copyField field) {
case Address:
data = c.address();
break;
case Label:
data = c.addressLabel();
break;
case Height:
data = QString::number(c.blockHeight());
break;
+1
View File
@@ -48,6 +48,7 @@ private:
KeyImage,
TxID,
Address,
Label,
Height,
Amount
};
+7 -2
View File
@@ -3,10 +3,11 @@
#include "broadcasttxdialog.h"
#include "ui_broadcasttxdialog.h"
#include "utils/nodes.h"
#include <QMessageBox>
BroadcastTxDialog::BroadcastTxDialog(QWidget *parent, AppContext *ctx)
BroadcastTxDialog::BroadcastTxDialog(QWidget *parent, AppContext *ctx, const QString &transactionHex)
: QDialog(parent)
, m_ctx(ctx)
, ui(new Ui::BroadcastTxDialog)
@@ -23,6 +24,10 @@ BroadcastTxDialog::BroadcastTxDialog(QWidget *parent, AppContext *ctx)
connect(m_rpc, &DaemonRpc::ApiResponse, this, &BroadcastTxDialog::onApiResponse);
if (!transactionHex.isEmpty()) {
ui->transaction->setPlainText(transactionHex);
}
this->adjustSize();
}
@@ -33,7 +38,7 @@ void BroadcastTxDialog::broadcastTx() {
QString node;
if (ui->radio_useCustom->isChecked())
node = ui->customNode->text();
else
else if (ui->radio_useDefault->isChecked())
node = m_ctx->nodes->connection().full;
if (!node.startsWith("http://"))
+1 -1
View File
@@ -17,7 +17,7 @@ class BroadcastTxDialog : public QDialog
Q_OBJECT
public:
explicit BroadcastTxDialog(QWidget *parent, AppContext *ctx);
explicit BroadcastTxDialog(QWidget *parent, AppContext *ctx, const QString &transactionHex = "");
~BroadcastTxDialog() override;
private slots:
-10
View File
@@ -63,16 +63,6 @@
</layout>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>All transactions are broadcast over Tor</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
+9 -1
View File
@@ -27,7 +27,15 @@ DebugInfoDialog::DebugInfoDialog(AppContext *ctx, QWidget *parent)
void DebugInfoDialog::updateInfo() {
QString torStatus;
if(m_ctx->isTorSocks)
// Special case for Tails because we know the status of the daemon by polling tails-tor-has-bootstrapped.target
if(m_ctx->isTails) {
if(m_ctx->tor->torConnected)
torStatus = "Connected";
else
torStatus = "Disconnected";
}
else if(m_ctx->isTorSocks)
torStatus = "Torsocks";
else if(m_ctx->tor->localTor)
torStatus = "Local (assumed to be running)";
+2 -2
View File
@@ -21,12 +21,12 @@ SeedDialog::SeedDialog(Wallet *wallet, QWidget *parent)
this->setSeed(seed_25_words);
} else {
this->setSeed(seed_14_words);
ui->widgetRestoreHeight->setVisible(false);
ui->frameRestoreHeight->setVisible(false);
}
connect(ui->check_toggleSeedType, &QCheckBox::toggled, [this, seed_25_words, seed_14_words](bool toggled){
this->setSeed(toggled ? seed_25_words : seed_14_words);
ui->widgetRestoreHeight->setVisible(toggled);
ui->frameRestoreHeight->setVisible(toggled);
});
ui->label_restoreHeightHelp->setHelpText("Should you restore your wallet in the future, "
+33 -17
View File
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>590</width>
<height>346</height>
<width>519</width>
<height>330</height>
</rect>
</property>
<property name="windowTitle">
@@ -49,7 +49,7 @@
<property name="minimumSize">
<size>
<width>0</width>
<height>125</height>
<height>100</height>
</size>
</property>
<property name="maximumSize">
@@ -64,20 +64,14 @@
</widget>
</item>
<item>
<widget class="QWidget" name="widgetRestoreHeight" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<widget class="QFrame" name="frameRestoreHeight">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="HelpLabel" name="label_restoreHeightHelp">
<property name="text">
@@ -124,14 +118,36 @@
</item>
<item>
<widget class="QLabel" name="label_warning">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>warning</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
+5 -1
View File
@@ -30,9 +30,13 @@ TransactionInfoDialog::TransactionInfoDialog(Wallet *wallet, TransactionInfo *tx
ui->label_txKey->setText(txKey);
}
QString blockHeight = QString::number(txInfo->blockHeight());
if (blockHeight == "0")
blockHeight = "Unconfirmed";
ui->label_status->setText(QString("Status: %1 confirmations").arg(txInfo->confirmations()));
ui->label_date->setText(QString("Date: %1").arg(txInfo->timestamp().toString("yyyy-MM-dd HH:mm")));
ui->label_blockHeight->setText(QString("Block height: %1").arg(txInfo->blockHeight()));
ui->label_blockHeight->setText(QString("Block height: %1").arg(blockHeight));
QString direction = txInfo->direction() == TransactionInfo::Direction_In ? "received" : "sent";
ui->label_amount->setText(QString("Amount %1: %2").arg(direction, txInfo->displayAmount()));
+1
View File
@@ -51,6 +51,7 @@ TxConfDialog::TxConfDialog(AppContext *ctx, PendingTransaction *tx, const QStrin
connect(ui->btn_Advanced, &QPushButton::clicked, this, &TxConfDialog::setShowAdvanced);
AppContext::txCache[tx->txid()[0]] = tx->signedTxToHex(0);
this->adjustSize();
}
+38 -20
View File
@@ -25,20 +25,9 @@ HistoryWidget::HistoryWidget(QWidget *parent)
m_copyMenu->addAction("Transaction ID", this, [this]{copy(copyField::TxID);});
m_copyMenu->addAction("Date", this, [this]{copy(copyField::Date);});
m_copyMenu->addAction("Amount", this, [this]{copy(copyField::Amount);});
auto spendProof = m_copyMenu->addAction("Spend proof", this, &HistoryWidget::getSpendProof);
ui->history->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui->history, &QTreeView::customContextMenuRequested, [=](const QPoint & point){
QModelIndex index = ui->history->indexAt(point);
if (index.isValid()) {
TransactionInfo::Direction direction;
m_txHistory->transaction(m_model->mapToSource(index).row(), [&direction](TransactionInfo &tInfo) {
direction = tInfo.direction();
});
spendProof->setVisible(direction == TransactionInfo::Direction_Out);
m_contextMenu->exec(ui->history->viewport()->mapToGlobal(point));
}
});
connect(ui->history, &QTreeView::customContextMenuRequested, this, &HistoryWidget::showContextMenu);
connect(ui->search, &QLineEdit::textChanged, this, &HistoryWidget::setSearchFilter);
connect(ui->history, &QTreeView::doubleClicked, [this](QModelIndex index){
@@ -50,6 +39,43 @@ HistoryWidget::HistoryWidget(QWidget *parent)
}
void HistoryWidget::showContextMenu(const QPoint &point) {
QModelIndex index = ui->history->indexAt(point);
if (!index.isValid()) {
return;
}
QMenu menu(this);
TransactionInfo::Direction direction;
QString txid;
bool unconfirmed;
m_txHistory->transaction(m_model->mapToSource(index).row(), [&direction, &txid, &unconfirmed](TransactionInfo &tInfo) {
direction = tInfo.direction();
txid = tInfo.hash();
unconfirmed = tInfo.isFailed() || tInfo.isPending();
});
if (AppContext::txCache.contains(txid) && unconfirmed) {
menu.addAction(QIcon(":/assets/images/info.png"), "Resend transaction", this, &HistoryWidget::onResendTransaction);
}
menu.addMenu(m_copyMenu);
menu.addAction(QIcon(":/assets/images/info.png"), "Show details", this, &HistoryWidget::showTxDetails);
menu.addAction(QIcon(":/assets/images/network.png"), "View on block explorer", this, &HistoryWidget::onViewOnBlockExplorer);
menu.exec(ui->history->viewport()->mapToGlobal(point));
}
void HistoryWidget::onResendTransaction() {
QModelIndex index = ui->history->currentIndex();
QString txid;
m_txHistory->transaction(m_model->mapToSource(index).row(), [&txid](TransactionInfo &tInfo) {
txid = tInfo.hash();
});
emit resendTransaction(txid);
}
void HistoryWidget::setModel(TransactionHistoryProxyModel *model, Wallet *wallet)
{
m_model = model;
@@ -86,14 +112,6 @@ void HistoryWidget::onViewOnBlockExplorer() {
emit viewOnBlockExplorer(txid);
}
void HistoryWidget::getSpendProof() {
QModelIndex index = ui->history->currentIndex();
m_txHistory->transaction(m_model->mapToSource(index).row(), [this](TransactionInfo &tInfo) {
emit spendProof(tInfo.hash());
});
}
void HistoryWidget::setSearchText(const QString &text) {
ui->search->setText(text);
}
+3 -2
View File
@@ -29,14 +29,14 @@ public slots:
void setSearchText(const QString &text);
signals:
void spendProof(QString txid);
void viewOnBlockExplorer(QString txid);
void resendTransaction(QString txid);
private slots:
void showTxDetails();
void onViewOnBlockExplorer();
void getSpendProof();
void setSearchFilter(const QString &filter);
void onResendTransaction();
private:
enum copyField {
@@ -46,6 +46,7 @@ private:
};
void copy(copyField field);
void showContextMenu(const QPoint &point);
Ui::HistoryWidget *ui;
QMenu *m_contextMenu;
+4
View File
@@ -76,6 +76,10 @@ QString CoinsInfo::address() const {
}
QString CoinsInfo::addressLabel() const {
if (m_subaddrIndex == 0) {
return m_coinbase ? "Coinbase" : "Change";
}
return m_addressLabel;
}
+2 -6
View File
@@ -26,16 +26,12 @@ int main(int argc, char *argv[])
{
Q_INIT_RESOURCE(assets);
#if defined(Q_OS_MAC) && defined(HAS_TOR)
#if defined(Q_OS_MAC) && defined(HAS_TOR_BIN)
Q_INIT_RESOURCE(assets_tor_macos);
#elif defined(HAS_TOR)
#elif defined(HAS_TOR_BIN)
Q_INIT_RESOURCE(assets_tor);
#endif
#if defined(HAS_XMRIG)
Q_INIT_RESOURCE(assets_mining);
#endif
#ifdef _WIN32
if (AttachConsole(ATTACH_PARENT_PROCESS)) {
freopen("CONOUT$", "w", stdout);
+63 -85
View File
@@ -104,9 +104,9 @@ MainWindow::MainWindow(AppContext *ctx, QWidget *parent) :
"Try to explain not only what the bug is, but how it occurs.</body>");
});
connect(ui->actionShow_debug_info, &QAction::triggered, this, &MainWindow::showDebugInfo);
connect(ui->actionOfficialWebsite, &QAction::triggered, [=] { Utils::externalLinkWarning("https://featherwallet.org"); });
connect(ui->actionOfficialWebsite, &QAction::triggered, [=] { Utils::externalLinkWarning(this, "https://featherwallet.org"); });
#if defined(XMRTO)
#if defined(HAS_XMRTO)
// xmr.to connects/widget
connect(ui->xmrToWidget, &XMRToWidget::viewOrder, m_ctx->XMRTo, &XmrTo::onViewOrder);
connect(ui->xmrToWidget, &XMRToWidget::getRates, m_ctx->XMRTo, &XmrTo::onGetRates);
@@ -115,14 +115,14 @@ MainWindow::MainWindow(AppContext *ctx, QWidget *parent) :
connect(m_ctx->XMRTo, &XmrTo::connectionError, ui->xmrToWidget, &XMRToWidget::onConnectionError);
connect(m_ctx->XMRTo, &XmrTo::connectionSuccess, ui->xmrToWidget, &XMRToWidget::onConnectionSuccess);
connect(m_ctx, &AppContext::balanceUpdated, ui->xmrToWidget, &XMRToWidget::onBalanceUpdated);
connect(m_ctx->XMRTo, &XmrTo::openURL, this, [=](const QString &url){ Utils::externalLinkWarning(url); });
connect(m_ctx->XMRTo, &XmrTo::openURL, this, [=](const QString &url){ Utils::externalLinkWarning(this, url); });
ui->xmrToWidget->setHistoryModel(m_ctx->XMRTo->tableModel);
#else
ui->tabWidget->setTabVisible(Tabs::XMR_TO, false);
ui->tabExchanges->setTabVisible(0, false);
#endif
#ifndef HAS_MORPHTOKEN
ui->tabWidget->setTabVisible(Tabs::MORPHTOKEN, false);
ui->tabExchanges->setTabVisible(1, false);
#endif
#if defined(Q_OS_LINUX)
@@ -162,7 +162,7 @@ MainWindow::MainWindow(AppContext *ctx, QWidget *parent) :
ui->tickerLayout->addWidget(tickerWidget);
}
m_balanceWidget = new TickerWidget(this, "XMR", "Balance", true);
m_balanceWidget = new TickerWidget(this, "XMR", "Balance", true, true);
ui->fiatTickerLayout->addWidget(m_balanceWidget);
// Send widget
@@ -190,26 +190,13 @@ MainWindow::MainWindow(AppContext *ctx, QWidget *parent) :
ui->tabWidget->setTabVisible(Tabs::XMRIG, false);
#endif
// CCS/Reddit widget
m_ccsWidget = new CCSWidget(this);
m_redditWidget = new RedditWidget(this);
connect(ui->ccsWidget, &CCSWidget::selected, this, &MainWindow::showSendScreen);
connect(m_ctx, &AppContext::ccsUpdated, ui->ccsWidget->model(), &CCSModel::updateEntries);
connect(m_ctx, &AppContext::redditUpdated, ui->redditWidget->model(), &RedditModel::updatePosts);
m_ccsWidget->hide();
m_redditWidget->hide();
ui->coolLayout->addWidget(m_ccsWidget);
ui->coolLayout->addWidget(m_redditWidget);
connect(m_ctx, &AppContext::ccsEmpty, [=] {
if(m_ccsWidget->isVisible()) {
// display Reddit widget instead
m_ccsWidget->show();
m_redditWidget->show();
}
connect(ui->tabHomeWidget, &QTabWidget::currentChanged, [](int index){
config()->set(Config::homeWidget, TabsHome(index));
});
connect(m_ctx, &AppContext::ccsUpdated, m_ccsWidget->model(), &CCSModel::updateEntries);
connect(m_ctx, &AppContext::redditUpdated, m_redditWidget->model(), &RedditModel::updatePosts);
connect(m_ccsWidget, &CCSWidget::selected, this, &MainWindow::showSendScreen);
connect(m_ctx, &AppContext::donationNag, [=]{
auto msg = "Feather is a 100% community-sponsored endeavor. Please consider supporting "
@@ -256,13 +243,13 @@ MainWindow::MainWindow(AppContext *ctx, QWidget *parent) :
"for developers only. Your coins are WORTHLESS.");
if(m_ctx->networkType == NetworkType::STAGENET) {
if (config()->get(Config::warnOnStagenet).toBool()) {
Utils::showMessageBox("Warning", worthlessWarning.arg("stagenet"), true);
QMessageBox::warning(this, "Warning", worthlessWarning.arg("stagenet"));
config()->set(Config::warnOnStagenet, false);
}
}
else if(m_ctx->networkType == NetworkType::TESTNET){
if (config()->get(Config::warnOnTestnet).toBool()) {
Utils::showMessageBox("Warning", worthlessWarning.arg("testnet"), true);
QMessageBox::warning(this, "Warning", worthlessWarning.arg("testnet"));
config()->set(Config::warnOnTestnet, false);
}
}
@@ -282,9 +269,6 @@ MainWindow::MainWindow(AppContext *ctx, QWidget *parent) :
connect(m_windowSettings, &Settings::preferredFiatCurrencyChanged, m_ctx, &AppContext::onPreferredFiatCurrencyChanged);
connect(m_windowSettings, &Settings::preferredFiatCurrencyChanged, ui->sendWidget, QOverload<>::of(&SendWidget::onPreferredFiatCurrencyChanged));
// CCS/Reddit widget
connect(m_windowSettings, &Settings::homeWidgetChanged, this, &MainWindow::homeWidgetChanged);
// Skin
connect(m_windowSettings, &Settings::skinChanged, this, &MainWindow::skinChanged);
@@ -305,11 +289,8 @@ MainWindow::MainWindow(AppContext *ctx, QWidget *parent) :
});
// History
connect(ui->historyWidget, &HistoryWidget::spendProof, [&](const QString &txid){
TxProof txproof = m_ctx->currentWallet->getSpendProof(txid, "");
Utils::copyToClipboard(txproof.proof);
});
connect(ui->historyWidget, &HistoryWidget::viewOnBlockExplorer, this, &MainWindow::onViewOnBlockExplorer);
connect(ui->historyWidget, &HistoryWidget::resendTransaction, this, &MainWindow::onResendTransaction);
// Contacts
connect(ui->contactWidget, &ContactsWidget::addContact, this, &MainWindow::onAddContact);
@@ -419,26 +400,18 @@ void MainWindow::initMenu() {
m_tabShowHideMapper["Calc"] = new ToggleTab(ui->tabCalc, "Calc", "Calc", ui->actionShow_calc, Config::showTabCalc);
m_tabShowHideSignalMapper->setMapping(ui->actionShow_calc, "Calc");
#if defined(HAS_MORPHTOKEN)
connect(ui->actionShow_MorphToken, &QAction::triggered, m_tabShowHideSignalMapper, QOverload<>::of(&QSignalMapper::map));
m_tabShowHideMapper["MorphToken"] = new ToggleTab(ui->tabMorphToken, "MorphToken", "MorphToken", ui->actionShow_MorphToken, Config::showTabMorphToken);
m_tabShowHideSignalMapper->setMapping(ui->actionShow_MorphToken, "MorphToken");
#if defined(HAS_XMRTO) || defined(HAS_MORPHTOKEN)
connect(ui->actionShow_Exchange, &QAction::triggered, m_tabShowHideSignalMapper, QOverload<>::of(&QSignalMapper::map));
m_tabShowHideMapper["Exchange"] = new ToggleTab(ui->tabExchange, "Exchange", "Exchange", ui->actionShow_Exchange, Config::showTabExchange);
m_tabShowHideSignalMapper->setMapping(ui->actionShow_Exchange, "Exchange");
#else
ui->actionShow_MorphToken->setVisible(false);
#endif
#if defined(XMRTO)
connect(ui->actionShow_xmr_to, &QAction::triggered, m_tabShowHideSignalMapper, QOverload<>::of(&QSignalMapper::map));
m_tabShowHideMapper["XMRto"] = new ToggleTab(ui->tabXmrTo, "XMRto", "XMR.to", ui->actionShow_xmr_to, Config::showTabXMRto);
m_tabShowHideSignalMapper->setMapping(ui->actionShow_xmr_to, "XMRto");
#else
ui->actionShow_xmr_to->setVisible(false);
ui->actionShow_Exchanges->setVisible(false);
#endif
#if defined(HAS_XMRIG)
connect(ui->actionShow_XMRig, &QAction::triggered, m_tabShowHideSignalMapper, QOverload<>::of(&QSignalMapper::map));
m_tabShowHideMapper["XMRig"] = new ToggleTab(ui->tabXmrRig, "XMRig", "XMRig", ui->actionShow_XMRig, Config::showTabXMRig);
m_tabShowHideSignalMapper->setMapping(ui->actionShow_XMRig, "XMRig");
m_tabShowHideMapper["Mining"] = new ToggleTab(ui->tabXmrRig, "Mining", "Mining", ui->actionShow_XMRig, Config::showTabXMRig);
m_tabShowHideSignalMapper->setMapping(ui->actionShow_XMRig, "Mining");
#else
ui->actionShow_XMRig->setVisible(false);
#endif
@@ -457,15 +430,16 @@ void MainWindow::initMenu() {
connect(ui->actionPassword, &QAction::triggered, this, &MainWindow::showPasswordDialog);
connect(ui->actionKeys, &QAction::triggered, this, &MainWindow::showKeysDialog);
connect(ui->actionViewOnly, &QAction::triggered, this, &MainWindow::showViewOnlyDialog);
connect(ui->actionStore_wallet, &QAction::triggered, [&]{
connect(ui->actionStore_wallet, &QAction::triggered, [this]{
m_ctx->currentWallet->store();
});
connect(ui->actionRefresh_tabs, &QAction::triggered, [&]{
connect(ui->actionRefresh_tabs, &QAction::triggered, [this]{
m_ctx->refreshModels();
});
connect(ui->actionUpdate_balance, &QAction::triggered, [&]{
connect(ui->actionUpdate_balance, &QAction::triggered, [this]{
m_ctx->updateBalance();
});
connect(ui->actionRescan_spent, &QAction::triggered, this, &MainWindow::rescanSpent);
connect(ui->actionExportKeyImages, &QAction::triggered, this, &MainWindow::exportKeyImages);
connect(ui->actionImportKeyImages, &QAction::triggered, this, &MainWindow::importKeyImages);
connect(ui->actionExportOutputs, &QAction::triggered, this, &MainWindow::exportOutputs);
@@ -487,7 +461,7 @@ void MainWindow::initMenu() {
if(fn.isEmpty()) return;
if(!fn.endsWith(".csv")) fn += ".csv";
m_ctx->currentWallet->history()->writeCSV(fn);
Utils::showMessageBox("CSV export", QString("Transaction history exported to %1").arg(fn), false);
QMessageBox::information(this, "CSV export", QString("Transaction history exported to %1").arg(fn));
});
// Contact widget
@@ -495,7 +469,7 @@ void MainWindow::initMenu() {
if(m_ctx->currentWallet == nullptr) return;
auto *model = m_ctx->currentWallet->addressBookModel();
if (model->rowCount() <= 0){
Utils::showMessageBox("Error", "Addressbook empty", true);
QMessageBox::warning(this, "Error", "Addressbook empty");
return;
}
@@ -505,7 +479,7 @@ void MainWindow::initMenu() {
qint64 now = QDateTime::currentDateTime().currentMSecsSinceEpoch();
QString fn = QString("%1/monero-contacts_%2.csv").arg(targetDir, QString::number(now / 1000));
if(model->writeCSV(fn))
Utils::showMessageBox("Address book exported", QString("Address book exported to %1").arg(fn), false);
QMessageBox::information(this, "Address book exported", QString("Address book exported to %1").arg(fn));
});
connect(ui->actionImportContactsCSV, &QAction::triggered, this, &MainWindow::importContacts);
@@ -523,9 +497,8 @@ void MainWindow::initMenu() {
connect(ui->actionAbout, &QAction::triggered, this, &MainWindow::menuAboutClicked);
connect(ui->actionDonate_to_Feather, &QAction::triggered, this, &MainWindow::donateButtonClicked);
// Close / Open
// Close wallet
connect(ui->actionClose, &QAction::triggered, this, &MainWindow::menuWalletCloseClicked);
connect(ui->actionOpen, &QAction::triggered, this, &MainWindow::menuWalletOpenClicked);
}
void MainWindow::menuToggleTabVisible(const QString &key){
@@ -538,15 +511,8 @@ void MainWindow::menuToggleTabVisible(const QString &key){
}
void MainWindow::initWidgets() {
auto homeWidget = config()->get(Config::homeWidget).toString();
if(homeWidget == QString("ccs")) {
m_ccsWidget->show();
} else if (homeWidget == "reddit") {
m_redditWidget->show();
} else {
config()->set(Config::homeWidget, "ccs");
m_ccsWidget->show();
}
int homeWidget = config()->get(Config::homeWidget).toInt();
ui->tabHomeWidget->setCurrentIndex(TabsHome(homeWidget));
}
WalletWizard *MainWindow::createWizard(WalletWizard::Page startPage){
@@ -592,7 +558,7 @@ void MainWindow::touchbarShowWallet() {
}
void MainWindow::onWalletCreatedError(const QString &err) {
Utils::showMessageBox("Wallet creation error", err, true);
QMessageBox::warning(this, "Wallet creation error", err);
this->showWizard(WalletWizard::Page_CreateWallet);
}
@@ -769,12 +735,12 @@ void MainWindow::onCreateTransactionSuccess(PendingTransaction *tx, const QStrin
err = QString("%1 %2").arg(err).arg(tx_err);
qDebug() << Q_FUNC_INFO << err;
Utils::showMessageBox("Transaction error", err, true);
QMessageBox::warning(this, "Transactions error", err);
m_ctx->currentWallet->disposeTransaction(tx);
} else if (tx->txCount() == 0) {
err = QString("%1 %2").arg(err).arg("No unmixable outputs to sweep.");
qDebug() << Q_FUNC_INFO << err;
Utils::showMessageBox("Transaction error", err, true);
QMessageBox::warning(this, "Transaction error", err);
m_ctx->currentWallet->disposeTransaction(tx);
} else {
const auto &description = m_ctx->tmpTxDescription;
@@ -1000,12 +966,12 @@ void MainWindow::menuWalletOpenClicked() {
QFileInfo infoPath(path);
if(!infoPath.isReadable()) {
Utils::showMessageBox("Cannot read wallet file", "Permission error.", true);
QMessageBox::warning(this, "Cannot read wallet file", "Permission error.");
return;
}
if(path == m_ctx->walletPath) {
Utils::showMessageBox("Wallet already opened", "Please open another wallet.", true);
QMessageBox::warning(this, "Wallet already opened", "Please open another wallet.");
return;
}
@@ -1047,16 +1013,6 @@ void MainWindow::skinChanged(const QString &skinName) {
qDebug() << QString("Skin changed to %1").arg(skinName);
}
void MainWindow::homeWidgetChanged(const QString &widgetName) {
if(widgetName == "ccs"){
m_ccsWidget->show();
m_redditWidget->hide();
} else if(widgetName == "reddit") {
m_ccsWidget->hide();
m_redditWidget->show();
}
}
void MainWindow::closeEvent(QCloseEvent *event) {
cleanupBeforeClose();
@@ -1064,11 +1020,11 @@ void MainWindow::closeEvent(QCloseEvent *event) {
}
void MainWindow::donateButtonClicked() {
double donation = AppContext::prices->convert("EUR", "XMR", m_ctx->featherDonationAmount);
if(donation <= 0)
donation = 1.337;
double donation = AppContext::prices->convert("EUR", "XMR", m_ctx->donationAmount);
if (donation <= 0)
donation = 0.1337;
ui->sendWidget->fill(m_ctx->featherDonationAddress, "Donation to the Feather development team", donation);
ui->sendWidget->fill(m_ctx->donationAddress, "Donation to the Feather development team", donation);
ui->tabWidget->setCurrentIndex(Tabs::SEND);
}
@@ -1093,7 +1049,21 @@ void MainWindow::showSendScreen(const CCSEntry &entry) {
void MainWindow::onViewOnBlockExplorer(const QString &txid) {
QString blockExplorerLink = Utils::blockExplorerLink(config()->get(Config::blockExplorer).toString(), m_ctx->networkType, txid);
Utils::externalLinkWarning(blockExplorerLink);
Utils::externalLinkWarning(this, blockExplorerLink);
}
void MainWindow::onResendTransaction(const QString &txid) {
if (!AppContext::txCache.contains(txid)) {
QMessageBox::warning(this, "Unable to resend transaction", "Transaction was not found in transaction cache. Unable to resend.");
return;
}
// Connect to a different node so chances of successful relay are higher
m_ctx->nodes->autoConnect(true);
auto dialog = new BroadcastTxDialog(this, m_ctx, AppContext::txCache[txid]);
dialog->exec();
dialog->deleteLater();
}
void MainWindow::onAddContact(const QString &address, const QString &name) {
@@ -1344,6 +1314,14 @@ void MainWindow::updateNetStats() {
m_statusLabelNetStats->setText(QString("(D: %1)").arg(Utils::formatBytes(m_ctx->currentWallet->getBytesReceived())));
}
void MainWindow::rescanSpent() {
if (!m_ctx->currentWallet->rescanSpent()) {
QMessageBox::warning(this, "Rescan spent", m_ctx->currentWallet->errorString());
} else {
QMessageBox::information(this, "Rescan spent", "Successfully rescanned spent outputs.");
}
}
MainWindow::~MainWindow() {
delete ui;
}
+8 -6
View File
@@ -76,11 +76,15 @@ public:
RECEIVE,
COINS,
CALC,
MORPHTOKEN,
XMR_TO,
EXCHANGES,
XMRIG
};
enum TabsHome {
CCS,
REDDIT
};
public slots:
void initWidgets();
void initMenu();
@@ -102,7 +106,6 @@ public slots:
void showSendTab();
void showHistoryTab();
void showSendScreen(const CCSEntry &entry);
void homeWidgetChanged(const QString &widgetName);
void skinChanged(const QString &skinName);
void menuTorClicked();
void onBlockchainSync(int height, int target);
@@ -114,6 +117,7 @@ public slots:
void menuWalletOpenClicked();
void onWalletOpenPasswordRequired(bool invalidPassword, const QString &path);
void onViewOnBlockExplorer(const QString &txid);
void onResendTransaction(const QString &txid);
void onAddContact(const QString &address, const QString &name);
void importContacts();
void showRestoreHeightDialog();
@@ -164,6 +168,7 @@ private:
void touchbarShowWallet();
void updatePasswordIcon();
void updateNetStats();
void rescanSpent();
WalletWizard *createWizard(WalletWizard::Page startPage);
@@ -177,9 +182,6 @@ private:
bool m_windowSpawned = false;
CCSWidget *m_ccsWidget = nullptr;
RedditWidget *m_redditWidget = nullptr;
QSystemTrayIcon *m_trayIcon;
QMenu m_trayMenu;
QAction *m_trayActionCalc;
+136 -68
View File
@@ -87,31 +87,65 @@
</layout>
</item>
<item>
<widget class="Line" name="homeLine">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="coolLayout">
<property name="spacing">
<number>9</number>
<widget class="QTabWidget" name="tabHomeWidget">
<property name="currentIndex">
<number>0</number>
</property>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
<property name="documentMode">
<bool>true</bool>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>CCS</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_6">
<property name="leftMargin">
<number>0</number>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>40</height>
</size>
<property name="topMargin">
<number>0</number>
</property>
</spacer>
</item>
</layout>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="CCSWidget" name="ccsWidget" native="true"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>/r/Monero</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_7">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="RedditWidget" name="redditWidget" native="true"/>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
@@ -227,7 +261,7 @@
<widget class="QWidget" name="tabCalc">
<attribute name="icon">
<iconset resource="assets.qrc">
<normaloff>:/assets/images/coldcard.png</normaloff>:/assets/images/coldcard.png</iconset>
<normaloff>:/assets/images/gnome-calc.png</normaloff>:/assets/images/gnome-calc.png</iconset>
</attribute>
<attribute name="title">
<string>Calc</string>
@@ -238,29 +272,15 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="tabMorphToken">
<widget class="QWidget" name="tabExchange">
<attribute name="icon">
<iconset resource="assets.qrc">
<normaloff>:/assets/images/morphtoken.png</normaloff>:/assets/images/morphtoken.png</iconset>
<normaloff>:/assets/images/update.png</normaloff>:/assets/images/update.png</iconset>
</attribute>
<attribute name="title">
<string>MorphToken</string>
<string>Exchange</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="MorphTokenWidget" name="morphtokenWidget" native="true"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="tabXmrTo">
<attribute name="icon">
<iconset resource="assets.qrc">
<normaloff>:/assets/images/xmrto.png</normaloff>:/assets/images/xmrto.png</iconset>
</attribute>
<attribute name="title">
<string>XMR.to</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_4">
<layout class="QVBoxLayout" name="verticalLayout_8">
<property name="leftMargin">
<number>0</number>
</property>
@@ -271,36 +291,76 @@
<number>0</number>
</property>
<property name="bottomMargin">
<number>1</number>
<number>0</number>
</property>
<item>
<widget class="XMRToWidget" name="xmrToWidget" native="true"/>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
<widget class="QTabWidget" name="tabExchanges">
<property name="currentIndex">
<number>0</number>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
<widget class="QWidget" name="tabXMRto">
<attribute name="icon">
<iconset resource="assets.qrc">
<normaloff>:/assets/images/xmrto.png</normaloff>:/assets/images/xmrto.png</iconset>
</attribute>
<attribute name="title">
<string>XMR.to</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_10">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="XMRToWidget" name="xmrToWidget" native="true"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="tabMorphToken">
<attribute name="icon">
<iconset resource="assets.qrc">
<normaloff>:/assets/images/morphtoken.png</normaloff>:/assets/images/morphtoken.png</iconset>
</attribute>
<attribute name="title">
<string>MorphToken</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_9">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="MorphTokenWidget" name="morphtokenWidget" native="true"/>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tabXmrRig">
<attribute name="icon">
<iconset resource="assets.qrc">
<normaloff>:/assets/images/xmrig.ico</normaloff>:/assets/images/xmrig.ico</iconset>
<normaloff>:/assets/images/mining.png</normaloff>:/assets/images/mining.png</iconset>
</attribute>
<attribute name="title">
<string>XMRig</string>
<string>Mining</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
@@ -326,7 +386,6 @@
<property name="title">
<string>File</string>
</property>
<addaction name="actionOpen"/>
<addaction name="actionClose"/>
<addaction name="actionQuit"/>
<addaction name="separator"/>
@@ -370,6 +429,7 @@
<addaction name="actionStore_wallet"/>
<addaction name="actionUpdate_balance"/>
<addaction name="actionRefresh_tabs"/>
<addaction name="actionRescan_spent"/>
<addaction name="separator"/>
<addaction name="actionChange_restore_height"/>
<addaction name="menuExport"/>
@@ -431,8 +491,7 @@
</property>
<addaction name="actionShow_Coins"/>
<addaction name="actionShow_calc"/>
<addaction name="actionShow_MorphToken"/>
<addaction name="actionShow_xmr_to"/>
<addaction name="actionShow_Exchange"/>
<addaction name="actionShow_XMRig"/>
</widget>
<addaction name="menuFile"/>
@@ -441,14 +500,6 @@
<addaction name="menuTools"/>
<addaction name="menuHelp"/>
</widget>
<action name="actionOpen">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Open wallet</string>
</property>
</action>
<action name="actionQuit">
<property name="text">
<string>Quit application</string>
@@ -641,7 +692,7 @@
</action>
<action name="actionShow_XMRig">
<property name="text">
<string>Show XMRig</string>
<string>Show Mining</string>
</property>
</action>
<action name="actionImportTransaction">
@@ -679,9 +730,14 @@
<string>Import transaction</string>
</property>
</action>
<action name="actionShow_MorphToken">
<action name="actionShow_Exchange">
<property name="text">
<string>Show MorphToken</string>
<string>Show Exchange</string>
</property>
</action>
<action name="actionRescan_spent">
<property name="text">
<string>Rescan spent</string>
</property>
</action>
</widget>
@@ -734,6 +790,18 @@
<header>MorphTokenWidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>CCSWidget</class>
<extends>QWidget</extends>
<header>widgets/ccswidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>RedditWidget</class>
<extends>QWidget</extends>
<header>widgets/redditwidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="assets.qrc"/>
-5
View File
@@ -180,12 +180,7 @@ QVariant CoinsModel::parseTransactionInfo(const CoinsInfo &cInfo, int column, in
case Address:
return ModelUtils::displayAddress(cInfo.address(), 1, "");
case AddressLabel:
{
if (cInfo.subaddrIndex() == 0) {
return cInfo.coinbase() ? "Coinbase" : "Change";
}
return cInfo.addressLabel();
}
case Spent:
return cInfo.spent();
case SpentHeight:
+4 -8
View File
@@ -55,17 +55,13 @@ void SendWidget::fill(double amount) {
ui->lineAmount->setText(QString::number(amount));
}
void SendWidget::fill(const QString &address, const QString& description){
ui->lineDescription->setText(description);
ui->lineAddress->setText(address);
ui->lineAddress->setCursorPosition(0);
}
void SendWidget::fill(const QString &address, const QString &description, double amount) {
ui->lineDescription->setText(description);
ui->lineAmount->setText(QString::number(amount));
ui->lineAddress->setText(address);
ui->lineAddress->setCursorPosition(0);
if (amount > 0)
ui->lineAmount->setText(QString::number(amount));
this->updateConversionLabel();
}
void SendWidget::fillAddress(const QString &address) {
@@ -74,7 +70,7 @@ void SendWidget::fillAddress(const QString &address) {
}
void SendWidget::sendClicked() {
double amount = 0.0;
double amount;
QString currency = ui->comboCurrencySelection->currentText();
QString recipient = ui->lineAddress->text().simplified().remove(' ');
QString description = ui->lineDescription->text();
+1 -2
View File
@@ -19,8 +19,7 @@ Q_OBJECT
public:
explicit SendWidget(QWidget *parent = nullptr);
void fill(const CCSEntry &entry);
void fill(const QString &address, const QString& description);
void fill(const QString &address, const QString& description, double amount);
void fill(const QString &address, const QString& description, double amount = 0);
void fill(double amount);
void clearFields();
~SendWidget() override;
-11
View File
@@ -38,16 +38,11 @@ Settings::Settings(QWidget *parent) :
ui->checkBox_hideBalance->setChecked(config()->get(Config::hideBalance).toBool());
// setup comboboxes
auto settingsHomeWidget = config()->get(Config::homeWidget).toString();
if (m_homeWidgets.contains(settingsHomeWidget))
ui->comboBox_homeWidget->setCurrentIndex(m_homeWidgets.indexOf(settingsHomeWidget));
this->setupSkinCombobox();
auto settingsSkin = config()->get(Config::skin).toString();
if (m_skins.contains(settingsSkin))
ui->comboBox_skin->setCurrentIndex(m_skins.indexOf(settingsSkin));
connect(ui->comboBox_homeWidget, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &Settings::comboBox_homeWidgetChanged);
connect(ui->comboBox_skin, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &Settings::comboBox_skinChanged);
connect(ui->comboBox_blockExplorer, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &Settings::comboBox_blockExplorerChanged);
@@ -83,12 +78,6 @@ void Settings::comboBox_skinChanged(int pos) {
emit skinChanged(m_skins.at(pos));
}
void Settings::comboBox_homeWidgetChanged(int pos) {
config()->set(Config::homeWidget, m_homeWidgets.at(pos));
emit homeWidgetChanged(m_homeWidgets.at(pos));
}
void Settings::comboBox_blockExplorerChanged(int pos) {
QString blockExplorer = ui->comboBox_blockExplorer->currentText();
config()->set(Config::blockExplorer, blockExplorer);
-3
View File
@@ -26,7 +26,6 @@ public:
signals:
void closed();
void preferredFiatCurrencyChanged(QString currency);
void homeWidgetChanged(QString widgetName);
void skinChanged(QString skinName);
void showHomeCCS(bool);
void blockExplorerChanged(QString blockExplorer);
@@ -35,12 +34,10 @@ public slots:
void copyToClipboard();
void checkboxExternalLinkWarn();
void fiatCurrencySelected(int index);
void comboBox_homeWidgetChanged(int pos);
void comboBox_skinChanged(int pos);
void comboBox_blockExplorerChanged(int post);
private:
const QStringList m_homeWidgets{"ccs", "reddit"};
QStringList m_skins{"Native", "QDarkStyle", "Breeze/Dark", "Breeze/Light"};
private:
+6 -27
View File
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>1019</width>
<height>358</height>
<height>336</height>
</rect>
</property>
<property name="windowTitle">
@@ -121,44 +121,23 @@
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Home screen widget:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="comboBox_homeWidget">
<item>
<property name="text">
<string>CCS proposals</string>
</property>
</item>
<item>
<property name="text">
<string>/r/monero</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Appearance:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<item row="1" column="1">
<widget class="QComboBox" name="comboBox_skin"/>
</item>
<item row="3" column="0">
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Block explorer:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<item row="2" column="1">
<widget class="QComboBox" name="comboBox_blockExplorer">
<item>
<property name="text">
@@ -182,14 +161,14 @@
</item>
</widget>
</item>
<item row="4" column="0">
<item row="3" column="0">
<widget class="QCheckBox" name="checkBox_externalLink">
<property name="text">
<string>Warn before opening external link</string>
</property>
</widget>
</item>
<item row="5" column="0">
<item row="4" column="0">
<widget class="QCheckBox" name="checkBox_hideBalance">
<property name="text">
<string>Hide balance</string>
+1 -2
View File
@@ -41,8 +41,7 @@ static const QHash<Config::ConfigKey, ConfigDirective> configStrings = {
{Config::nodeSource,{QS("nodeSource"), 0}},
{Config::useOnionNodes,{QS("useOnionNodes"), false}},
{Config::showTabCoins,{QS("showTabCoins"), false}},
{Config::showTabMorphToken, {QS("showTabMorphToken"), false}},
{Config::showTabXMRto,{QS("showTabXMRto"), true}},
{Config::showTabExchange, {QS("showTabExchange"), true}},
{Config::showTabXMRig,{QS("showTabXMRig"), false}},
{Config::showTabCalc,{QS("showTabCalc"), true}},
{Config::geometry, {QS("geometry"), {}}},
+1 -2
View File
@@ -39,8 +39,7 @@ public:
nodeSource,
useOnionNodes,
showTabCoins,
showTabMorphToken,
showTabXMRto,
showTabExchange,
showTabCalc,
showTabXMRig,
geometry,
+1 -1
View File
@@ -43,7 +43,7 @@ Tor::Tor(AppContext *ctx, QObject *parent)
return;
}
#ifndef HAS_TOR
#ifndef HAS_TOR_BIN
qCritical() << "Feather built without embedded Tor. Assuming --use-local-tor";
this->localTor = true;
return;
+2 -22
View File
@@ -276,7 +276,7 @@ bool Utils::testSocks5(const QString &host, quint16 port){
return false;
}
void Utils::externalLinkWarning(const QString &url){
void Utils::externalLinkWarning(QWidget *parent, const QString &url){
if(!config()->get(Config::warnOnExternalLink).toBool()) {
QDesktopServices::openUrl(QUrl(url));
return;
@@ -286,7 +286,7 @@ void Utils::externalLinkWarning(const QString &url){
body += QString("%1\n\n").arg(url);
body += "You will NOT be using Tor.";
switch (Utils::showMessageBox("External link warning", body, true)) {
switch (QMessageBox::warning(parent, "External link warning", body, QMessageBox::Cancel|QMessageBox::Ok)) {
case QMessageBox::Cancel:
break;
default:
@@ -327,26 +327,6 @@ bool Utils::walletExists(QString name, const QString &path) {
return Utils::fileExists(walletPath);
}
int Utils::showMessageBox(const QString &windowTitle, const QString &body, bool warning){
QMessageBox msgBox(QApplication::activeWindow());
msgBox.setWindowTitle(windowTitle);
msgBox.setText(body);
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
msgBox.setDefaultButton(QMessageBox::Ok);
if(warning) {
QPixmap iconWarning = QPixmap(":/assets/images/ghost_icon.png");
msgBox.setIconPixmap(iconWarning);
}
else {
QPixmap iconInfo = QPixmap(":/assets/images/info.png")
.scaled(QSize(48,48), Qt::KeepAspectRatio, Qt::SmoothTransformation);
msgBox.setIconPixmap(iconInfo);
}
return msgBox.exec();
}
void Utils::copyToClipboard(const QString &string){
QClipboard * clipboard = QApplication::clipboard();
if (!clipboard) {
+1 -4
View File
@@ -75,8 +75,7 @@ public:
static QStringList readJsonStringToQStringList(const QString &input);
static void applicationLogHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg);
static void openWindow(QWidget *w);
static void externalLinkWarning(const QString &url);
static int showMessageBox(const QString &windowTitle, const QString &body, bool warning);
static void externalLinkWarning(QWidget *parent, const QString &url);
static QList<processStruct> procList();
static bool dirExists(const QString &path);
static QString barrayToString(const QByteArray &data);
@@ -98,8 +97,6 @@ public:
static QString formatBytes(quint64 bytes);
static QString amountToCurrencyString(double amount, const QString &currencyCode);
static QStringList randomHTTPAgents;
template<typename QEnum>
static QString QtEnumToString (const QEnum value)
{
-35
View File
@@ -9,22 +9,13 @@
#include "utils/utils.h"
#include "utils/xmrig.h"
#include "appcontext.h"
XmRig::XmRig(const QString &configDir, QObject *parent) : QObject(parent) {
this->rigDir = QDir(configDir).filePath("xmrig");
}
void XmRig::prepare() {
// unpack and set process signals
if(!this->unpackBins()) {
qCritical() << "failed to write XMRig to config directory";
return;
}
m_process.setProcessChannelMode(QProcess::MergedChannels);
connect(&m_process, &QProcess::readyReadStandardOutput, this, &XmRig::handleProcessOutput);
connect(&m_process, &QProcess::errorOccurred, this, &XmRig::handleProcessError);
@@ -110,29 +101,3 @@ void XmRig::handleProcessError(QProcess::ProcessError err) {
emit error(QString("XMRig binary failed to start: %1").arg(path));
}
}
bool XmRig::unpackBins() {
QString rigFile;
rigFile = ":/assets/exec/xmrig";
if (!Utils::fileExists(rigFile))
return false;
// write to disk
QFile f(rigFile);
QFileInfo fileInfo(f);
this->rigPath = QDir(this->rigDir).filePath(fileInfo.fileName());
#if defined(Q_OS_WIN)
if(!this->rigPath.endsWith(".exe"))
this->rigPath += ".exe";
#endif
qDebug() << "Writing XMRig executable to " << this->rigPath;
f.copy(rigPath);
f.close();
#if defined(Q_OS_UNIX)
QFile rigBin(this->rigPath);
rigBin.setPermissions(QFile::ExeGroup | QFile::ExeOther | QFile::ExeOther | QFile::ExeUser);
#endif
return true;
}
+1 -1
View File
@@ -42,7 +42,7 @@ void CCSWidget::linkClicked() {
auto entry = m_model->entry(index.row());
if (entry)
Utils::externalLinkWarning(entry->url);
Utils::externalLinkWarning(this, entry->url);
}
void CCSWidget::donateClicked() {
-33
View File
@@ -48,39 +48,6 @@
</attribute>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="warnLabel">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Powered by ccs.getmonero.org</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
+2 -2
View File
@@ -113,14 +113,14 @@ void NodeWidget::onContextWSStatusURL() {
QModelIndex index = ui->wsView->currentIndex();
if (!index.isValid()) return;
FeatherNode node = m_wsModel->node(index.row());
Utils::externalLinkWarning(node.as_url());
Utils::externalLinkWarning(this, node.as_url());
}
void NodeWidget::onContextCustomStatusURL() {
QModelIndex index = ui->customView->currentIndex();
if (!index.isValid()) return;
FeatherNode node = m_customModel->node(index.row());
Utils::externalLinkWarning(node.as_url());
Utils::externalLinkWarning(this, node.as_url());
}
void NodeWidget::onContextDisconnect() {
+1 -1
View File
@@ -37,7 +37,7 @@ void RedditWidget::linkClicked() {
auto post = m_model->post(index.row());
if (post) {
Utils::externalLinkWarning(post->url);
Utils::externalLinkWarning(this, post->url);
}
}
-30
View File
@@ -51,36 +51,6 @@
</attribute>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Powered by Reddit</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
+6 -7
View File
@@ -8,11 +8,12 @@
#include "utils/config.h"
#include "mainwindow.h"
TickerWidget::TickerWidget(QWidget *parent, QString symbol, QString title, bool convertBalance) :
TickerWidget::TickerWidget(QWidget *parent, QString symbol, QString title, bool convertBalance, bool hidePercent) :
QWidget(parent),
ui(new Ui::TickerWidget),
m_symbol(std::move(symbol)),
m_convertBalance(convertBalance)
m_convertBalance(convertBalance),
m_hidePercent(hidePercent)
{
ui->setupUi(this);
m_ctx = MainWindow::getContext();
@@ -27,6 +28,8 @@ TickerWidget::TickerWidget(QWidget *parent, QString symbol, QString title, bool
this->setPctText(defaultPct, true);
this->setFiatText(defaultFiat, 0.0);
ui->tickerPct->setHidden(hidePercent);
connect(AppContext::prices, &Prices::fiatPricesUpdated, this, &TickerWidget::init);
connect(AppContext::prices, &Prices::cryptoPricesUpdated, this, &TickerWidget::init);
if (convertBalance)
@@ -47,7 +50,7 @@ void TickerWidget::init() {
double amount = m_convertBalance ? AppContext::balance : 1.0;
double conversion = AppContext::prices->convert(m_symbol, fiatCurrency, amount);
if (conversion < 0) return;
setPercentHidden(conversion == 0);
ui->tickerPct->setHidden(conversion == 0 || m_hidePercent);
auto markets = AppContext::prices->markets;
if(!markets.contains(m_symbol)) return;
@@ -85,10 +88,6 @@ void TickerWidget::removePctContainer() {
ui->tickerPct->deleteLater();
}
void TickerWidget::setPercentHidden(bool hidden) {
ui->tickerPct->setVisible(!hidden);
}
TickerWidget::~TickerWidget() {
delete ui;
}
+2 -3
View File
@@ -17,7 +17,7 @@ class TickerWidget : public QWidget
Q_OBJECT
public:
explicit TickerWidget(QWidget *parent, QString symbol, QString title = "", bool convertBalance = false);
explicit TickerWidget(QWidget *parent, QString symbol, QString title = "", bool convertBalance = false, bool hidePercent = false);
void removePctContainer();
void setFiatText(QString &fiatCurrency, double amount);
void setPctText(QString &text, bool positive);
@@ -29,11 +29,10 @@ public slots:
void init();
private:
void setPercentHidden(bool hidden);
Ui::TickerWidget *ui;
QString m_symbol;
bool m_convertBalance;
bool m_hidePercent;
AppContext *m_ctx;
};
+6 -25
View File
@@ -36,7 +36,7 @@ XMRigWidget::XMRigWidget(AppContext *ctx, QWidget *parent) :
// threads
ui->threadSlider->setMinimum(1);
int threads = QThread::idealThreadCount();
m_threads = (unsigned int) threads / 2;
m_threads = threads / 2;
ui->threadSlider->setMaximum(threads);
ui->threadSlider->setValue(m_threads);
ui->label_threads->setText(QString("CPU threads: %1").arg(m_threads));
@@ -55,15 +55,12 @@ XMRigWidget::XMRigWidget(AppContext *ctx, QWidget *parent) :
ui->check_tls->setChecked(true);
ui->label_status->setTextInteractionFlags(Qt::TextSelectableByMouse);
ui->label_status->hide();
ui->pathFrame->hide();
ui->soloFrame->hide();
ui->poolFrame->hide();
// XMRig binary
auto path = config()->get(Config::xmrigPath).toString();
if(!path.isEmpty()) {
ui->pathFrame->show();
ui->check_custompath->setChecked(true);
ui->lineEdit_path->setText(path);
}
@@ -99,7 +96,6 @@ XMRigWidget::XMRigWidget(AppContext *ctx, QWidget *parent) :
});
// checkbox connects
connect(ui->check_custompath, &QCheckBox::stateChanged, this, &XMRigWidget::onCustomPathChecked);
connect(ui->check_solo, &QCheckBox::stateChanged, this, &XMRigWidget::onSoloChecked);
}
@@ -127,7 +123,7 @@ void XMRigWidget::onWalletOpened(){
}
void XMRigWidget::onThreadsValueChanged(int threads) {
m_threads = (unsigned int) threads;
m_threads = threads;
ui->label_threads->setText(QString("CPU threads: %1").arg(m_threads));
}
@@ -150,12 +146,7 @@ void XMRigWidget::onClearClicked() {
void XMRigWidget::onStartClicked() {
QString xmrigPath;
bool solo = ui->check_solo->isChecked();
bool customBinary = ui->check_custompath->isChecked();
if(customBinary)
xmrigPath = config()->get(Config::xmrigPath).toString();
else
xmrigPath = m_ctx->XMRig->rigPath;
xmrigPath = config()->get(Config::xmrigPath).toString();
// username is receiving address usually
auto username = m_ctx->currentWallet->getCacheAttribute("feather.xmrig_username");
@@ -164,7 +155,7 @@ void XMRigWidget::onStartClicked() {
if(username.isEmpty()) {
QString err = "Please specify a receiving address on the Settings screen";
ui->console->appendPlainText(err);
Utils::showMessageBox("Error", err, true);
QMessageBox::warning(this, "Error", err);
return;
}
@@ -245,7 +236,7 @@ void XMRigWidget::onDownloads(const QJsonObject &data) {
os_assets = const_cast<QJsonArray *>(&_linux);
}
unsigned int i = 0;
int i = 0;
for(const auto &entry: *os_assets) {
auto _obj = entry.toObject();
auto _name = _obj.value("name").toString();
@@ -280,16 +271,6 @@ void XMRigWidget::showContextMenu(const QPoint &pos) {
m_contextMenu->exec(ui->tableView->viewport()->mapToGlobal(pos));
}
void XMRigWidget::onCustomPathChecked(int state) {
if(state == 2) {
ui->pathFrame->show();
} else {
ui->lineEdit_path->setText("");
config()->set(Config::xmrigPath, "");
ui->pathFrame->hide();
}
}
void XMRigWidget::onSoloChecked(int state) {
if(state == 2) {
ui->poolFrame->hide();
@@ -305,7 +286,7 @@ void XMRigWidget::onSoloChecked(int state) {
void XMRigWidget::linkClicked() {
QModelIndex index = ui->tableView->currentIndex();
auto download_link = m_urls.at(index.row());
Utils::externalLinkWarning(download_link);
Utils::externalLinkWarning(this, download_link);
}
QStandardItemModel *XMRigWidget::model() {
+2 -3
View File
@@ -22,7 +22,7 @@ class XMRigWidget : public QWidget
public:
explicit XMRigWidget(AppContext *ctx, QWidget *parent = nullptr);
~XMRigWidget();
~XMRigWidget() override;
QStandardItemModel *model();
public slots:
@@ -36,7 +36,6 @@ public slots:
void onProcessError(const QString &msg);
void onProcessOutput(const QByteArray &msg);
void onHashrate(const QString &hashrate);
void onCustomPathChecked(int state);
void onSoloChecked(int state);
private slots:
@@ -55,7 +54,7 @@ private:
Ui::XMRigWidget *ui;
QStandardItemModel *m_model;
QMenu *m_contextMenu;
unsigned int m_threads;
int m_threads;
QStringList m_urls;
QStringList m_pools{"pool.xmr.pt:9000", "pool.supportxmr.com:9000", "mine.xmrpool.net:443", "xmrpool.eu:9999", "xmr-eu1.nanopool.org:14433", "pool.minexmr.com:6666", "us-west.minexmr.com:6666", "monerohash.com:9999", "cryptonote.social:5555", "cryptonote.social:5556"};
};
+89 -156
View File
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>556</height>
<width>1329</width>
<height>540</height>
</rect>
</property>
<property name="windowTitle">
@@ -161,38 +161,7 @@
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_9">
<item>
<widget class="QCheckBox" name="check_solo">
<property name="text">
<string>Solo mine</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="check_custompath">
<property name="text">
<string>Custom XMRig executable</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_7">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<width>0</width>
<height>20</height>
</size>
</property>
@@ -221,27 +190,47 @@
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLineEdit" name="lineEdit_path">
<property name="placeholderText">
<string>/path/to/xmrig</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_browse">
<property name="text">
<string>Browse</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QCheckBox" name="check_tls">
<property name="text">
<string>TLS</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="relayTor">
<property name="text">
<string>Tor</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="check_solo">
<property name="text">
<string>Solo mine</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_12">
<item>
@@ -267,15 +256,15 @@
</property>
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Pool</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Pool</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="combo_pools">
<property name="sizePolicy">
@@ -329,15 +318,15 @@
</property>
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout_8">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Node address</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Node address</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_solo">
<property name="text">
@@ -368,80 +357,54 @@
</layout>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Receiving address</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_address"/>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Receiving address</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineEdit_address"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Password (optional)</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_10">
<item row="1" column="1">
<widget class="QLineEdit" name="lineEdit_password"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>XMRig executable</string>
</property>
</widget>
</item>
<item row="2" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLineEdit" name="lineEdit_password"/>
<widget class="QLineEdit" name="lineEdit_path">
<property name="placeholderText">
<string>/path/to/xmrig</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<widget class="QPushButton" name="btn_browse">
<property name="text">
<string>Browse</string>
</property>
<property name="sizeType">
<enum>QSizePolicy::Maximum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>60</width>
<height>20</height>
</size>
</property>
</spacer>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_13">
<item>
<widget class="QCheckBox" name="check_tls">
<property name="text">
<string>TLS</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="relayTor">
<property name="text">
<string>Tor</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_9">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
<item>
@@ -494,7 +457,7 @@
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>2000</height>
<height>0</height>
</size>
</property>
</spacer>
@@ -552,36 +515,6 @@
</attribute>
</widget>
</item>
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Powered by Github API v3</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
+1 -1
View File
@@ -74,7 +74,7 @@
<bool>false</bool>
</property>
<property name="text">
<string>by dsc &amp; thotbot</string>
<string>by dsc &amp; tobtoht</string>
</property>
</widget>
</item>
+3 -2
View File
@@ -8,6 +8,7 @@
#include <QPushButton>
#include <QFileDialog>
#include <QMessageBox>
// @TODO: rescan wallet dir on wizard open
@@ -27,7 +28,7 @@ OpenWalletPage::OpenWalletPage(AppContext *ctx, QWidget *parent) :
QFileInfo infoPath(path);
if(!infoPath.isReadable()) {
Utils::showMessageBox("Cannot read wallet file", "Permission error.", true);
QMessageBox::warning(this, "Cannot read wallet file", "Permission error.");
return;
}
@@ -67,7 +68,7 @@ int OpenWalletPage::nextId() const {
bool OpenWalletPage::validatePage() {
QModelIndex index = ui->walletTable->currentIndex();
if(!index.isValid()) {
Utils::showMessageBox("Wallet not selected", "Please select a wallet from the list.", true);
QMessageBox::warning(this, "Wallet not selected", "Please select a wallet from the list.");
return false;
}
QString walletPath = index.model()->data(index.siblingAtColumn(WalletKeysFilesModel::ModelColumns::Path), Qt::UserRole).toString();
+2 -2
View File
@@ -86,7 +86,7 @@ void XMRToWidget::onCreateOrder() {
auto amount = ui->lineAmount->text();
if(amount.isEmpty()) {
Utils::showMessageBox("Cannot create XMR.To order", "Invalid amount", false);
QMessageBox::warning(this, "Cannot create XMR.To order", "Invalid amount");
return;
}
@@ -99,7 +99,7 @@ void XMRToWidget::onCreateOrder() {
auto available = m_unlockedBalance;
if(amount_xmr > available){
Utils::showMessageBox("Cannot create XMR.To order", "Not enough Monero to create order.", false);
QMessageBox::warning(this, "Cannot create XMR.To order", "Not enough Monero to create order.");
return;
}
+1 -1
View File
@@ -14,7 +14,7 @@ git submodule update --init --depth 120 monero
git submodule update --init --depth 120 --recursive monero
cp "/Users/administrator/tor/libevent-2.1.7.dylib" "/Users/administrator/feather/src/assets/exec/libevent-2.1.7.dylib"
CMAKE_PREFIX_PATH="~/Qt/5.15.1/clang_64" TOR="/Users/administrator/tor/tor" XMRIG="/Users/administrator/xmrig/xmrig" make -j3 mac-release
CMAKE_PREFIX_PATH="~/Qt/5.15.1/clang_64" TOR_BIN="/Users/administrator/tor/tor" make -j3 mac-release
if [[ $? -eq 0 ]]; then
echo "[+] Feather built OK"
+52
View File
@@ -0,0 +1,52 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQINBF/HogkBEAChsjCJUsZhDxOx5FrnRA3X5/mJd2xdKskLSPFtnYiQUtKvpRW6
i/RVNMkTwFovzbXB6ucKJtY+OoEMu7xDhIkDWp//UlfHuP9AWAvqbhq6V5xVrZ41
9oQ7JNN4gwAI8+ZjcNq3IVFQQ9mZ3py9t1IUdgWtWM3P/SD7vWiPIjG0D3Bt3Ptl
/mZjIFZZWUtFBItJLkiTpW0Ue4t98XMP6mvQiQ/LhP82OtSyCZ6agj4Wa3ve5KjA
pdEqamBGytx2kmN+AQFgMt66yOvr+97zzuEzI6mlWYORzOc1CFMsmPd6bu/dtQ4Z
96T8PNI6i1Lv5VqvqC7RBErvD7hO36JZb8j+PnbE1YADTKrw0HmgpI6d3RLyVop3
n6ZQri0+nZ+TH0JG74MiihyZIz826zJO5OIwltexRcW0ZiRSpRCxZekU894lEs5Q
SxacRLeqM8ZVawB+9brqbeU3IJxmOCZgXLkkns0dBiSWGxtt+Tji+KXjogNfghmA
dVw9NQoBS+W5+pBtKEORD0YIGiUou9a7ukyMe2uvsl7rT+7BCOdvYtMBRbsfV5NP
s644wfJNIGa7OOjkWhuGwy6BVKTohDhJdKeZUpiTPKLV7ZLHjT4pkjuJgGQB7c+w
v7QYeUpwARwQNi8ZHuij2loG3Fb4l+3ejkcvivw0DLnDDhvUY57ezq53JwARAQAB
tCVGZWF0aGVyV2FsbGV0IDxkZXZAZmVhdGhlcndhbGxldC5vcmc+iQJOBBMBCgA4
FiEEgYXhWKMzMMf9YbwNH3bhVc77pxwFAl/HogkCGwMFCwkIBwMFFQoJCAsFFgID
AQACHgECF4AACgkQH3bhVc77pxzAxw/9GYXGm71lUlZl2yfBPmo91euSc3w/irEC
88X1kFBsdKwL19B8HUaksCOQJRG8fJQmKvJmFnRZg3NK/GLIHam+1WVObFZc1MTv
y2ERzX5ILr9sb7FptB0Wr9gk0y0Nv032ZKci3wn1j2nA87o40uopDoQTaadDTKXa
s3M2+y6zM4dCmCaV6ylJromTzIaL2Q+tWSHDD8EDF2GbnfSeeEV6TV4xj3vqfT5P
34rK4vuVNxEy/YvRQJVRYntveNMJu9C4KJvIpo8onauUHEgBu4m+qfFpixDLwQzq
bJiJQaCUrwJ3liKMolBKiPqjGNl5JRRDy+YR1Dgsj6CRobWg1fDNnrGXUwDLaBwx
zVdCB0VSmcjXpt+FKTxw1mbY+6i6trUfJSjaaawXJbktOkO6sl0bVX83oQxEgod1
aHwuo+eFCAW5zF0r+8R9Lk97Y5jkLWRKjXMFnMIyHaRhPdc24fOfojIQrXzQBMEO
lDhbWVd5vdOALhqvSOGYvjGjxBd9TE0pGzayNfPaee6kFEbxO3wZgF/QLPABl8i9
b6hHJewpY5W9mM9/yP4lHL2TRcEMzk6I7XxPQUGEb3fzTAEHRM+My4SLwaUBIFvM
L8+hRhbfNnLZPd0xDAmvH6wToL3qgK/xSl9SYwuZkzaynblmyXE4+dCFp+T2XTam
FIbphOl8Yt+5Ag0EX8eiCQEQAKv0XnHtGhWTaq/sQ4lulYWNRjBsFQRMqwSFIosO
PfzWwATQeHxxIgRlWkc25w8W0O//t8x0UcNA5rU4R+C7kVrchVSYYYl9PY0vBhKP
3efVtPgntl/VgGH8LAdShHEt3H8ZDMFjqT6gx4xnpgt3C5OdGOA3bIWuvSZ1P7qp
SYiFZakrDfPeCdI/ifucipd+EnZhFv7ivnaoIGs+jgaImQH/5uEEVxpA89Bpxoju
gXlEKSVkVAanZsUwQkc/xzhsh8dzuEF5yKomVbwTYmXDTYmpff02ycdUP7gHw0Qg
WrWaQ2M0Xq1qcZL3ZpoaWUa/A92OfuncCSDNq1pRLqwJrExqQUP9cHGwGbqeGl8K
n2tFds8Pnnv+57ZKiO8E1VTDyBey1J3/Y1hOzctfEz6BzrL52Vj4vPWh2WNNh5fL
u1ZEIdykflH/Kho0zQkRfBfD93FbN/nH1xL3V7pO/wXVGqHSD3HbFLIcJ9Ax+Jgc
Z9fm9Bvc2RkXC8lJU5+htQ+YwHPLDExvUKrBL8b8xksODCvJSWLKcTPooFQyKgbK
EnPW5kmn3eT0SHHHOArn6EHoQttkR0pV2Lrgpfg+uhy3LSTmKbtRWo7VgDY0kfVL
hsatIUqYAVdDTBzsuMhehaoWwtLAsJ01OqxAoc6+0velLddLBuLxtzGtsF0u2mEF
QJmBABEBAAGJAjYEGAEKACAWIQSBheFYozMwx/1hvA0fduFVzvunHAUCX8eiCQIb
DAAKCRAfduFVzvunHDx1D/45GVAtIP1X640PR6N8qa4Iysc/crKepgDqm8zzvpQ8
58MdeJZ9oPFEHDMkIMM8FGK9GbK4UE5mJzWJ2y5acMDOwvX4C9M206YaWQW9jPZt
fTfElP1KdAfTWz2/1UeOZKtOUuq9Wq+QlZGYg532JlX09TMyvINRM/w0+f4IBDlE
XIeRzRI6UQfz3BxpFpfWtMq/ayJnmJPrDsKQBPalai01OsbC+h4BUysZf1n7eTRF
DVaAKkSeOu+4gOVguE9PgKr11lDlKOI38tR6xBXzidBe3cPdun6vQbd1Bdfdmx3J
yFtlQo16kwwG2ZiVicXXugASBsrOFJa2/0lrtAPOnUWJsp2+1Ea6IzpRN8d1mNqr
6ND+CLxBsWj16UXq34GW6vt/QM7N1Br4/6SuPtv8OmDGRkRH7h2pz5yMf5GOwQFq
kgvOHt/x/sFPwk0GMgGn8aFr3vPH2YDg90mPn306Kv12e0JGkYVl4KqdL7u51gxT
3z5C/4+hhPVGHSPkf+g0VY/eY136kuuAZjV3P36M6UaBeCyqeD7b3fJ5IJcLwD9N
R0ustnn8IJ9zEwn+LY8kjRG8J3V57t2qAVGkMCiXnwFu3Vb+AYozOYi2ibu/N9QX
V4dTHarw64HUtLu/HEtcYuzuM5nGOXYvWPz3pQBtlqsyrhIfeaywQ+O55h5/KBo8
Ig==
=2rq8
-----END PGP PUBLIC KEY BLOCK-----