27 #define _WIN32_WINNT 0x0501    31 #define _WIN32_IE 0x0501    32 #define WIN32_LEAN_AND_MEAN 1    41 #include <QAbstractItemView>    42 #include <QApplication>    45 #include <QDesktopServices>    46 #include <QDesktopWidget>    47 #include <QDoubleValidator>    48 #include <QFileDialog>    53 #include <QTextDocument>     56 #include <QMouseEvent>    59 #if QT_VERSION >= 0x50200    60 #include <QFontDatabase>    67     return date.date().toString(Qt::SystemLocaleShortDate) + QString(
" ") + date.toString(
"hh:mm");
    72     return dateTimeStr(QDateTime::fromTime_t((qint32)nTime));
    77 #if QT_VERSION >= 0x50200    78     return QFontDatabase::systemFont(QFontDatabase::FixedFont);
    80     QFont font(
"Monospace");
    81     font.setStyleHint(QFont::Monospace);
    87 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};
    90 static std::string DummyAddress(
const CChainParams ¶ms)
    93     sourcedata.insert(sourcedata.end(), dummydata, dummydata + 
sizeof(dummydata));
    94     for(
int i=0; i<256; ++i) { 
    95         std::string s = 
EncodeBase58(sourcedata.data(), sourcedata.data() + sourcedata.size());
    99         sourcedata[sourcedata.size()-1] += 1;
   106     parent->setFocusProxy(widget);
   111     widget->setPlaceholderText(QObject::tr(
"Enter a BSHA3 address (e.g. %1)").arg(
   112         QString::fromStdString(DummyAddress(
Params()))));
   120     if(!uri.isValid() || uri.scheme() != QString(
"bitcoin"))
   126     if (rv.
address.endsWith(
"/")) {
   131     QUrlQuery uriQuery(uri);
   132     QList<QPair<QString, QString> > items = uriQuery.queryItems();
   133     for (QList<QPair<QString, QString> >::iterator i = items.begin(); i != items.end(); i++)
   135         bool fShouldReturnFalse = 
false;
   136         if (i->first.startsWith(
"req-"))
   138             i->first.remove(0, 4);
   139             fShouldReturnFalse = 
true;
   142         if (i->first == 
"label")
   144             rv.
label = i->second;
   145             fShouldReturnFalse = 
false;
   147         if (i->first == 
"message")
   150             fShouldReturnFalse = 
false;
   152         else if (i->first == 
"amount")
   154             if(!i->second.isEmpty())
   161             fShouldReturnFalse = 
false;
   164         if (fShouldReturnFalse)
   176     QUrl uriInstance(uri);
   182     QString 
ret = QString(
"bitcoin:%1").arg(info.
address);
   191     if (!info.
label.isEmpty())
   193         QString lbl(QUrl::toPercentEncoding(info.
label));
   194         ret += QString(
"%1label=%2").arg(paramCount == 0 ? 
"?" : 
"&").arg(lbl);
   200         QString msg(QUrl::toPercentEncoding(info.
message));
   201         ret += QString(
"%1message=%2").arg(paramCount == 0 ? 
"?" : 
"&").arg(msg);
   212     CTxOut txOut(amount, script);
   218     QString escaped = str.toHtmlEscaped();
   221         escaped = escaped.replace(
"\n", 
"<br>\n");
   228     return HtmlEscape(QString::fromStdString(str), fMultiLine);
   233     if(!view || !view->selectionModel())
   235     QModelIndexList selection = view->selectionModel()->selectedRows(column);
   237     if(!selection.isEmpty())
   246     if(!view || !view->selectionModel())
   247         return QList<QModelIndex>();
   248     return view->selectionModel()->selectedRows(column);
   253     QString *selectedSuffixOut)
   255     QString selectedFilter;
   259         myDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
   269     QRegExp filter_re(
".* \\(\\*\\.(.*)[ \\)]");
   270     QString selectedSuffix;
   271     if(filter_re.exactMatch(selectedFilter))
   273         selectedSuffix = filter_re.cap(1);
   277     QFileInfo info(result);
   278     if(!result.isEmpty())
   280         if(info.suffix().isEmpty() && !selectedSuffix.isEmpty())
   283             if(!result.endsWith(
"."))
   285             result.append(selectedSuffix);
   290     if(selectedSuffixOut)
   292         *selectedSuffixOut = selectedSuffix;
   299     QString *selectedSuffixOut)
   301     QString selectedFilter;
   305         myDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
   314     if(selectedSuffixOut)
   317         QRegExp filter_re(
".* \\(\\*\\.(.*)[ \\)]");
   318         QString selectedSuffix;
   319         if(filter_re.exactMatch(selectedFilter))
   321             selectedSuffix = filter_re.cap(1);
   323         *selectedSuffixOut = selectedSuffix;
   330     if(QThread::currentThread() != qApp->thread())
   332         return Qt::BlockingQueuedConnection;
   336         return Qt::DirectConnection;
   342     QWidget *atW = QApplication::widgetAt(w->mapToGlobal(p));
   343     if (!atW) 
