Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions doc/release-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ Note that while multi-wallet is now fully supported, the RPC multi-wallet interf
GUI changes
-----------

- The launch-on-startup option is no longer available on macOS

### Settings

A new checkbox has been added to the wallet settings UI to enable or disable automatic port mapping with NAT-PMP.
Expand Down
4 changes: 2 additions & 2 deletions src/compat/byteswap.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#include <byteswap.h>
#endif

#if defined(__APPLE__)
#if defined(MAC_OSX)

#include <libkern/OSByteOrder.h>
#define bswap_16(x) OSSwapInt16(x)
Expand Down Expand Up @@ -54,6 +54,6 @@ inline uint64_t bswap_64(uint64_t x)
}
#endif // HAVE_DECL_BSWAP64 == 0

#endif // defined(__APPLE__)
#endif // defined(MAC_OSX)

#endif // BITCOIN_COMPAT_BYTESWAP_H
264 changes: 1 addition & 263 deletions src/qt/guiutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,24 +56,10 @@
#include <QUrlQuery>
#include <QMouseEvent>


#if defined(Q_OS_MAC)
extern double NSAppKitVersionNumber;
#if !defined(NSAppKitVersionNumber10_8)
#define NSAppKitVersionNumber10_8 1187
#endif
#if !defined(NSAppKitVersionNumber10_9)
#define NSAppKitVersionNumber10_9 1265
#endif
#endif

#define URI_SCHEME "pivx"

#if defined(Q_OS_MAC)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"

#include <CoreServices/CoreServices.h>
#include <QProcess>

void ForceActivation();
Expand Down Expand Up @@ -373,7 +359,7 @@ bool checkPoint(const QPoint& p, const QWidget* w)
{
QWidget* atW = QApplication::widgetAt(w->mapToGlobal(p));
if (!atW) return false;
return atW->topLevelWidget() == w;
return atW->window() == w;
}

bool isObscured(QWidget* w)
Expand Down Expand Up @@ -435,40 +421,6 @@ bool showBackups()
return openFile(GetDataDir() / "backups", false);
}

void SubstituteFonts(const QString& language)
{
#if defined(Q_OS_MAC)
// Background:
// 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.
// 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
// render correctly.
//
// The same thing happened with 10.10. .Helvetica Neue DeskInterface is now default.
//
// 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
// happen before the QApplication is created.
#if defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_8
if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_8) {
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_9)
/* On a 10.9 - 10.9.x system */
QFont::insertSubstitution(".Lucida Grande UI", "Lucida Grande");
else {
/* 10.10 or later system */
if (language == "zh_CN" || language == "zh_TW" || language == "zh_HK") // traditional or simplified Chinese
QFont::insertSubstitution(".Helvetica Neue DeskInterface", "Heiti SC");
else if (language == "ja") // Japanesee
QFont::insertSubstitution(".Helvetica Neue DeskInterface", "Songti SC");
else
QFont::insertSubstitution(".Helvetica Neue DeskInterface", "Lucida Grande");
}
}
#endif
#endif
}

ToolTipToRichTextFilter::ToolTipToRichTextFilter(int size_threshold, QObject* parent) : QObject(parent),
size_threshold(size_threshold)
{
Expand All @@ -493,140 +445,6 @@ bool ToolTipToRichTextFilter::eventFilter(QObject* obj, QEvent* evt)
return QObject::eventFilter(obj, evt);
}

void TableViewLastColumnResizingFixer::connectViewHeadersSignals()
{
connect(tableView->horizontalHeader(), &QHeaderView::sectionResized, this, &TableViewLastColumnResizingFixer::on_sectionResized);
connect(tableView->horizontalHeader(), &QHeaderView::geometriesChanged, this, &TableViewLastColumnResizingFixer::on_geometriesChanged);
}

// We need to disconnect these while handling the resize events, otherwise we can enter infinite loops.
void TableViewLastColumnResizingFixer::disconnectViewHeadersSignals()
{
disconnect(tableView->horizontalHeader(), &QHeaderView::sectionResized, this, &TableViewLastColumnResizingFixer::on_sectionResized);
disconnect(tableView->horizontalHeader(), &QHeaderView::geometriesChanged, this, &TableViewLastColumnResizingFixer::on_geometriesChanged);
}

