Skip to content

Commit 95252ae

Browse files
committed
Merge bitcoin-core/gui-qml#488: QML Snapshot Load
2 parents 30bfb2b + a904558 commit 95252ae

24 files changed

Lines changed: 616 additions & 28 deletions

.gitmodules

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
[submodule "bitcoin"]
22
path = bitcoin
3-
url = https://github.com/bitcoin/bitcoin
3+
url = https://github.com/D33r-Gee/bitcoin
4+
branch = interface-load-snapshot

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ set(USE_QRCODE TRUE)
5454
# We need this libraries, can ignore the executable bitcoin-qt
5555
set(BUILD_GUI ON)
5656
set(ENABLE_WALLET ON)
57+
set(ENABLE_IPC OFF)
5758

5859
# Bitcoin Core codebase
5960
# Builds libraries: univalue, core_interface, bitcoin_node, bitcoin_wallet

bitcoin

Submodule bitcoin updated 2012 files

qml/bitcoin.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,6 @@ AppMode SetupAppMode()
122122

123123
bool InitErrorMessageBox(
124124
const bilingual_str& message,
125-
[[maybe_unused]] const std::string& caption,
126125
[[maybe_unused]] unsigned int style)
127126
{
128127
QQmlApplicationEngine engine;
@@ -146,7 +145,7 @@ void DebugMessageHandler(QtMsgType type, const QMessageLogContext& context, cons
146145
if (type == QtDebugMsg) {
147146
LogDebug(BCLog::QT, "GUI: %s\n", msg.toStdString());
148147
} else {
149-
LogPrintf("GUI: %s\n", msg.toStdString());
148+
LogInfo("GUI: %s\n", msg.toStdString());
150149
}
151150
}
152151

qml/bitcoin_qml.qrc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
<file>components/ProxySettings.qml</file>
2020
<file>components/StorageLocations.qml</file>
2121
<file>components/Separator.qml</file>
22+
<file>components/SnapshotLoadSettings.qml</file>
2223
<file>components/StorageOptions.qml</file>
2324
<file>components/StorageSettings.qml</file>
2425
<file>components/ThemeSettings.qml</file>
@@ -32,6 +33,7 @@
3233
<file>controls/CoreTextField.qml</file>
3334
<file>controls/ExternalLink.qml</file>
3435
<file>controls/FocusBorder.qml</file>
36+
<file>controls/GreenCheckIcon.qml</file>
3537
<file>controls/Header.qml</file>
3638
<file>controls/Icon.qml</file>
3739
<file>controls/IconButton.qml</file>
@@ -83,6 +85,7 @@
8385
<file>pages/settings/SettingsDeveloper.qml</file>
8486
<file>pages/settings/SettingsDisplay.qml</file>
8587
<file>pages/settings/SettingsProxy.qml</file>
88+
<file>pages/settings/SettingsSnapshotLoad.qml</file>
8689
<file>pages/settings/SettingsStorage.qml</file>
8790
<file>pages/settings/SettingsTheme.qml</file>
8891
<file>pages/wallet/Activity.qml</file>
@@ -126,6 +129,9 @@
126129
<file alias="circle-green-check">res/icons/circle-green-check.png</file>
127130
<file alias="circle-red-cross">res/icons/circle-red-cross.png</file>
128131
<file alias="coinbase">res/icons/coinbase.png</file>
132+
<file alias="circle-file">res/icons/circle-file.png</file>
133+
<file alias="circle-green-check">res/icons/circle-green-check.png</file>
134+
<file alias="circle-red-cross">res/icons/circle-red-cross.png</file>
129135
<file alias="cross">res/icons/cross.png</file>
130136
<file alias="ellipsis">res/icons/ellipsis.png</file>
131137
<file alias="error">res/icons/error.png</file>

qml/components/ConnectionSettings.qml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,38 @@ import "../controls"
1010
ColumnLayout {
1111
id: root
1212
signal next
13+
signal gotoSnapshot
14+
property bool onboarding: false
15+
property bool snapshotImportCompleted: onboarding ? false : chainModel.isSnapshotActive
16+
property bool isIBDCompleted: nodeModel.isIBDCompleted
1317
spacing: 4
18+
Setting {
19+
id: gotoSnapshot
20+
visible: !snapshotImportCompleted && !root.isIBDCompleted
21+
Layout.fillWidth: true
22+
header: qsTr("Load snapshot")
23+
description: qsTr("Instant use with background sync")
24+
actionItem: Item {
25+
width: 26
26+
height: 26
27+
CaretRightIcon {
28+
anchors.centerIn: parent
29+
visible: !snapshotImportCompleted
30+
color: gotoSnapshot.stateColor
31+
}
32+
GreenCheckIcon {
33+
anchors.centerIn: parent
34+
visible: snapshotImportCompleted
35+
color: Theme.color.transparent
36+
size: 30
37+
}
38+
}
39+
onClicked: root.gotoSnapshot()
40+
}
41+
Separator {
42+
visible: !snapshotImportCompleted && !root.isIBDCompleted
43+
Layout.fillWidth: true
44+
}
1445
Setting {
1546
Layout.fillWidth: true
1647
header: qsTr("Enable listening")
Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
// Copyright (c) 2023-present The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
import QtQuick 2.15
6+
import QtQuick.Controls 2.15
7+
import QtQuick.Layouts 1.15
8+
import QtQuick.Dialogs
9+
10+
import "../controls"
11+
12+
ColumnLayout {
13+
id: columnLayout
14+
signal back
15+
property bool snapshotLoading: nodeModel.snapshotLoading
16+
property bool snapshotLoaded: nodeModel.isSnapshotLoaded
17+
property bool snapshotImportCompleted: onboarding ? false : chainModel.isSnapshotActive
18+
property bool onboarding: false
19+
property bool snapshotVerified: onboarding ? false : chainModel.isSnapshotActive
20+
property string snapshotFileName: ""
21+
property var snapshotInfo: (snapshotVerified || snapshotLoaded) ? chainModel.getSnapshotInfo() : ({})
22+
property string selectedFile: ""
23+
property bool headersSynced: nodeModel.headersSynced
24+
property bool snapshotError: nodeModel.snapshotError
25+
26+
width: Math.min(parent.width, 450)
27+
anchors.horizontalCenter: parent.horizontalCenter
28+
29+
StackLayout {
30+
id: settingsStack
31+
currentIndex: onboarding ? 0 : snapshotLoaded ? 2 : snapshotVerified ? 2 : snapshotLoading ? 1 : snapshotError ? 3 : 0
32+
33+
ColumnLayout {
34+
Layout.alignment: Qt.AlignHCenter
35+
Layout.preferredWidth: Math.min(parent.width, 450)
36+
37+
Image {
38+
Layout.alignment: Qt.AlignCenter
39+
source: "image://images/circle-file"
40+
41+
sourceSize.width: 200
42+
sourceSize.height: 200
43+
}
44+
45+
Header {
46+
Layout.fillWidth: true
47+
Layout.topMargin: 20
48+
headerBold: true
49+
header: qsTr("Load snapshot")
50+
descriptionBold: false
51+
descriptionColor: Theme.color.neutral6
52+
descriptionSize: 17
53+
descriptionLineHeight: 1.1
54+
description: qsTr("You can start using the application more quickly by loading a recent transaction snapshot." +
55+
" It will be automatically verified in the background.")
56+
}
57+
58+
CoreText {
59+
Layout.fillWidth: true
60+
Layout.topMargin: 20
61+
color: Theme.color.neutral6
62+
font.pixelSize: 17
63+
visible: !headersSynced && !onboarding
64+
text: !headersSynced
65+
? qsTr("Please wait for headers to sync before loading a snapshot.")
66+
: qsTr("")
67+
wrap: true
68+
wrapMode: Text.WordWrap
69+
}
70+
71+
ContinueButton {
72+
Layout.preferredWidth: Math.min(300, columnLayout.width - 2 * Layout.leftMargin)
73+
Layout.topMargin: 40
74+
Layout.leftMargin: 20
75+
Layout.rightMargin: Layout.leftMargin
76+
Layout.bottomMargin: 20
77+
Layout.alignment: Qt.AlignCenter
78+
text: qsTr("Choose snapshot file")
79+
enabled: headersSynced || onboarding
80+
onClicked: fileDialog.open()
81+
}
82+
83+
FileDialog {
84+
id: fileDialog
85+
currentFolder: optionsModel.getDefaultDataDirectory
86+
nameFilters: ["Snapshot files (*.dat)", "All files (*)"]
87+
onAccepted: {
88+
snapshotFileName = selectedFile
89+
console.log("snapshotFileName", snapshotFileName)
90+
if (!onboarding) {
91+
nodeModel.snapshotLoadThread(snapshotFileName)
92+
} else {
93+
nodeModel.setSnapshotFilePath(snapshotFileName)
94+
back()
95+
}
96+
}
97+
}
98+
}
99+
100+
ColumnLayout {
101+
Layout.alignment: Qt.AlignHCenter
102+
Layout.preferredWidth: Math.min(parent.width, 450)
103+
104+
Image {
105+
Layout.alignment: Qt.AlignCenter
106+
source: "image://images/circle-file"
107+
108+
sourceSize.width: 200
109+
sourceSize.height: 200
110+
}
111+
112+
Header {
113+
Layout.fillWidth: true
114+
Layout.topMargin: 20
115+
Layout.leftMargin: 20
116+
Layout.rightMargin: 20
117+
header: qsTr("Loading Snapshot")
118+
description: qsTr("This might take a while...")
119+
}
120+
121+
ProgressIndicator {
122+
id: progressIndicator
123+
Layout.topMargin: 20
124+
width: 200
125+
height: 20
126+
progress: nodeModel.snapshotProgress
127+
Layout.alignment: Qt.AlignCenter
128+
progressColor: Theme.color.blue
129+
}
130+
}
131+
132+
ColumnLayout {
133+
id: loadedSnapshotColumn
134+
Layout.alignment: Qt.AlignHCenter
135+
Layout.preferredWidth: Math.min(parent.width, 450)
136+
137+
Image {
138+
Layout.alignment: Qt.AlignCenter
139+
source: "image://images/circle-green-check"
140+
141+
sourceSize.width: 60
142+
sourceSize.height: 60
143+
}
144+
145+
Header {
146+
Layout.fillWidth: true
147+
Layout.topMargin: 20
148+
headerBold: true
149+
header: qsTr("Snapshot Loaded")
150+
descriptionBold: false
151+
descriptionColor: Theme.color.neutral6
152+
descriptionSize: 17
153+
descriptionLineHeight: 1.1
154+
description: snapshotInfo && snapshotInfo["date"] ?
155+
qsTr("It contains unspent transactions up to %1. Next, transactions will be verified and newer transactions downloaded.").arg(snapshotInfo["date"]) :
156+
qsTr("It contains transactions up to DEBUG. Newer transactions still need to be downloaded." +
157+
" The data will be verified in the background.")
158+
}
159+
160+
ContinueButton {
161+
Layout.preferredWidth: Math.min(300, columnLayout.width - 2 * Layout.leftMargin)
162+
Layout.topMargin: 40
163+
Layout.alignment: Qt.AlignCenter
164+
text: qsTr("Done")
165+
onClicked: {
166+
chainModel.isSnapshotActiveChanged()
167+
back()
168+
}
169+
}
170+
171+
Setting {
172+
id: viewDetails
173+
Layout.alignment: Qt.AlignCenter
174+
header: qsTr("View details")
175+
actionItem: CaretRightIcon {
176+
id: caretIcon
177+
color: viewDetails.stateColor
178+
rotation: viewDetails.expanded ? 90 : 0
179+
Behavior on rotation { NumberAnimation { duration: 200 } }
180+
}
181+
182+
property bool expanded: false
183+
184+
onClicked: {
185+
expanded = !expanded
186+
}
187+
}
188+
189+
ColumnLayout {
190+
id: detailsContent
191+
visible: viewDetails.expanded
192+
Layout.preferredWidth: Math.min(300, parent.width - 2 * Layout.leftMargin)
193+
Layout.alignment: Qt.AlignCenter
194+
Layout.leftMargin: 80
195+
Layout.rightMargin: 80
196+
Layout.topMargin: 10
197+
spacing: 10
198+
// TODO: make sure the block height number aligns right
199+
RowLayout {
200+
CoreText {
201+
text: qsTr("Block Height:")
202+
Layout.alignment: Qt.AlignLeft
203+
font.pixelSize: 14
204+
}
205+
CoreText {
206+
text: snapshotInfo && snapshotInfo["height"] ?
207+
snapshotInfo["height"] : qsTr("DEBUG")
208+
Layout.alignment: Qt.AlignRight
209+
font.pixelSize: 14
210+
}
211+
}
212+
Separator { Layout.fillWidth: true }
213+
ColumnLayout {
214+
Layout.fillWidth: true
215+
spacing: 5
216+
CoreText {
217+
text: qsTr("Hash:")
218+
font.pixelSize: 14
219+
}
220+
CoreText {
221+
text: snapshotInfo && snapshotInfo["hashSerializedFirstHalf"] ?
222+
snapshotInfo["hashSerializedFirstHalf"] + "\n" + snapshotInfo["hashSerializedSecondHalf"] :
223+
qsTr("DEBUG")
224+
Layout.fillWidth: true
225+
font.pixelSize: 14
226+
textFormat: Text.PlainText
227+
}
228+
}
229+
}
230+
}
231+
232+
ColumnLayout {
233+
id: snapshotErrorColumn
234+
Layout.alignment: Qt.AlignHCenter
235+
Layout.preferredWidth: Math.min(parent.width, 450)
236+
237+
Image {
238+
Layout.alignment: Qt.AlignCenter
239+
source: "image://images/circle-red-cross"
240+
241+
sourceSize.width: 60
242+
sourceSize.height: 60
243+
}
244+
245+
Header {
246+
Layout.fillWidth: true
247+
Layout.topMargin: 20
248+
headerBold: true
249+
header: qsTr("Snapshot Could Not Be Verified")
250+
descriptionBold: false
251+
descriptionColor: Theme.color.neutral6
252+
descriptionSize: 17
253+
descriptionLineHeight: 1.1
254+
description: qsTr("There was a problem with the transactions in the snapshot. Please try a different file.")
255+
}
256+
257+
ContinueButton {
258+
Layout.preferredWidth: Math.min(300, columnLayout.width - 2 * Layout.leftMargin)
259+
Layout.topMargin: 40
260+
Layout.alignment: Qt.AlignCenter
261+
text: qsTr("OK")
262+
onClicked: {
263+
nodeModel.setSnapshotError(false)
264+
back()
265+
}
266+
}
267+
}
268+
}
269+
}

qml/controls/GreenCheckIcon.qml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright (c) 2023 - present The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
import QtQuick 2.15
6+
import QtQuick.Controls 2.15
7+
8+
Icon {
9+
source: "image://images/green-check"
10+
size: 30
11+
}

0 commit comments

Comments
 (0)