return false;
   344     return atW->topLevelWidget() == w;
   352         && 
checkPoint(QPoint(w->width() - 1, w->height() - 1), w)
   353         && 
checkPoint(QPoint(w->width() / 2, w->height() / 2), w));
   358     fs::path pathDebug = 
GetDataDir() / 
"debug.log";
   361     if (fs::exists(pathDebug))
   372     if (!configFile.good())
   378     return QDesktopServices::openUrl(QUrl::fromLocalFile(
boostPathToQString(pathConfig)));
   383     size_threshold(_size_threshold)
   390     if(evt->type() == QEvent::ToolTipChange)
   392         QWidget *widget = 
static_cast<QWidget*
>(obj);
   393         QString tooltip = widget->toolTip();
   394         if(tooltip.size() > 
size_threshold && !tooltip.startsWith(
"<qt") && !Qt::mightBeRichText(tooltip))
   398             tooltip = 
"<qt>" + 
HtmlEscape(tooltip, 
true) + 
"</qt>";
   399             widget->setToolTip(tooltip);
   403     return QObject::eventFilter(obj, evt);
   423     tableView->horizontalHeader()->setSectionResizeMode(logicalIndex, resizeMode);
   428     tableView->setColumnWidth(nColumnIndex, width);
   429     tableView->horizontalHeader()->resizeSection(nColumnIndex, width);
   434     int nColumnsWidthSum = 0;
   437         nColumnsWidthSum += 
tableView->horizontalHeader()->sectionSize(i);
   439     return nColumnsWidthSum;
   445     int nTableWidth = 
tableView->horizontalHeader()->width();
   450         nResult = std::max(nResult, nTableWidth - nOtherColsWidth);
   463     int nTableWidth = 
tableView->horizontalHeader()->width();
   465     if (nColsWidth > nTableWidth)
   484     if (newSize > remainingWidth)
   509     lastColumnMinimumWidth(lastColMinimumWidth),
   510     allColumnsMinimumWidth(allColsMinimumWidth)
   521 fs::path 
static StartupShortcutPath()
   525         return GetSpecialFolderPath(CSIDL_STARTUP) / 
"BSHA3.lnk";
   527         return GetSpecialFolderPath(CSIDL_STARTUP) / 
"BSHA3 (testnet).lnk";
   528     return GetSpecialFolderPath(CSIDL_STARTUP) / 
strprintf(
"BSHA3 (%s).lnk", chain);
   534     return fs::exists(StartupShortcutPath());
   540     fs::remove(StartupShortcutPath());
   544         CoInitialize(
nullptr);
   547         IShellLinkW* psl = 
nullptr;
   548         HRESULT hres = CoCreateInstance(CLSID_ShellLink, 
nullptr,
   549             CLSCTX_INPROC_SERVER, IID_IShellLinkW,
   550             reinterpret_cast<void**>(&psl));
   556             GetModuleFileNameW(
nullptr, pszExePath, ARRAYSIZE(pszExePath));
   559             QString strArgs = 
"-min";
   564             psl->SetPath(pszExePath);
   565             PathRemoveFileSpecW(pszExePath);
   566             psl->SetWorkingDirectory(pszExePath);
   567             psl->SetShowCmd(SW_SHOWMINNOACTIVE);
   568             psl->SetArguments(strArgs.toStdWString().c_str());
   572             IPersistFile* ppf = 
nullptr;
   573             hres = psl->QueryInterface(IID_IPersistFile, reinterpret_cast<void**>(&ppf));
   577                 hres = ppf->Save(StartupShortcutPath().wstring().c_str(), TRUE);
   590 #elif defined(Q_OS_LINUX)   595 fs::path 
static GetAutostartDir()
   597     char* pszConfigHome = getenv(
"XDG_CONFIG_HOME");
   598     if (pszConfigHome) 
return fs::path(pszConfigHome) / 
"autostart";
   599     char* pszHome = getenv(
"HOME");
   600     if (pszHome) 
return fs::path(pszHome) / 
".config" / 
"autostart";
   604 fs::path 
static GetAutostartFilePath()
   608         return GetAutostartDir() / 