// Setup the resize mode, handles compatibility for Qt5 and below as the method signatures changed.
// Refactored here for readability.
void TableViewLastColumnResizingFixer::setViewHeaderResizeMode(int logicalIndex, QHeaderView::ResizeMode resizeMode)
{
tableView->horizontalHeader()->setSectionResizeMode(logicalIndex, resizeMode);
}

void TableViewLastColumnResizingFixer::resizeColumn(int nColumnIndex, int width)
{
tableView->setColumnWidth(nColumnIndex, width);
tableView->horizontalHeader()->resizeSection(nColumnIndex, width);
}

int TableViewLastColumnResizingFixer::getColumnsWidth()
{
int nColumnsWidthSum = 0;
for (int i = 0; i < columnCount; i++) {
nColumnsWidthSum += tableView->horizontalHeader()->sectionSize(i);
}
return nColumnsWidthSum;
}

int TableViewLastColumnResizingFixer::getAvailableWidthForColumn(int column)
{
int nResult = lastColumnMinimumWidth;
int nTableWidth = tableView->horizontalHeader()->width();

if (nTableWidth > 0) {
int nOtherColsWidth = getColumnsWidth() - tableView->horizontalHeader()->sectionSize(column);
nResult = std::max(nResult, nTableWidth - nOtherColsWidth);
}

return nResult;
}

// Make sure we don't make the columns wider than the tables viewport width.
void TableViewLastColumnResizingFixer::adjustTableColumnsWidth()
{
disconnectViewHeadersSignals();
resizeColumn(lastColumnIndex, getAvailableWidthForColumn(lastColumnIndex));
connectViewHeadersSignals();

int nTableWidth = tableView->horizontalHeader()->width();
int nColsWidth = getColumnsWidth();
if (nColsWidth > nTableWidth) {
resizeColumn(secondToLastColumnIndex, getAvailableWidthForColumn(secondToLastColumnIndex));
}
}

// Make column use all the space available, useful during window resizing.
void TableViewLastColumnResizingFixer::stretchColumnWidth(int column)
{
disconnectViewHeadersSignals();
resizeColumn(column, getAvailableWidthForColumn(column));
connectViewHeadersSignals();
}

// When a section is resized this is a slot-proxy for ajustAmountColumnWidth().
void TableViewLastColumnResizingFixer::on_sectionResized(int logicalIndex, int oldSize, int newSize)
{
adjustTableColumnsWidth();
int remainingWidth = getAvailableWidthForColumn(logicalIndex);
if (newSize > remainingWidth) {
resizeColumn(logicalIndex, remainingWidth);
}
}

// When the tabless geometry is ready, we manually perform the stretch of the "Message" column,
// as the "Stretch" resize mode does not allow for interactive resizing.
void TableViewLastColumnResizingFixer::on_geometriesChanged()
{
if ((getColumnsWidth() - this->tableView->horizontalHeader()->width()) != 0) {
disconnectViewHeadersSignals();
resizeColumn(secondToLastColumnIndex, getAvailableWidthForColumn(secondToLastColumnIndex));
connectViewHeadersSignals();
}
}

/**
* Initializes all internal variables and prepares the
* the resize modes of the last 2 columns of the table and
*/
TableViewLastColumnResizingFixer::TableViewLastColumnResizingFixer(QTableView* table, int lastColMinimumWidth, int allColsMinimumWidth) : tableView(table),
lastColumnMinimumWidth(lastColMinimumWidth),
allColumnsMinimumWidth(allColsMinimumWidth)
{
columnCount = tableView->horizontalHeader()->count();
lastColumnIndex = columnCount - 1;
secondToLastColumnIndex = columnCount - 2;
tableView->horizontalHeader()->setMinimumSectionSize(allColumnsMinimumWidth);
setViewHeaderResizeMode(secondToLastColumnIndex, QHeaderView::Interactive);
setViewHeaderResizeMode(lastColumnIndex, QHeaderView::Interactive);
}

/**
* Class constructor.
* @param[in] seconds Number of seconds to convert to a DHMS string
*/
DHMSTableWidgetItem::DHMSTableWidgetItem(const int64_t seconds) : QTableWidgetItem(),
value(seconds)
{
this->setText(QString::fromStdString(DurationToDHMS(seconds)));
}

