Skip to content

Commit

Permalink
Merge #6337: backport: merge bitcoin-core/gui#337, #354, #317, #349, #…
Browse files Browse the repository at this point in the history
…403, #418, #416, #449, #477, #563, #554, #615 (qt backports: part 2)

1a2c02a merge bitcoin-core/gui#615: If -prune=0 is set, Uncheck Prune on Intro page (Kittywhiskers Van Gogh)
3d5aca6 merge bitcoin-core/gui#554: Add and improve translator comments and tooltips for peers tab address fields (Kittywhiskers Van Gogh)
0c545ac merge bitcoin-core/gui#563: Remove network detection based on address in BIP21 (Kittywhiskers Van Gogh)
f088334 merge bitcoin-core/gui#477: Monospaced output in Console on macOS (Kittywhiskers Van Gogh)
694f3e9 merge bitcoin-core/gui#449: Restore "S" accelerator for "Start on system login" option (Kittywhiskers Van Gogh)
063ef3a merge bitcoin-core/gui#416: Add RPC setting (Kittywhiskers Van Gogh)
fa2f7ac merge bitcoin-core/gui#418: fix bitcoin-qt app categorization on apple silicon (Kittywhiskers Van Gogh)
594177d merge bitcoin-core/gui#403: Make paths to update Encryption and HD wallet statuses simpler (Kittywhiskers Van Gogh)
ba5ad1f merge bitcoin-core/gui#349: replace QDateTime::fromTime_t with QDateTime::fromSecsSinceEpoch (Kittywhiskers Van Gogh)
70d4e08 merge bitcoin-core/gui#317: Add Direction column to Peers Tab (Kittywhiskers Van Gogh)
0a5481c merge bitcoin-core/gui#354: Refactor open date range to use std::optional (Kittywhiskers Van Gogh)
17a7e9b merge bitcoin-core/gui#337: Use Regex Search in Apptests (Kittywhiskers Van Gogh)

