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