"bitcoin.desktop";
   609     return GetAutostartDir() / 
strprintf(
"bitcoin-%s.lnk", chain);
   615     if (!optionFile.good())
   619     while (!optionFile.eof())
   621         getline(optionFile, line);
   622         if (line.find(
"Hidden") != std::string::npos &&
   623             line.find(
"true") != std::string::npos)
   634         fs::remove(GetAutostartFilePath());
   638         ssize_t r = readlink(
"/proc/self/exe", pszExePath, 
sizeof(pszExePath) - 1);
   641         pszExePath[r] = 
'\0';
   643         fs::create_directories(GetAutostartDir());
   645         fsbridge::ofstream optionFile(GetAutostartFilePath(), std::ios_base::out | std::ios_base::trunc);
   646         if (!optionFile.good())
   650         optionFile << 
"[Desktop Entry]\n";
   651         optionFile << 
"Type=Application\n";
   653             optionFile << 
"Name=Bitcoin\n";
   655             optionFile << 
strprintf(
"Name=Bitcoin (%s)\n", chain);
   657         optionFile << 
"Terminal=false\n";
   658         optionFile << 
"Hidden=false\n";
   665 #elif defined(Q_OS_MAC)   666 #pragma GCC diagnostic push   667 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"   670 #include <CoreFoundation/CoreFoundation.h>   671 #include <CoreServices/CoreServices.h>   673 LSSharedFileListItemRef findStartupItemInList(LSSharedFileListRef list, CFURLRef findUrl);
   674 LSSharedFileListItemRef findStartupItemInList(LSSharedFileListRef list, CFURLRef findUrl)
   676     CFArrayRef listSnapshot = LSSharedFileListCopySnapshot(list, 
nullptr);
   677     if (listSnapshot == 
nullptr) {
   682     for(
int i = 0; i < CFArrayGetCount(listSnapshot); i++) {
   683         LSSharedFileListItemRef item = (LSSharedFileListItemRef)CFArrayGetValueAtIndex(listSnapshot, i);
   684         UInt32 resolutionFlags = kLSSharedFileListNoUserInteraction | kLSSharedFileListDoNotMountVolumes;
   685         CFURLRef currentItemURL = 
nullptr;
   687 #if defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED >= 10100   688         if(&LSSharedFileListItemCopyResolvedURL)
   689             currentItemURL = LSSharedFileListItemCopyResolvedURL(item, resolutionFlags, 
nullptr);
   690 #if defined(MAC_OS_X_VERSION_MIN_REQUIRED) && MAC_OS_X_VERSION_MIN_REQUIRED < 10100   692             LSSharedFileListItemResolve(item, resolutionFlags, ¤tItemURL, 
nullptr);
   695         LSSharedFileListItemResolve(item, resolutionFlags, ¤tItemURL, 
nullptr);
   699             if (CFEqual(currentItemURL, findUrl)) {
   701                 CFRelease(listSnapshot);
   702                 CFRelease(currentItemURL);
   705             CFRelease(currentItemURL);
   709     CFRelease(listSnapshot);
   715     CFURLRef bitcoinAppUrl = CFBundleCopyBundleURL(CFBundleGetMainBundle());
   716     if (bitcoinAppUrl == 
nullptr) {
   720     LSSharedFileListRef loginItems = LSSharedFileListCreate(
nullptr, kLSSharedFileListSessionLoginItems, 
nullptr);
   721     LSSharedFileListItemRef foundItem = findStartupItemInList(loginItems, bitcoinAppUrl);
   723     CFRelease(bitcoinAppUrl);
   729     CFURLRef bitcoinAppUrl = CFBundleCopyBundleURL(CFBundleGetMainBundle());
   730     if (bitcoinAppUrl == 
nullptr) {
   734     LSSharedFileListRef loginItems = LSSharedFileListCreate(
nullptr, kLSSharedFileListSessionLoginItems, 
nullptr);
   735     LSSharedFileListItemRef foundItem = findStartupItemInList(loginItems, bitcoinAppUrl);
   737     if(fAutoStart && !foundItem) {
   739         LSSharedFileListInsertItemURL(loginItems, kLSSharedFileListItemBeforeFirst, 
nullptr, 
nullptr, bitcoinAppUrl, 
nullptr, 
nullptr);
   741     else if(!fAutoStart && foundItem) {
   743         LSSharedFileListItemRemove(loginItems, foundItem);
   746     CFRelease(bitcoinAppUrl);
   749 #pragma GCC diagnostic pop   759     QApplication::clipboard()->setText(str, QClipboard::Clipboard);
   760     QApplication::clipboard()->setText(str, QClipboard::Selection);
   765     return fs::path(path.toStdString());
   770     return QString::fromStdString(path.string());
   776     int days = secs / 86400;
   777     int hours = (secs % 86400) / 3600;
   778     int mins = (secs % 3600) / 60;
   779     int seconds = secs % 60;
   782         strList.append(QString(QObject::tr(
"%1 d")).arg(days));
   784         strList.append(QString(QObject::tr(
"%1 h")).arg(hours));
   786         strList.append(QString(QObject::tr(
"%1 m")).arg(mins));
   787     if (seconds || (!days && !hours && !mins))
   788         strList.append(QString(QObject::tr(
"%1 s")).arg(seconds));
   790     return strList.join(
" ");
   798     for (
int i = 0; i < 8; i++) {
   799         uint64_t check = 1 << i;
   805                 strList.append(
"NETWORK");
   808                 strList.append(
"GETUTXO");
   811                 strList.append(
"BLOOM");
   814                 strList.append(
"WITNESS");
   817                 strList.append(
"XTHIN");
   820                 strList.append(QString(
"%1[%2]").arg(
"UNKNOWN").arg(check));
   826         return strList.join(
" & ");
   828         return QObject::tr(
"None");
   833     return (dPingTime == std::numeric_limits<int64_t>::max()/1e6 || dPingTime == 0) ? QObject::tr(
"N/A") : QString(QObject::tr(
"%1 ms")).arg(QString::number((
int)(dPingTime * 1000), 10));
   838   return QString(QObject::tr(
"%1 s")).arg(QString::number((
int)nTimeOffset, 10));
   844     QString timeBehindText;
   845     const int HOUR_IN_SECONDS = 60*60;
   846     const int DAY_IN_SECONDS = 24*60*60;
   847     const int WEEK_IN_SECONDS = 7*24*60*60;
   848     const int YEAR_IN_SECONDS = 31556952; 
   851         timeBehindText = QObject::tr(
"%n second(s)",
"",secs);
   853     else if(secs < 2*HOUR_IN_SECONDS)
   855         timeBehindText = QObject::tr(
"%n minute(s)",
"",secs/60);
   857     else if(secs < 2*DAY_IN_SECONDS)
   859         timeBehindText = QObject::tr(
"%n hour(s)",
"",secs/HOUR_IN_SECONDS);
   861     else if(secs < 2*WEEK_IN_SECONDS)
   863         timeBehindText = QObject::tr(
"%n day(s)",
"",secs/DAY_IN_SECONDS);
   865     else if(secs < YEAR_IN_SECONDS)
   867         timeBehindText = QObject::tr(
"%n week(s)",
"",secs/WEEK_IN_SECONDS);
   871         qint64 years = secs / YEAR_IN_SECONDS;
   872         qint64 remainder = secs % YEAR_IN_SECONDS;
   873         timeBehindText = QObject::tr(
"%1 and %2").arg(QObject::tr(
"%n year(s)", 
"", years)).arg(QObject::tr(
"%n week(s)",
"", remainder/WEEK_IN_SECONDS));
   875     return timeBehindText;
   881         return QString(QObject::tr(
"%1 B")).arg(bytes);
   882     if(bytes < 1024 * 1024)
   883         return QString(QObject::tr(
"%1 KB")).arg(bytes / 1024);
   884     if(bytes < 1024 * 1024 * 1024)
   885         return QString(QObject::tr(
"%1 MB")).arg(bytes / 1024 / 1024);
   887     return QString(QObject::tr(
"%1 GB")).arg(bytes / 1024 / 1024 / 1024);
   891     while(font_size >= minPointSize) {
   892         font.setPointSizeF(font_size);
   893         QFontMetrics fm(font);
   894         if (fm.width(text) < width) {
   914     if (event->type() == QEvent::KeyPress) {
   915         if (static_cast<QKeyEvent*>(event)->key() == Qt::Key_Escape) {
   919     return QItemDelegate::eventFilter(
object, event);
 void stretchColumnWidth(int column)
 
Utility functions used by the Bitcoin Qt UI. 
 
QString getOpenFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedSuffixOut)
Get open filename, convenience wrapper for QFileDialog::getOpenFileName. 
 
QList< QModelIndex > getEntryData(QAbstractItemView *view, int column)
Return a field of the currently selected entry as a QString. 
 
const char *const BITCOIN_CONF_FILENAME
 
void setViewHeaderResizeMode(int logicalIndex, QHeaderView::ResizeMode resizeMode)
 
bool IsValidDestinationString(const std::string &str, const CChainParams ¶ms)
 
void on_geometriesChanged()
 
bool isDust(interfaces::Node &node, const QString &address, const CAmount &amount)
 
int secondToLastColumnIndex
 
UniValue ret(UniValue::VARR)
 
QString dateTimeStr(const QDateTime &date)
 
std::string EncodeBase58(const unsigned char *pbegin, const unsigned char *pend)
Why base-58 instead of standard base-64 encoding? 
 
Qt::ConnectionType blockingGUIThreadConnection()
Get connection type to call object slot in GUI thread with invokeMethod. 
 
QString formatBytes(uint64_t bytes)
 
QString formatTimeOffset(int64_t nTimeOffset)
 
bool GetStartOnSystemStartup()
 
ToolTipToRichTextFilter(int size_threshold, QObject *parent=0)
 
CChainParams defines various tweakable parameters of a given instance of the Bitcoin system...
 
QString HtmlEscape(const QString &str, bool fMultiLine)
 
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value. 
 
void connectViewHeadersSignals()
 
Line edit that can be marked as "invalid" to show input validation feedback. 
 
int getAvailableWidthForColumn(int column)
 
bool parseBitcoinURI(const QUrl &uri, SendCoinsRecipient *out)
 
virtual CFeeRate getDustRelayFee()=0
Get dust relay fee. 
 
QString formatBitcoinURI(const SendCoinsRecipient &info)
 
static bool parse(int unit, const QString &value, CAmount *val_out)
Parse string to coin amount. 
 
static const std::string MAIN
BIP70 chain name strings (main, test or regtest) 
 
TableViewLastColumnResizingFixer(QTableView *table, int lastColMinimumWidth, int allColsMinimumWidth, QObject *parent)
Initializes all internal variables and prepares the the resize modes of the last 2 columns of the tab...
 
int64_t CAmount
Amount in satoshis (Can be negative) 
 
void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent)
 
bool isObscured(QWidget *w)
 
bool eventFilter(QObject *obj, QEvent *evt)
 
qreal calculateIdealFontSize(int width, const QString &text, QFont font, qreal minPointSize, qreal font_size)
 
QString formatDurationStr(int secs)
 
void setClipboard(const QString &str)
 
boost::variant< CNoDestination, CKeyID, CScriptID, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessUnknown > CTxDestination
A txout script template with a specific destination. 
 
int lastColumnMinimumWidth
 
void clicked(const QPoint &point)
Emitted when the label is clicked. 
 
Base58 entry widget validator, checks for valid characters and removes some whitespace. 
 
An output of a transaction. 
 
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination. 
 
bool eventFilter(QObject *object, QEvent *event)
 
QString formatPingTime(double dPingTime)
 
void on_sectionResized(int logicalIndex, int oldSize, int newSize)
 
void mouseReleaseEvent(QMouseEvent *event)
 
CTxDestination DecodeDestination(const std::string &str)
 
void disconnectViewHeadersSignals()
 
int allColumnsMinimumWidth
 
void mouseReleaseEvent(QMouseEvent *event)
 
fs::path qstringToBoostPath(const QString &path)
 
const CChainParams & Params()
Return the currently selected parameters. 
 
fs::path GetConfigFile(const std::string &confPath)
 
Serialized script, used inside transaction inputs and outputs. 
 
QString formatServicesStr(quint64 mask)
 
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 ...
 
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value. 
 
void adjustTableColumnsWidth()
 
bool checkPoint(const QPoint &p, const QWidget *w)
 
void setCheckValidator(const QValidator *v)
 
static const std::string TESTNET
 
bool IsDust(const CTxOut &txout, const CFeeRate &dustRelayFeeIn)
 
std::string GetChainName() const
Looks for -regtest, -testnet and returns the appropriate BIP70 chain name. 
 
bool SetStartOnSystemStartup(bool fAutoStart)
 
const fs::path & GetDataDir(bool fNetSpecific)
 
void clicked(const QPoint &point)
Emitted when the progressbar is clicked. 
 
QString formatNiceTimeOffset(qint64 secs)
 
void copyEntryData(QAbstractItemView *view, int column, int role)
Copy a field of the currently selected entry of a view to the clipboard. 
 
QString boostPathToQString(const fs::path &path)
 
BSHA3 address widget validator, checks for a valid bitcoin address. 
 
Top-level interface for a bitcoin node (bsha3d process). 
 
void resizeColumn(int nColumnIndex, int width)
 
static QString format(int unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=separatorStandard)
Format as string. 
 
const std::vector< unsigned char > & Base58Prefix(Base58Type type) const