Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 37 additions & 6 deletions src/qt/bitcoingui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@ BitcoinGUI::BitcoinGUI(const PlatformStyle *_platformStyle, const NetworkStyle *
masternodeAction(0),
quitAction(0),
sendCoinsAction(0),
privateSendCoinsAction(0),
sendCoinsMenuAction(0),
privateSendCoinsMenuAction(0),
usedSendingAddressesAction(0),
usedReceivingAddressesAction(0),
signMessageAction(0),
Expand Down Expand Up @@ -334,14 +336,29 @@ void BitcoinGUI::createActions()
sendCoinsMenuAction->setStatusTip(sendCoinsAction->statusTip());
sendCoinsMenuAction->setToolTip(sendCoinsMenuAction->statusTip());

privateSendCoinsAction = new QAction(tr("&PrivateSend"), this);
privateSendCoinsAction->setStatusTip(tr("PrivateSend coins to a Dash address"));
privateSendCoinsAction->setToolTip(privateSendCoinsAction->statusTip());
privateSendCoinsAction->setCheckable(true);
#ifdef Q_OS_MAC
privateSendCoinsAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_3));
#else
privateSendCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_3));
#endif
tabGroup->addAction(privateSendCoinsAction);

privateSendCoinsMenuAction = new QAction(QIcon(":/icons/send"), privateSendCoinsAction->text(), this);
privateSendCoinsMenuAction->setStatusTip(privateSendCoinsAction->statusTip());
privateSendCoinsMenuAction->setToolTip(privateSendCoinsMenuAction->statusTip());

receiveCoinsAction = new QAction(tr("&Receive"), this);
receiveCoinsAction->setStatusTip(tr("Request payments (generates QR codes and dash: URIs)"));
receiveCoinsAction->setToolTip(receiveCoinsAction->statusTip());
receiveCoinsAction->setCheckable(true);
#ifdef Q_OS_MAC
receiveCoinsAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_3));
receiveCoinsAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_4));
#else
receiveCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_3));
receiveCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_4));
#endif
tabGroup->addAction(receiveCoinsAction);

Expand All @@ -354,9 +371,9 @@ void BitcoinGUI::createActions()
historyAction->setToolTip(historyAction->statusTip());
historyAction->setCheckable(true);
#ifdef Q_OS_MAC
historyAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_4));
historyAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_5));
#else
historyAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_4));
historyAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_5));
#endif
tabGroup->addAction(historyAction);

