qt: Finetune CoinControlDialog + bitcoin#14828 (#3701)

* qt: Add min-height for CoinControlTreeWidget#treeWidget::item

The rows resize without it if they get locked and the lock icon appears
besides the checkbox. Looks weird.. and especially if you press the lock
all button its just not nice.

* qt: Set background transparency for CoinControl item::hover

* Merge #14828: qt: Remove hidden columns in coin control dialog

1c28feb7d qt: Remove hidden columns in coin control dialog (João Barbosa)

Pull request description:

  Instead of having hidden columns, store the data in specific roles.

  Overlaps with #14817, fixes #11811.

Tree-SHA512: e86e9ca426b9146ac28997ca1920dbae6cc4e2e494ff94fe131d605cd6c013183fc5de10036c886a4d6dcae497ac4067de3791be0ef9c88f7ce9f57f7bd97422

* qt: Add border-bottom for tree items in CoinControl

* qt: Stretch address column in CoinControlDialog

* Adjust column width for a couple of columns

* qt: Hide PrivateSend rounds column for normal Send tab's CoinControl

* qt: Hide unrelated coins in CoinControl based on active mode. Still allow to show them.

* qt: Hide empty top level items in CoinControlDialog's tree mode

* qt: Hide tree/list radio buttons and default to list for PrivateSend

* qt: Hide address/label column in CoinControl for PrivateSend

* qt: Remove obsolete empty columns

* qt: Rename column "PS Rounds" to "Mixing Rounds"

* qt: Move border-bottom in already existing css selector

* Reveal all PS related coins in coincontrol while in PS mode, not only ones with rounds>=1

Also tweak button text

* qt: Only moving a statement a bit

* qt: Hide the "hideButton" in CoinControlDialog if PrivatSend is disabled

And make it default to show all coins in that case..

Co-authored-by: Jonas Schnelli <dev@jonasschnelli.ch>
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
This commit is contained in:
dustinface 2020-09-23 09:31:50 +02:00 committed by pasta
parent e405f553b9
commit f4e3bf95d0
No known key found for this signature in database
GPG Key ID: 52527BEDABE87984
6 changed files with 192 additions and 111 deletions

View File

