diff options
Diffstat (limited to 'src/qt')
-rw-r--r-- | src/qt/bitcoin.cpp | 14 | ||||
-rw-r--r-- | src/qt/clientmodel.cpp | 3 | ||||
-rw-r--r-- | src/qt/forms/modaloverlay.ui | 4 | ||||
-rw-r--r-- | src/qt/guiutil.cpp | 12 | ||||
-rw-r--r-- | src/qt/guiutil.h | 3 | ||||
-rw-r--r-- | src/qt/paymentrequestplus.h | 2 | ||||
-rw-r--r-- | src/qt/paymentserver.cpp | 2 | ||||
-rw-r--r-- | src/qt/recentrequeststablemodel.h | 2 | ||||
-rw-r--r-- | src/qt/rpcconsole.cpp | 116 | ||||
-rw-r--r-- | src/qt/rpcconsole.h | 4 | ||||
-rw-r--r-- | src/qt/walletmodel.h | 2 |
11 files changed, 94 insertions, 70 deletions
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 9986af4957..c828234f44 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -496,7 +496,7 @@ void BitcoinApplication::shutdownResult(int retval) void BitcoinApplication::handleRunawayException(const QString &message) { QMessageBox::critical(0, "Runaway exception", BitcoinGUI::tr("A fatal error occurred. Bitcoin can no longer continue safely and will quit.") + QString("\n\n") + message); - ::exit(1); + ::exit(EXIT_FAILURE); } WId BitcoinApplication::getMainWinId() const @@ -573,13 +573,13 @@ int main(int argc, char *argv[]) { HelpMessageDialog help(NULL, mapArgs.count("-version")); help.showOrPrint(); - return 1; + return EXIT_SUCCESS; } /// 5. Now that settings and translations are available, ask user for data directory // User language is set up: pick a data directory if (!Intro::pickDataDirectory()) - return 0; + return EXIT_SUCCESS; /// 6. Determine availability of data directory and parse bitcoin.conf /// - Do not call GetDataDir(true) before this step finishes @@ -587,14 +587,14 @@ int main(int argc, char *argv[]) { QMessageBox::critical(0, QObject::tr(PACKAGE_NAME), QObject::tr("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(mapArgs["-datadir"]))); - return 1; + return EXIT_FAILURE; } try { ReadConfigFile(GetArg("-conf", BITCOIN_CONF_FILENAME), mapArgs, mapMultiArgs); } catch (const std::exception& e) { QMessageBox::critical(0, QObject::tr(PACKAGE_NAME), QObject::tr("Error: Cannot parse configuration file: %1. Only use key=value syntax.").arg(e.what())); - return false; + return EXIT_FAILURE; } /// 7. Determine network (and switch to network specific options) @@ -608,7 +608,7 @@ int main(int argc, char *argv[]) SelectParams(ChainNameFromCommandLine()); } catch(std::exception &e) { QMessageBox::critical(0, QObject::tr(PACKAGE_NAME), QObject::tr("Error: %1").arg(e.what())); - return 1; + return EXIT_FAILURE; } #ifdef ENABLE_WALLET // Parse URIs on command line -- this can affect Params() @@ -630,7 +630,7 @@ int main(int argc, char *argv[]) // - Do this after creating app and setting up translations, so errors are // translated properly. if (PaymentServer::ipcSendCommandLine()) - exit(0); + exit(EXIT_SUCCESS); // Start up the payment server early, too, so impatient users that click on // bitcoin: links repeatedly have their payment requests routed to this process: diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 87704c641d..f9caca6878 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -6,6 +6,7 @@ #include "bantablemodel.h" #include "guiconstants.h" +#include "guiutil.h" #include "peertablemodel.h" #include "chainparams.h" @@ -208,7 +209,7 @@ QString ClientModel::formatClientStartupTime() const QString ClientModel::dataDir() const { - return QString::fromStdString(GetDataDir().string()); + return GUIUtil::boostPathToQString(GetDataDir()); } void ClientModel::updateBanlist() diff --git a/src/qt/forms/modaloverlay.ui b/src/qt/forms/modaloverlay.ui index 27998f90c5..a37672ad53 100644 --- a/src/qt/forms/modaloverlay.ui +++ b/src/qt/forms/modaloverlay.ui @@ -130,7 +130,7 @@ QLabel { color: rgb(40,40,40); }</string> <item> <widget class="QLabel" name="infoText"> <property name="text"> - <string>The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. This means that recent transactions will not be visible, and the balance will not be up-to-date until this process has completed.</string> + <string>Recent transactions may not yet be visible, and therefore your wallet's balance might be incorrect. This information will be correct once your wallet has finished synchronizing with the bitcoin network, as detailed below.</string> </property> <property name="textFormat"> <enum>Qt::RichText</enum> @@ -149,7 +149,7 @@ QLabel { color: rgb(40,40,40); }</string> </font> </property> <property name="text"> - <string>Spending bitcoins may not be possible during that phase!</string> + <string>Attempting to spend bitcoins that are affected by not-yet-displayed transactions will not be accepted by the network.</string> </property> <property name="textFormat"> <enum>Qt::RichText</enum> diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 42dafa1175..9dc75c2e1a 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -291,17 +291,11 @@ void copyEntryData(QAbstractItemView *view, int column, int role) } } -QVariant getEntryData(QAbstractItemView *view, int column, int role) +QList<QModelIndex> getEntryData(QAbstractItemView *view, int column) { if(!view || !view->selectionModel()) - return QVariant(); - QModelIndexList selection = view->selectionModel()->selectedRows(column); - - if(!selection.isEmpty()) { - // Return first item - return (selection.at(0).data(role)); - } - return QVariant(); + return QList<QModelIndex>(); + return view->selectionModel()->selectedRows(column); } QString getSaveFileName(QWidget *parent, const QString &caption, const QString &dir, diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index e28f68930f..64cbd51eb6 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -67,10 +67,9 @@ namespace GUIUtil /** Return a field of the currently selected entry as a QString. Does nothing if nothing is selected. @param[in] column Data column to extract from the model - @param[in] role Data role to extract from the model @see TransactionView::copyLabel, TransactionView::copyAmount, TransactionView::copyAddress */ - QVariant getEntryData(QAbstractItemView *view, int column, int role); + QList<QModelIndex> getEntryData(QAbstractItemView *view, int column); void setClipboard(const QString& str); diff --git a/src/qt/paymentrequestplus.h b/src/qt/paymentrequestplus.h index a73fe5f29d..a8bfcd2ac4 100644 --- a/src/qt/paymentrequestplus.h +++ b/src/qt/paymentrequestplus.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2015 The Bitcoin developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index 9f23e77a13..478f5ccf12 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -80,7 +80,7 @@ static QString ipcServerName() // Append a simple hash of the datadir // Note that GetDataDir(true) returns a different path // for -testnet versus main net - QString ddir(QString::fromStdString(GetDataDir(true).string())); + QString ddir(GUIUtil::boostPathToQString(GetDataDir(true))); name.append(QString::number(qHash(ddir))); return name; diff --git a/src/qt/recentrequeststablemodel.h b/src/qt/recentrequeststablemodel.h index 0193e748d7..8ee2c9cbac 100644 --- a/src/qt/recentrequeststablemodel.h +++ b/src/qt/recentrequeststablemodel.h @@ -27,7 +27,7 @@ public: ADD_SERIALIZE_METHODS; template <typename Stream, typename Operation> - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + inline void SerializationOp(Stream& s, Operation ser_action) { unsigned int nDate = date.toTime_t(); READWRITE(this->nVersion); diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index f10dddf589..a9fef731e1 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -343,7 +343,6 @@ RPCConsole::RPCConsole(const PlatformStyle *_platformStyle, QWidget *parent) : ui(new Ui::RPCConsole), clientModel(0), historyPtr(0), - cachedNodeid(-1), platformStyle(_platformStyle), peersTableContextMenu(0), banTableContextMenu(0), @@ -469,7 +468,7 @@ void RPCConsole::setClientModel(ClientModel *model) ui->peerWidget->verticalHeader()->hide(); ui->peerWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); ui->peerWidget->setSelectionBehavior(QAbstractItemView::SelectRows); - ui->peerWidget->setSelectionMode(QAbstractItemView::SingleSelection); + ui->peerWidget->setSelectionMode(QAbstractItemView::ExtendedSelection); ui->peerWidget->setContextMenuPolicy(Qt::CustomContextMenu); ui->peerWidget->setColumnWidth(PeerTableModel::Address, ADDRESS_COLUMN_WIDTH); ui->peerWidget->setColumnWidth(PeerTableModel::Subversion, SUBVERSION_COLUMN_WIDTH); @@ -477,11 +476,11 @@ void RPCConsole::setClientModel(ClientModel *model) ui->peerWidget->horizontalHeader()->setStretchLastSection(true); // create peer table context menu actions - QAction* disconnectAction = new QAction(tr("&Disconnect Node"), this); - QAction* banAction1h = new QAction(tr("Ban Node for") + " " + tr("1 &hour"), this); - QAction* banAction24h = new QAction(tr("Ban Node for") + " " + tr("1 &day"), this); - QAction* banAction7d = new QAction(tr("Ban Node for") + " " + tr("1 &week"), this); - QAction* banAction365d = new QAction(tr("Ban Node for") + " " + tr("1 &year"), this); + QAction* disconnectAction = new QAction(tr("&Disconnect"), this); + QAction* banAction1h = new QAction(tr("Ban for") + " " + tr("1 &hour"), this); + QAction* banAction24h = new QAction(tr("Ban for") + " " + tr("1 &day"), this); + QAction* banAction7d = new QAction(tr("Ban for") + " " + tr("1 &week"), this); + QAction* banAction365d = new QAction(tr("Ban for") + " " + tr("1 &year"), this); // create peer table context menu peersTableContextMenu = new QMenu(); @@ -514,7 +513,9 @@ void RPCConsole::setClientModel(ClientModel *model) this, SLOT(peerSelected(const QItemSelection &, const QItemSelection &))); // peer table signal handling - update peer details when new nodes are added to the model connect(model->getPeerTableModel(), SIGNAL(layoutChanged()), this, SLOT(peerLayoutChanged())); - + // peer table signal handling - cache selected node ids + connect(model->getPeerTableModel(), SIGNAL(layoutAboutToChange()), this, SLOT(peerLayoutAboutToChange())); + // set up ban table ui->banlistWidget->setModel(model->getBanTableModel()); ui->banlistWidget->verticalHeader()->hide(); @@ -527,7 +528,7 @@ void RPCConsole::setClientModel(ClientModel *model) ui->banlistWidget->horizontalHeader()->setStretchLastSection(true); // create ban table context menu action - QAction* unbanAction = new QAction(tr("&Unban Node"), this); + QAction* unbanAction = new QAction(tr("&Unban"), this); // create ban table context menu banTableContextMenu = new QMenu(); @@ -825,6 +826,17 @@ void RPCConsole::peerSelected(const QItemSelection &selected, const QItemSelecti updateNodeDetail(stats); } +void RPCConsole::peerLayoutAboutToChange() +{ + QModelIndexList selected = ui->peerWidget->selectionModel()->selectedIndexes(); + cachedNodeids.clear(); + for(int i = 0; i < selected.size(); i++) + { + const CNodeCombinedStats *stats = clientModel->getPeerTableModel()->getNodeStats(selected.at(i).row()); + cachedNodeids.append(stats->nodeStats.nodeid); + } +} + void RPCConsole::peerLayoutChanged() { if (!clientModel || !clientModel->getPeerTableModel()) @@ -834,7 +846,7 @@ void RPCConsole::peerLayoutChanged() bool fUnselect = false; bool fReselect = false; - if (cachedNodeid == -1) // no node selected yet + if (cachedNodeids.empty()) // no node selected yet return; // find the currently selected row @@ -846,7 +858,7 @@ void RPCConsole::peerLayoutChanged() // check if our detail node has a row in the table (it may not necessarily // be at selectedRow since its position can change after a layout change) - int detailNodeRow = clientModel->getPeerTableModel()->getRowByNodeId(cachedNodeid); + int detailNodeRow = clientModel->getPeerTableModel()->getRowByNodeId(cachedNodeids.first()); if (detailNodeRow < 0) { @@ -872,7 +884,10 @@ void RPCConsole::peerLayoutChanged() if (fReselect) { - ui->peerWidget->selectRow(detailNodeRow); + for(int i = 0; i < cachedNodeids.size(); i++) + { + ui->peerWidget->selectRow(clientModel->getPeerTableModel()->getRowByNodeId(cachedNodeids.at(i))); + } } if (stats) @@ -881,9 +896,6 @@ void RPCConsole::peerLayoutChanged() void RPCConsole::updateNodeDetail(const CNodeCombinedStats *stats) { - // Update cached nodeid - cachedNodeid = stats->nodeStats.nodeid; - // update the detail ui with latest node information QString peerAddrDetails(QString::fromStdString(stats->nodeStats.addrName) + " "); peerAddrDetails += tr("(node id: %1)").arg(QString::number(stats->nodeStats.nodeid)); @@ -973,33 +985,44 @@ void RPCConsole::disconnectSelectedNode() { if(!g_connman) return; - // Get currently selected peer address - NodeId id = GUIUtil::getEntryData(ui->peerWidget, 0, PeerTableModel::NetNodeId).toInt(); - // Find the node, disconnect it and clear the selected node - if(g_connman->DisconnectNode(id)) - clearSelectedNode(); + + // Get selected peer addresses + QList<QModelIndex> nodes = GUIUtil::getEntryData(ui->peerWidget, 0); + for(int i = 0; i < nodes.count(); i++) + { + // Get currently selected peer address + NodeId id = nodes.at(i).data(PeerTableModel::NetNodeId).toInt(); + // Find the node, disconnect it and clear the selected node + if(g_connman->DisconnectNode(id)) + clearSelectedNode(); + } } void RPCConsole::banSelectedNode(int bantime) { if (!clientModel || !g_connman) return; - - if(cachedNodeid == -1) - return; - - // Get currently selected peer address - int detailNodeRow = clientModel->getPeerTableModel()->getRowByNodeId(cachedNodeid); - if(detailNodeRow < 0) - return; - - // Find possible nodes, ban it and clear the selected node - const CNodeCombinedStats *stats = clientModel->getPeerTableModel()->getNodeStats(detailNodeRow); - if(stats) { - g_connman->Ban(stats->nodeStats.addr, BanReasonManuallyAdded, bantime); - clearSelectedNode(); - clientModel->getBanTableModel()->refresh(); + + // Get selected peer addresses + QList<QModelIndex> nodes = GUIUtil::getEntryData(ui->peerWidget, 0); + for(int i = 0; i < nodes.count(); i++) + { + // Get currently selected peer address + NodeId id = nodes.at(i).data(PeerTableModel::NetNodeId).toInt(); + + // Get currently selected peer address + int detailNodeRow = clientModel->getPeerTableModel()->getRowByNodeId(id); + if(detailNodeRow < 0) + return; + + // Find possible nodes, ban it and clear the selected node + const CNodeCombinedStats *stats = clientModel->getPeerTableModel()->getNodeStats(detailNodeRow); + if(stats) { + g_connman->Ban(stats->nodeStats.addr, BanReasonManuallyAdded, bantime); + } } + clearSelectedNode(); + clientModel->getBanTableModel()->refresh(); } void RPCConsole::unbanSelectedNode() @@ -1007,22 +1030,27 @@ void RPCConsole::unbanSelectedNode() if (!clientModel) return; - // Get currently selected ban address - QString strNode = GUIUtil::getEntryData(ui->banlistWidget, 0, BanTableModel::Address).toString(); - CSubNet possibleSubnet; - - LookupSubNet(strNode.toStdString().c_str(), possibleSubnet); - if (possibleSubnet.IsValid() && g_connman) + // Get selected ban addresses + QList<QModelIndex> nodes = GUIUtil::getEntryData(ui->banlistWidget, 0); + for(int i = 0; i < nodes.count(); i++) { - g_connman->Unban(possibleSubnet); - clientModel->getBanTableModel()->refresh(); + // Get currently selected ban address + QString strNode = nodes.at(i).data(BanTableModel::Address).toString(); + CSubNet possibleSubnet; + + LookupSubNet(strNode.toStdString().c_str(), possibleSubnet); + if (possibleSubnet.IsValid() && g_connman) + { + g_connman->Unban(possibleSubnet); + clientModel->getBanTableModel()->refresh(); + } } } void RPCConsole::clearSelectedNode() { ui->peerWidget->selectionModel()->clearSelection(); - cachedNodeid = -1; + cachedNodeids.clear(); ui->detailWidget->hide(); ui->peerHeading->setText(tr("Select a peer to view detailed information.")); } diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h index 50224a1cc0..8e1d878ae5 100644 --- a/src/qt/rpcconsole.h +++ b/src/qt/rpcconsole.h @@ -98,6 +98,8 @@ public Q_SLOTS: void scrollToEnd(); /** Handle selection of peer in peers list */ void peerSelected(const QItemSelection &selected, const QItemSelection &deselected); + /** Handle selection caching before update */ + void peerLayoutAboutToChange(); /** Handle updated peer information */ void peerLayoutChanged(); /** Disconnect a selected node on the Peers tab */ @@ -135,7 +137,7 @@ private: ClientModel *clientModel; QStringList history; int historyPtr; - NodeId cachedNodeid; + QList<NodeId> cachedNodeids; const PlatformStyle *platformStyle; RPCTimerInterface *rpcTimerInterface; QMenu *peersTableContextMenu; diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index 6a5670e378..eedf6e8cea 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -65,7 +65,7 @@ public: ADD_SERIALIZE_METHODS; template <typename Stream, typename Operation> - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + inline void SerializationOp(Stream& s, Operation ser_action) { std::string sAddress = address.toStdString(); std::string sLabel = label.toStdString(); std::string sMessage = message.toStdString(); |