28 #define REQUEST_PREPARE_TX 1
29 #define REQUEST_REFRESH_BALANCE 2
34 coinIcon(new QPushButton())
38 this->setStyleSheet(parent->styleSheet());
42 ui->left->setContentsMargins(0,20,0,20);
44 ui->right->setContentsMargins(20,10,20,20);
48 fontLight.setWeight(QFont::Light);
52 ui->labelTitle->setFont(fontLight);
56 ui->pushLeft->setChecked(
true);
73 ui->btnCoinControl->setTitleClassAndText(
"btn-title-grey", tr(
"Coin Control"));
74 ui->btnCoinControl->setSubTitleClassAndText(
"text-subtitle", tr(
"Select the source of the coins"));
77 ui->btnChangeAddress->setTitleClassAndText(
"btn-title-grey", tr(
"Change Address"));
78 ui->btnChangeAddress->setSubTitleClassAndText(
"text-subtitle", tr(
"Customize the change address"));
81 ui->btnUri->setTitleClassAndText(
"btn-title-grey", tr(
"Open URI"));
82 ui->btnUri->setSubTitleClassAndText(
"text-subtitle", tr(
"Parse a PIVX URI"));
85 ui->btnShieldCoins->setTitleClassAndText(
"btn-title-grey", tr(
"Shield Coins"));
86 ui->btnShieldCoins->setSubTitleClassAndText(
"text-subtitle", tr(
"Convert all transparent coins into shielded coins"));
87 ui->btnShieldCoins->setVisible(
false);
94 connect(
ui->pushButtonReset, &QPushButton::clicked, [
this](){ onResetCustomOptions(true); });
116 QSize BUTTON_SIZE = QSize(24, 24);
117 coinIcon->setMinimumSize(BUTTON_SIZE);
118 coinIcon->setMaximumSize(BUTTON_SIZE);
131 connect(
ui->pushLeft, &QPushButton::clicked, [
this](){onPIVSelected(true);});
132 connect(
ui->pushRight, &QPushButton::clicked, [
this](){onPIVSelected(false);});
135 connect(
ui->pushButtonClear, &QPushButton::clicked, [
this](){clearAll(true);});
143 QMutableListIterator<SendMultiRow*> it(
entries);
144 while (it.hasNext()) {
155 QString titleTotalRemaining;
158 std::vector<OutPointWrapper> coins;
161 for (
const auto& coin : coins) {
162 selectedBalance += coin.value;
164 totalAmount = selectedBalance - total;
165 titleTotalRemaining = tr(
"Total remaining from the selected UTXO");
178 titleTotalRemaining = tr(
"Unlocked remaining");
183 QMetaObject::invokeMethod(
this,
"updateAmounts", Qt::QueuedConnection,
184 Q_ARG(QString, titleTotalRemaining),
186 Q_ARG(QString, labelAmountRemaining),
187 Q_ARG(
CAmount, delegatedBalance));
191 const QString& _labelAmountSend,
192 const QString& _labelAmountRemaining,
195 ui->labelTitleTotalRemaining->setText(_titleTotalRemaining);
196 ui->labelAmountSend->setText(_labelAmountSend);
197 ui->labelAmountRemaining->setText(_labelAmountRemaining);
265 ui->btnChangeAddress->setActive(
false);
266 if (
ui->checkBoxDelegations->isChecked())
ui->checkBoxDelegations->setChecked(
false);
268 if (fRefreshAmounts) {
276 ui->btnCoinControl->setActive(
false);
285 ui->btnChangeAddress->setActive(
false);
291 for (
int i = 0; i < num; ++i) {
292 ui->scrollAreaWidgetContents->layout()->takeAt(0)->widget()->deleteLater();
308 }
else if (
entries.length() == MAX_SEND_POPUP_ENTRIES) {
309 inform(tr(
"Maximum amount of outputs reached"));
325 ui->scrollAreaWidgetContents->layout()->addWidget(sendMultiRow);
336 if (!entry || !entry->validate()) {
337 inform(tr(
"Invalid entry, previous entries must be valid before add a new one"));
347 QWidget::resizeEvent(event);
367 const bool hasDel = delegationBalance > 0;
369 const bool showCheckBox =
isTransparent && !isCControl && hasDel;
370 ui->checkBoxDelegations->setVisible(showCheckBox);
372 ui->checkBoxDelegations->setToolTip(
373 tr(
"Possibly spend coins delegated for cold-staking (currently available: %1").arg(
383 QList<SendCoinsRecipient> recipients;
384 bool hasShieldedOutput =
false;
389 if (entry && entry->validate()) {
390 auto recipient = entry->getValue();
391 bool isShielded = recipient.isShieldedAddr;
392 if (!hasShieldedOutput) hasShieldedOutput = isShielded;
393 if (!recipient.message.isEmpty() && !isShielded) {
395 if (!
ask(tr(
"Warning!"),
396 tr(
"Cannot send memo to address\n%1\n\n"
397 "Encrypted memo messages are available only for shielded recipients.\n\n"
398 "Do you wish to proceed without memo?\n").arg(recipient.address))) {
402 recipient.message.clear();
405 recipients.append(recipient);
407 inform(tr(
"Invalid entry"));
412 if (recipients.isEmpty()) {
413 inform(tr(
"No set recipients"));
421 const std::function<
bool(QList<SendCoinsRecipient>&)>& func)
427 inform(tr(
"Sapling Protocol temporarily in maintenance. Shielded transactions disabled (SPORK 20)"));
433 if (!ptrUnlockedContext->isValid()) {
435 inform(tr(
"Cannot send, wallet locked"));
440 if (func && !func(recipients))
return;
444 inform(tr(
"On going process being executed, please wait until it's finished to create a new transaction"));
503 if (!informMsg.isEmpty()) {
504 return errorOut(informMsg.toStdString());
508 return errorOut(
"Cannot create transaction.");
517 QString warningStr = QString();
518 if (fStakeDelegationVoided)
519 warningStr = tr(
"WARNING:\nTransaction spends a cold-stake delegation, voiding it.\n"
520 "These coins will no longer be cold-staked.");
524 dialog->adjustSize();
539 inform(tr(
"Transaction sent"));
540 dialog->deleteLater();
545 dialog->deleteLater();
585 inform(tr(
"Processing full, refreshing amounts later"));
592 QString label = rec.label;
593 if (!label.isNull()) {
595 if (label.compare(labelOld) != 0) {
598 this->walletModel->isMine(dest) ?
627 ui->btnChangeAddress->setActive(
false);
631 tr(
"The change address doesn't belong to this wallet.\n\nDo you want to continue?"))) {
632 dialog->deleteLater();
635 ui->btnChangeAddress->setActive(
true);
640 if (transparentDest) {
649 dialog->deleteLater();
660 inform(tr(
"Invalid URI"));
664 inform(tr(
"Invalid address in URI"));
719 inform(tr(
"Sapling Protocol temporarily in maintenance. Shielded transactions disabled (SPORK 20)"));
725 if (availableBalance > 0) {
728 std::map<WalletModel::ListCoinsKey, std::vector<WalletModel::ListCoinsValue>> mapCoins;
730 unsigned int nBytesInputs = 0;
731 for (
const auto& out : mapCoins) {
732 bool isP2CS = out.first.stakerAddress != nullopt;
746 QList<SendCoinsRecipient> recipients;
748 recipient.
amount = availableBalance - nPayFee;
750 recipients.append(recipient);
753 if (!
ask(tr(
"Shield Coins"),
754 tr(
"You are just about to anonymize all of your balance!\nAvailable %1\nWith fee %2\n\n"
755 "Meaning that you will be able to perform completely\nanonymous transactions"
763 ProcessSend(recipients,
true, [
this](QList<SendCoinsRecipient>& recipients) {
766 inform(tr(
"Error generating address to shield PIVs"));
769 recipients.back().address = QString::fromStdString(res.getObjResult()->ToString());
774 inform(tr(
"You don't have any transparent PIVs to shield."));
782 QMutableListIterator<SendMultiRow*> it(
entries);
783 while (it.hasNext()) {
784 const auto& entry = it.next();
796 const bool checked =
ui->checkBoxDelegations->isChecked();
823 if (contactsSize == 0) {
824 inform(tr(
"No contacts available, you can go to the contacts screen and add some there!"));
840 if (label !=
"(no label)")
865 pos.setX(pos.x() + 20);
876 QPoint pos = entry->pos();
886 this->
menu->setMinimumHeight(157);
887 this->
menu->setMinimumSize(this->
menu->width() + 30, this->menu->height());
905 if (address.isEmpty()) {
906 inform(tr(
"Address field is empty"));
910 bool isStaking =
false, isExchange =
false, isShielded =
false;
914 inform(tr(
"Invalid address"));
919 inform(tr(
"Cannot store your own address as contact"));
926 if (!label.isNull()) {
927 dialog->
setTexts(tr(
"Update Contact"),
"Edit label for the selected address:\n%1");
928 dialog->
setData(address, label);
930 dialog->
setTexts(tr(
"Create New Contact"),
"Save label for the selected address:\n%1");
940 inform(tr(
"New Contact Stored"));
942 inform(tr(
"Error Storing Contact"));
945 dialog->deleteLater();
973 QMutableListIterator<SendMultiRow*> it(
entries);
974 while (it.hasNext()) {
1004 pos.setX(pos.x() + 20);
1015 tr(
"Customize Fee"));
int64_t CAmount
Amount in PIV (Can be negative)
static const QString ShieldedSend
Specifies shielded receive address.
int sizeShieldedSend() const
static const QString Send
Specifies send address.
QString labelForAddress(const QString &address) const
static QString format(int unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=separatorStandard, bool cleanRemainderZeros=true)
Format as string.
static QString formatWithUnit(int unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=separatorStandard)
Format as string (with unit)
MessageBoxFlags
Flags for CClientUIInterface::ThreadSafeMessageBox.
void ListSelected(std::vector< OutPointWrapper > &vOutpoints) const
CTxDestination destChange
Optional< libzcash::SaplingPaymentAddress > destShieldChange
CAmount GetFeePerK() const
void numBlocksChanged(int count)
void setSelectionType(bool isTransparent)
void setModel(WalletModel *model)
CCoinControl * coinControl
void addPayAmount(const CAmount &amount, bool isShieldedRecipient)
void execute(Runnable *runnable, int type, std::unique_ptr< WalletModel::UnlockContext > pctx=nullptr)
std::string getError() const
CWDestination getDestination() const
void setAddress(QString address)
bool isCustomFeeChecked()
void setLabel(const QString &label)
void toggleSubtractFeeFromAmount()
void setNumber(int number)
bool getSubtractFeeFromAmount() const
void setAmount(const QString &amount)
void setAddressAndLabelOrDescription(const QString &address, const QString &message)
void onMenuClicked(SendMultiRow *entry)
void onContactsClicked(SendMultiRow *entry)
void setAddress(const QString &address)
WalletModel::SendCoinsReturn getStatus()
void setDisplayUnit(int unit)
void setData(WalletModel *model, WalletModelTransaction *tx)
bool validateAddress(const QString &address)
bool isMine(const CWDestination &address)
bool updateAddressBookLabels(const CWDestination &address, const std::string &strName, const std::string &strPurpose)
bool isSaplingInMaintenance() const
CAmount getLockedBalance(bool isTransparent) const
void listCoins(std::map< ListCoinsKey, std::vector< ListCoinsValue >> &mapCoins, bool fSelectTransparent) const
void setWalletCustomFee(bool fUseCustomFee, const CAmount nFee=DEFAULT_TRANSACTION_FEE)
CallResult< Destination > getNewShieldedAddress(std::string strLabel="")
Return a new shielded address.
bool getWalletCustomFee(CAmount &nFeeRet)
OperationResult PrepareShieldedTransaction(WalletModelTransaction *modelTransaction, bool fromTransparent, const CCoinControl *coinControl=nullptr)
AddressTableModel * getAddressTableModel()
OptionsModel * getOptionsModel()
SendCoinsReturn prepareTransaction(WalletModelTransaction *transaction, const CCoinControl *coinControl=nullptr, bool fIncludeDelegations=true)
interfaces::WalletBalances GetWalletBalances()
void setWalletDefaultFee(CAmount fee=DEFAULT_TRANSACTION_FEE)
CAmount getBalance(const CCoinControl *coinControl=nullptr, bool fIncludeDelegated=true, bool fUnlockedOnly=false, bool fIncludeShielded=true) const
UnlockContext requestUnlock()
Data model for a walletmodel transaction.
QList< SendCoinsRecipient > getRecipients()
CAmount getTransactionFee()
bool fIsStakeDelegationVoided
boost::variant< CTxDestination, libzcash::SaplingPaymentAddress > CWDestination
const std::string CURRENCY_UNIT
const std::string RECEIVE
QString formatBalanceWithoutHtml(CAmount amount, int nDisplayUnit, bool isZpiv)
QString formatBalance(CAmount amount, int nDisplayUnit, bool isZpiv)
bool parseBitcoinURI(const QUrl &uri, SendCoinsRecipient *out)
void ProcessSendCoinsReturnAndInform(PWidget *parent, const WalletModel::SendCoinsReturn &sendCoinsReturn, WalletModel *walletModel, const QString &msgArg, bool fPrepare)
QString ProcessSendCoinsReturn(const WalletModel::SendCoinsReturn &sendCoinsReturn, WalletModel *walletModel, CClientUIInterface::MessageBoxFlags &informType, const QString &msgArg, bool fPrepare)
std::string EncodePaymentAddress(const libzcash::PaymentAddress &zaddr)
const CTxDestination * GetTransparentDestination(const CWDestination &dest)
bool IsValidDestination(const CWDestination &address)
std::string EncodeDestination(const CWDestination &address, const CChainParams::Base58Type addrType)
CWDestination DecodeDestination(const std::string &strAddress)
const libzcash::SaplingPaymentAddress * GetShieldedDestination(const CWDestination &dest)
OperationResult errorOut(const std::string &errorStr)
bool openDialogWithOpaqueBackgroundFullScreen(QDialog *widget, PIVXGUI *gui)
bool openDialogWithOpaqueBackgroundY(QDialog *widget, PIVXGUI *gui, double posX, int posY, bool hideOpaqueBackground)
void setCssProperty(std::initializer_list< QWidget * > args, const QString &value)
void setCssBtnPrimary(QPushButton *btn, bool forceUpdate)
void setCssBtnSecondary(QPushButton *btn, bool forceUpdate)
void updateStyle(QWidget *widget)
#define CTXIN_SPEND_DUST_SIZE
#define OUTPUTDESCRIPTION_SIZE
#define REQUEST_PREPARE_TX
#define REQUEST_REFRESH_BALANCE
boost::variant< CNoDestination, CKeyID, CScriptID, CExchangeKeyID > CTxDestination
A txout script template with a specific destination.
Collection of wallet balances.
bool error(const char *fmt, const Args &... args)
CAmount GetMinRelayFee(const CTransaction &tx, const CTxMemPool &pool, unsigned int nBytes)