@ -143,15 +143,15 @@ CoinControlDialog::CoinControlDialog(QWidget* parent) :
// see https://github.com/bitcoin/bitcoin/issues/5716
ui->treeWidget->headerItem()->setText(COLUMN_CHECKBOX, QString());
ui->treeWidget->setColumnWidth(COLUMN_CHECKBOX, 84);
ui->treeWidget->setColumnWidth(COLUMN_CHECKBOX, 94);
ui->treeWidget->setColumnWidth(COLUMN_AMOUNT, 100);
ui->treeWidget->setColumnWidth(COLUMN_LABEL, 170);
ui->treeWidget->setColumnWidth(COLUMN_ADDRESS, 190);
ui->treeWidget->setColumnWidth(COLUMN_PRIVATESEND_ROUNDS, 88);
ui->treeWidget->setColumnWidth(COLUMN_DATE, 80);
ui->treeWidget->setColumnWidth(COLUMN_CONFIRMATIONS, 100);
ui->treeWidget->setColumnHidden(COLUMN_TXHASH, true); // store transaction hash in this column, but don't show it
ui->treeWidget->setColumnHidden(COLUMN_VOUT_INDEX, true); // store vout index in this column, but don't show it
ui->treeWidget->setColumnWidth(COLUMN_PRIVATESEND_ROUNDS, 110);
ui->treeWidget->setColumnWidth(COLUMN_DATE, 120);
ui->treeWidget->setColumnWidth(COLUMN_CONFIRMATIONS, 110);
ui->treeWidget->header()->setStretchLastSection(false);
ui->treeWidget->header()->setSectionResizeMode(COLUMN_ADDRESS, QHeaderView::Stretch);
// default view is sorted by amount desc
sortView(COLUMN_AMOUNT, Qt::DescendingOrder);
@ -224,8 +224,12 @@ void CoinControlDialog::buttonToggleLockClicked()
ui->treeWidget->setEnabled(false);
for (int i = 0; i < ui->treeWidget->topLevelItemCount(); i++){
item = ui->treeWidget->topLevelItem(i);
COutPoint outpt(uint256S(item->text(COLUMN_TXHASH).toStdString()), item->text(COLUMN_VOUT_INDEX).toUInt());
if (model->isLockedCoin(uint256S(item->text(COLUMN_TXHASH).toStdString()), item->text(COLUMN_VOUT_INDEX).toUInt())){
COutPoint outpt(uint256S(item->data(COLUMN_ADDRESS, TxHashRole).toString().toStdString()), item->data(COLUMN_ADDRESS, VOutRole).toUInt());
// Don't toggle the lock state of partially mixed coins if they are not hidden in PrivateSend mode
if (coinControl()->IsUsingPrivateSend() && !fHideAdditional && !model->isFullyMixed(outpt)) {
continue;
}
if (model->isLockedCoin(uint256S(item->data(COLUMN_ADDRESS, TxHashRole).toString().toStdString()), item->data(COLUMN_ADDRESS, VOutRole).toUInt())){
model->unlockCoin(outpt);
item->setDisabled(false);
item->setIcon(COLUMN_CHECKBOX, QIcon());
@ -257,10 +261,10 @@ void CoinControlDialog::showMenu(const QPoint &point)
contextMenuItem = item;
// disable some items (like Copy Transaction ID, lock, unlock) for tree roots in context menu
if (item->text(COLUMN_TXHASH).length() == 64) // transaction hash is 64 characters (this means its a child node, so its not a parent node in tree mode)
if (item->data(COLUMN_ADDRESS, TxHashRole).toString().length() == 64) // transaction hash is 64 characters (this means its a child node, so its not a parent node in tree mode)
{
copyTransactionHashAction->setEnabled(true);
if (model->isLockedCoin(uint256S(item->text(COLUMN_TXHASH).toStdString()), item->text(COLUMN_VOUT_INDEX).toUInt()))
if (model->isLockedCoin(uint256S(item->data(COLUMN_ADDRESS, TxHashRole).toString().toStdString()), item->data(COLUMN_ADDRESS, VOutRole).toUInt()))
{
lockAction->setEnabled(false);
unlockAction->setEnabled(true);
@ -310,7 +314,7 @@ void CoinControlDialog::copyAddress()
// context menu action: copy transaction id
void CoinControlDialog::copyTransactionHash()
{
GUIUtil::setClipboard(contextMenuItem->text(COLUMN_TXHASH));
GUIUtil::setClipboard(contextMenuItem->data(COLUMN_ADDRESS, TxHashRole).toString());
}
// context menu action: lock coin
@ -319,7 +323,7 @@ void CoinControlDialog::lockCoin()
if (contextMenuItem->checkState(COLUMN_CHECKBOX) == Qt::Checked)
contextMenuItem->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked);
COutPoint outpt(uint256S(contextMenuItem->text(COLUMN_TXHASH).toStdString()), contextMenuItem->text(COLUMN_VOUT_INDEX).toUInt());
COutPoint outpt(uint256S(contextMenuItem->data(COLUMN_ADDRESS, TxHashRole).toString().toStdString()), contextMenuItem->data(COLUMN_ADDRESS, VOutRole).toUInt());
model->lockCoin(outpt);
contextMenuItem->setDisabled(true);
contextMenuItem->setIcon(COLUMN_CHECKBOX, GUIUtil::getIcon("lock_closed", GUIUtil::ThemedColor::RED));
@ -329,7 +333,7 @@ void CoinControlDialog::lockCoin()
// context menu action: unlock coin
void CoinControlDialog::unlockCoin()
{
COutPoint outpt(uint256S(contextMenuItem->text(COLUMN_TXHASH).toStdString()), contextMenuItem->text(COLUMN_VOUT_INDEX).toUInt());
COutPoint outpt(uint256S(contextMenuItem->data(COLUMN_ADDRESS, TxHashRole).toString().toStdString()), contextMenuItem->data(COLUMN_ADDRESS, VOutRole).toUInt());
model->unlockCoin(outpt);
contextMenuItem->setDisabled(false);
contextMenuItem->setIcon(COLUMN_CHECKBOX, QIcon());
@ -425,9 +429,9 @@ void CoinControlDialog::radioListMode(bool checked)
// checkbox clicked by user
void CoinControlDialog::viewItemChanged(QTreeWidgetItem* item, int column)
{
if (column == COLUMN_CHECKBOX && item->text(COLUMN_TXHASH).length() == 64) // transaction hash is 64 characters (this means its a child node, so its not a parent node in tree mode)
if (column == COLUMN_CHECKBOX && item->data(COLUMN_ADDRESS, TxHashRole).toString().length() == 64) // transaction hash is 64 characters (this means its a child node, so its not a parent node in tree mode)
{
COutPoint outpt(uint256S(item->text(COLUMN_TXHASH).toStdString()), item->text(COLUMN_VOUT_INDEX).toUInt());
COutPoint outpt(uint256S(item->data(COLUMN_ADDRESS, TxHashRole).toString().toStdString()), item->data(COLUMN_ADDRESS, VOutRole).toUInt());
if (item->checkState(COLUMN_CHECKBOX) == Qt::Unchecked)
coinControl()->UnSelect(outpt);
@ -466,6 +470,13 @@ void CoinControlDialog::updateLabelLocked()
else ui->labelLocked->setVisible(false);
}
void CoinControlDialog::on_hideButton_clicked()
{
fHideAdditional = !fHideAdditional;
updateView();
CoinControlDialog::updateLabels(model, this);
}
void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
{
if (!model)
@ -683,6 +694,37 @@ void CoinControlDialog::updateView()
if (!model || !model->getOptionsModel() || !model->getAddressTableModel())
return;
bool fNormalMode = mode == Mode::NORMAL;
ui->treeWidget->setColumnHidden(COLUMN_PRIVATESEND_ROUNDS, fNormalMode);
ui->treeWidget->setColumnHidden(COLUMN_LABEL, !fNormalMode);
ui->radioTreeMode->setVisible(fNormalMode);
ui->radioListMode->setVisible(fNormalMode);
if (!CPrivateSendClientOptions::IsEnabled()) {
fHideAdditional = false;
ui->hideButton->setVisible(false);
}
QString strHideButton;
switch (mode) {
case Mode::NORMAL:
if (fHideAdditional) {
strHideButton = tr("Show all coins");
} else {
strHideButton = tr("Hide PrivateSend coins");
}
break;
case Mode::PRIVATESEND:
if (fHideAdditional) {
strHideButton = tr("Show all PrivateSend coins");
} else {
strHideButton = tr("Show spendable coins only");
}
ui->radioListMode->setChecked(true);
break;
}
ui->hideButton->setText(strHideButton);
bool treeMode = ui->radioTreeMode->isChecked();
ui->treeWidget->clear();
ui->treeWidget->setEnabled(false); // performance, otherwise updateLabels would be called for every checked checkbox
@ -724,89 +766,108 @@ void CoinControlDialog::updateView()
int nChildren = 0;
for (const COutput& out : coins.second) {
COutPoint outpoint = COutPoint(out.tx->tx->GetHash(), out.i);
bool fFullyMixed{false};
CAmount nAmount = out.tx->tx->vout[out.i].nValue;
if ((coinControl()->IsUsingPrivateSend() && model->isFullyMixed(outpoint)) || !(coinControl()->IsUsingPrivateSend())) {
nSum += out.tx->tx->vout[out.i].nValue;
nChildren++;
bool fPrivateSendAmount = CPrivateSend::IsDenominatedAmount(nAmount) || CPrivateSend::IsCollateralAmount(nAmount);
CCoinControlWidgetItem* itemOutput;
if (treeMode) {
itemOutput = new CCoinControlWidgetItem(itemWalletAddress);
} else {
itemOutput = new CCoinControlWidgetItem(ui->treeWidget);
if (coinControl()->IsUsingPrivateSend()) {
fFullyMixed = model->isFullyMixed(outpoint);
if ((fHideAdditional && !fFullyMixed) || (!fHideAdditional && !fPrivateSendAmount)) {
coinControl()->UnSelect(outpoint);
continue;
}
itemOutput->setFlags(flgCheckbox);
itemOutput->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked);
} else {
if (fHideAdditional && fPrivateSendAmount) {
coinControl()->UnSelect(outpoint);
continue;
}
}
// address
CTxDestination outputAddress;
QString sAddress = "";
if (ExtractDestination(out.tx->tx->vout[out.i].scriptPubKey, outputAddress)) {
sAddress = QString::fromStdString(EncodeDestination(outputAddress));
nSum += out.tx->tx->vout[out.i].nValue;
nChildren++;
// 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);
}
CCoinControlWidgetItem* itemOutput;
if (treeMode) {
itemOutput = new CCoinControlWidgetItem(itemWalletAddress);
} else {
itemOutput = new CCoinControlWidgetItem(ui->treeWidget);
}
itemOutput->setFlags(flgCheckbox);
itemOutput->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked);
itemOutput->setToolTip(COLUMN_ADDRESS, sAddress);
// 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);
}
// 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);
itemOutput->setToolTip(COLUMN_ADDRESS, sAddress);
}
// 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);
}
// 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
// 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()));
// 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
int nRounds = model->getRealOutpointPrivateSendRounds(outpoint);
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));
// PrivateSend rounds
int nRounds = model->getRealOutpointPrivateSendRounds(outpoint);
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->setData(COLUMN_ADDRESS, TxHashRole, QString::fromStdString(txhash.GetHex()));
// vout index
itemOutput->setText(COLUMN_VOUT_INDEX, QString::number(out.i));
// vout index
itemOutput->setData(COLUMN_ADDRESS, VOutRole, 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, GUIUtil::getIcon("lock_closed", GUIUtil::ThemedColor::RED));
}
// 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, GUIUtil::getIcon("lock_closed", GUIUtil::ThemedColor::RED));
}
// 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);
}
if (coinControl()->IsUsingPrivateSend() && !fHideAdditional && !fFullyMixed) {
itemOutput->setDisabled(true);
}
}
@ -820,12 +881,15 @@ void CoinControlDialog::updateView()
}
}
// expand all partially selected
// expand all partially selected and hide the empty
if (treeMode)
{
for (int i = 0; i < ui->treeWidget->topLevelItemCount(); i++)
if (ui->treeWidget->topLevelItem(i)->checkState(COLUMN_CHECKBOX) == Qt::PartiallyChecked)
ui->treeWidget->topLevelItem(i)->setExpanded(true);
for (int i = 0; i < ui->treeWidget->topLevelItemCount(); i++) {
QTreeWidgetItem* topLevelItem = ui->treeWidget->topLevelItem(i);
topLevelItem->setHidden(topLevelItem->childCount() == 0);
if (topLevelItem->checkState(COLUMN_CHECKBOX) == Qt::PartiallyChecked)
topLevelItem->setExpanded(true);
}
}
// sort view

