Changeset View
Changeset View
Standalone View
Standalone View
src/qt/guiutil.cpp
Show First 20 Lines • Show All 300 Lines • ▼ Show 20 Lines | QString HtmlEscape(const QString &str, bool fMultiLine) { | ||||
return escaped; | return escaped; | ||||
} | } | ||||
QString HtmlEscape(const std::string &str, bool fMultiLine) { | QString HtmlEscape(const std::string &str, bool fMultiLine) { | ||||
return HtmlEscape(QString::fromStdString(str), fMultiLine); | return HtmlEscape(QString::fromStdString(str), fMultiLine); | ||||
} | } | ||||
void copyEntryData(QAbstractItemView *view, int column, int role) { | void copyEntryData(QAbstractItemView *view, int column, int role) { | ||||
if (!view || !view->selectionModel()) return; | if (!view || !view->selectionModel()) { | ||||
return; | |||||
} | |||||
QModelIndexList selection = view->selectionModel()->selectedRows(column); | QModelIndexList selection = view->selectionModel()->selectedRows(column); | ||||
if (!selection.isEmpty()) { | if (!selection.isEmpty()) { | ||||
// Copy first item | // Copy first item | ||||
setClipboard(selection.at(0).data(role).toString()); | setClipboard(selection.at(0).data(role).toString()); | ||||
} | } | ||||
} | } | ||||
QList<QModelIndex> getEntryData(QAbstractItemView *view, int column) { | QList<QModelIndex> getEntryData(QAbstractItemView *view, int column) { | ||||
if (!view || !view->selectionModel()) return QList<QModelIndex>(); | if (!view || !view->selectionModel()) { | ||||
return QList<QModelIndex>(); | |||||
} | |||||
return view->selectionModel()->selectedRows(column); | return view->selectionModel()->selectedRows(column); | ||||
} | } | ||||
QString getSaveFileName(QWidget *parent, const QString &caption, | QString getSaveFileName(QWidget *parent, const QString &caption, | ||||
const QString &dir, const QString &filter, | const QString &dir, const QString &filter, | ||||
QString *selectedSuffixOut) { | QString *selectedSuffixOut) { | ||||
QString selectedFilter; | QString selectedFilter; | ||||
QString myDir; | QString myDir; | ||||
Show All 16 Lines | if (filter_re.exactMatch(selectedFilter)) { | ||||
selectedSuffix = filter_re.cap(1); | selectedSuffix = filter_re.cap(1); | ||||
} | } | ||||
/* Add suffix if needed */ | /* Add suffix if needed */ | ||||
QFileInfo info(result); | QFileInfo info(result); | ||||
if (!result.isEmpty()) { | if (!result.isEmpty()) { | ||||
if (info.suffix().isEmpty() && !selectedSuffix.isEmpty()) { | if (info.suffix().isEmpty() && !selectedSuffix.isEmpty()) { | ||||
/* No suffix specified, add selected suffix */ | /* No suffix specified, add selected suffix */ | ||||
if (!result.endsWith(".")) result.append("."); | if (!result.endsWith(".")) { | ||||
result.append("."); | |||||
} | |||||
result.append(selectedSuffix); | result.append(selectedSuffix); | ||||
} | } | ||||
} | } | ||||
/* Return selected suffix if asked to */ | /* Return selected suffix if asked to */ | ||||
if (selectedSuffixOut) { | if (selectedSuffixOut) { | ||||
*selectedSuffixOut = selectedSuffix; | *selectedSuffixOut = selectedSuffix; | ||||
} | } | ||||
return result; | return result; | ||||
} | } | ||||
QString getOpenFileName(QWidget *parent, const QString &caption, | QString getOpenFileName(QWidget *parent, const QString &caption, | ||||
const QString &dir, const QString &filter, | const QString &dir, const QString &filter, | ||||
QString *selectedSuffixOut) { | QString *selectedSuffixOut) { | ||||
QString selectedFilter; | QString selectedFilter; | ||||
QString myDir; | QString myDir; | ||||
if (dir.isEmpty()) // Default to user documents location | // Default to user documents location | ||||
{ | if (dir.isEmpty()) { | ||||
myDir = | myDir = | ||||
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); | QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); | ||||
} else { | } else { | ||||
myDir = dir; | myDir = dir; | ||||
} | } | ||||
/* Directly convert path to native OS path separators */ | /* Directly convert path to native OS path separators */ | ||||
QString result = QDir::toNativeSeparators(QFileDialog::getOpenFileName( | QString result = QDir::toNativeSeparators(QFileDialog::getOpenFileName( | ||||
parent, caption, myDir, filter, &selectedFilter)); | parent, caption, myDir, filter, &selectedFilter)); | ||||
Show All 16 Lines | if (QThread::currentThread() != qApp->thread()) { | ||||
return Qt::BlockingQueuedConnection; | return Qt::BlockingQueuedConnection; | ||||
} else { | } else { | ||||
return Qt::DirectConnection; | return Qt::DirectConnection; | ||||
} | } | ||||
} | } | ||||
bool checkPoint(const QPoint &p, const QWidget *w) { | bool checkPoint(const QPoint &p, const QWidget *w) { | ||||
QWidget *atW = QApplication::widgetAt(w->mapToGlobal(p)); | QWidget *atW = QApplication::widgetAt(w->mapToGlobal(p)); | ||||
if (!atW) return false; | if (!atW) { | ||||
return false; | |||||
} | |||||
return atW->topLevelWidget() == w; | return atW->topLevelWidget() == w; | ||||
} | } | ||||
bool isObscured(QWidget *w) { | bool isObscured(QWidget *w) { | ||||
return !(checkPoint(QPoint(0, 0), w) && | return !(checkPoint(QPoint(0, 0), w) && | ||||
checkPoint(QPoint(w->width() - 1, 0), w) && | checkPoint(QPoint(w->width() - 1, 0), w) && | ||||
checkPoint(QPoint(0, w->height() - 1), w) && | checkPoint(QPoint(0, w->height() - 1), w) && | ||||
checkPoint(QPoint(w->width() - 1, w->height() - 1), w) && | checkPoint(QPoint(w->width() - 1, w->height() - 1), w) && | ||||
checkPoint(QPoint(w->width() / 2, w->height() / 2), w)); | checkPoint(QPoint(w->width() / 2, w->height() / 2), w)); | ||||
} | } | ||||
void openDebugLogfile() { | void openDebugLogfile() { | ||||
fs::path pathDebug = GetDataDir() / "debug.log"; | fs::path pathDebug = GetDataDir() / "debug.log"; | ||||
/* Open debug.log with the associated application */ | /* Open debug.log with the associated application */ | ||||
if (fs::exists(pathDebug)) | if (fs::exists(pathDebug)) { | ||||
QDesktopServices::openUrl( | QDesktopServices::openUrl( | ||||
QUrl::fromLocalFile(boostPathToQString(pathDebug))); | QUrl::fromLocalFile(boostPathToQString(pathDebug))); | ||||
} | } | ||||
} | |||||
void SubstituteFonts(const QString &language) { | void SubstituteFonts(const QString &language) { | ||||
#if defined(Q_OS_MAC) | #if defined(Q_OS_MAC) | ||||
// Background: | // Background: | ||||
// OSX's default font changed in 10.9 and Qt is unable to find it with its | // OSX's default font changed in 10.9 and Qt is unable to find it with its | ||||
// usual fallback methods when building against the 10.7 sdk or lower. | // usual fallback methods when building against the 10.7 sdk or lower. | ||||
// The 10.8 SDK added a function to let it find the correct fallback font. | // The 10.8 SDK added a function to let it find the correct fallback font. | ||||
// If this fallback is not properly loaded, some characters may fail to | // If this fallback is not properly loaded, some characters may fail to | ||||
// render correctly. | // render correctly. | ||||
// | // | ||||
// The same thing happened with 10.10. .Helvetica Neue DeskInterface is now | // The same thing happened with 10.10. .Helvetica Neue DeskInterface is now | ||||
// default. | // default. | ||||
// | // | ||||
// Solution: If building with the 10.7 SDK or lower and the user's platform | // Solution: If building with the 10.7 SDK or lower and the user's platform | ||||
// is 10.9 or higher at runtime, substitute the correct font. This needs to | // is 10.9 or higher at runtime, substitute the correct font. This needs to | ||||
// happen before the QApplication is created. | // happen before the QApplication is created. | ||||
#if defined(MAC_OS_X_VERSION_MAX_ALLOWED) && \ | #if defined(MAC_OS_X_VERSION_MAX_ALLOWED) && \ | ||||
MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_8 | MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_8 | ||||
if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_8) { | if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_8) { | ||||
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_9) | if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_9) { | ||||
/* On a 10.9 - 10.9.x system */ | /* On a 10.9 - 10.9.x system */ | ||||
QFont::insertSubstitution(".Lucida Grande UI", "Lucida Grande"); | QFont::insertSubstitution(".Lucida Grande UI", "Lucida Grande"); | ||||
else { | } else { | ||||
/* 10.10 or later system */ | /* 10.10 or later system */ | ||||
if (language == "zh_CN" || language == "zh_TW" || | if (language == "zh_CN" || language == "zh_TW" || | ||||
language == "zh_HK") // traditional or simplified Chinese | language == "zh_HK") { | ||||
// traditional or simplified Chinese | |||||
QFont::insertSubstitution(".Helvetica Neue DeskInterface", | QFont::insertSubstitution(".Helvetica Neue DeskInterface", | ||||
"Heiti SC"); | "Heiti SC"); | ||||
else if (language == "ja") // Japanesee | } else if (language == "ja") { | ||||
// Japanesee | |||||
QFont::insertSubstitution(".Helvetica Neue DeskInterface", | QFont::insertSubstitution(".Helvetica Neue DeskInterface", | ||||
"Songti SC"); | "Songti SC"); | ||||
else | } else { | ||||
QFont::insertSubstitution(".Helvetica Neue DeskInterface", | QFont::insertSubstitution(".Helvetica Neue DeskInterface", | ||||
"Lucida Grande"); | "Lucida Grande"); | ||||
} | } | ||||
} | } | ||||
} | |||||
#endif | #endif | ||||
#endif | #endif | ||||
} | } | ||||
ToolTipToRichTextFilter::ToolTipToRichTextFilter(int _size_threshold, | ToolTipToRichTextFilter::ToolTipToRichTextFilter(int _size_threshold, | ||||
QObject *parent) | QObject *parent) | ||||
: QObject(parent), size_threshold(_size_threshold) {} | : QObject(parent), size_threshold(_size_threshold) {} | ||||
▲ Show 20 Lines • Show All 130 Lines • ▼ Show 20 Lines | tableView->horizontalHeader()->setMinimumSectionSize( | ||||
allColumnsMinimumWidth); | allColumnsMinimumWidth); | ||||
setViewHeaderResizeMode(secondToLastColumnIndex, QHeaderView::Interactive); | setViewHeaderResizeMode(secondToLastColumnIndex, QHeaderView::Interactive); | ||||
setViewHeaderResizeMode(lastColumnIndex, QHeaderView::Interactive); | setViewHeaderResizeMode(lastColumnIndex, QHeaderView::Interactive); | ||||
} | } | ||||
#ifdef WIN32 | #ifdef WIN32 | ||||
static fs::path StartupShortcutPath() { | static fs::path StartupShortcutPath() { | ||||
std::string chain = gArgs.GetChainName(); | std::string chain = gArgs.GetChainName(); | ||||
if (chain == CBaseChainParams::MAIN) | if (chain == CBaseChainParams::MAIN) { | ||||
return GetSpecialFolderPath(CSIDL_STARTUP) / "Bitcoin.lnk"; | return GetSpecialFolderPath(CSIDL_STARTUP) / "Bitcoin.lnk"; | ||||
} | |||||
// Remove this special case when CBaseChainParams::TESTNET = "testnet4" | // Remove this special case when CBaseChainParams::TESTNET = "testnet4" | ||||
if (chain == CBaseChainParams::TESTNET) | if (chain == CBaseChainParams::TESTNET) { | ||||
return GetSpecialFolderPath(CSIDL_STARTUP) / "Bitcoin (testnet).lnk"; | return GetSpecialFolderPath(CSIDL_STARTUP) / "Bitcoin (testnet).lnk"; | ||||
} | |||||
return GetSpecialFolderPath(CSIDL_STARTUP) / | return GetSpecialFolderPath(CSIDL_STARTUP) / | ||||
strprintf("Bitcoin (%s).lnk", chain); | strprintf("Bitcoin (%s).lnk", chain); | ||||
} | } | ||||
bool GetStartOnSystemStartup() { | bool GetStartOnSystemStartup() { | ||||
// check for Bitcoin*.lnk | // check for Bitcoin*.lnk | ||||
return fs::exists(StartupShortcutPath()); | return fs::exists(StartupShortcutPath()); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 69 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
#elif defined(Q_OS_LINUX) | #elif defined(Q_OS_LINUX) | ||||
// Follow the Desktop Application Autostart Spec: | // Follow the Desktop Application Autostart Spec: | ||||
// http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html | // http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html | ||||
static fs::path GetAutostartDir() { | static fs::path GetAutostartDir() { | ||||
char *pszConfigHome = getenv("XDG_CONFIG_HOME"); | char *pszConfigHome = getenv("XDG_CONFIG_HOME"); | ||||
if (pszConfigHome) return fs::path(pszConfigHome) / "autostart"; | if (pszConfigHome) { | ||||
return fs::path(pszConfigHome) / "autostart"; | |||||
} | |||||
char *pszHome = getenv("HOME"); | char *pszHome = getenv("HOME"); | ||||
if (pszHome) return fs::path(pszHome) / ".config" / "autostart"; | if (pszHome) { | ||||
return fs::path(pszHome) / ".config" / "autostart"; | |||||
} | |||||
return fs::path(); | return fs::path(); | ||||
} | } | ||||
static fs::path GetAutostartFilePath() { | static fs::path GetAutostartFilePath() { | ||||
std::string chain = gArgs.GetChainName(); | std::string chain = gArgs.GetChainName(); | ||||
if (chain == CBaseChainParams::MAIN) | if (chain == CBaseChainParams::MAIN) { | ||||
return GetAutostartDir() / "bitcoin.desktop"; | return GetAutostartDir() / "bitcoin.desktop"; | ||||
} | |||||
return GetAutostartDir() / strprintf("bitcoin-%s.lnk", chain); | return GetAutostartDir() / strprintf("bitcoin-%s.lnk", chain); | ||||
} | } | ||||
bool GetStartOnSystemStartup() { | bool GetStartOnSystemStartup() { | ||||
fs::ifstream optionFile(GetAutostartFilePath()); | fs::ifstream optionFile(GetAutostartFilePath()); | ||||
if (!optionFile.good()) return false; | if (!optionFile.good()) { | ||||
return false; | |||||
} | |||||
// Scan through file for "Hidden=true": | // Scan through file for "Hidden=true": | ||||
std::string line; | std::string line; | ||||
while (!optionFile.eof()) { | while (!optionFile.eof()) { | ||||
getline(optionFile, line); | getline(optionFile, line); | ||||
if (line.find("Hidden") != std::string::npos && | if (line.find("Hidden") != std::string::npos && | ||||
line.find("true") != std::string::npos) | line.find("true") != std::string::npos) { | ||||
return false; | return false; | ||||
} | } | ||||
} | |||||
optionFile.close(); | optionFile.close(); | ||||
return true; | return true; | ||||
} | } | ||||
bool SetStartOnSystemStartup(bool fAutoStart) { | bool SetStartOnSystemStartup(bool fAutoStart) { | ||||
if (!fAutoStart) | if (!fAutoStart) { | ||||
fs::remove(GetAutostartFilePath()); | fs::remove(GetAutostartFilePath()); | ||||
else { | } else { | ||||
char pszExePath[MAX_PATH + 1]; | char pszExePath[MAX_PATH + 1]; | ||||
memset(pszExePath, 0, sizeof(pszExePath)); | memset(pszExePath, 0, sizeof(pszExePath)); | ||||
if (readlink("/proc/self/exe", pszExePath, sizeof(pszExePath) - 1) == | if (readlink("/proc/self/exe", pszExePath, sizeof(pszExePath) - 1) == | ||||
-1) | -1) { | ||||
return false; | return false; | ||||
} | |||||
fs::create_directories(GetAutostartDir()); | fs::create_directories(GetAutostartDir()); | ||||
fs::ofstream optionFile(GetAutostartFilePath(), | fs::ofstream optionFile(GetAutostartFilePath(), | ||||
std::ios_base::out | std::ios_base::trunc); | std::ios_base::out | std::ios_base::trunc); | ||||
if (!optionFile.good()) return false; | if (!optionFile.good()) { | ||||
return false; | |||||
} | |||||
std::string chain = gArgs.GetChainName(); | std::string chain = gArgs.GetChainName(); | ||||
// Write a bitcoin.desktop file to the autostart directory: | // Write a bitcoin.desktop file to the autostart directory: | ||||
optionFile << "[Desktop Entry]\n"; | optionFile << "[Desktop Entry]\n"; | ||||
optionFile << "Type=Application\n"; | optionFile << "Type=Application\n"; | ||||
if (chain == CBaseChainParams::MAIN) | if (chain == CBaseChainParams::MAIN) { | ||||
optionFile << "Name=Bitcoin\n"; | optionFile << "Name=Bitcoin\n"; | ||||
else | } else { | ||||
optionFile << strprintf("Name=Bitcoin (%s)\n", chain); | optionFile << strprintf("Name=Bitcoin (%s)\n", chain); | ||||
} | |||||
optionFile << "Exec=" << pszExePath | optionFile << "Exec=" << pszExePath | ||||
<< strprintf(" -min -testnet=%d -regtest=%d\n", | << strprintf(" -min -testnet=%d -regtest=%d\n", | ||||
gArgs.GetBoolArg("-testnet", false), | gArgs.GetBoolArg("-testnet", false), | ||||
gArgs.GetBoolArg("-regtest", false)); | gArgs.GetBoolArg("-regtest", false)); | ||||
optionFile << "Terminal=false\n"; | optionFile << "Terminal=false\n"; | ||||
optionFile << "Hidden=false\n"; | optionFile << "Hidden=false\n"; | ||||
optionFile.close(); | optionFile.close(); | ||||
} | } | ||||
Show All 18 Lines | for (int i = 0; !foundItem && i < CFArrayGetCount(listSnapshot); ++i) { | ||||
LSSharedFileListItemRef item = | LSSharedFileListItemRef item = | ||||
(LSSharedFileListItemRef)CFArrayGetValueAtIndex(listSnapshot, i); | (LSSharedFileListItemRef)CFArrayGetValueAtIndex(listSnapshot, i); | ||||
UInt32 resolutionFlags = kLSSharedFileListNoUserInteraction | | UInt32 resolutionFlags = kLSSharedFileListNoUserInteraction | | ||||
kLSSharedFileListDoNotMountVolumes; | kLSSharedFileListDoNotMountVolumes; | ||||
CFURLRef currentItemURL = nullptr; | CFURLRef currentItemURL = nullptr; | ||||
#if defined(MAC_OS_X_VERSION_MAX_ALLOWED) && \ | #if defined(MAC_OS_X_VERSION_MAX_ALLOWED) && \ | ||||
MAC_OS_X_VERSION_MAX_ALLOWED >= 10100 | MAC_OS_X_VERSION_MAX_ALLOWED >= 10100 | ||||
if (&LSSharedFileListItemCopyResolvedURL) | if (&LSSharedFileListItemCopyResolvedURL) { | ||||
currentItemURL = LSSharedFileListItemCopyResolvedURL( | currentItemURL = LSSharedFileListItemCopyResolvedURL( | ||||
item, resolutionFlags, nullptr); | item, resolutionFlags, nullptr); | ||||
} | |||||
#if defined(MAC_OS_X_VERSION_MIN_REQUIRED) && \ | #if defined(MAC_OS_X_VERSION_MIN_REQUIRED) && \ | ||||
MAC_OS_X_VERSION_MIN_REQUIRED < 10100 | MAC_OS_X_VERSION_MIN_REQUIRED < 10100 | ||||
else | else { | ||||
LSSharedFileListItemResolve(item, resolutionFlags, ¤tItemURL, | LSSharedFileListItemResolve(item, resolutionFlags, ¤tItemURL, | ||||
nullptr); | nullptr); | ||||
} | |||||
#endif | #endif | ||||
#else | #else | ||||
LSSharedFileListItemResolve(item, resolutionFlags, ¤tItemURL, | LSSharedFileListItemResolve(item, resolutionFlags, ¤tItemURL, | ||||
nullptr); | nullptr); | ||||
#endif | #endif | ||||
if (currentItemURL && CFEqual(currentItemURL, findUrl)) { | if (currentItemURL && CFEqual(currentItemURL, findUrl)) { | ||||
// found | // found | ||||
▲ Show 20 Lines • Show All 73 Lines • ▼ Show 20 Lines | |||||
QString formatDurationStr(int secs) { | QString formatDurationStr(int secs) { | ||||
QStringList strList; | QStringList strList; | ||||
int days = secs / 86400; | int days = secs / 86400; | ||||
int hours = (secs % 86400) / 3600; | int hours = (secs % 86400) / 3600; | ||||
int mins = (secs % 3600) / 60; | int mins = (secs % 3600) / 60; | ||||
int seconds = secs % 60; | int seconds = secs % 60; | ||||
if (days) strList.append(QString(QObject::tr("%1 d")).arg(days)); | if (days) { | ||||
if (hours) strList.append(QString(QObject::tr("%1 h")).arg(hours)); | strList.append(QString(QObject::tr("%1 d")).arg(days)); | ||||
if (mins) strList.append(QString(QObject::tr("%1 m")).arg(mins)); | } | ||||
if (seconds || (!days && !hours && !mins)) | if (hours) { | ||||
strList.append(QString(QObject::tr("%1 h")).arg(hours)); | |||||
} | |||||
if (mins) { | |||||
strList.append(QString(QObject::tr("%1 m")).arg(mins)); | |||||
} | |||||
if (seconds || (!days && !hours && !mins)) { | |||||
strList.append(QString(QObject::tr("%1 s")).arg(seconds)); | strList.append(QString(QObject::tr("%1 s")).arg(seconds)); | ||||
} | |||||
return strList.join(" "); | return strList.join(" "); | ||||
} | } | ||||
QString formatServicesStr(quint64 mask) { | QString formatServicesStr(quint64 mask) { | ||||
QStringList strList; | QStringList strList; | ||||
// Just scan the last 11 bits for now. | // Just scan the last 11 bits for now. | ||||
Show All 20 Lines | for (int i = 0; i < 11; i++) { | ||||
strList.append("LIMITED"); | strList.append("LIMITED"); | ||||
break; | break; | ||||
default: | default: | ||||
strList.append(QString("%1[%2]").arg("UNKNOWN").arg(check)); | strList.append(QString("%1[%2]").arg("UNKNOWN").arg(check)); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
if (strList.size()) | if (strList.size()) { | ||||
return strList.join(" & "); | return strList.join(" & "); | ||||
else | } else { | ||||
return QObject::tr("None"); | return QObject::tr("None"); | ||||
} | } | ||||
} | |||||
QString formatPingTime(double dPingTime) { | QString formatPingTime(double dPingTime) { | ||||
return (dPingTime == std::numeric_limits<int64_t>::max() / 1e6 || | return (dPingTime == std::numeric_limits<int64_t>::max() / 1e6 || | ||||
dPingTime == 0) | dPingTime == 0) | ||||
? QObject::tr("N/A") | ? QObject::tr("N/A") | ||||
: QString(QObject::tr("%1 ms")) | : QString(QObject::tr("%1 ms")) | ||||
.arg(QString::number((int)(dPingTime * 1000), 10)); | .arg(QString::number((int)(dPingTime * 1000), 10)); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 44 Lines • Show Last 20 Lines |