Bitcoin Core  22.99.0
P2P Digital Currency
guiutil.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2021 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 #include <qt/guiutil.h>
6 
8 #include <qt/bitcoinunits.h>
9 #include <qt/platformstyle.h>
10 #include <qt/qvalidatedlineedit.h>
11 #include <qt/sendcoinsrecipient.h>
12 
13 #include <base58.h>
14 #include <chainparams.h>
15 #include <interfaces/node.h>
16 #include <key_io.h>
17 #include <policy/policy.h>
18 #include <primitives/transaction.h>
19 #include <protocol.h>
20 #include <script/script.h>
21 #include <script/standard.h>
22 #include <util/system.h>
23 #include <util/time.h>
24 
25 #ifdef WIN32
26 #ifndef NOMINMAX
27 #define NOMINMAX
28 #endif
29 #include <shellapi.h>
30 #include <shlobj.h>
31 #include <shlwapi.h>
32 #endif
33 
34 #include <QAbstractButton>
35 #include <QAbstractItemView>
36 #include <QApplication>
37 #include <QClipboard>
38 #include <QDateTime>
39 #include <QDesktopServices>
40 #include <QDialog>
41 #include <QDoubleValidator>
42 #include <QFileDialog>
43 #include <QFont>
44 #include <QFontDatabase>
45 #include <QFontMetrics>
46 #include <QGuiApplication>
47 #include <QJsonObject>
48 #include <QKeyEvent>
49 #include <QLatin1String>
50 #include <QLineEdit>
51 #include <QList>
52 #include <QLocale>
53 #include <QMenu>
54 #include <QMouseEvent>
55 #include <QPluginLoader>
56 #include <QProgressDialog>
57 #include <QScreen>
58 #include <QSettings>
59 #include <QShortcut>
60 #include <QSize>
61 #include <QString>
62 #include <QTextDocument> // for Qt::mightBeRichText
63 #include <QThread>
64 #include <QUrlQuery>
65 #include <QtGlobal>
66 
67 #include <cassert>
68 #include <chrono>
69 
70 #if defined(Q_OS_MAC)
71 
72 #include <QProcess>
73 
74 void ForceActivation();
75 #endif
76 
77 namespace GUIUtil {
78 
79 QString dateTimeStr(const QDateTime &date)
80 {
81  return QLocale::system().toString(date.date(), QLocale::ShortFormat) + QString(" ") + date.toString("hh:mm");
82 }
83 
84 QString dateTimeStr(qint64 nTime)
85 {
86  return dateTimeStr(QDateTime::fromSecsSinceEpoch(nTime));
87 }
88 
89 QFont fixedPitchFont(bool use_embedded_font)
90 {
91  if (use_embedded_font) {
92  return {"Roboto Mono"};
93  }
94  return QFontDatabase::systemFont(QFontDatabase::FixedFont);
95 }
96 
97 // Just some dummy data to generate a convincing random-looking (but consistent) address
98 static const uint8_t dummydata[] = {0xeb,0x15,0x23,0x1d,0xfc,0xeb,0x60,0x92,0x58,0x86,0xb6,0x7d,0x06,0x52,0x99,0x92,0x59,0x15,0xae,0xb1,0x72,0xc0,0x66,0x47};
99 
100 // Generate a dummy address with invalid CRC, starting with the network prefix.
101 static std::string DummyAddress(const CChainParams &params)
102 {
103  std::vector<unsigned char> sourcedata = params.Base58Prefix(CChainParams::PUBKEY_ADDRESS);
104  sourcedata.insert(sourcedata.end(), dummydata, dummydata + sizeof(dummydata));
105  for(int i=0; i<256; ++i) { // Try every trailing byte
106  std::string s = EncodeBase58(sourcedata);
107  if (!IsValidDestinationString(s)) {
108  return s;
109  }
110  sourcedata[sourcedata.size()-1] += 1;
111  }
112  return "";
113 }
114 
115 void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent)
116 {
117  parent->setFocusProxy(widget);
118 
119  widget->setFont(fixedPitchFont());
120  // We don't want translators to use own addresses in translations
121  // and this is the only place, where this address is supplied.
122  widget->setPlaceholderText(QObject::tr("Enter a Bitcoin address (e.g. %1)").arg(
123  QString::fromStdString(DummyAddress(Params()))));
124  widget->setValidator(new BitcoinAddressEntryValidator(parent));
125  widget->setCheckValidator(new BitcoinAddressCheckValidator(parent));
126 }
127 
128 void AddButtonShortcut(QAbstractButton* button, const QKeySequence& shortcut)
129 {
130  QObject::connect(new QShortcut(shortcut, button), &QShortcut::activated, [button]() { button->animateClick(); });
131 }
132 
133 bool parseBitcoinURI(const QUrl &uri, SendCoinsRecipient *out)
134 {
135  // return if URI is not valid or is no bitcoin: URI
136  if(!uri.isValid() || uri.scheme() != QString("bitcoin"))
137  return false;
138 
140  rv.address = uri.path();
141  // Trim any following forward slash which may have been added by the OS
142  if (rv.address.endsWith("/")) {
143  rv.address.truncate(rv.address.length() - 1);
144  }
145  rv.amount = 0;
146 
147  QUrlQuery uriQuery(uri);
148  QList<QPair<QString, QString> > items = uriQuery.queryItems();
149  for (QList<QPair<QString, QString> >::iterator i = items.begin(); i != items.end(); i++)
150  {
151  bool fShouldReturnFalse = false;
152  if (i->first.startsWith("req-"))
153  {
154  i->first.remove(0, 4);
155  fShouldReturnFalse = true;
156  }
157 
158  if (i->first == "label")
159  {
160  rv.label = i->second;
161  fShouldReturnFalse = false;
162  }
163  if (i->first == "message")
164  {
165  rv.message = i->second;
166  fShouldReturnFalse = false;
167  }
168  else if (i->first == "amount")
169  {
170  if(!i->second.isEmpty())
171  {
172  if(!BitcoinUnits::parse(BitcoinUnits::BTC, i->second, &rv.amount))
173  {
174  return false;
175  }
176  }
177  fShouldReturnFalse = false;
178  }
179 
180  if (fShouldReturnFalse)
181  return false;
182  }
183  if(out)
184  {
185  *out = rv;
186  }
187  return true;
188 }
189 
190 bool parseBitcoinURI(QString uri, SendCoinsRecipient *out)
191 {
192  QUrl uriInstance(uri);
193  return parseBitcoinURI(uriInstance, out);
194 }
195 
197 {
198  bool bech_32 = info.address.startsWith(QString::fromStdString(Params().Bech32HRP() + "1"));
199 
200  QString ret = QString("bitcoin:%1").arg(bech_32 ? info.address.toUpper() : info.address);
201  int paramCount = 0;
202 
203  if (info.amount)
204  {
205  ret += QString("?amount=%1").arg(BitcoinUnits::format(BitcoinUnits::BTC, info.amount, false, BitcoinUnits::SeparatorStyle::NEVER));
206  paramCount++;
207  }
208 
209  if (!info.label.isEmpty())
210  {
211  QString lbl(QUrl::toPercentEncoding(info.label));
212  ret += QString("%1label=%2").arg(paramCount == 0 ? "?" : "&").arg(lbl);
213  paramCount++;
214  }
215 
216  if (!info.message.isEmpty())
217  {
218  QString msg(QUrl::toPercentEncoding(info.message));
219  ret += QString("%1message=%2").arg(paramCount == 0 ? "?" : "&").arg(msg);
220  paramCount++;
221  }
222 
223  return ret;
224 }
225 
226 bool isDust(interfaces::Node& node, const QString& address, const CAmount& amount)
227 {
228  CTxDestination dest = DecodeDestination(address.toStdString());
229  CScript script = GetScriptForDestination(dest);
230  CTxOut txOut(amount, script);
231  return IsDust(txOut, node.getDustRelayFee());
232 }
233 
234 QString HtmlEscape(const QString& str, bool fMultiLine)
235 {
236  QString escaped = str.toHtmlEscaped();
237  if(fMultiLine)
238  {
239  escaped = escaped.replace("\n", "<br>\n");
240  }
241  return escaped;
242 }
243 
244 QString HtmlEscape(const std::string& str, bool fMultiLine)
245 {
246  return HtmlEscape(QString::fromStdString(str), fMultiLine);
247 }
248 
249 void copyEntryData(const QAbstractItemView *view, int column, int role)
250 {
251  if(!view || !view->selectionModel())
252  return;
253  QModelIndexList selection = view->selectionModel()->selectedRows(column);
254 
255  if(!selection.isEmpty())
256  {
257  // Copy first item
258  setClipboard(selection.at(0).data(role).toString());
259  }
260 }
261 
262 QList<QModelIndex> getEntryData(const QAbstractItemView *view, int column)
263 {
264  if(!view || !view->selectionModel())
265  return QList<QModelIndex>();
266  return view->selectionModel()->selectedRows(column);
267 }
268 
269 bool hasEntryData(const QAbstractItemView *view, int column, int role)
270 {
271  QModelIndexList selection = getEntryData(view, column);
272  if (selection.isEmpty()) return false;
273  return !selection.at(0).data(role).toString().isEmpty();
274 }
275 
276 void LoadFont(const QString& file_name)
277 {
278  const int id = QFontDatabase::addApplicationFont(file_name);
279  assert(id != -1);
280 }
281 
283 {
285 }
286 
287 QString getSaveFileName(QWidget *parent, const QString &caption, const QString &dir,
288  const QString &filter,
289  QString *selectedSuffixOut)
290 {
291  QString selectedFilter;
292  QString myDir;
293  if(dir.isEmpty()) // Default to user documents location
294  {
295  myDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
296  }
297  else
298  {
299  myDir = dir;
300  }
301  /* Directly convert path to native OS path separators */
302  QString result = QDir::toNativeSeparators(QFileDialog::getSaveFileName(parent, caption, myDir, filter, &selectedFilter));
303 
304  /* Extract first suffix from filter pattern "Description (*.foo)" or "Description (*.foo *.bar ...) */
305  QRegExp filter_re(".* \\(\\*\\.(.*)[ \\)]");
306  QString selectedSuffix;
307  if(filter_re.exactMatch(selectedFilter))
308  {
309  selectedSuffix = filter_re.cap(1);
310  }
311 
312  /* Add suffix if needed */
313  QFileInfo info(result);
314  if(!result.isEmpty())
315  {
316  if(info.suffix().isEmpty() && !selectedSuffix.isEmpty())
317  {
318  /* No suffix specified, add selected suffix */
319  if(!result.endsWith("."))
320  result.append(".");
321  result.append(selectedSuffix);
322  }
323  }
324 
325  /* Return selected suffix if asked to */
326  if(selectedSuffixOut)
327  {
328  *selectedSuffixOut = selectedSuffix;
329  }
330  return result;
331 }
332 
333 QString getOpenFileName(QWidget *parent, const QString &caption, const QString &dir,
334  const QString &filter,
335  QString *selectedSuffixOut)
336 {
337  QString selectedFilter;
338  QString myDir;
339  if(dir.isEmpty()) // Default to user documents location
340  {
341  myDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
342  }
343  else
344  {
345  myDir = dir;
346  }
347  /* Directly convert path to native OS path separators */
348  QString result = QDir::toNativeSeparators(QFileDialog::getOpenFileName(parent, caption, myDir, filter, &selectedFilter));
349 
350  if(selectedSuffixOut)
351  {
352  /* Extract first suffix from filter pattern "Description (*.foo)" or "Description (*.foo *.bar ...) */
353  QRegExp filter_re(".* \\(\\*\\.(.*)[ \\)]");
354  QString selectedSuffix;
355  if(filter_re.exactMatch(selectedFilter))
356  {
357  selectedSuffix = filter_re.cap(1);
358  }
359  *selectedSuffixOut = selectedSuffix;
360  }
361  return result;
362 }
363 
365 {
366  if(QThread::currentThread() != qApp->thread())
367  {
368  return Qt::BlockingQueuedConnection;
369  }
370  else
371  {
372  return Qt::DirectConnection;
373  }
374 }
375 
376 bool checkPoint(const QPoint &p, const QWidget *w)
377 {
378  QWidget *atW = QApplication::widgetAt(w->mapToGlobal(p));
379  if (!atW) return false;
380  return atW->window() == w;
381 }
382 
383 bool isObscured(QWidget *w)
384 {
385  return !(checkPoint(QPoint(0, 0), w)
386  && checkPoint(QPoint(w->width() - 1, 0), w)
387  && checkPoint(QPoint(0, w->height() - 1), w)
388  && checkPoint(QPoint(w->width() - 1, w->height() - 1), w)
389  && checkPoint(QPoint(w->width() / 2, w->height() / 2), w));
390 }
391 
392 void bringToFront(QWidget* w)
393 {
394 #ifdef Q_OS_MAC
395  ForceActivation();
396 #endif
397 
398  if (w) {
399  // activateWindow() (sometimes) helps with keyboard focus on Windows
400  if (w->isMinimized()) {
401  w->showNormal();
402  } else {
403  w->show();
404  }
405  w->activateWindow();
406  w->raise();
407  }
408 }
409 
411 {
412  QObject::connect(new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_W), w), &QShortcut::activated, w, &QWidget::close);
413 }
414 
416 {
417  fs::path pathDebug = gArgs.GetDataDirNet() / "debug.log";
418 
419  /* Open debug.log with the associated application */
420  if (fs::exists(pathDebug))
421  QDesktopServices::openUrl(QUrl::fromLocalFile(PathToQString(pathDebug)));
422 }
423 
425 {
426  fs::path pathConfig = GetConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME));
427 
428  /* Create the file */
429  fsbridge::ofstream configFile(pathConfig, std::ios_base::app);
430 
431  if (!configFile.good())
432  return false;
433 
434  configFile.close();
435 
436  /* Open bitcoin.conf with the associated application */
437  bool res = QDesktopServices::openUrl(QUrl::fromLocalFile(PathToQString(pathConfig)));
438 #ifdef Q_OS_MAC
439  // Workaround for macOS-specific behavior; see #15409.
440  if (!res) {
441  res = QProcess::startDetached("/usr/bin/open", QStringList{"-t", PathToQString(pathConfig)});
442  }
443 #endif
444 
445  return res;
446 }
447 
448 ToolTipToRichTextFilter::ToolTipToRichTextFilter(int _size_threshold, QObject *parent) :
449  QObject(parent),
450  size_threshold(_size_threshold)
451 {
452 
453 }
454 
455 bool ToolTipToRichTextFilter::eventFilter(QObject *obj, QEvent *evt)
456 {
457  if(evt->type() == QEvent::ToolTipChange)
458  {
459  QWidget *widget = static_cast<QWidget*>(obj);
460  QString tooltip = widget->toolTip();
461  if(tooltip.size() > size_threshold && !tooltip.startsWith("<qt") && !Qt::mightBeRichText(tooltip))
462  {
463  // Envelop with <qt></qt> to make sure Qt detects this as rich text
464  // Escape the current message as HTML and replace \n by <br>
465  tooltip = "<qt>" + HtmlEscape(tooltip, true) + "</qt>";
466  widget->setToolTip(tooltip);
467  return true;
468  }
469  }
470  return QObject::eventFilter(obj, evt);
471 }
472 
474  : QObject(parent)
475 {
476 }
477 
478 bool LabelOutOfFocusEventFilter::eventFilter(QObject* watched, QEvent* event)
479 {
480  if (event->type() == QEvent::FocusOut) {
481  auto focus_out = static_cast<QFocusEvent*>(event);
482  if (focus_out->reason() != Qt::PopupFocusReason) {
483  auto label = qobject_cast<QLabel*>(watched);
484  if (label) {
485  auto flags = label->textInteractionFlags();
486  label->setTextInteractionFlags(Qt::NoTextInteraction);
487  label->setTextInteractionFlags(flags);
488  }
489  }
490  }
491 
492  return QObject::eventFilter(watched, event);
493 }
494 
495 #ifdef WIN32
496 fs::path static StartupShortcutPath()
497 {
498  std::string chain = gArgs.GetChainName();
499  if (chain == CBaseChainParams::MAIN)
500  return GetSpecialFolderPath(CSIDL_STARTUP) / "Bitcoin.lnk";
501  if (chain == CBaseChainParams::TESTNET) // Remove this special case when CBaseChainParams::TESTNET = "testnet4"
502  return GetSpecialFolderPath(CSIDL_STARTUP) / "Bitcoin (testnet).lnk";
503  return GetSpecialFolderPath(CSIDL_STARTUP) / strprintf("Bitcoin (%s).lnk", chain);
504 }
505 
507 {
508  // check for Bitcoin*.lnk
509  return fs::exists(StartupShortcutPath());
510 }
511 
512 bool SetStartOnSystemStartup(bool fAutoStart)
513 {
514  // If the shortcut exists already, remove it for updating
515  fs::remove(StartupShortcutPath());
516 
517  if (fAutoStart)
518  {
519  CoInitialize(nullptr);
520 
521  // Get a pointer to the IShellLink interface.
522  IShellLinkW* psl = nullptr;
523  HRESULT hres = CoCreateInstance(CLSID_ShellLink, nullptr,
524  CLSCTX_INPROC_SERVER, IID_IShellLinkW,
525  reinterpret_cast<void**>(&psl));
526 
527  if (SUCCEEDED(hres))
528  {
529  // Get the current executable path
530  WCHAR pszExePath[MAX_PATH];
531  GetModuleFileNameW(nullptr, pszExePath, ARRAYSIZE(pszExePath));
532 
533  // Start client minimized
534  QString strArgs = "-min";
535  // Set -testnet /-regtest options
536  strArgs += QString::fromStdString(strprintf(" -chain=%s", gArgs.GetChainName()));
537 
538  // Set the path to the shortcut target
539  psl->SetPath(pszExePath);
540  PathRemoveFileSpecW(pszExePath);
541  psl->SetWorkingDirectory(pszExePath);
542  psl->SetShowCmd(SW_SHOWMINNOACTIVE);
543  psl->SetArguments(strArgs.toStdWString().c_str());
544 
545  // Query IShellLink for the IPersistFile interface for
546  // saving the shortcut in persistent storage.
547  IPersistFile* ppf = nullptr;
548  hres = psl->QueryInterface(IID_IPersistFile, reinterpret_cast<void**>(&ppf));
549  if (SUCCEEDED(hres))
550  {
551  // Save the link by calling IPersistFile::Save.
552  hres = ppf->Save(StartupShortcutPath().wstring().c_str(), TRUE);
553  ppf->Release();
554  psl->Release();
555  CoUninitialize();
556  return true;
557  }
558  psl->Release();
559  }
560  CoUninitialize();
561  return false;
562  }
563  return true;
564 }
565 #elif defined(Q_OS_LINUX)
566 
567 // Follow the Desktop Application Autostart Spec:
568 // https://specifications.freedesktop.org/autostart-spec/autostart-spec-latest.html
569 
570 fs::path static GetAutostartDir()
571 {
572  char* pszConfigHome = getenv("XDG_CONFIG_HOME");
573  if (pszConfigHome) return fs::path(pszConfigHome) / "autostart";
574  char* pszHome = getenv("HOME");
575  if (pszHome) return fs::path(pszHome) / ".config" / "autostart";
576  return fs::path();
577 }
578 
579 fs::path static GetAutostartFilePath()
580 {
581  std::string chain = gArgs.GetChainName();
582  if (chain == CBaseChainParams::MAIN)
583  return GetAutostartDir() / "bitcoin.desktop";
584  return GetAutostartDir() / strprintf("bitcoin-%s.desktop", chain);
585 }
586 
588 {
589  fsbridge::ifstream optionFile(GetAutostartFilePath());
590  if (!optionFile.good())
591  return false;
592  // Scan through file for "Hidden=true":
593  std::string line;
594  while (!optionFile.eof())
595  {
596  getline(optionFile, line);
597  if (line.find("Hidden") != std::string::npos &&
598  line.find("true") != std::string::npos)
599  return false;
600  }
601  optionFile.close();
602 
603  return true;
604 }
605 
606 bool SetStartOnSystemStartup(bool fAutoStart)
607 {
608  if (!fAutoStart)
609  fs::remove(GetAutostartFilePath());
610  else
611  {
612  char pszExePath[MAX_PATH+1];
613  ssize_t r = readlink("/proc/self/exe", pszExePath, sizeof(pszExePath) - 1);
614  if (r == -1)
615  return false;
616  pszExePath[r] = '\0';
617 
618  fs::create_directories(GetAutostartDir());
619 
620  fsbridge::ofstream optionFile(GetAutostartFilePath(), std::ios_base::out | std::ios_base::trunc);
621  if (!optionFile.good())
622  return false;
623  std::string chain = gArgs.GetChainName();
624  // Write a bitcoin.desktop file to the autostart directory:
625  optionFile << "[Desktop Entry]\n";
626  optionFile << "Type=Application\n";
627  if (chain == CBaseChainParams::MAIN)
628  optionFile << "Name=Bitcoin\n";
629  else
630  optionFile << strprintf("Name=Bitcoin (%s)\n", chain);
631  optionFile << "Exec=" << pszExePath << strprintf(" -min -chain=%s\n", chain);
632  optionFile << "Terminal=false\n";
633  optionFile << "Hidden=false\n";
634  optionFile.close();
635  }
636  return true;
637 }
638 
639 #else
640 
641 bool GetStartOnSystemStartup() { return false; }
642 bool SetStartOnSystemStartup(bool fAutoStart) { return false; }
643 
644 #endif
645 
646 void setClipboard(const QString& str)
647 {
648  QClipboard* clipboard = QApplication::clipboard();
649  clipboard->setText(str, QClipboard::Clipboard);
650  if (clipboard->supportsSelection()) {
651  clipboard->setText(str, QClipboard::Selection);
652  }
653 }
654 
655 fs::path QStringToPath(const QString &path)
656 {
657  return fs::u8path(path.toStdString());
658 }
659 
660 QString PathToQString(const fs::path &path)
661 {
662  return QString::fromStdString(path.u8string());
663 }
664 
666 {
667  switch (net) {
668  case NET_UNROUTABLE: return QObject::tr("Unroutable");
669  case NET_IPV4: return "IPv4";
670  case NET_IPV6: return "IPv6";
671  case NET_ONION: return "Onion";
672  case NET_I2P: return "I2P";
673  case NET_CJDNS: return "CJDNS";
674  case NET_INTERNAL: return QObject::tr("Internal");
675  case NET_MAX: assert(false);
676  } // no default case, so the compiler can warn about missing cases
677  assert(false);
678 }
679 
680 QString ConnectionTypeToQString(ConnectionType conn_type, bool prepend_direction)
681 {
682  QString prefix;
683  if (prepend_direction) {
684  prefix = (conn_type == ConnectionType::INBOUND) ?
685  /*: An inbound connection from a peer. An inbound connection
686  is a connection initiated by a peer. */
687  QObject::tr("Inbound") :
688  /*: An outbound connection to a peer. An outbound connection
689  is a connection initiated by us. */
690  QObject::tr("Outbound") + " ";
691  }
692  switch (conn_type) {
693  case ConnectionType::INBOUND: return prefix;
694  //: Peer connection type that relays all network information.
695  case ConnectionType::OUTBOUND_FULL_RELAY: return prefix + QObject::tr("Full Relay");
696  /*: Peer connection type that relays network information about
697  blocks and not transactions or addresses. */
698  case ConnectionType::BLOCK_RELAY: return prefix + QObject::tr("Block Relay");
699  //: Peer connection type established manually through one of several methods.
700  case ConnectionType::MANUAL: return prefix + QObject::tr("Manual");
701  //: Short-lived peer connection type that tests the aliveness of known addresses.
702  case ConnectionType::FEELER: return prefix + QObject::tr("Feeler");
703  //: Short-lived peer connection type that solicits known addresses from a peer.
704  case ConnectionType::ADDR_FETCH: return prefix + QObject::tr("Address Fetch");
705  } // no default case, so the compiler can warn about missing cases
706  assert(false);
707 }
708 
709 QString formatDurationStr(std::chrono::seconds dur)
710 {
711  const auto secs = count_seconds(dur);
712  QStringList strList;
713  int days = secs / 86400;
714  int hours = (secs % 86400) / 3600;
715  int mins = (secs % 3600) / 60;
716  int seconds = secs % 60;
717 
718  if (days)
719  strList.append(QObject::tr("%1 d").arg(days));
720  if (hours)
721  strList.append(QObject::tr("%1 h").arg(hours));
722  if (mins)
723  strList.append(QObject::tr("%1 m").arg(mins));
724  if (seconds || (!days && !hours && !mins))
725  strList.append(QObject::tr("%1 s").arg(seconds));
726 
727  return strList.join(" ");
728 }
729 
730 QString formatServicesStr(quint64 mask)
731 {
732  QStringList strList;
733 
734  for (const auto& flag : serviceFlagsToStr(mask)) {
735  strList.append(QString::fromStdString(flag));
736  }
737 
738  if (strList.size())
739  return strList.join(", ");
740  else
741  return QObject::tr("None");
742 }
743 
744 QString formatPingTime(std::chrono::microseconds ping_time)
745 {
746  return (ping_time == std::chrono::microseconds::max() || ping_time == 0us) ?
747  QObject::tr("N/A") :
748  QObject::tr("%1 ms").arg(QString::number((int)(count_microseconds(ping_time) / 1000), 10));
749 }
750 
751 QString formatTimeOffset(int64_t nTimeOffset)
752 {
753  return QObject::tr("%1 s").arg(QString::number((int)nTimeOffset, 10));
754 }
755 
756 QString formatNiceTimeOffset(qint64 secs)
757 {
758  // Represent time from last generated block in human readable text
759  QString timeBehindText;
760  const int HOUR_IN_SECONDS = 60*60;
761  const int DAY_IN_SECONDS = 24*60*60;
762  const int WEEK_IN_SECONDS = 7*24*60*60;
763  const int YEAR_IN_SECONDS = 31556952; // Average length of year in Gregorian calendar
764  if(secs < 60)
765  {
766  timeBehindText = QObject::tr("%n second(s)","",secs);
767  }
768  else if(secs < 2*HOUR_IN_SECONDS)
769  {
770  timeBehindText = QObject::tr("%n minute(s)","",secs/60);
771  }
772  else if(secs < 2*DAY_IN_SECONDS)
773  {
774  timeBehindText = QObject::tr("%n hour(s)","",secs/HOUR_IN_SECONDS);
775  }
776  else if(secs < 2*WEEK_IN_SECONDS)
777  {
778  timeBehindText = QObject::tr("%n day(s)","",secs/DAY_IN_SECONDS);
779  }
780  else if(secs < YEAR_IN_SECONDS)
781  {
782  timeBehindText = QObject::tr("%n week(s)","",secs/WEEK_IN_SECONDS);
783  }
784  else
785  {
786  qint64 years = secs / YEAR_IN_SECONDS;
787  qint64 remainder = secs % YEAR_IN_SECONDS;
788  timeBehindText = QObject::tr("%1 and %2").arg(QObject::tr("%n year(s)", "", years)).arg(QObject::tr("%n week(s)","", remainder/WEEK_IN_SECONDS));
789  }
790  return timeBehindText;
791 }
792 
793 QString formatBytes(uint64_t bytes)
794 {
795  if (bytes < 1'000)
796  return QObject::tr("%1 B").arg(bytes);
797  if (bytes < 1'000'000)
798  return QObject::tr("%1 kB").arg(bytes / 1'000);
799  if (bytes < 1'000'000'000)
800  return QObject::tr("%1 MB").arg(bytes / 1'000'000);
801 
802  return QObject::tr("%1 GB").arg(bytes / 1'000'000'000);
803 }
804 
805 qreal calculateIdealFontSize(int width, const QString& text, QFont font, qreal minPointSize, qreal font_size) {
806  while(font_size >= minPointSize) {
807  font.setPointSizeF(font_size);
808  QFontMetrics fm(font);
809  if (TextWidth(fm, text) < width) {
810  break;
811  }
812  font_size -= 0.5;
813  }
814  return font_size;
815 }
816 
817 ThemedLabel::ThemedLabel(const PlatformStyle* platform_style, QWidget* parent)
818  : QLabel{parent}, m_platform_style{platform_style}
819 {
820  assert(m_platform_style);
821 }
822 
823 void ThemedLabel::setThemedPixmap(const QString& image_filename, int width, int height)
824 {
825  m_image_filename = image_filename;
826  m_pixmap_width = width;
827  m_pixmap_height = height;
829 }
830 
832 {
833  if (e->type() == QEvent::PaletteChange) {
835  }
836 
837  QLabel::changeEvent(e);
838 }
839 
841 {
843 }
844 
845 ClickableLabel::ClickableLabel(const PlatformStyle* platform_style, QWidget* parent)
846  : ThemedLabel{platform_style, parent}
847 {
848 }
849 
850 void ClickableLabel::mouseReleaseEvent(QMouseEvent *event)
851 {
852  Q_EMIT clicked(event->pos());
853 }
854 
856 {
857  Q_EMIT clicked(event->pos());
858 }
859 
860 bool ItemDelegate::eventFilter(QObject *object, QEvent *event)
861 {
862  if (event->type() == QEvent::KeyPress) {
863  if (static_cast<QKeyEvent*>(event)->key() == Qt::Key_Escape) {
864  Q_EMIT keyEscapePressed();
865  }
866  }
867  return QItemDelegate::eventFilter(object, event);
868 }
869 
870 void PolishProgressDialog(QProgressDialog* dialog)
871 {
872 #ifdef Q_OS_MAC
873  // Workaround for macOS-only Qt bug; see: QTBUG-65750, QTBUG-70357.
874  const int margin = TextWidth(dialog->fontMetrics(), ("X"));
875  dialog->resize(dialog->width() + 2 * margin, dialog->height());
876 #endif
877  // QProgressDialog estimates the time the operation will take (based on time
878  // for steps), and only shows itself if that estimate is beyond minimumDuration.
879  // The default minimumDuration value is 4 seconds, and it could make users
880  // think that the GUI is frozen.
881  dialog->setMinimumDuration(0);
882 }
883 
884 int TextWidth(const QFontMetrics& fm, const QString& text)
885 {
886 #if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
887  return fm.horizontalAdvance(text);
888 #else
889  return fm.width(text);
890 #endif
891 }
892 
893 void LogQtInfo()
894 {
895 #ifdef QT_STATIC
896  const std::string qt_link{"static"};
897 #else
898  const std::string qt_link{"dynamic"};
899 #endif
900 #ifdef QT_STATICPLUGIN
901  const std::string plugin_link{"static"};
902 #else
903  const std::string plugin_link{"dynamic"};
904 #endif
905  LogPrintf("Qt %s (%s), plugin=%s (%s)\n", qVersion(), qt_link, QGuiApplication::platformName().toStdString(), plugin_link);
906  const auto static_plugins = QPluginLoader::staticPlugins();
907  if (static_plugins.empty()) {
908  LogPrintf("No static plugins.\n");
909  } else {
910  LogPrintf("Static plugins:\n");
911  for (const QStaticPlugin& p : static_plugins) {
912  QJsonObject meta_data = p.metaData();
913  const std::string plugin_class = meta_data.take(QString("className")).toString().toStdString();
914  const int plugin_version = meta_data.take(QString("version")).toInt();
915  LogPrintf(" %s, version %d\n", plugin_class, plugin_version);
916  }
917  }
918 
919  LogPrintf("Style: %s / %s\n", QApplication::style()->objectName().toStdString(), QApplication::style()->metaObject()->className());
920  LogPrintf("System: %s, %s\n", QSysInfo::prettyProductName().toStdString(), QSysInfo::buildAbi().toStdString());
921  for (const QScreen* s : QGuiApplication::screens()) {
922  LogPrintf("Screen: %s %dx%d, pixel ratio=%.1f\n", s->name().toStdString(), s->size().width(), s->size().height(), s->devicePixelRatio());
923  }
924 }
925 
926 void PopupMenu(QMenu* menu, const QPoint& point, QAction* at_action)
927 {
928  // The qminimal plugin does not provide window system integration.
929  if (QApplication::platformName() == "minimal") return;
930  menu->popup(point, at_action);
931 }
932 
933 QDateTime StartOfDay(const QDate& date)
934 {
935 #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
936  return date.startOfDay();
937 #else
938  return QDateTime(date);
939 #endif
940 }
941 
942 bool HasPixmap(const QLabel* label)
943 {
944 #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
945  return !label->pixmap(Qt::ReturnByValue).isNull();
946 #else
947  return label->pixmap() != nullptr;
948 #endif
949 }
950 
951 QImage GetImage(const QLabel* label)
952 {
953  if (!HasPixmap(label)) {
954  return QImage();
955  }
956 
957 #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
958  return label->pixmap(Qt::ReturnByValue).toImage();
959 #else
960  return label->pixmap()->toImage();
961 #endif
962 }
963 
964 QString MakeHtmlLink(const QString& source, const QString& link)
965 {
966  return QString(source).replace(
967  link,
968  QLatin1String("<a href=\"") + link + QLatin1String("\">") + link + QLatin1String("</a>"));
969 }
970 
972  const std::exception* exception,
973  const QObject* sender,
974  const QObject* receiver)
975 {
976  std::string description = sender->metaObject()->className();
977  description += "->";
978  description += receiver->metaObject()->className();
979  PrintExceptionContinue(exception, description.c_str());
980 }
981 
982 void ShowModalDialogAndDeleteOnClose(QDialog* dialog)
983 {
984  dialog->setAttribute(Qt::WA_DeleteOnClose);
985  dialog->setWindowModality(Qt::ApplicationModal);
986  dialog->show();
987 }
988 
989 } // namespace GUIUtil
SendCoinsRecipient::amount
CAmount amount
Definition: sendcoinsrecipient.h:33
QValidatedLineEdit::setCheckValidator
void setCheckValidator(const QValidator *v)
Definition: qvalidatedlineedit.cpp:106
policy.h
GUIUtil::PathToQString
QString PathToQString(const fs::path &path)
Convert OS specific boost path to QString through UTF-8.
Definition: guiutil.cpp:660
BitcoinUnits::SeparatorStyle::NEVER
@ NEVER
fs::exists
static bool exists(const path &p)
Definition: fs.h:77
fsbridge::ifstream
fs::ifstream ifstream
Definition: fs.h:234
GUIUtil::openBitcoinConf
bool openBitcoinConf()
Definition: guiutil.cpp:424
GUIUtil::PopupMenu
void PopupMenu(QMenu *menu, const QPoint &point, QAction *at_action)
Call QMenu::popup() only on supported QT_QPA_PLATFORM.
Definition: guiutil.cpp:926
NET_UNROUTABLE
@ NET_UNROUTABLE
Addresses from these networks are not publicly routable on the global Internet.
Definition: netaddress.h:47
assert
assert(!tx.IsCoinBase())
NET_IPV4
@ NET_IPV4
IPv4.
Definition: netaddress.h:50
GUIUtil::QStringToPath
fs::path QStringToPath(const QString &path)
Convert QString to OS specific boost path through UTF-8.
Definition: guiutil.cpp:655
BitcoinAddressCheckValidator
Bitcoin address widget validator, checks for a valid bitcoin address.
Definition: bitcoinaddressvalidator.h:25
GetDefaultDataDir
fs::path GetDefaultDataDir()
Definition: system.cpp:783
flags
int flags
Definition: bitcoin-tx.cpp:525
ArgsManager::GetDataDirNet
const fs::path & GetDataDirNet() const
Get data directory path with appended network identifier.
Definition: system.h:288
key_io.h
GUIUtil::ToolTipToRichTextFilter::ToolTipToRichTextFilter
ToolTipToRichTextFilter(int size_threshold, QObject *parent=nullptr)
Definition: guiutil.cpp:448
PlatformStyle::SingleColorIcon
QIcon SingleColorIcon(const QString &filename) const
Colorize an icon (given filename) with the icon color.
Definition: platformstyle.cpp:105
GUIUtil::SetStartOnSystemStartup
bool SetStartOnSystemStartup(bool fAutoStart)
Definition: guiutil.cpp:642
NET_INTERNAL
@ NET_INTERNAL
A set of addresses that represent the hash of a string or FQDN.
Definition: netaddress.h:66
transaction.h
GetScriptForDestination
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
Definition: standard.cpp:310
GUIUtil::ItemDelegate::eventFilter
bool eventFilter(QObject *object, QEvent *event) override
Definition: guiutil.cpp:860
source
const char * source
Definition: rpcconsole.cpp:64
NET_MAX
@ NET_MAX
Dummy value to indicate the number of NET_* constants.
Definition: netaddress.h:69
GUIUtil::ClickableProgressBar::clicked
void clicked(const QPoint &point)
Emitted when the progressbar is clicked.
ArgsManager::GetChainName
std::string GetChainName() const
Returns the appropriate chain name from the program arguments.
Definition: system.cpp:984
ConnectionType::OUTBOUND_FULL_RELAY
@ OUTBOUND_FULL_RELAY
These are the default connections that we use to connect with the network.
SendCoinsRecipient::label
QString label
Definition: sendcoinsrecipient.h:32
serviceFlagsToStr
std::vector< std::string > serviceFlagsToStr(uint64_t flags)
Convert service flags (a bitmask of NODE_*) to human readable strings.
Definition: protocol.cpp:210
CBaseChainParams::TESTNET
static const std::string TESTNET
Definition: chainparamsbase.h:23
GUIUtil
Utility functions used by the Bitcoin Qt UI.
Definition: bitcoingui.h:59
CChainParams
CChainParams defines various tweakable parameters of a given instance of the Bitcoin system.
Definition: chainparams.h:69
GUIUtil::openDebugLogfile
void openDebugLogfile()
Definition: guiutil.cpp:415
GUIUtil::hasEntryData
bool hasEntryData(const QAbstractItemView *view, int column, int role)
Returns true if the specified field of the currently selected view entry is not empty.
Definition: guiutil.cpp:269
GUIUtil::parseBitcoinURI
bool parseBitcoinURI(const QUrl &uri, SendCoinsRecipient *out)
Definition: guiutil.cpp:133
GUIUtil::formatBitcoinURI
QString formatBitcoinURI(const SendCoinsRecipient &info)
Definition: guiutil.cpp:196
GUIUtil::bringToFront
void bringToFront(QWidget *w)
Definition: guiutil.cpp:392
chainparams.h
Network
Network
A network type.
Definition: netaddress.h:45
GUIUtil::ItemDelegate::keyEscapePressed
void keyEscapePressed()
BITCOIN_CONF_FILENAME
const char *const BITCOIN_CONF_FILENAME
Definition: system.cpp:77
GUIUtil::isObscured
bool isObscured(QWidget *w)
Definition: guiutil.cpp:383
ConnectionType::MANUAL
@ MANUAL
We open manual connections to addresses that users explicitly requested via the addnode RPC or the -a...
GUIUtil::setClipboard
void setClipboard(const QString &str)
Definition: guiutil.cpp:646
BitcoinUnits::parse
static bool parse(int unit, const QString &value, CAmount *val_out)
Parse string to coin amount.
Definition: bitcoinunits.cpp:174
prefix
const char * prefix
Definition: rest.cpp:926
GUIUtil::ClickableLabel::ClickableLabel
ClickableLabel(const PlatformStyle *platform_style, QWidget *parent=nullptr)
Definition: guiutil.cpp:845
GUIUtil::GetImage
QImage GetImage(const QLabel *label)
Definition: guiutil.cpp:951
ConnectionType::INBOUND
@ INBOUND
Inbound connections are those initiated by a peer.
GUIUtil::ThemedLabel::m_pixmap_width
int m_pixmap_width
Definition: guiutil.h:255
fsbridge::ofstream
fs::ofstream ofstream
Definition: fs.h:235
SendCoinsRecipient
Definition: sendcoinsrecipient.h:19
NET_I2P
@ NET_I2P
I2P.
Definition: netaddress.h:59
GUIUtil::ConnectionTypeToQString
QString ConnectionTypeToQString(ConnectionType conn_type, bool prepend_direction)
Convert enum ConnectionType to QString.
Definition: guiutil.cpp:680
GUIUtil::checkPoint
bool checkPoint(const QPoint &p, const QWidget *w)
Definition: guiutil.cpp:376
GUIUtil::dummydata
static const uint8_t dummydata[]
Definition: guiutil.cpp:98
GUIUtil::ThemedLabel
Definition: guiutil.h:241
GUIUtil::formatTimeOffset
QString formatTimeOffset(int64_t nTimeOffset)
Format a CNodeCombinedStats.nTimeOffset into a user-readable string.
Definition: guiutil.cpp:751
GUIUtil::formatDurationStr
QString formatDurationStr(std::chrono::seconds dur)
Convert seconds into a QString with days, hours, mins, secs.
Definition: guiutil.cpp:709
EncodeBase58
std::string EncodeBase58(Span< const unsigned char > input)
Why base-58 instead of standard base-64 encoding?
Definition: base58.cpp:87
CTxDestination
std::variant< CNoDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:157
GUIUtil::getOpenFileName
QString getOpenFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedSuffixOut)
Get open filename, convenience wrapper for QFileDialog::getOpenFileName.
Definition: guiutil.cpp:333
GUIUtil::formatNiceTimeOffset
QString formatNiceTimeOffset(qint64 secs)
Definition: guiutil.cpp:756
CTxOut
An output of a transaction.
Definition: transaction.h:128
GUIUtil::StartOfDay
QDateTime StartOfDay(const QDate &date)
Returns the start-moment of the day in local time.
Definition: guiutil.cpp:933
fs::path
Path class wrapper to prepare application code for transition from boost::filesystem library to std::...
Definition: fs.h:33
GUIUtil::ClickableLabel::clicked
void clicked(const QPoint &point)
Emitted when the label is clicked.
node.h
GUIUtil::PrintSlotException
void PrintSlotException(const std::exception *exception, const QObject *sender, const QObject *receiver)
Definition: guiutil.cpp:971
GUIUtil::ClickableLabel::mouseReleaseEvent
void mouseReleaseEvent(QMouseEvent *event) override
Definition: guiutil.cpp:850
GUIUtil::LabelOutOfFocusEventFilter::eventFilter
bool eventFilter(QObject *watched, QEvent *event) override
Definition: guiutil.cpp:478
GUIUtil::ThemedLabel::changeEvent
void changeEvent(QEvent *e) override
Definition: guiutil.cpp:831
CChainParams::Base58Prefix
const std::vector< unsigned char > & Base58Prefix(Base58Type type) const
Definition: chainparams.h:115
time.h
ArgsManager::GetArg
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: system.cpp:585
GUIUtil::PolishProgressDialog
void PolishProgressDialog(QProgressDialog *dialog)
Definition: guiutil.cpp:870
LogPrintf
#define LogPrintf(...)
Definition: logging.h:187
CAmount
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
QValidatedLineEdit
Line edit that can be marked as "invalid" to show input validation feedback.
Definition: qvalidatedlineedit.h:13
standard.h
GUIUtil::AddButtonShortcut
void AddButtonShortcut(QAbstractButton *button, const QKeySequence &shortcut)
Connects an additional shortcut to a QAbstractButton.
Definition: guiutil.cpp:128
guiutil.h
BitcoinAddressEntryValidator
Base58 entry widget validator, checks for valid characters and removes some whitespace.
Definition: bitcoinaddressvalidator.h:13
GUIUtil::formatBytes
QString formatBytes(uint64_t bytes)
Definition: guiutil.cpp:793
GUIUtil::formatServicesStr
QString formatServicesStr(quint64 mask)
Format CNodeStats.nServices bitmask into a user-readable string.
Definition: guiutil.cpp:730
CScript
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:405
ConnectionType::FEELER
@ FEELER
Feeler connections are short-lived connections made to check that a node is alive.
script.h
GUIUtil::fixedPitchFont
QFont fixedPitchFont(bool use_embedded_font)
Definition: guiutil.cpp:89
gArgs
ArgsManager gArgs
Definition: system.cpp:80
GUIUtil::MakeHtmlLink
QString MakeHtmlLink(const QString &source, const QString &link)
Replaces a plain text link with an HTML tagged one.
Definition: guiutil.cpp:964
GUIUtil::getDefaultDataDirectory
QString getDefaultDataDirectory()
Determine default data directory for operating system.
Definition: guiutil.cpp:282
interfaces::Node
Top-level interface for a bitcoin node (bitcoind process).
Definition: node.h:68
qvalidatedlineedit.h
GUIUtil::HasPixmap
bool HasPixmap(const QLabel *label)
Returns true if pixmap has been set.
Definition: guiutil.cpp:942
CBaseChainParams::MAIN
static const std::string MAIN
Chain name strings.
Definition: chainparamsbase.h:22
GUIUtil::ToolTipToRichTextFilter::eventFilter
bool eventFilter(QObject *obj, QEvent *evt) override
Definition: guiutil.cpp:455
SUCCEEDED
@ SUCCEEDED
Succeeded.
Definition: netbase.cpp:266
GUIUtil::getSaveFileName
QString getSaveFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedSuffixOut)
Get save filename, mimics QFileDialog::getSaveFileName, except that it appends a default suffix when ...
Definition: guiutil.cpp:287
fs::path::u8string
std::string u8string() const
Definition: fs.h:59
platformstyle.h
GUIUtil::ThemedLabel::m_pixmap_height
int m_pixmap_height
Definition: guiutil.h:256
system.h
strprintf
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1164
GUIUtil::LabelOutOfFocusEventFilter::LabelOutOfFocusEventFilter
LabelOutOfFocusEventFilter(QObject *parent)
Definition: guiutil.cpp:473
count_microseconds
constexpr int64_t count_microseconds(std::chrono::microseconds t)
Definition: time.h:31
GUIUtil::GetStartOnSystemStartup
bool GetStartOnSystemStartup()
Definition: guiutil.cpp:641
GUIUtil::ThemedLabel::m_image_filename
QString m_image_filename
Definition: guiutil.h:254
GUIUtil::DummyAddress
static std::string DummyAddress(const CChainParams &params)
Definition: guiutil.cpp:101
GUIUtil::HtmlEscape
QString HtmlEscape(const QString &str, bool fMultiLine)
Definition: guiutil.cpp:234
bitcoinaddressvalidator.h
GUIUtil::copyEntryData
void copyEntryData(const QAbstractItemView *view, int column, int role)
Copy a field of the currently selected entry of a view to the clipboard.
Definition: guiutil.cpp:249
GetConfigFile
fs::path GetConfigFile(const std::string &confPath)
Definition: system.cpp:814
GUIUtil::ThemedLabel::ThemedLabel
ThemedLabel(const PlatformStyle *platform_style, QWidget *parent=nullptr)
Definition: guiutil.cpp:817
ConnectionType::ADDR_FETCH
@ ADDR_FETCH
AddrFetch connections are short lived connections used to solicit addresses from peers.
SendCoinsRecipient::address
QString address
Definition: sendcoinsrecipient.h:31
fs::u8path
static path u8path(const std::string &string)
Definition: fs.h:63
NET_ONION
@ NET_ONION
TOR (v2 or v3)
Definition: netaddress.h:56
GUIUtil::ToolTipToRichTextFilter::size_threshold
int size_threshold
Definition: guiutil.h:190
DecodeDestination
CTxDestination DecodeDestination(const std::string &str, std::string &error_msg, std::vector< int > *error_locations)
Definition: key_io.cpp:281
GUIUtil::blockingGUIThreadConnection
Qt::ConnectionType blockingGUIThreadConnection()
Get connection type to call object slot in GUI thread with invokeMethod.
Definition: guiutil.cpp:364
GUIUtil::NetworkToQString
QString NetworkToQString(Network net)
Convert enum Network to QString.
Definition: guiutil.cpp:665
GUIUtil::LogQtInfo
void LogQtInfo()
Writes to debug.log short info about the used Qt and the host system.
Definition: guiutil.cpp:893
Params
const CChainParams & Params()
Return the currently selected parameters.
Definition: chainparams.cpp:561
count_seconds
constexpr int64_t count_seconds(std::chrono::seconds t)
Helper to count the seconds of a duration.
Definition: time.h:29
IsDust
bool IsDust(const CTxOut &txout, const CFeeRate &dustRelayFeeIn)
Definition: policy.cpp:53
CChainParams::PUBKEY_ADDRESS
@ PUBKEY_ADDRESS
Definition: chainparams.h:73
bitcoinunits.h
node
Definition: init.h:22
IsValidDestinationString
bool IsValidDestinationString(const std::string &str, const CChainParams &params)
Definition: key_io.cpp:292
ForceActivation
void ForceActivation()
Force application activation on macOS.
Definition: macdockiconhandler.mm:50
GUIUtil::ClickableProgressBar::mouseReleaseEvent
void mouseReleaseEvent(QMouseEvent *event) override
Definition: guiutil.cpp:855
GUIUtil::ShowModalDialogAndDeleteOnClose
void ShowModalDialogAndDeleteOnClose(QDialog *dialog)
Shows a QDialog instance asynchronously, and deletes it on close.
Definition: guiutil.cpp:982
NET_IPV6
@ NET_IPV6
IPv6.
Definition: netaddress.h:53
GUIUtil::calculateIdealFontSize
qreal calculateIdealFontSize(int width, const QString &text, QFont font, qreal minPointSize, qreal font_size)
Definition: guiutil.cpp:805
GUIUtil::isDust
bool isDust(interfaces::Node &node, const QString &address, const CAmount &amount)
Definition: guiutil.cpp:226
base58.h
GUIUtil::TextWidth
int TextWidth(const QFontMetrics &fm, const QString &text)
Returns the distance in pixels appropriate for drawing a subsequent character after text.
Definition: guiutil.cpp:884
GUIUtil::dateTimeStr
QString dateTimeStr(const QDateTime &date)
Definition: guiutil.cpp:79
ConnectionType::BLOCK_RELAY
@ BLOCK_RELAY
We use block-relay-only connections to help prevent against partition attacks.
GUIUtil::handleCloseWindowShortcut
void handleCloseWindowShortcut(QWidget *w)
Definition: guiutil.cpp:410
PrintExceptionContinue
void PrintExceptionContinue(const std::exception *pex, const char *pszThread)
Definition: system.cpp:776
GUIUtil::getEntryData
QList< QModelIndex > getEntryData(const QAbstractItemView *view, int column)
Return a field of the currently selected entry as a QString.
Definition: guiutil.cpp:262
NET_CJDNS
@ NET_CJDNS
CJDNS.
Definition: netaddress.h:62
GUIUtil::ThemedLabel::setThemedPixmap
void setThemedPixmap(const QString &image_filename, int width, int height)
Definition: guiutil.cpp:823
GUIUtil::LoadFont
void LoadFont(const QString &file_name)
Loads the font from the file specified by file_name, aborts if it fails.
Definition: guiutil.cpp:276
PlatformStyle
Definition: platformstyle.h:13
GUIUtil::formatPingTime
QString formatPingTime(std::chrono::microseconds ping_time)
Format a CNodeStats.m_last_ping_time into a user-readable string or display N/A, if 0.
Definition: guiutil.cpp:744
GUIUtil::setupAddressWidget
void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent)
Definition: guiutil.cpp:115
GUIUtil::ThemedLabel::m_platform_style
const PlatformStyle * m_platform_style
Definition: guiutil.h:253
ConnectionType
ConnectionType
Different types of connections to a peer.
Definition: net.h:121
MAX_PATH
#define MAX_PATH
Definition: compat.h:71
sendcoinsrecipient.h
GUIUtil::ThemedLabel::updateThemedPixmap
void updateThemedPixmap()
Definition: guiutil.cpp:840
BitcoinUnits::BTC
@ BTC
Definition: bitcoinunits.h:43
BitcoinUnits::format
static QString format(int unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=SeparatorStyle::STANDARD, bool justify=false)
Format as string.
Definition: bitcoinunits.cpp:103
SendCoinsRecipient::message
QString message
Definition: sendcoinsrecipient.h:35