1 // Copyright (c) 2019-2020 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 #if defined(HAVE_CONFIG_H)
6 #include <config/bitcoin-config.h>
7 #endif
8
9 #include <external_signer.h>
10 #include <qt/createwalletdialog.h>
11 #include <qt/forms/ui_createwalletdialog.h>
12
13 #include <qt/guiutil.h>
14
15 #include <QPushButton>
16
CreateWalletDialog(QWidget * parent)17 CreateWalletDialog::CreateWalletDialog(QWidget* parent) :
18 QDialog(parent, GUIUtil::dialog_flags),
19 ui(new Ui::CreateWalletDialog)
20 {
21 ui->setupUi(this);
22 ui->buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Create"));
23 ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
24 ui->wallet_name_line_edit->setFocus(Qt::ActiveWindowFocusReason);
25
26 connect(ui->wallet_name_line_edit, &QLineEdit::textEdited, [this](const QString& text) {
27 ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!text.isEmpty());
28 });
29
30 connect(ui->encrypt_wallet_checkbox, &QCheckBox::toggled, [this](bool checked) {
31 // Disable the disable_privkeys_checkbox and external_signer_checkbox when isEncryptWalletChecked is
32 // set to true, enable it when isEncryptWalletChecked is false.
33 ui->disable_privkeys_checkbox->setEnabled(!checked);
34 #ifdef ENABLE_EXTERNAL_SIGNER
35 ui->external_signer_checkbox->setEnabled(m_has_signers && !checked);
36 #endif
37 // When the disable_privkeys_checkbox is disabled, uncheck it.
38 if (!ui->disable_privkeys_checkbox->isEnabled()) {
39 ui->disable_privkeys_checkbox->setChecked(false);
40 }
41
42 // When the external_signer_checkbox box is disabled, uncheck it.
43 if (!ui->external_signer_checkbox->isEnabled()) {
44 ui->external_signer_checkbox->setChecked(false);
45 }
46
47 });
48
49 connect(ui->external_signer_checkbox, &QCheckBox::toggled, [this](bool checked) {
50 ui->encrypt_wallet_checkbox->setEnabled(!checked);
51 ui->blank_wallet_checkbox->setEnabled(!checked);
52 ui->disable_privkeys_checkbox->setEnabled(!checked);
53 ui->descriptor_checkbox->setEnabled(!checked);
54
55 // The external signer checkbox is only enabled when a device is detected.
56 // In that case it is checked by default. Toggling it restores the other
57 // options to their default.
58 ui->descriptor_checkbox->setChecked(checked);
59 ui->encrypt_wallet_checkbox->setChecked(false);
60 ui->disable_privkeys_checkbox->setChecked(checked);
61 // The blank check box is ambiguous. This flag is always true for a
62 // watch-only wallet, even though we immedidately fetch keys from the
63 // external signer.
64 ui->blank_wallet_checkbox->setChecked(checked);
65 });
66
67 connect(ui->disable_privkeys_checkbox, &QCheckBox::toggled, [this](bool checked) {
68 // Disable the encrypt_wallet_checkbox when isDisablePrivateKeysChecked is
69 // set to true, enable it when isDisablePrivateKeysChecked is false.
70 ui->encrypt_wallet_checkbox->setEnabled(!checked);
71
72 // Wallets without private keys start out blank
73 if (checked) {
74 ui->blank_wallet_checkbox->setChecked(true);
75 }
76
77 // When the encrypt_wallet_checkbox is disabled, uncheck it.
78 if (!ui->encrypt_wallet_checkbox->isEnabled()) {
79 ui->encrypt_wallet_checkbox->setChecked(false);
80 }
81 });
82
83 connect(ui->blank_wallet_checkbox, &QCheckBox::toggled, [this](bool checked) {
84 if (!checked) {
85 ui->disable_privkeys_checkbox->setChecked(false);
86 }
87 });
88
89 #ifndef USE_SQLITE
90 ui->descriptor_checkbox->setToolTip(tr("Compiled without sqlite support (required for descriptor wallets)"));
91 ui->descriptor_checkbox->setEnabled(false);
92 ui->descriptor_checkbox->setChecked(false);
93 ui->external_signer_checkbox->setEnabled(false);
94 ui->external_signer_checkbox->setChecked(false);
95 #endif
96
97 #ifndef USE_BDB
98 ui->descriptor_checkbox->setEnabled(false);
99 ui->descriptor_checkbox->setChecked(true);
100 #endif
101
102 #ifndef ENABLE_EXTERNAL_SIGNER
103 //: "External signing" means using devices such as hardware wallets.
104 ui->external_signer_checkbox->setToolTip(tr("Compiled without external signing support (required for external signing)"));
105 ui->external_signer_checkbox->setEnabled(false);
106 ui->external_signer_checkbox->setChecked(false);
107 #endif
108
109 }
110
~CreateWalletDialog()111 CreateWalletDialog::~CreateWalletDialog()
112 {
113 delete ui;
114 }
115
setSigners(const std::vector<ExternalSigner> & signers)116 void CreateWalletDialog::setSigners(const std::vector<ExternalSigner>& signers)
117 {
118 m_has_signers = !signers.empty();
119 if (m_has_signers) {
120 ui->external_signer_checkbox->setEnabled(true);
121 ui->external_signer_checkbox->setChecked(true);
122 ui->encrypt_wallet_checkbox->setEnabled(false);
123 ui->encrypt_wallet_checkbox->setChecked(false);
124 // The order matters, because connect() is called when toggling a checkbox:
125 ui->blank_wallet_checkbox->setEnabled(false);
126 ui->blank_wallet_checkbox->setChecked(false);
127 ui->disable_privkeys_checkbox->setEnabled(false);
128 ui->disable_privkeys_checkbox->setChecked(true);
129 const std::string label = signers[0].m_name;
130 ui->wallet_name_line_edit->setText(QString::fromStdString(label));
131 ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
132 } else {
133 ui->external_signer_checkbox->setEnabled(false);
134 }
135 }
136
walletName() const137 QString CreateWalletDialog::walletName() const
138 {
139 return ui->wallet_name_line_edit->text();
140 }
141
isEncryptWalletChecked() const142 bool CreateWalletDialog::isEncryptWalletChecked() const
143 {
144 return ui->encrypt_wallet_checkbox->isChecked();
145 }
146
isDisablePrivateKeysChecked() const147 bool CreateWalletDialog::isDisablePrivateKeysChecked() const
148 {
149 return ui->disable_privkeys_checkbox->isChecked();
150 }
151
isMakeBlankWalletChecked() const152 bool CreateWalletDialog::isMakeBlankWalletChecked() const
153 {
154 return ui->blank_wallet_checkbox->isChecked();
155 }
156
isDescriptorWalletChecked() const157 bool CreateWalletDialog::isDescriptorWalletChecked() const
158 {
159 return ui->descriptor_checkbox->isChecked();
160 }
161
isExternalSignerChecked() const162 bool CreateWalletDialog::isExternalSignerChecked() const
163 {
164 return ui->external_signer_checkbox->isChecked();
165 }
166