Pull request description:

  ## Additional Information

  | `develop` (3a18f08)                                       | This PR                                                      |
  | ------------------------------------------------------------ | ------------------------------------------------------------ |
  | ![image](https://github.com/user-attachments/assets/e5d48b17-2eae-4e58-bbbf-6c011dc98c9c) | ![image](https://github.com/user-attachments/assets/fc47c1f1-d3c2-45dc-bdd5-2e94bc02489d) |
  | ![image](https://github.com/user-attachments/assets/e75bd85a-30a7-4e49-8a75-c8ce5090ba50) | ![image](https://github.com/user-attachments/assets/51fd865a-91fd-4742-b745-1cfb6866ae14) |

  ## Breaking changes

  None observed.

  ## Checklist

  - [x] I have performed a self-review of my own code
  - [x] I have commented my code, particularly in hard-to-understand areas (note: N/A)
  - [x] I have added or updated relevant unit/integration/functional/e2e tests (note: N/A)
  - [x] I have made corresponding changes to the documentation (note: N/A)
  - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_

ACKs for top commit:
  UdjinM6:
    utACK 1a2c02a

Tree-SHA512: d424a0ebe817c08a50c2455fea1c3bf798a1a53dd87bc9b71cd7173824d7892a83035f046dfccc85d1925b91705d4db7ac2a498e4299d91504a1a8306762e5b0
  • Loading branch information
PastaPastaPasta committed Oct 26, 2024
2 parents 9d27259 + 1a2c02a commit ceb1fe7
Show file tree
Hide file tree
Showing 28 changed files with 128 additions and 100 deletions.
5 changes: 5 additions & 0 deletions doc/release-notes-6337.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
GUI changes
-----------

A new option has been added in to the "Main" tab in "Options" that allow
users to enable RPC server functionality.
5 changes: 5 additions & 0 deletions share/qt/Info.plist.in
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>

<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>

<key>CFBundleShortVersionString</key>
<string>@CLIENT_VERSION_MAJOR@.@CLIENT_VERSION_MINOR@.@CLIENT_VERSION_BUILD@</string>

Expand Down
2 changes: 1 addition & 1 deletion src/qt/bitcoin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@ int GuiMain(int argc, char* argv[])
return EXIT_FAILURE;
}
#ifdef ENABLE_WALLET
// Parse URIs on command line -- this can affect Params()
// Parse URIs on command line
PaymentServer::ipcParseCommandLine(argc, argv);
#endif

Expand Down
25 changes: 13 additions & 12 deletions src/qt/bitcoingui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,15 @@ BitcoinGUI::BitcoinGUI(interfaces::Node& node, const NetworkStyle* networkStyle,
{
/** Create wallet frame*/
walletFrame = new WalletFrame(this);
connect(walletFrame, &WalletFrame::message, [this](const QString& title, const QString& message, unsigned int style) {
this->message(title, message, style);
});
connect(walletFrame, &WalletFrame::createWalletButtonClicked, [this] {
auto activity = new CreateWalletActivity(getWalletController(), this);
connect(activity, &CreateWalletActivity::finished, activity, &QObject::deleteLater);
activity->create();
});
connect(walletFrame, &WalletFrame::message, [this](const QString& title, const QString& message, unsigned int style) {
this->message(title, message, style);
});
connect(walletFrame, &WalletFrame::currentWalletSet, [this] { updateWalletStatus(); });
} else
#endif // ENABLE_WALLET
{
Expand Down Expand Up @@ -819,8 +820,8 @@ void BitcoinGUI::setClientModel(ClientModel *_clientModel, interfaces::BlockAndH
connect(_clientModel, &ClientModel::numConnectionsChanged, this, &BitcoinGUI::setNumConnections);
connect(_clientModel, &ClientModel::networkActiveChanged, this, &BitcoinGUI::setNetworkActive);

modalOverlay->setKnownBestHeight(tip_info->header_height, QDateTime::fromTime_t(tip_info->header_time));
setNumBlocks(tip_info->block_height, QDateTime::fromTime_t(tip_info->block_time), QString::fromStdString(tip_info->block_hash.ToString()), tip_info->verification_progress, false, SynchronizationState::INIT_DOWNLOAD);
modalOverlay->setKnownBestHeight(tip_info->header_height, QDateTime::fromSecsSinceEpoch(tip_info->header_time));
setNumBlocks(tip_info->block_height, QDateTime::fromSecsSinceEpoch(tip_info->block_time), QString::fromStdString(tip_info->block_hash.ToString()), tip_info->verification_progress, false, SynchronizationState::INIT_DOWNLOAD);
connect(_clientModel, &ClientModel::numBlocksChanged, this, &BitcoinGUI::setNumBlocks);

connect(_clientModel, &ClientModel::additionalDataSyncProgressChanged, this, &BitcoinGUI::setAdditionalDataSyncProgress);
Expand Down Expand Up @@ -932,7 +933,6 @@ void BitcoinGUI::addWallet(WalletModel* walletModel)
});
connect(wallet_view, &WalletView::encryptionStatusChanged, this, &BitcoinGUI::updateWalletStatus);
connect(wallet_view, &WalletView::incomingTransaction, this, &BitcoinGUI::incomingTransaction);
connect(wallet_view, &WalletView::hdEnabledStatusChanged, this, &BitcoinGUI::updateWalletStatus);
connect(this, &BitcoinGUI::setPrivacy, wallet_view, &WalletView::setPrivacy);
wallet_view->setPrivacy(isPrivacyModeActivated());
const QString display_name = walletModel->getDisplayName();
Expand Down Expand Up @@ -1281,7 +1281,7 @@ void BitcoinGUI::updateNetworkState()
}

if (fNetworkBecameActive || fNetworkBecameInactive) {
setNumBlocks(m_node.getNumBlocks(), QDateTime::fromTime_t(m_node.getLastBlockTime()), QString::fromStdString(m_node.getLastBlockHash()), m_node.getVerificationProgress(), false, SynchronizationState::INIT_DOWNLOAD);
setNumBlocks(m_node.getNumBlocks(), QDateTime::fromSecsSinceEpoch(m_node.getLastBlockTime()), QString::fromStdString(m_node.getLastBlockHash()), m_node.getVerificationProgress(), false, SynchronizationState::INIT_DOWNLOAD);
}

nCountPrev = count;
Expand Down Expand Up @@ -1545,7 +1545,7 @@ void BitcoinGUI::setAdditionalDataSyncProgress(double nSyncProgress)

// If masternodeSync->Reset() has been called make sure status bar shows the correct information.
if (nSyncProgress == -1) {
setNumBlocks(m_node.getNumBlocks(), QDateTime::fromTime_t(m_node.getLastBlockTime()), QString::fromStdString(m_node.getLastBlockHash()), m_node.getVerificationProgress(), false, SynchronizationState::INIT_DOWNLOAD);
setNumBlocks(m_node.getNumBlocks(), QDateTime::fromSecsSinceEpoch(m_node.getLastBlockTime()), QString::fromStdString(m_node.getLastBlockHash()), m_node.getVerificationProgress(), false, SynchronizationState::INIT_DOWNLOAD);
if (clientModel->getNumConnections()) {
labelBlocksIcon->show();
startSpinner();
Expand Down Expand Up @@ -1679,7 +1679,9 @@ void BitcoinGUI::changeEvent(QEvent *e)
if (e->type() == QEvent::StyleChange) {
updateNetworkState();
#ifdef ENABLE_WALLET
updateWalletStatus();
if (walletFrame) {
updateWalletStatus();
}
#endif
if (m_node.masternodeSync().isSynced()) {
labelBlocksIcon->setPixmap(GUIUtil::getIcon("synced", GUIUtil::ThemedColor::GREEN).pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
Expand Down Expand Up @@ -1911,9 +1913,8 @@ void BitcoinGUI::setEncryptionStatus(int status)

void BitcoinGUI::updateWalletStatus()
{
if (!walletFrame) {
return;
}
assert(walletFrame);

WalletView * const walletView = walletFrame->currentWalletView();
if (!walletView) {
return;
Expand Down
4 changes: 2 additions & 2 deletions src/qt/clientmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ bool ClientModel::isReleaseVersion() const

QString ClientModel::formatClientStartupTime() const
{
return QDateTime::fromTime_t(GetStartupTime()).toString();
return QDateTime::fromSecsSinceEpoch(GetStartupTime()).toString();
}

QString ClientModel::dataDir() const
Expand Down Expand Up @@ -329,7 +329,7 @@ static void BlockTipChanged(ClientModel* clientmodel, SynchronizationState sync_

bool invoked = QMetaObject::invokeMethod(clientmodel, "numBlocksChanged", Qt::QueuedConnection,
Q_ARG(int, tip.block_height),
Q_ARG(QDateTime, QDateTime::fromTime_t(tip.block_time)),
Q_ARG(QDateTime, QDateTime::fromSecsSinceEpoch(tip.block_time)),
Q_ARG(QString, QString::fromStdString(tip.block_hash.ToString())),
Q_ARG(double, verificationProgress),
Q_ARG(bool, fHeader),
Expand Down
12 changes: 6 additions & 6 deletions src/qt/forms/debugwindow.ui
Original file line number Diff line number Diff line change
Expand Up @@ -1587,10 +1587,10 @@
<item row="27" column="0">
<widget class="QLabel" name="peerAddrRelayEnabledLabel">
<property name="toolTip">
<string extracomment="Tooltip text for the Address Relay field in the peer details area.">Whether we relay addresses to this peer.</string>
<string extracomment="Tooltip text for the Address Relay field in the peer details area, which displays whether we relay addresses to this peer (Yes/No).">Whether we relay addresses to this peer.</string>
</property>
<property name="text">
<string>Address Relay</string>
<string extracomment="Text title for the Address Relay field in the peer details area, which displays whether we relay addresses to this peer (Yes/No).">Address Relay</string>
</property>
</widget>
</item>
Expand All @@ -1613,10 +1613,10 @@
<item row="28" column="0">
<widget class="QLabel" name="peerAddrProcessedLabel">
<property name="toolTip">
<string extracomment="Tooltip text for the Addresses Processed field in the peer details area.">Total number of addresses processed, excluding those dropped due to rate-limiting.</string>
<string extracomment="Tooltip text for the Addresses Processed field in the peer details area, which displays the total number of addresses received from this peer that were processed (excludes addresses that were dropped due to rate-limiting).">The total number of addresses received from this peer that were processed (excludes addresses that were dropped due to rate-limiting).</string>
</property>
<property name="text">
<string>Addresses Processed</string>
<string extracomment="Text title for the Addresses Processed field in the peer details area, which displays the total number of addresses received from this peer that were processed (excludes addresses that were dropped due to rate-limiting).">Addresses Processed</string>
</property>
</widget>
</item>
Expand All @@ -1639,10 +1639,10 @@
<item row="29" column="0">
<widget class="QLabel" name="peerAddrRateLimitedLabel">
<property name="toolTip">
<string extracomment="Tooltip text for the Addresses Rate-Limited field in the peer details area.">Total number of addresses dropped due to rate-limiting.</string>
<string extracomment="Tooltip text for the Addresses Rate-Limited field in the peer details area, which displays the total number of addresses received from this peer that were dropped (not processed) due to rate-limiting.">The total number of addresses received from this peer that were dropped (not processed) due to rate-limiting.</string>
</property>
<property name="text">
<string>Addresses Rate-Limited</string>
<string extracomment="Text title for the Addresses Rate-Limited field in the peer details area, which displays the total number of addresses received from this peer that were dropped (not processed) due to rate-limiting.">Addresses Rate-Limited</string>
</property>
</widget>
</item>
Expand Down
12 changes: 11 additions & 1 deletion src/qt/forms/optionsdialog.ui
Original file line number Diff line number Diff line change
Expand Up @@ -291,13 +291,23 @@
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="enableServer">
<property name="toolTip">
<string extracomment="Tooltip text for Options window setting that enables the RPC server.">This allows you or a third party tool to communicate with the node through command-line and JSON-RPC commands.</string>
</property>
<property name="text">
<string extracomment="An Options window setting to enable the RPC server.">Enable R&amp;PC server</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_Main">
<property name="orientation">
Expand Down
2 changes: 1 addition & 1 deletion src/qt/guiutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ QString dateTimeStr(const QDateTime &date)

QString dateTimeStr(qint64 nTime)
{
return dateTimeStr(QDateTime::fromTime_t((qint32)nTime));
return dateTimeStr(QDateTime::fromSecsSinceEpoch((qint32)nTime));
}

QFont fixedPitchFont(bool use_embedded_font)
Expand Down
2 changes: 1 addition & 1 deletion src/qt/intro.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ void Intro::setStatus(int status, const QString &message, quint64 bytesAvailable
ui->freeSpace->setText("");
} else {
m_bytes_available = bytesAvailable;
if (ui->prune->isEnabled()) {
if (ui->prune->isEnabled() && !(gArgs.IsArgSet("-prune") && gArgs.GetArg("-prune", 0) == 0)) {
ui->prune->setChecked(m_bytes_available < (m_blockchain_size_gb + m_chain_state_size_gb + 10) * GB_BYTES);
}
UpdateFreeSpaceLabel();
Expand Down
2 changes: 2 additions & 0 deletions src/qt/optionsdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ void OptionsDialog::setModel(OptionsModel *_model)
connect(ui->spendZeroConfChange, &QCheckBox::clicked, this, &OptionsDialog::showRestartWarning);
/* Network */
connect(ui->allowIncoming, &QCheckBox::clicked, this, &OptionsDialog::showRestartWarning);
connect(ui->enableServer, &QCheckBox::clicked, this, &OptionsDialog::showRestartWarning);
connect(ui->connectSocks, &QCheckBox::clicked, this, &OptionsDialog::showRestartWarning);
connect(ui->connectSocksTor, &QCheckBox::clicked, this, &OptionsDialog::showRestartWarning);
/* Display */
Expand Down Expand Up @@ -344,6 +345,7 @@ void OptionsDialog::setMapper()
mapper->addMapping(ui->mapPortUpnp, OptionsModel::MapPortUPnP);
mapper->addMapping(ui->mapPortNatpmp, OptionsModel::MapPortNatpmp);
mapper->addMapping(ui->allowIncoming, OptionsModel::Listen);
mapper->addMapping(ui->enableServer, OptionsModel::Server);

mapper->addMapping(ui->connectSocks, OptionsModel::ProxyUse);
mapper->addMapping(ui->proxyIp, OptionsModel::ProxyIP);
Expand Down
15 changes: 15 additions & 0 deletions src/qt/optionsmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,13 @@ void OptionsModel::Init(bool resetSettings)
gArgs.SoftSetBoolArg("-listenonion", false);
}

if (!settings.contains("server")) {
settings.setValue("server", false);
}
if (!gArgs.SoftSetBoolArg("-server", settings.value("server").toBool())) {
addOverriddenOption("-server");
}

if (!settings.contains("fUseProxy"))
settings.setValue("fUseProxy", false);
if (!settings.contains("addrProxy"))
Expand Down Expand Up @@ -536,6 +543,8 @@ QVariant OptionsModel::data(const QModelIndex & index, int role) const
return settings.value("nThreadsScriptVerif");
case Listen:
return settings.value("fListen");
case Server:
return settings.value("server");
default:
return QVariant();
}
Expand Down Expand Up @@ -806,6 +815,12 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in
setRestartRequired(true);
}
break;
case Server:
if (settings.value("server") != value) {
settings.setValue("server", value);
setRestartRequired(true);
}
break;
default:
break;
}
Expand Down
1 change: 1 addition & 0 deletions src/qt/optionsmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ class OptionsModel : public QAbstractListModel
CoinJoinDenomsHardCap,// int
CoinJoinMultiSession, // bool
Listen, // bool
Server, // bool
OptionIDRowCount,
};

Expand Down
23 changes: 1 addition & 22 deletions src/qt/paymentserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,32 +79,11 @@ void PaymentServer::ipcParseCommandLine(int argc, char* argv[])
for (int i = 1; i < argc; i++)
{
QString arg(argv[i]);
if (arg.startsWith("-"))
continue;
if (arg.startsWith("-")) continue;

// If the dash: URI contains a payment request, we are not able to detect the
// network as that would require fetching and parsing the payment request.
// That means clicking such an URI which contains a testnet payment request
// will start a mainnet instance and throw a "wrong network" error.
if (arg.startsWith(BITCOIN_IPC_PREFIX, Qt::CaseInsensitive)) // dash: URI
{
if (savedPaymentRequests.contains(arg)) continue;
savedPaymentRequests.insert(arg);

SendCoinsRecipient r;
if (GUIUtil::parseBitcoinURI(arg, &r) && !r.address.isEmpty())
{
auto tempChainParams = CreateChainParams(gArgs, CBaseChainParams::MAIN);

if (IsValidDestinationString(r.address.toStdString(), *tempChainParams)) {
SelectParams(CBaseChainParams::MAIN);
} else {
tempChainParams = CreateChainParams(gArgs, CBaseChainParams::TESTNET);
if (IsValidDestinationString(r.address.toStdString(), *tempChainParams)) {
SelectParams(CBaseChainParams::TESTNET);
}
}
}
}
}
}
Expand Down
10 changes: 8 additions & 2 deletions src/qt/peertablemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,13 @@ QVariant PeerTableModel::data(const QModelIndex& index, int role) const
case Age:
return GUIUtil::FormatPeerAge(rec->nodeStats.m_connected);
case Address:
// prepend to peer address down-arrow symbol for inbound connection and up-arrow for outbound connection
return QString::fromStdString((rec->nodeStats.fInbound ? "" : "") + rec->nodeStats.m_addr_name);
return QString::fromStdString(rec->nodeStats.m_addr_name);
case Direction:
return QString(rec->nodeStats.fInbound ?
//: An Inbound Connection from a Peer.
tr("Inbound") :
//: An Outbound Connection to a Peer.
tr("Outbound"));
case ConnectionType:
return GUIUtil::ConnectionTypeToQString(rec->nodeStats.m_conn_type, /* prepend_direction */ false);
case Network:
Expand All @@ -97,6 +102,7 @@ QVariant PeerTableModel::data(const QModelIndex& index, int role) const
return QVariant(Qt::AlignRight | Qt::AlignVCenter);
case Address:
return {};
case Direction:
case ConnectionType:
case Network:
return QVariant(Qt::AlignCenter);
Expand Down
4 changes: 4 additions & 0 deletions src/qt/peertablemodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class PeerTableModel : public QAbstractTableModel
NetNodeId = 0,
Age,
Address,
Direction,
ConnectionType,
Network,
Ping,
Expand Down Expand Up @@ -88,6 +89,9 @@ public Q_SLOTS:
/*: Title of Peers Table column which contains the
IP/Onion/I2P address of the connected peer. */
tr("Address"),
/*: Title of Peers Table column which indicates the direction
the peer connection was initiated from. */
tr("Direction"),
/*: Title of Peers Table column which describes the type of
peer connection. The "type" describes why the connection exists. */
tr("Type"),
Expand Down
2 changes: 2 additions & 0 deletions src/qt/peertablesortproxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ bool PeerTableSortProxy::lessThan(const QModelIndex& left_index, const QModelInd
return left_stats.m_connected > right_stats.m_connected;
case PeerTableModel::Address:
return left_stats.m_addr_name.compare(right_stats.m_addr_name) < 0;
case PeerTableModel::Direction:
return left_stats.fInbound > right_stats.fInbound; // default sort Inbound, then Outbound
case PeerTableModel::ConnectionType:
return left_stats.m_conn_type < right_stats.m_conn_type;
case PeerTableModel::Network:
Expand Down
2 changes: 1 addition & 1 deletion src/qt/recentrequeststablemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ bool RecentRequestEntryLessThan::operator()(const RecentRequestEntry& left, cons
switch(column)
{
case RecentRequestsTableModel::Date:
return pLeft->date.toTime_t() < pRight->date.toTime_t();
return pLeft->date.toSecsSinceEpoch() < pRight->date.toSecsSinceEpoch();
case RecentRequestsTableModel::Label:
return pLeft->recipient.label < pRight->recipient.label;
case RecentRequestsTableModel::Message:
Expand Down
6 changes: 4 additions & 2 deletions src/qt/recentrequeststablemodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

#include <qt/sendcoinsrecipient.h>

#include <string>

#include <QAbstractTableModel>
#include <QStringList>
#include <QDateTime>
Expand All @@ -26,9 +28,9 @@ class RecentRequestEntry

SERIALIZE_METHODS(RecentRequestEntry, obj) {
unsigned int date_timet;
SER_WRITE(obj, date_timet = obj.date.toTime_t());
SER_WRITE(obj, date_timet = obj.date.toSecsSinceEpoch());
READWRITE(obj.nVersion, obj.id, date_timet, obj.recipient);
SER_READ(obj, obj.date = QDateTime::fromTime_t(date_timet));
SER_READ(obj, obj.date = QDateTime::fromSecsSinceEpoch(date_timet));
}
};

Expand Down
Loading

0 comments on commit ceb1fe7

Please sign in to comment.