View File

@ -67,6 +67,8 @@ private:
QAction *lockAction;
QAction *unlockAction;
bool fHideAdditional{true};
void sortView(int, Qt::SortOrder);
void updateView();
@ -79,9 +81,14 @@ private:
COLUMN_PRIVATESEND_ROUNDS,
COLUMN_DATE,
COLUMN_CONFIRMATIONS,
COLUMN_TXHASH,
COLUMN_VOUT_INDEX,
};
enum
{
TxHashRole = Qt::UserRole,
VOutRole
};
friend class CCoinControlWidgetItem;
enum class Mode {
@ -114,6 +121,7 @@ private Q_SLOTS:
void buttonSelectAllClicked();
void buttonToggleLockClicked();
void updateLabelLocked();
void on_hideButton_clicked();
};
#endif // BITCOIN_QT_COINCONTROLDIALOG_H

View File

@ -277,7 +277,7 @@
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayoutPanel" stretch="0,0,0,0,0,0">
<layout class="QHBoxLayout" name="horizontalLayoutPanel" stretch="0,0,0,0,0,0,0">
<property name="spacing">
<number>14</number>
</property>
@ -313,6 +313,22 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="hideButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioTreeMode">
<property name="sizePolicy">
@ -376,7 +392,7 @@
<bool>false</bool>
</property>
<property name="columnCount">
<number>11</number>
<number>7</number>
</property>
<attribute name="headerShowSortIndicator" stdset="0">
<bool>true</bool>
@ -406,7 +422,7 @@
</column>
<column>
<property name="text">
<string>PS Rounds</string>
<string>Mixing Rounds</string>
</property>
</column>
<column>
@ -422,26 +438,6 @@
<string>Confirmed</string>
</property>
</column>
<column>
<property name="text">
<string/>
</property>
</column>
<column>
<property name="text">
<string/>
</property>
</column>
<column>
<property name="text">
<string/>
</property>
</column>
<column>
<property name="text">
<string/>
</property>
</column>
</widget>
</item>
<item>