Expand All @@ -368,9 +385,9 @@ void BitcoinGUI::createActions()
masternodeAction->setToolTip(masternodeAction->statusTip());
masternodeAction->setCheckable(true);
#ifdef Q_OS_MAC
masternodeAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_5));
masternodeAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_6));
#else
masternodeAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_5));
masternodeAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_6));
#endif
tabGroup->addAction(masternodeAction);
connect(masternodeAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
Expand All @@ -385,6 +402,10 @@ void BitcoinGUI::createActions()
connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(gotoSendCoinsPage()));
connect(sendCoinsMenuAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
connect(sendCoinsMenuAction, SIGNAL(triggered()), this, SLOT(gotoSendCoinsPage()));
connect(privateSendCoinsAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
connect(privateSendCoinsAction, SIGNAL(triggered()), this, SLOT(gotoPrivateSendCoinsPage()));
connect(privateSendCoinsMenuAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
connect(privateSendCoinsMenuAction, SIGNAL(triggered()), this, SLOT(gotoPrivateSendCoinsPage()));
connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(gotoReceiveCoinsPage()));
connect(receiveCoinsMenuAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
Expand Down Expand Up @@ -582,6 +603,7 @@ void BitcoinGUI::createToolBars()
toolbar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
toolbar->addAction(overviewAction);
toolbar->addAction(sendCoinsAction);
toolbar->addAction(privateSendCoinsAction);
toolbar->addAction(receiveCoinsAction);
toolbar->addAction(historyAction);
QSettings settings;
Expand Down Expand Up @@ -748,6 +770,8 @@ void BitcoinGUI::setWalletActionsEnabled(bool enabled)
overviewAction->setEnabled(enabled);
sendCoinsAction->setEnabled(enabled);
sendCoinsMenuAction->setEnabled(enabled);
privateSendCoinsAction->setEnabled(enabled && privateSendClient.fEnablePrivateSend);
privateSendCoinsMenuAction->setEnabled(enabled && privateSendClient.fEnablePrivateSend);
receiveCoinsAction->setEnabled(enabled);
receiveCoinsMenuAction->setEnabled(enabled);
historyAction->setEnabled(enabled);
Expand Down Expand Up @@ -781,6 +805,7 @@ void BitcoinGUI::createIconMenu(QMenu *pmenu)
pmenu->addAction(toggleHideAction);
pmenu->addSeparator();
pmenu->addAction(sendCoinsMenuAction);
pmenu->addAction(privateSendCoinsMenuAction);
pmenu->addAction(receiveCoinsMenuAction);
pmenu->addSeparator();
pmenu->addAction(signMessageAction);
Expand Down Expand Up @@ -939,6 +964,12 @@ void BitcoinGUI::gotoSendCoinsPage(QString addr)
if (walletFrame) walletFrame->gotoSendCoinsPage(addr);
}

void BitcoinGUI::gotoPrivateSendCoinsPage(QString addr)
{
privateSendCoinsAction->setChecked(true);
if (walletFrame) walletFrame->gotoPrivateSendCoinsPage(addr);
}

void BitcoinGUI::gotoSignMessageTab(QString addr)
{
if (walletFrame) walletFrame->gotoSignMessageTab(addr);
Expand Down
4 changes: 4 additions & 0 deletions src/qt/bitcoingui.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ class BitcoinGUI : public QMainWindow
QAction *quitAction;
QAction *sendCoinsAction;
QAction *sendCoinsMenuAction;
QAction *privateSendCoinsAction;
QAction *privateSendCoinsMenuAction;
QAction *usedSendingAddressesAction;
QAction *usedReceivingAddressesAction;
QAction *signMessageAction;
Expand Down Expand Up @@ -239,6 +241,8 @@ private Q_SLOTS:
void gotoReceiveCoinsPage();
/** Switch to send coins page */
void gotoSendCoinsPage(QString addr = "");
/** Switch to PrivateSend coins page */
void gotoPrivateSendCoinsPage(QString addr = "");

/** Show Sign/Verify Message dialog and switch to sign message tab */
void gotoSignMessageTab(QString addr = "");
Expand Down
171 changes: 96 additions & 75 deletions src/qt/coincontroldialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -427,13 +427,6 @@ void CoinControlDialog::viewItemChanged(QTreeWidgetItem* item, int column)
item->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked);
else {
coinControl()->Select(outpt);
int nRounds = item->data(COLUMN_PRIVATESEND_ROUNDS, Qt::UserRole).toLongLong();
if (coinControl()->IsUsingPrivateSend() && nRounds < privateSendClient.nPrivateSendRounds) {
QMessageBox::warning(this, windowTitle(),
tr("Non-mixed input selected. <b>PrivateSend will be disabled.</b><br><br>If you still want to use PrivateSend, please deselect all non-mixed inputs first and then check the PrivateSend checkbox again."),
QMessageBox::Ok, QMessageBox::Ok);
coinControl()->UsePrivateSend(false);
}
}

// selection changed -> update labels
Expand Down Expand Up @@ -494,6 +487,8 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
unsigned int nBytesInputs = 0;
unsigned int nQuantity = 0;
int nQuantityUncompressed = 0;
bool fUnselectedSpent{false};
bool fUnselectedNonMixed{false};

std::vector<COutPoint> vCoinControl;
std::vector<COutput> vOutputs;
Expand All @@ -508,9 +503,20 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
if (model->isSpent(outpt))
{
coinControl()->UnSelect(outpt);
fUnselectedSpent = true;
continue;
}

// unselect non-fully-mixed, this can happen when users switch from Send to PrivateSend
if (coinControl()->IsUsingPrivateSend()) {
int nRounds = model->getRealOutpointPrivateSendRounds(outpt);
if (nRounds < privateSendClient.nPrivateSendRounds) {
coinControl()->UnSelect(outpt);
fUnselectedNonMixed = true;
continue;
}
}

// Quantity
nQuantity++;

Expand Down Expand Up @@ -643,6 +649,17 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
QLabel *label = dialog->findChild<QLabel *>("labelCoinControlInsuffFunds");
if (label)
label->setVisible(nChange < 0);

// Warn about unselected coins
if (fUnselectedSpent) {
QMessageBox::warning(dialog, "CoinControl",
tr("Some coins were unselected because they were spent."),
QMessageBox::Ok, QMessageBox::Ok);
} else if (fUnselectedNonMixed) {
QMessageBox::warning(dialog, "CoinControl",
tr("Some coins were unselected because they do not have enough mixing rounds."),
QMessageBox::Ok, QMessageBox::Ok);
}
}

CCoinControl* CoinControlDialog::coinControl()
Expand Down Expand Up @@ -696,87 +713,91 @@ void CoinControlDialog::updateView()
CAmount nSum = 0;
int nChildren = 0;
for (const COutput& out : coins.second) {
nSum += out.tx->tx->vout[out.i].nValue;
nChildren++;

CCoinControlWidgetItem *itemOutput;
if (treeMode) itemOutput = new CCoinControlWidgetItem(itemWalletAddress);
else itemOutput = new CCoinControlWidgetItem(ui->treeWidget);
itemOutput->setFlags(flgCheckbox);
itemOutput->setCheckState(COLUMN_CHECKBOX,Qt::Unchecked);

// address
CTxDestination outputAddress;
QString sAddress = "";
if(ExtractDestination(out.tx->tx->vout[out.i].scriptPubKey, outputAddress))
{
sAddress = QString::fromStdString(EncodeDestination(outputAddress));

// if listMode or change => show dash address. In tree mode, address is not shown again for direct wallet address outputs
if (!treeMode || (!(sAddress == sWalletAddress)))
itemOutput->setText(COLUMN_ADDRESS, sAddress);
COutPoint outpoint = COutPoint(out.tx->tx->GetHash(), out.i);
int nRounds = model->getRealOutpointPrivateSendRounds(outpoint);

itemOutput->setToolTip(COLUMN_ADDRESS, sAddress);
}
if ((coinControl()->IsUsingPrivateSend() && nRounds >= privateSendClient.nPrivateSendRounds) || !(coinControl()->IsUsingPrivateSend())) {
nSum += out.tx->tx->vout[out.i].nValue;
nChildren++;

// label
if (!(sAddress == sWalletAddress)) // change
{
// tooltip from where the change comes from
itemOutput->setToolTip(COLUMN_LABEL, tr("change from %1 (%2)").arg(sWalletLabel).arg(sWalletAddress));
itemOutput->setText(COLUMN_LABEL, tr("(change)"));
}
else if (!treeMode)
{
QString sLabel = model->getAddressTableModel()->labelForAddress(sAddress);
if (sLabel.isEmpty())
sLabel = tr("(no label)");
itemOutput->setText(COLUMN_LABEL, sLabel);
}
CCoinControlWidgetItem* itemOutput;
if (treeMode) {
itemOutput = new CCoinControlWidgetItem(itemWalletAddress);
} else {
itemOutput = new CCoinControlWidgetItem(ui->treeWidget);
}
itemOutput->setFlags(flgCheckbox);
itemOutput->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked);

// amount
itemOutput->setText(COLUMN_AMOUNT, BitcoinUnits::format(nDisplayUnit, out.tx->tx->vout[out.i].nValue));
itemOutput->setToolTip(COLUMN_AMOUNT, BitcoinUnits::format(nDisplayUnit, out.tx->tx->vout[out.i].nValue));
itemOutput->setData(COLUMN_AMOUNT, Qt::UserRole, QVariant((qlonglong)out.tx->tx->vout[out.i].nValue)); // padding so that sorting works correctly
// address
CTxDestination outputAddress;
QString sAddress = "";
if (ExtractDestination(out.tx->tx->vout[out.i].scriptPubKey, outputAddress)) {
sAddress = QString::fromStdString(EncodeDestination(outputAddress));

// date
itemOutput->setText(COLUMN_DATE, GUIUtil::dateTimeStr(out.tx->GetTxTime()));
itemOutput->setToolTip(COLUMN_DATE, GUIUtil::dateTimeStr(out.tx->GetTxTime()));
itemOutput->setData(COLUMN_DATE, Qt::UserRole, QVariant((qlonglong)out.tx->GetTxTime()));
// if listMode or change => show dash address. In tree mode, address is not shown again for direct wallet address outputs
if (!treeMode || (!(sAddress == sWalletAddress))) {
itemOutput->setText(COLUMN_ADDRESS, sAddress);
}

itemOutput->setToolTip(COLUMN_ADDRESS, sAddress);
}

// PrivateSend rounds
COutPoint outpoint = COutPoint(out.tx->tx->GetHash(), out.i);
int nRounds = model->getRealOutpointPrivateSendRounds(outpoint);
// label
if (!(sAddress == sWalletAddress)) { //change
// tooltip from where the change comes from
itemOutput->setToolTip(COLUMN_LABEL, tr("change from %1 (%2)").arg(sWalletLabel).arg(sWalletAddress));
itemOutput->setText(COLUMN_LABEL, tr("(change)"));
} else if (!treeMode) {
QString sLabel = model->getAddressTableModel()->labelForAddress(sAddress);
if (sLabel.isEmpty()) {
sLabel = tr("(no label)");
}
itemOutput->setText(COLUMN_LABEL, sLabel);
}

if (nRounds >= 0 || LogAcceptCategory(BCLog::PRIVATESEND)) itemOutput->setText(COLUMN_PRIVATESEND_ROUNDS, QString::number(nRounds));
else itemOutput->setText(COLUMN_PRIVATESEND_ROUNDS, tr("n/a"));
itemOutput->setData(COLUMN_PRIVATESEND_ROUNDS, Qt::UserRole, QVariant((qlonglong)nRounds));
// amount
itemOutput->setText(COLUMN_AMOUNT, BitcoinUnits::format(nDisplayUnit, out.tx->tx->vout[out.i].nValue));
itemOutput->setToolTip(COLUMN_AMOUNT, BitcoinUnits::format(nDisplayUnit, out.tx->tx->vout[out.i].nValue));
itemOutput->setData(COLUMN_AMOUNT, Qt::UserRole, QVariant((qlonglong)out.tx->tx->vout[out.i].nValue)); // padding so that sorting works correctly

// date
itemOutput->setText(COLUMN_DATE, GUIUtil::dateTimeStr(out.tx->GetTxTime()));
itemOutput->setToolTip(COLUMN_DATE, GUIUtil::dateTimeStr(out.tx->GetTxTime()));
itemOutput->setData(COLUMN_DATE, Qt::UserRole, QVariant((qlonglong)out.tx->GetTxTime()));

// PrivateSend rounds
if (nRounds >= 0 || LogAcceptCategory(BCLog::PRIVATESEND)) {
itemOutput->setText(COLUMN_PRIVATESEND_ROUNDS, QString::number(nRounds));
} else {
itemOutput->setText(COLUMN_PRIVATESEND_ROUNDS, tr("n/a"));
}
itemOutput->setData(COLUMN_PRIVATESEND_ROUNDS, Qt::UserRole, QVariant((qlonglong)nRounds));

// confirmations
itemOutput->setText(COLUMN_CONFIRMATIONS, QString::number(out.nDepth));
itemOutput->setData(COLUMN_CONFIRMATIONS, Qt::UserRole, QVariant((qlonglong)out.nDepth));

// confirmations
itemOutput->setText(COLUMN_CONFIRMATIONS, QString::number(out.nDepth));
itemOutput->setData(COLUMN_CONFIRMATIONS, Qt::UserRole, QVariant((qlonglong)out.nDepth));
// transaction hash
uint256 txhash = out.tx->GetHash();
itemOutput->setText(COLUMN_TXHASH, QString::fromStdString(txhash.GetHex()));

// transaction hash
uint256 txhash = out.tx->GetHash();
itemOutput->setText(COLUMN_TXHASH, QString::fromStdString(txhash.GetHex()));
// vout index
itemOutput->setText(COLUMN_VOUT_INDEX, QString::number(out.i));

// vout index
itemOutput->setText(COLUMN_VOUT_INDEX, QString::number(out.i));
// disable locked coins
if (model->isLockedCoin(txhash, out.i)) {
COutPoint outpt(txhash, out.i);
coinControl()->UnSelect(outpt); // just to be sure
itemOutput->setDisabled(true);
itemOutput->setIcon(COLUMN_CHECKBOX, QIcon(":/icons/lock_closed"));
}

// disable locked coins
if (model->isLockedCoin(txhash, out.i))
{
COutPoint outpt(txhash, out.i);
coinControl()->UnSelect(outpt); // just to be sure
itemOutput->setDisabled(true);
itemOutput->setIcon(COLUMN_CHECKBOX, QIcon(":/icons/lock_closed"));
// set checkbox
if (coinControl()->IsSelected(COutPoint(txhash, out.i))) {
itemOutput->setCheckState(COLUMN_CHECKBOX, Qt::Checked);
}
}

// set checkbox
if (coinControl()->IsSelected(COutPoint(txhash, out.i)))
itemOutput->setCheckState(COLUMN_CHECKBOX, Qt::Checked);
}

// amount
Expand Down
16 changes: 0 additions & 16 deletions src/qt/forms/sendcoinsdialog.ui
Original file line number Diff line number Diff line change
Expand Up @@ -1210,22 +1210,6 @@
<property name="spacing">
<number>3</number>
</property>
<item>
<widget class="QCheckBox" name="checkUsePrivateSend">
<property name="minimumSize">
<size>
<width>95</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>PrivateSend</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
Expand Down
4 changes: 4 additions & 0 deletions src/qt/res/css/dark.css
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ border: 0;
font-weight: bold;
}

QToolBar > QToolButton:disabled {
color: #444;
}

QToolBar > QLabel {
border: 0;
margin:10px 0 0 0;
Expand Down
4 changes: 4 additions & 0 deletions src/qt/res/css/light.css
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ border: 0;
font-weight: bold;
}

QToolBar > QToolButton:disabled {
color: #444;
}

QToolBar > QLabel {
border:0;
margin:10px 0 0 0;
Expand Down
Loading