/**
* Comparator overload to ensure that the "DHMS"-type durations as used in
* the "active-since" list in the masternode tab are sorted by the elapsed
* duration (versus the string value being sorted).
* @param[in] item Right hand side of the less than operator
*/
bool DHMSTableWidgetItem::operator<(QTableWidgetItem const& item) const
{
DHMSTableWidgetItem const* rhs =
dynamic_cast<DHMSTableWidgetItem const*>(&item);

if (!rhs)
return QTableWidgetItem::operator<(item);

return value < rhs->value;
}

#ifdef WIN32
fs::path static StartupShortcutPath()
{
Expand Down Expand Up @@ -766,86 +584,6 @@ bool SetStartOnSystemStartup(bool fAutoStart)
return true;
}


#elif defined(Q_OS_MAC)
// based on: https://github.com/Mozketo/LaunchAtLoginController/blob/master/LaunchAtLoginController.m

LSSharedFileListItemRef findStartupItemInList(LSSharedFileListRef list, CFURLRef findUrl);
LSSharedFileListItemRef findStartupItemInList(LSSharedFileListRef list, CFURLRef findUrl)
{
CFArrayRef listSnapshot = LSSharedFileListCopySnapshot(list, nullptr);
if (listSnapshot == nullptr) {
return nullptr;
}

// loop through the list of startup items and try to find the pivx app
for (int i = 0; i < CFArrayGetCount(listSnapshot); i++) {
LSSharedFileListItemRef item = (LSSharedFileListItemRef)CFArrayGetValueAtIndex(listSnapshot, i);
UInt32 resolutionFlags = kLSSharedFileListNoUserInteraction | kLSSharedFileListDoNotMountVolumes;
CFURLRef currentItemURL = nullptr;

#if defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED >= 10100
if (&LSSharedFileListItemCopyResolvedURL)
currentItemURL = LSSharedFileListItemCopyResolvedURL(item, resolutionFlags, nullptr);
#if defined(MAC_OS_X_VERSION_MIN_REQUIRED) && MAC_OS_X_VERSION_MIN_REQUIRED < 10100
else
LSSharedFileListItemResolve(item, resolutionFlags, &currentItemURL, nullptr);
#endif
#else
LSSharedFileListItemResolve(item, resolutionFlags, &currentItemURL, nullptr);
#endif

if (currentItemURL) {
if (CFEqual(currentItemURL, findUrl)) {
// found
CFRelease(listSnapshot);
CFRelease(currentItemURL);
return item;
}
CFRelease(currentItemURL);
}
}

CFRelease(listSnapshot);
return nullptr;
}

bool GetStartOnSystemStartup()
{
CFURLRef bitcoinAppUrl = CFBundleCopyBundleURL(CFBundleGetMainBundle());
if (bitcoinAppUrl == nullptr) {
return false;
}

LSSharedFileListRef loginItems = LSSharedFileListCreate(nullptr, kLSSharedFileListSessionLoginItems, nullptr);
LSSharedFileListItemRef foundItem = findStartupItemInList(loginItems, bitcoinAppUrl);

CFRelease(bitcoinAppUrl);
return !!foundItem; // return boolified object
}

bool SetStartOnSystemStartup(bool fAutoStart)
{
CFURLRef bitcoinAppUrl = CFBundleCopyBundleURL(CFBundleGetMainBundle());
if (bitcoinAppUrl == nullptr) {
return false;
}

LSSharedFileListRef loginItems = LSSharedFileListCreate(nullptr, kLSSharedFileListSessionLoginItems, nullptr);
LSSharedFileListItemRef foundItem = findStartupItemInList(loginItems, bitcoinAppUrl);

if (fAutoStart && !foundItem) {
// add pivx app to startup item list
LSSharedFileListInsertItemURL(loginItems, kLSSharedFileListItemBeforeFirst, nullptr, nullptr, bitcoinAppUrl, nullptr, nullptr);
} else if (!fAutoStart && foundItem) {
// remove item
LSSharedFileListItemRemove(loginItems, foundItem);
}

CFRelease(bitcoinAppUrl);
return true;
}
#pragma GCC diagnostic pop
#else

bool GetStartOnSystemStartup()
Expand Down
Loading