View File

@ -794,6 +794,10 @@ AskPassphraseDialog
CoinControlDialog
******************************************************/
QDialog#CoinControlDialog .CoinControlTreeWidget#treeWidget::item {
border-color: #4a4a4b;
}
QDialog#CoinControlDialog .CoinControlTreeWidget#treeWidget::item:selected,
QDialog#CoinControlDialog .CoinControlTreeWidget#treeWidget::item:checked,
QDialog#CoinControlDialog .CoinControlTreeWidget#treeWidget::branch:selected,

View File

@ -1145,6 +1145,11 @@ QDialog#CoinControlDialog QHeaderView::section:first { /* Bug Fix: the number 1
}
QDialog#CoinControlDialog .CoinControlTreeWidget#treeWidget::item {
border-bottom: 1px solid red;
min-height: 25px;
}
QDialog#CoinControlDialog .CoinControlTreeWidget#treeWidget::item:hover {
background-color: #00000000;
}
QDialog#CoinControlDialog .CoinControlTreeWidget#treeWidget::item:selected { /* Coin Control Item (selected) */
}

View File

@ -779,6 +779,10 @@ AskPassphraseDialog
CoinControlDialog
******************************************************/
QDialog#CoinControlDialog .CoinControlTreeWidget#treeWidget::item {
border-color: #c7c7c7;
}
QDialog#CoinControlDialog .CoinControlTreeWidget#treeWidget::item:selected,
QDialog#CoinControlDialog .CoinControlTreeWidget#treeWidget::item:checked,
QDialog#CoinControlDialog .CoinControlTreeWidget#treeWidget::branch:selected,