diff options
40 files changed, 1527 insertions, 488 deletions
@@ -49,8 +49,8 @@ Testing ------- Testing and code review is the bottleneck for development; we get more pull -requests than we can review and test. Please be patient and help out, and -remember this is a security-critical project where any mistake might cost people +requests than we can review and test on short notice. Please be patient and help out by testing +other people's pull requests, and remember this is a security-critical project where any mistake might cost people lots of money. ### Automated Testing diff --git a/doc/gitian-building.md b/doc/gitian-building.md index 544bbc12c1..378a45eda5 100644 --- a/doc/gitian-building.md +++ b/doc/gitian-building.md @@ -34,19 +34,22 @@ Table of Contents - [Signing externally](#signing-externally) - [Uploading signatures](#uploading-signatures) -Create a new VirtualBox VM ---------------------------- +Preparing the Gitian builder host +--------------------------------- -The first step is to create a new Virtual Machine, which will be explained in -this section. This VM will be used to do the Gitian builds. In this guide it -will be explained how to set up the environment, and how to get the builds -started. +The first step is to prepare the host environment that will be used to perform the Gitian builds. +In this guide it is explained how to set up the environment, and how to get the builds started. -Debian Linux was chosen as the host distribution because it has a lightweight install (in -contrast to Ubuntu) and is readily available. We here show the steps for -VirtualBox [1], but any kind of virtualization can be used. You can also install -on actual hardware instead of using a VM, in this case you can skip this section. +Debian Linux was chosen as the host distribution because it has a lightweight install (in contrast to Ubuntu) and is readily available. +Any kind of virtualization can be used, for example: +- [VirtualBox](https://www.virtualbox.org/), covered by this guide +- [KVM](http://www.linux-kvm.org/page/Main_Page) +- [LXC](https://linuxcontainers.org/), see also [Gitian host docker container](https://github.com/gdm85/tenku/tree/master/docker/gitian-bitcoin-host/README.md). +You can also install on actual hardware instead of using virtualization. + +Create a new VirtualBox VM +--------------------------- In the VirtualBox GUI click "Create" and choose the following parameters in the wizard: ![](gitian-building/create_vm_page1.png) @@ -74,11 +77,11 @@ In the VirtualBox GUI click "Create" and choose the following parameters in the - Disk size: at least 40GB; as low as 20GB *may* be possible, but better to err on the safe side - Push the `Create` button -Get the [Debian 7.4 net installer](http://cdimage.debian.org/debian-cd/7.4.0/amd64/iso-cd/debian-7.4.0-amd64-netinst.iso). +Get the [Debian 7.4 net installer](http://ftp.at.debian.org/debian-jigdo/current/amd64/iso-cd/debian-7.4.0-amd64-netinst.iso) (a more recent minor version should also work, see also [Debian Network installation](https://www.debian.org/CD/netinst/)). This DVD image can be validated using a SHA256 hashing tool, for example on Unixy OSes by entering the following in a terminal: - echo "b712a141bc60269db217d3b3e456179bd6b181645f90e4aac9c42ed63de492e9 /home/orion/Downloads/debian-7.4.0-amd64-netinst.iso" | sha256sum -c + echo "b712a141bc60269db217d3b3e456179bd6b181645f90e4aac9c42ed63de492e9 debian-7.4.0-amd64-netinst.iso" | sha256sum -c # (must return OK) After creating the VM, we need to configure it. @@ -106,8 +109,6 @@ Then start the VM. On the first launch you will be asked for a CD or DVD image. ![](gitian-building/select_startup_disk.png) -[1] https://www.virtualbox.org/ - Installing Debian ------------------ @@ -279,11 +280,14 @@ cd .. **Note**: When sudo asks for a password, enter the password for the user *debian* not for *root*. -Clone the git repositories for bitcoin and gitian, +Clone the git repositories for bitcoin and gitian and then checkout the bitcoin version that you are willing to build. ```bash git clone https://github.com/devrandom/gitian-builder.git git clone https://github.com/bitcoin/bitcoin +cd bitcoin +git checkout v${VERSION} +cd .. ``` Setting up gitian images @@ -402,9 +406,6 @@ gitian build. Uploading signatures --------------------- -After building and signing you can push your signatures (both the `.assert` and -`.assert.sig` files) to the -[bitcoin/gitian.sigs](https://github.com/bitcoin/gitian.sigs/) repository, or -if not possible create a pull request. You can also mail the files to me -(laanwj@gmail.com) and I'll commit them. - +After building and signing you can push your signatures (both the `.assert` and `.assert.sig` files) to the +[bitcoin/gitian.sigs](https://github.com/bitcoin/gitian.sigs/) repository, or if not possible create a pull +request. You can also mail the files to me (laanwj@gmail.com) and I'll commit them. diff --git a/src/init.cpp b/src/init.cpp index 995f2700cf..3255f5bf10 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -859,7 +859,7 @@ bool AppInit2(boost::thread_group& threadGroup) } uiInterface.InitMessage(_("Verifying blocks...")); - if (!VerifyDB(GetArg("-checklevel", 3), + if (!CVerifyDB().VerifyDB(GetArg("-checklevel", 3), GetArg("-checkblocks", 288))) { strLoadError = _("Corrupted block database detected"); break; diff --git a/src/main.cpp b/src/main.cpp index 5cb6e706bb..b1258839d0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2968,7 +2968,17 @@ bool static LoadBlockIndexDB() return true; } -bool VerifyDB(int nCheckLevel, int nCheckDepth) +CVerifyDB::CVerifyDB() +{ + uiInterface.ShowProgress(_("Verifying blocks..."), 0); +} + +CVerifyDB::~CVerifyDB() +{ + uiInterface.ShowProgress("", 100); +} + +bool CVerifyDB::VerifyDB(int nCheckLevel, int nCheckDepth) { LOCK(cs_main); if (chainActive.Tip() == NULL || chainActive.Tip()->pprev == NULL) @@ -2989,6 +2999,7 @@ bool VerifyDB(int nCheckLevel, int nCheckDepth) for (CBlockIndex* pindex = chainActive.Tip(); pindex && pindex->pprev; pindex = pindex->pprev) { boost::this_thread::interruption_point(); + uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100))))); if (pindex->nHeight < chainActive.Height()-nCheckDepth) break; CBlock block; @@ -3028,6 +3039,7 @@ bool VerifyDB(int nCheckLevel, int nCheckDepth) CBlockIndex *pindex = pindexState; while (pindex != chainActive.Tip()) { boost::this_thread::interruption_point(); + uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, 100 - (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * 50)))); pindex = chainActive.Next(pindex); CBlock block; if (!ReadBlockFromDisk(block, pindex)) diff --git a/src/main.h b/src/main.h index 26f66630ae..3fccd32a29 100644 --- a/src/main.h +++ b/src/main.h @@ -144,8 +144,6 @@ bool InitBlockIndex(); bool LoadBlockIndex(); /** Unload database information */ void UnloadBlockIndex(); -/** Verify consistency of the block and coin databases */ -bool VerifyDB(int nCheckLevel, int nCheckDepth); /** Print the loaded block tree */ void PrintBlockTree(); /** Process protocol messages received from a given node */ @@ -1024,6 +1022,15 @@ public: std::string GetRejectReason() const { return strRejectReason; } }; +/** RAII wrapper for VerifyDB: Verify consistency of the block and coin databases */ +class CVerifyDB { +public: + + CVerifyDB(); + ~CVerifyDB(); + bool VerifyDB(int nCheckLevel, int nCheckDepth); +}; + /** An in-memory indexed chain of blocks. */ class CChain { private: diff --git a/src/mruset.h b/src/mruset.h index c36a0c8f37..c1c08b0288 100644 --- a/src/mruset.h +++ b/src/mruset.h @@ -32,6 +32,7 @@ public: bool empty() const { return set.empty(); } iterator find(const key_type& k) const { return set.find(k); } size_type count(const key_type& k) const { return set.count(k); } + void clear() { set.clear(); queue.clear(); } bool inline friend operator==(const mruset<T>& a, const mruset<T>& b) { return a.set == b.set; } bool inline friend operator==(const mruset<T>& a, const std::set<T>& b) { return a.set == b; } bool inline friend operator<(const mruset<T>& a, const mruset<T>& b) { return a.set < b.set; } diff --git a/src/net.cpp b/src/net.cpp index c2dde97040..b0e6699ed2 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1455,13 +1455,13 @@ bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOu // for now, use a very simple selection metric: the node from which we received // most recently -double static NodeSyncScore(const CNode *pnode) { - return -pnode->nLastRecv; +static int64_t NodeSyncScore(const CNode *pnode) { + return pnode->nLastRecv; } void static StartSync(const vector<CNode*> &vNodes) { CNode *pnodeNewSync = NULL; - double dBestScore = 0; + int64_t nBestScore = 0; int nBestHeight = g_signals.GetHeight().get_value_or(0); @@ -1473,10 +1473,10 @@ void static StartSync(const vector<CNode*> &vNodes) { (pnode->nStartingHeight > (nBestHeight - 144)) && (pnode->nVersion < NOBLKS_VERSION_START || pnode->nVersion >= NOBLKS_VERSION_END)) { // if ok, compare node's score with the best so far - double dScore = NodeSyncScore(pnode); - if (pnodeNewSync == NULL || dScore > dBestScore) { + int64_t nScore = NodeSyncScore(pnode); + if (pnodeNewSync == NULL || nScore > nBestScore) { pnodeNewSync = pnode; - dBestScore = dScore; + nBestScore = nScore; } } } @@ -262,7 +262,7 @@ public: // flood relay std::vector<CAddress> vAddrToSend; - std::set<CAddress> setAddrKnown; + mruset<CAddress> setAddrKnown; bool fGetAddr; std::set<uint256> setKnown; @@ -278,7 +278,7 @@ public: int64_t nPingUsecTime; bool fPingQueued; - CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn = "", bool fInboundIn=false) : ssSend(SER_NETWORK, INIT_PROTO_VERSION) + CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn = "", bool fInboundIn=false) : ssSend(SER_NETWORK, INIT_PROTO_VERSION), setAddrKnown(5000) { nServices = 0; hSocket = hSocketIn; diff --git a/src/netbase.h b/src/netbase.h index f5a64cb51f..23cfb1f158 100644 --- a/src/netbase.h +++ b/src/netbase.h @@ -17,6 +17,7 @@ #include <vector> extern int nConnectTimeout; +extern bool fNameLookup; #ifdef WIN32 // In MSVC, this is defined as a macro, undefine it to prevent a compile and link error @@ -33,9 +34,6 @@ enum Network NET_MAX, }; -extern int nConnectTimeout; -extern bool fNameLookup; - /** IP address (IPv6, or IPv4 using mapped IPv6 range (::FFFF:0:0/96)) */ class CNetAddr { diff --git a/src/qt/Makefile.am b/src/qt/Makefile.am index 648971bd8f..1d85113d78 100644 --- a/src/qt/Makefile.am +++ b/src/qt/Makefile.am @@ -126,6 +126,7 @@ QT_MOC_CPP = \ moc_optionsdialog.cpp \ moc_optionsmodel.cpp \ moc_overviewpage.cpp \ + moc_peertablemodel.cpp \ moc_paymentserver.cpp \ moc_qvalidatedlineedit.cpp \ moc_qvaluecombobox.cpp \ @@ -191,6 +192,7 @@ BITCOIN_QT_H = \ overviewpage.h \ paymentrequestplus.h \ paymentserver.h \ + peertablemodel.h \ qvalidatedlineedit.h \ qvaluecombobox.h \ receivecoinsdialog.h \ @@ -294,6 +296,7 @@ BITCOIN_QT_CPP += \ overviewpage.cpp \ paymentrequestplus.cpp \ paymentserver.cpp \ + peertablemodel.cpp \ receivecoinsdialog.cpp \ receiverequestdialog.cpp \ recentrequeststablemodel.cpp \ diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 68ae8b4668..3469f990ac 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -40,6 +40,7 @@ #include <QMessageBox> #include <QMimeData> #include <QProgressBar> +#include <QProgressDialog> #include <QSettings> #include <QStackedWidget> #include <QStatusBar> @@ -409,6 +410,9 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel) // Receive and report messages from client model connect(clientModel, SIGNAL(message(QString,QString,unsigned int)), this, SLOT(message(QString,QString,unsigned int))); + // Show progress dialog + connect(clientModel, SIGNAL(showProgress(QString,int)), this, SLOT(showProgress(QString,int))); + rpcConsole->setClientModel(clientModel); #ifdef ENABLE_WALLET if(walletFrame) @@ -949,6 +953,29 @@ void BitcoinGUI::detectShutdown() } } +void BitcoinGUI::showProgress(const QString &title, int nProgress) +{ + if (nProgress == 0) + { + progressDialog = new QProgressDialog(title, "", 0, 100); + progressDialog->setWindowModality(Qt::ApplicationModal); + progressDialog->setMinimumDuration(0); + progressDialog->setCancelButton(0); + progressDialog->setAutoClose(false); + progressDialog->setValue(0); + } + else if (nProgress == 100) + { + if (progressDialog) + { + progressDialog->close(); + progressDialog->deleteLater(); + } + } + else if (progressDialog) + progressDialog->setValue(nProgress); +} + static bool ThreadSafeMessageBox(BitcoinGUI *gui, const std::string& message, const std::string& caption, unsigned int style) { bool modal = (style & CClientUIInterface::MODAL); diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index b4675b95ac..275fa35f39 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -26,6 +26,7 @@ QT_BEGIN_NAMESPACE class QAction; class QLabel; class QProgressBar; +class QProgressDialog; QT_END_NAMESPACE /** @@ -73,6 +74,7 @@ private: QLabel *labelBlocksIcon; QLabel *progressBarLabel; QProgressBar *progressBar; + QProgressDialog *progressDialog; QMenuBar *appMenuBar; QAction *overviewAction; @@ -191,6 +193,9 @@ private slots: /** called by a timer to check if fRequestShutdown has been set **/ void detectShutdown(); + + /** Show progress dialog e.g. for verifychain */ + void showProgress(const QString &title, int nProgress); }; #endif // BITCOINGUI_H diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index d1f68ebd22..403b03378f 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -5,6 +5,7 @@ #include "clientmodel.h" #include "guiconstants.h" +#include "peertablemodel.h" #include "alert.h" #include "chainparams.h" @@ -22,11 +23,14 @@ static const int64_t nClientStartupTime = GetTime(); ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) : - QObject(parent), optionsModel(optionsModel), + QObject(parent), + optionsModel(optionsModel), + peerTableModel(0), cachedNumBlocks(0), cachedReindexing(0), cachedImporting(0), numBlocksAtStartup(-1), pollTimer(0) { + peerTableModel = new PeerTableModel(this); pollTimer = new QTimer(this); connect(pollTimer, SIGNAL(timeout()), this, SLOT(updateTimer())); pollTimer->start(MODEL_UPDATE_DELAY); @@ -173,6 +177,11 @@ OptionsModel *ClientModel::getOptionsModel() return optionsModel; } +PeerTableModel *ClientModel::getPeerTableModel() +{ + return peerTableModel; +} + QString ClientModel::formatFullVersion() const { return QString::fromStdString(FormatFullVersion()); @@ -199,6 +208,14 @@ QString ClientModel::formatClientStartupTime() const } // Handlers for core signals +static void ShowProgress(ClientModel *clientmodel, const std::string &title, int nProgress) +{ + // emits signal "showProgress" + QMetaObject::invokeMethod(clientmodel, "showProgress", Qt::QueuedConnection, + Q_ARG(QString, QString::fromStdString(title)), + Q_ARG(int, nProgress)); +} + static void NotifyBlocksChanged(ClientModel *clientmodel) { // This notification is too frequent. Don't trigger a signal. @@ -223,6 +240,7 @@ static void NotifyAlertChanged(ClientModel *clientmodel, const uint256 &hash, Ch void ClientModel::subscribeToCoreSignals() { // Connect signals to client + uiInterface.ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2)); uiInterface.NotifyBlocksChanged.connect(boost::bind(NotifyBlocksChanged, this)); uiInterface.NotifyNumConnectionsChanged.connect(boost::bind(NotifyNumConnectionsChanged, this, _1)); uiInterface.NotifyAlertChanged.connect(boost::bind(NotifyAlertChanged, this, _1, _2)); @@ -231,6 +249,7 @@ void ClientModel::subscribeToCoreSignals() void ClientModel::unsubscribeFromCoreSignals() { // Disconnect signals from client + uiInterface.ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2)); uiInterface.NotifyBlocksChanged.disconnect(boost::bind(NotifyBlocksChanged, this)); uiInterface.NotifyNumConnectionsChanged.disconnect(boost::bind(NotifyNumConnectionsChanged, this, _1)); uiInterface.NotifyAlertChanged.disconnect(boost::bind(NotifyAlertChanged, this, _1, _2)); diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h index cab853d92d..9c9a35b654 100644 --- a/src/qt/clientmodel.h +++ b/src/qt/clientmodel.h @@ -9,6 +9,7 @@ class AddressTableModel; class OptionsModel; +class PeerTableModel; class TransactionTableModel; class CWallet; @@ -42,6 +43,7 @@ public: ~ClientModel(); OptionsModel *getOptionsModel(); + PeerTableModel *getPeerTableModel(); //! Return number of connections, default is in- and outbound (total) int getNumConnections(unsigned int flags = CONNECTIONS_ALL) const; @@ -71,6 +73,7 @@ public: private: OptionsModel *optionsModel; + PeerTableModel *peerTableModel; int cachedNumBlocks; bool cachedReindexing; @@ -92,6 +95,9 @@ signals: //! Fired when a message should be reported to the user void message(const QString &title, const QString &message, unsigned int style); + // Show progress dialog e.g. for verifychain + void showProgress(const QString &title, int nProgress); + public slots: void updateTimer(); void updateNumConnections(int numConnections); diff --git a/src/qt/forms/aboutdialog.ui b/src/qt/forms/aboutdialog.ui index 3ab4675bf3..fec63f737a 100644 --- a/src/qt/forms/aboutdialog.ui +++ b/src/qt/forms/aboutdialog.ui @@ -110,9 +110,12 @@ <string> This is experimental software. -Distributed under the MIT/X11 software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php. +Distributed under the MIT/X11 software license, see the accompanying file COPYING or <a href="http://www.opensource.org/licenses/mit-license.php">http://www.opensource.org/licenses/mit-license.php</a>. -This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard.</string> +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (<a href="https://www.openssl.org/">https://www.openssl.org/</a>) and cryptographic software written by Eric Young (<a href="mailto:eay@cryptsoft.com">eay@cryptsoft.com</a>) and UPnP software written by Thomas Bernard.</string> + </property> + <property name="textFormat"> + <enum>Qt::RichText</enum> </property> <property name="wordWrap"> <bool>true</bool> diff --git a/src/qt/forms/rpcconsole.ui b/src/qt/forms/rpcconsole.ui index fcb6bb60bb..bf737d9b99 100644 --- a/src/qt/forms/rpcconsole.ui +++ b/src/qt/forms/rpcconsole.ui @@ -652,6 +652,281 @@ </item> </layout> </widget> + <widget class="QWidget" name="tab_peers"> + <attribute name="title"> + <string>&Peers</string> + </attribute> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="0" column="1"> + <widget class="QLabel" name="peerHeading"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Minimum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Select a peer to view detailed information.</string> + </property> + <property name="margin"> + <number>3</number> + </property> + </widget> + </item> + <item row="0" column="0" rowspan="2"> + <widget class="QTableView" name="peerWidget"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="horizontalScrollBarPolicy"> + <enum>Qt::ScrollBarAlwaysOff</enum> + </property> + <property name="editTriggers"> + <set>QAbstractItemView::AnyKeyPressed|QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed</set> + </property> + <property name="sortingEnabled"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QWidget" name="detailWidget" native="true"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <layout class="QGridLayout" name="gridLayout_3"> + <property name="leftMargin"> + <number>3</number> + </property> + <item row="12" column="0"> + <widget class="QLabel" name="label_21"> + <property name="text"> + <string>Version:</string> + </property> + </widget> + </item> + <item row="11" column="1"> + <widget class="QLabel" name="peerPingTime"> + <property name="text"> + <string>N/A</string> + </property> + </widget> + </item> + <item row="5" column="0"> + <widget class="QLabel" name="label_19"> + <property name="text"> + <string>Last Receive:</string> + </property> + </widget> + </item> + <item row="14" column="0"> + <widget class="QLabel" name="label_28"> + <property name="text"> + <string>User Agent:</string> + </property> + </widget> + </item> + <item row="12" column="1"> + <widget class="QLabel" name="peerVersion"> + <property name="text"> + <string>N/A</string> + </property> + </widget> + </item> + <item row="8" column="1"> + <widget class="QLabel" name="peerConnTime"> + <property name="minimumSize"> + <size> + <width>160</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>N/A</string> + </property> + </widget> + </item> + <item row="11" column="0"> + <widget class="QLabel" name="label_26"> + <property name="text"> + <string>Ping Time:</string> + </property> + </widget> + </item> + <item row="5" column="1"> + <widget class="QLabel" name="peerLastRecv"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>N/A</string> + </property> + </widget> + </item> + <item row="8" column="0"> + <widget class="QLabel" name="label_22"> + <property name="text"> + <string>Connection Time:</string> + </property> + </widget> + </item> + <item row="6" column="1"> + <widget class="QLabel" name="peerBytesSent"> + <property name="text"> + <string>N/A</string> + </property> + </widget> + </item> + <item row="14" column="1"> + <widget class="QLabel" name="peerSubversion"> + <property name="text"> + <string>N/A</string> + </property> + </widget> + </item> + <item row="15" column="0"> + <widget class="QLabel" name="label_29"> + <property name="text"> + <string>Starting Height:</string> + </property> + </widget> + </item> + <item row="7" column="1"> + <widget class="QLabel" name="peerBytesRecv"> + <property name="text"> + <string>N/A</string> + </property> + </widget> + </item> + <item row="6" column="0"> + <widget class="QLabel" name="label_18"> + <property name="text"> + <string>Bytes Sent:</string> + </property> + </widget> + </item> + <item row="7" column="0"> + <widget class="QLabel" name="label_20"> + <property name="text"> + <string>Bytes Received:</string> + </property> + </widget> + </item> + <item row="15" column="1"> + <widget class="QLabel" name="peerHeight"> + <property name="text"> + <string>N/A</string> + </property> + </widget> + </item> + <item row="16" column="0"> + <widget class="QLabel" name="label_24"> + <property name="text"> + <string>Ban Score:</string> + </property> + </widget> + </item> + <item row="16" column="1"> + <widget class="QLabel" name="peerBanScore"> + <property name="text"> + <string>N/A</string> + </property> + </widget> + </item> + <item row="17" column="0"> + <widget class="QLabel" name="label_23"> + <property name="text"> + <string>Direction:</string> + </property> + </widget> + </item> + <item row="17" column="1"> + <widget class="QLabel" name="peerDirection"> + <property name="text"> + <string>N/A</string> + </property> + </widget> + </item> + <item row="19" column="0"> + <widget class="QLabel" name="label_25"> + <property name="text"> + <string>Sync Node:</string> + </property> + </widget> + </item> + <item row="19" column="1"> + <widget class="QLabel" name="peerSyncNode"> + <property name="text"> + <string>N/A</string> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="label_15"> + <property name="text"> + <string>Last Send:</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>Services:</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_27"> + <property name="text"> + <string>IP Address/port:</string> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QLabel" name="peerLastSend"> + <property name="text"> + <string>N/A</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLabel" name="peerServices"> + <property name="text"> + <string>N/A</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLabel" name="peerAddr"> + <property name="text"> + <string>N/A</string> + </property> + </widget> + </item> + <item row="20" column="0"> + <widget class="QWidget" name="widget" native="true"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> </widget> </item> </layout> diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 183fcac4a0..1922d228c5 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -11,6 +11,7 @@ #include "core.h" #include "init.h" +#include "protocol.h" #include "util.h" #ifdef WIN32 @@ -754,4 +755,50 @@ QString boostPathToQString(const boost::filesystem::path &path) } #endif +QString formatDurationStr(int secs) +{ + QStringList strList; + int days = secs / 86400; + int hours = (secs % 86400) / 3600; + int mins = (secs % 3600) / 60; + int seconds = secs % 60; + + if (days) + strList.append(QString(QObject::tr("%1 d")).arg(days)); + 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)); + + return strList.join(" "); +} + +QString formatServicesStr(uint64_t mask) +{ + QStringList strList; + + // Just scan the last 8 bits for now. + for (int i = 0; i < 8; i++) { + uint64_t check = 1 << i; + if (mask & check) + { + switch (check) + { + case NODE_NETWORK: + strList.append(QObject::tr("NETWORK")); + break; + default: + strList.append(QString("%1[%2]").arg(QObject::tr("UNKNOWN")).arg(check)); + } + } + } + + if (strList.size()) + return strList.join(" & "); + else + return QObject::tr("None"); +} + } // namespace GUIUtil diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index 4f9416d1af..45c78b4e14 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -173,6 +173,11 @@ namespace GUIUtil /* Convert OS specific boost path to QString through UTF-8 */ QString boostPathToQString(const boost::filesystem::path &path); + /* Convert seconds into a QString with days, hours, mins, secs */ + QString formatDurationStr(int secs); + + /* Format CNodeStats.nServices bitmask into a user-readable string */ + QString formatServicesStr(uint64_t mask); } // namespace GUIUtil #endif // GUIUTIL_H diff --git a/src/qt/locale/bitcoin_da.ts b/src/qt/locale/bitcoin_da.ts index b13b38a878..a0514035fd 100644 --- a/src/qt/locale/bitcoin_da.ts +++ b/src/qt/locale/bitcoin_da.ts @@ -3,11 +3,11 @@ <name>AboutDialog</name> <message> <source>About Bitcoin Core</source> - <translation type="unfinished"/> + <translation>Om Bitcoin Core</translation> </message> <message> <source><b>Bitcoin Core</b> version</source> - <translation type="unfinished"/> + <translation><b>Bitcoin Core</b> version</translation> </message> <message> <source> @@ -29,11 +29,11 @@ Produktet indeholder software som er udviklet af OpenSSL Project til brug i Open </message> <message> <source>The Bitcoin Core developers</source> - <translation type="unfinished"/> + <translation>Udviklerne af Bitcoin Core</translation> </message> <message> <source>(%1-bit)</source> - <translation type="unfinished"/> + <translation>(%1-bit)</translation> </message> </context> <context> @@ -48,7 +48,7 @@ Produktet indeholder software som er udviklet af OpenSSL Project til brug i Open </message> <message> <source>&New</source> - <translation>&Ny</translation> + <translation>Ny</translation> </message> <message> <source>Copy the currently selected address to the system clipboard</source> @@ -56,11 +56,11 @@ Produktet indeholder software som er udviklet af OpenSSL Project til brug i Open </message> <message> <source>&Copy</source> - <translation>&Kopiér</translation> + <translation>Kopiér</translation> </message> <message> <source>C&lose</source> - <translation type="unfinished"/> + <translation>Luk</translation> </message> <message> <source>&Copy Address</source> @@ -84,15 +84,15 @@ Produktet indeholder software som er udviklet af OpenSSL Project til brug i Open </message> <message> <source>Choose the address to send coins to</source> - <translation type="unfinished"/> + <translation>Vælg adresse at sende bitcoins til</translation> </message> <message> <source>Choose the address to receive coins with</source> - <translation type="unfinished"/> + <translation>Vælg adresse at modtage bitcoins med</translation> </message> <message> <source>C&hoose</source> - <translation type="unfinished"/> + <translation>Vælg</translation> </message> <message> <source>Sending addresses</source> @@ -108,7 +108,7 @@ Produktet indeholder software som er udviklet af OpenSSL Project til brug i Open </message> <message> <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source> - <translation type="unfinished"/> + <translation>Dette er dine Bitcoin-adresser til at modtage betalinger med. Det anbefales are bruge en ny modtagelsesadresse for hver transaktion.</translation> </message> <message> <source>Copy &Label</source> @@ -120,7 +120,7 @@ Produktet indeholder software som er udviklet af OpenSSL Project til brug i Open </message> <message> <source>Export Address List</source> - <translation type="unfinished"/> + <translation>Eksportér adresseliste</translation> </message> <message> <source>Comma separated file (*.csv)</source> @@ -128,11 +128,11 @@ Produktet indeholder software som er udviklet af OpenSSL Project til brug i Open </message> <message> <source>Exporting Failed</source> - <translation type="unfinished"/> + <translation>Eksport mislykkedes</translation> </message> <message> <source>There was an error trying to save the address list to %1.</source> - <translation type="unfinished"/> + <translation>En fejl opstod under gemning af adresseliste til %1.</translation> </message> </context> <context> @@ -273,7 +273,7 @@ Produktet indeholder software som er udviklet af OpenSSL Project til brug i Open </message> <message> <source>Node</source> - <translation type="unfinished"/> + <translation>Knude</translation> </message> <message> <source>Show general overview of wallet</source> @@ -325,15 +325,15 @@ Produktet indeholder software som er udviklet af OpenSSL Project til brug i Open </message> <message> <source>&Sending addresses...</source> - <translation>&Afsendelsesadresser...</translation> + <translation>Afsendelsesadresser …</translation> </message> <message> <source>&Receiving addresses...</source> - <translation>&Modtagelsesadresser...</translation> + <translation>Modtagelsesadresser …</translation> </message> <message> <source>Open &URI...</source> - <translation type="unfinished"/> + <translation>Åbn URI …</translation> </message> <message> <source>Importing blocks from disk...</source> @@ -433,31 +433,31 @@ Produktet indeholder software som er udviklet af OpenSSL Project til brug i Open </message> <message> <source>Request payments (generates QR codes and bitcoin: URIs)</source> - <translation type="unfinished"/> + <translation>Forespørg betalinger (genererer QR-koder og "bitcoin:"-URI'er)</translation> </message> <message> <source>&About Bitcoin Core</source> - <translation type="unfinished"/> + <translation>Om Bitcoin Core</translation> </message> <message> <source>Show the list of used sending addresses and labels</source> - <translation type="unfinished"/> + <translation>Vis listen over brugte afsendelsesadresser og -mærkater</translation> </message> <message> <source>Show the list of used receiving addresses and labels</source> - <translation type="unfinished"/> + <translation>Vis listen over brugte modtagelsesadresser og -mærkater</translation> </message> <message> <source>Open a bitcoin: URI or payment request</source> - <translation type="unfinished"/> + <translation>Åbn en "bitcoin:"-URI eller betalingsforespørgsel</translation> </message> <message> <source>&Command-line options</source> - <translation type="unfinished"/> + <translation>Tilvalg for kommandolinje</translation> </message> <message> <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source> - <translation type="unfinished"/> + <translation>Vis Bitcoin Core hjælpebesked for at få en liste over mulige tilvalg for Bitcoin kommandolinje</translation> </message> <message> <source>Bitcoin client</source> @@ -493,11 +493,11 @@ Produktet indeholder software som er udviklet af OpenSSL Project til brug i Open </message> <message> <source>%1 and %2</source> - <translation type="unfinished"/> + <translation>%1 og %2</translation> </message> <message numerus="yes"> <source>%n year(s)</source> - <translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation> + <translation><numerusform>%n år</numerusform><numerusform>%n år</numerusform></translation> </message> <message> <source>%1 behind</source> @@ -575,15 +575,15 @@ Adresse: %4 <name>CoinControlDialog</name> <message> <source>Coin Control Address Selection</source> - <translation type="unfinished"/> + <translation>Adressevalg for coin-styring</translation> </message> <message> <source>Quantity:</source> - <translation type="unfinished"/> + <translation>Mængde:</translation> </message> <message> <source>Bytes:</source> - <translation type="unfinished"/> + <translation>Byte:</translation> </message> <message> <source>Amount:</source> @@ -591,35 +591,35 @@ Adresse: %4 </message> <message> <source>Priority:</source> - <translation type="unfinished"/> + <translation>Prioritet:</translation> </message> <message> <source>Fee:</source> - <translation type="unfinished"/> + <translation>Gebyr:</translation> </message> <message> <source>Low Output:</source> - <translation type="unfinished"/> + <translation>Lavt output:</translation> </message> <message> <source>After Fee:</source> - <translation type="unfinished"/> + <translation>Efter gebyr:</translation> </message> <message> <source>Change:</source> - <translation type="unfinished"/> + <translation>Byttepenge:</translation> </message> <message> <source>(un)select all</source> - <translation type="unfinished"/> + <translation>(af)vælg alle</translation> </message> <message> <source>Tree mode</source> - <translation type="unfinished"/> + <translation>Trætilstand</translation> </message> <message> <source>List mode</source> - <translation type="unfinished"/> + <translation>Listetilstand</translation> </message> <message> <source>Amount</source> @@ -635,7 +635,7 @@ Adresse: %4 </message> <message> <source>Confirmations</source> - <translation type="unfinished"/> + <translation>Bekræftelser</translation> </message> <message> <source>Confirmed</source> @@ -643,151 +643,151 @@ Adresse: %4 </message> <message> <source>Priority</source> - <translation type="unfinished"/> + <translation>Prioritet</translation> </message> <message> <source>Copy address</source> - <translation>Kopier adresse</translation> + <translation>Kopiér adresse</translation> </message> <message> <source>Copy label</source> - <translation>Kopier mærkat</translation> + <translation>Kopiér mærkat</translation> </message> <message> <source>Copy amount</source> - <translation>Kopier beløb</translation> + <translation>Kopiér beløb</translation> </message> <message> <source>Copy transaction ID</source> - <translation>Kopier transaktionens ID</translation> + <translation>Kopiér transaktions-ID</translation> </message> <message> <source>Lock unspent</source> - <translation type="unfinished"/> + <translation>Fastlås ubrugte</translation> </message> <message> <source>Unlock unspent</source> - <translation type="unfinished"/> + <translation>Lås ubrugte op</translation> </message> <message> <source>Copy quantity</source> - <translation type="unfinished"/> + <translation>Kopiér mængde</translation> </message> <message> <source>Copy fee</source> - <translation type="unfinished"/> + <translation>Kopiér gebyr</translation> </message> <message> <source>Copy after fee</source> - <translation type="unfinished"/> + <translation>Kopiér efter-gebyr</translation> </message> <message> <source>Copy bytes</source> - <translation type="unfinished"/> + <translation>Kopiér byte</translation> </message> <message> <source>Copy priority</source> - <translation type="unfinished"/> + <translation>Kopiér prioritet</translation> </message> <message> <source>Copy low output</source> - <translation type="unfinished"/> + <translation>Kopiér lavt output</translation> </message> <message> <source>Copy change</source> - <translation type="unfinished"/> + <translation>Kopiér byttepenge</translation> </message> <message> <source>highest</source> - <translation type="unfinished"/> + <translation>højest</translation> </message> <message> <source>higher</source> - <translation type="unfinished"/> + <translation>højere</translation> </message> <message> <source>high</source> - <translation type="unfinished"/> + <translation>højt</translation> </message> <message> <source>medium-high</source> - <translation type="unfinished"/> + <translation>mellemhøj</translation> </message> <message> <source>medium</source> - <translation type="unfinished"/> + <translation>medium</translation> </message> <message> <source>low-medium</source> - <translation type="unfinished"/> + <translation>mellemlav</translation> </message> <message> <source>low</source> - <translation type="unfinished"/> + <translation>lav</translation> </message> <message> <source>lower</source> - <translation type="unfinished"/> + <translation>lavere</translation> </message> <message> <source>lowest</source> - <translation type="unfinished"/> + <translation>lavest</translation> </message> <message> <source>(%1 locked)</source> - <translation type="unfinished"/> + <translation>(%1 fastlåst)</translation> </message> <message> <source>none</source> - <translation type="unfinished"/> + <translation>ingen</translation> </message> <message> <source>Dust</source> - <translation type="unfinished"/> + <translation>Støv</translation> </message> <message> <source>yes</source> - <translation type="unfinished"/> + <translation>ja</translation> </message> <message> <source>no</source> - <translation type="unfinished"/> + <translation>nej</translation> </message> <message> <source>This label turns red, if the transaction size is greater than 1000 bytes.</source> - <translation type="unfinished"/> + <translation>Dette mærkat bliver rødt, hvis transaktionsstørrelsen er større end 1000 byte.</translation> </message> <message> <source>This means a fee of at least %1 per kB is required.</source> - <translation type="unfinished"/> + <translation>Dette betyder, at et gebyr på mindst %1 pr. kB er nødvendigt.</translation> </message> <message> <source>Can vary +/- 1 byte per input.</source> - <translation type="unfinished"/> + <translation>Kan variere ±1 byte pr. input.</translation> </message> <message> <source>Transactions with higher priority are more likely to get included into a block.</source> - <translation type="unfinished"/> + <translation>Transaktioner med højere prioritet har højere sansynlighed for at blive inkluderet i en blok.</translation> </message> <message> <source>This label turns red, if the priority is smaller than "medium".</source> - <translation type="unfinished"/> + <translation>Dette mærkat bliver rødt, hvis prioriteten er mindre end "medium".</translation> </message> <message> <source>This label turns red, if any recipient receives an amount smaller than %1.</source> - <translation type="unfinished"/> + <translation>Dette mærkat bliver rødt, hvis mindst én modtager et beløb mindre end %1.</translation> </message> <message> <source>This means a fee of at least %1 is required.</source> - <translation type="unfinished"/> + <translation>Dette betyder, at et gebyr på mindst %1 er nødvendigt.</translation> </message> <message> <source>Amounts below 0.546 times the minimum relay fee are shown as dust.</source> - <translation type="unfinished"/> + <translation>Beløb under 0,546 gange det minimale videreførselsgebyr vises som støv.</translation> </message> <message> <source>This label turns red, if the change is smaller than %1.</source> - <translation type="unfinished"/> + <translation>Dette mærkat bliver rødt, hvis byttepengene er mindre end %1.</translation> </message> <message> <source>(no label)</source> @@ -795,11 +795,11 @@ Adresse: %4 </message> <message> <source>change from %1 (%2)</source> - <translation type="unfinished"/> + <translation>byttepenge fra %1 (%2)</translation> </message> <message> <source>(change)</source> - <translation type="unfinished"/> + <translation>(byttepange)</translation> </message> </context> <context> @@ -814,11 +814,11 @@ Adresse: %4 </message> <message> <source>The label associated with this address list entry</source> - <translation type="unfinished"/> + <translation>Mærkatet, der er associeret med denne indgang i adresselisten</translation> </message> <message> <source>The address associated with this address list entry. This can only be modified for sending addresses.</source> - <translation type="unfinished"/> + <translation>Adressen, der er associeret med denne indgang i adresselisten. Denne kan kune ændres for afsendelsesadresser.</translation> </message> <message> <source>&Address</source> @@ -884,7 +884,7 @@ Adresse: %4 <name>HelpMessageDialog</name> <message> <source>Bitcoin Core - Command-line options</source> - <translation type="unfinished"/> + <translation>Bitcoin Core – tilvalg for kommandolinje</translation> </message> <message> <source>Bitcoin Core</source> @@ -908,7 +908,7 @@ Adresse: %4 </message> <message> <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Angiv sprog, f.eks "de_DE" (standard: systemlokalitet)</translation> + <translation>Angiv sprog, fx "da_DK" (standard: systemlokalitet)</translation> </message> <message> <source>Start minimized</source> @@ -916,15 +916,15 @@ Adresse: %4 </message> <message> <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation type="unfinished"/> + <translation>Sæt SSL-rodcertifikater for betalingsforespørgsel (standard: -system-)</translation> </message> <message> <source>Show splash screen on startup (default: 1)</source> - <translation>Vis opstartsbillede ved start (standard: 1)</translation> + <translation>Vis opstartsbillede ved opstart (standard: 1)</translation> </message> <message> <source>Choose data directory on startup (default: 0)</source> - <translation type="unfinished"/> + <translation>Vælg datamappe ved opstart (standard: 0)</translation> </message> </context> <context> @@ -935,15 +935,15 @@ Adresse: %4 </message> <message> <source>Welcome to Bitcoin Core.</source> - <translation type="unfinished"/> + <translation>Velkommen til Bitcoin Core.</translation> </message> <message> <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source> - <translation type="unfinished"/> + <translation>Siden dette er første gang, programmet startes, kan du vælge, hvor Bitcoin Core skal gemme sin data.</translation> </message> <message> <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source> - <translation type="unfinished"/> + <translation>Bitcoin Core vil downloade og gemme et kopi af Bitcoin-blokkæden. Mindst %1 GB data vil blive gemt i denne mappe, og den vil vokse over tid. Tegnebogen vil også blive gemt i denne mappe.</translation> </message> <message> <source>Use the default data directory</source> @@ -959,7 +959,7 @@ Adresse: %4 </message> <message> <source>Error: Specified data directory "%1" can not be created.</source> - <translation type="unfinished"/> + <translation>Fejl: Angivet datamappe "%1" kan ikke oprettes.</translation> </message> <message> <source>Error</source> @@ -978,23 +978,23 @@ Adresse: %4 <name>OpenURIDialog</name> <message> <source>Open URI</source> - <translation type="unfinished"/> + <translation>Åbn URI</translation> </message> <message> <source>Open payment request from URI or file</source> - <translation type="unfinished"/> + <translation>Åbn betalingsforespørgsel fra URI eller fil</translation> </message> <message> <source>URI:</source> - <translation type="unfinished"/> + <translation>URI:</translation> </message> <message> <source>Select payment request file</source> - <translation type="unfinished"/> + <translation>Vælg fil for betalingsforespørgsel</translation> </message> <message> <source>Select payment request file to open</source> - <translation type="unfinished"/> + <translation>Vælg fil for betalingsforespørgsel til åbning</translation> </message> </context> <context> @@ -1025,39 +1025,39 @@ Adresse: %4 </message> <message> <source>Size of &database cache</source> - <translation type="unfinished"/> + <translation>Størrelsen på databasens cache</translation> </message> <message> <source>MB</source> - <translation type="unfinished"/> + <translation>MB</translation> </message> <message> <source>Number of script &verification threads</source> - <translation type="unfinished"/> + <translation>Antallet af scriptverificeringstråde</translation> </message> <message> <source>Connect to the Bitcoin network through a SOCKS proxy.</source> - <translation type="unfinished"/> + <translation>Forbind til Bitcoin-netværket gennem en SOCKS-proxy.</translation> </message> <message> <source>&Connect through SOCKS proxy (default proxy):</source> - <translation type="unfinished"/> + <translation>Forbind gennem SOCKS-proxy (standard-proxy):</translation> </message> <message> <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source> - <translation type="unfinished"/> + <translation>IP-adresse for proxyen (fx IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> <message> <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> - <translation type="unfinished"/> + <translation>Tredjeparts-URL'er (fx et blokhåndteringsværktøj), der vises i transaktionsfanen som genvejsmenupunkter. %s i URL'en erstattes med transaktionens hash. Flere URL'er separeres med en lodret streg |.</translation> </message> <message> <source>Third party transaction URLs</source> - <translation type="unfinished"/> + <translation>Tredjeparts-transaktions-URL'er</translation> </message> <message> <source>Active command-line options that override above options:</source> - <translation type="unfinished"/> + <translation>Aktuelle tilvalg for kommandolinjen, der tilsidesætter ovenstående tilvalg:</translation> </message> <message> <source>Reset all client options to default.</source> @@ -1073,27 +1073,27 @@ Adresse: %4 </message> <message> <source>(0 = auto, <0 = leave that many cores free)</source> - <translation type="unfinished"/> + <translation>(0 = auto, <0 = efterlad så mange kerner fri)</translation> </message> <message> <source>W&allet</source> - <translation type="unfinished"/> + <translation>Tegnebog</translation> </message> <message> <source>Expert</source> - <translation type="unfinished"/> + <translation>Ekspert</translation> </message> <message> <source>Enable coin &control features</source> - <translation type="unfinished"/> + <translation>Slå egenskaber for coin-styring til</translation> </message> <message> <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source> - <translation type="unfinished"/> + <translation>Hvis du slår brug af ubekræftede byttepenge fra, kan byttepengene fra en transaktion ikke bruges, før pågældende transaktion har mindst én bekræftelse. Dette påvirker også måden hvorpå din saldo beregnes.</translation> </message> <message> <source>&Spend unconfirmed change</source> - <translation type="unfinished"/> + <translation>Brug ubekræftede byttepenge</translation> </message> <message> <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source> @@ -1173,7 +1173,7 @@ Adresse: %4 </message> <message> <source>Whether to show coin control features or not.</source> - <translation type="unfinished"/> + <translation>Hvorvidt egenskaber for coin-styring skal vises eller ej.</translation> </message> <message> <source>&OK</source> @@ -1189,7 +1189,7 @@ Adresse: %4 </message> <message> <source>none</source> - <translation type="unfinished"/> + <translation>ingeningen</translation> </message> <message> <source>Confirm options reset</source> @@ -1197,15 +1197,15 @@ Adresse: %4 </message> <message> <source>Client restart required to activate changes.</source> - <translation type="unfinished"/> + <translation>Genstart af klienten er nødvendig for at aktivere ændringer.</translation> </message> <message> <source>Client will be shutdown, do you want to proceed?</source> - <translation type="unfinished"/> + <translation>Klienten vil blive lukket ned; vil du fortsætte?</translation> </message> <message> <source>This change would require a client restart.</source> - <translation type="unfinished"/> + <translation>Denne ændring vil kræve en genstart af klienten.</translation> </message> <message> <source>The supplied proxy address is invalid.</source> @@ -1228,7 +1228,7 @@ Adresse: %4 </message> <message> <source>Available:</source> - <translation type="unfinished"/> + <translation>Tilgængelig:</translation> </message> <message> <source>Your current spendable balance</source> @@ -1236,7 +1236,7 @@ Adresse: %4 </message> <message> <source>Pending:</source> - <translation type="unfinished"/> + <translation>Uafgjort:</translation> </message> <message> <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source> @@ -1279,7 +1279,7 @@ Adresse: %4 </message> <message> <source>Requested payment amount of %1 is too small (considered dust).</source> - <translation type="unfinished"/> + <translation>Forespurgt betalingsbeløb på %1 er for lille (regnes som støv).</translation> </message> <message> <source>Payment request error</source> @@ -1291,27 +1291,27 @@ Adresse: %4 </message> <message> <source>Net manager warning</source> - <translation type="unfinished"/> + <translation>Net-håndterings-advarsel</translation> </message> <message> <source>Your active proxy doesn't support SOCKS5, which is required for payment requests via proxy.</source> - <translation type="unfinished"/> + <translation>Din aktuelle proxy understøtter ikke SOCKS5, hvilket kræves for betalingsforespørgsler via proxy.</translation> </message> <message> <source>Payment request fetch URL is invalid: %1</source> - <translation type="unfinished"/> + <translation>Betalingsforespørgslens hentnings-URL er ugyldig: %1</translation> </message> <message> <source>Payment request file handling</source> - <translation type="unfinished"/> + <translation>Filhåndtering for betalingsanmodninger</translation> </message> <message> <source>Payment request file can not be read or processed! This can be caused by an invalid payment request file.</source> - <translation type="unfinished"/> + <translation>Betalingsanmodningsfil kan ikke indlæses eller bearbejdes! Dette kan skyldes en ugyldig betalingsanmodningsfil.</translation> </message> <message> <source>Unverified payment requests to custom payment scripts are unsupported.</source> - <translation type="unfinished"/> + <translation>Ikke-verificerede betalingsforespørgsler for tilpassede betalings-scripts understøttes ikke.</translation> </message> <message> <source>Refund from %1</source> @@ -1319,19 +1319,19 @@ Adresse: %4 </message> <message> <source>Error communicating with %1: %2</source> - <translation type="unfinished"/> + <translation>Fejl under kommunikation med %1: %2</translation> </message> <message> <source>Payment request can not be parsed or processed!</source> - <translation type="unfinished"/> + <translation>Betalingsanmodning kan ikke fortolkes eller bearbejdes!</translation> </message> <message> <source>Bad response from server %1</source> - <translation type="unfinished"/> + <translation>Fejlagtigt svar fra server %1</translation> </message> <message> <source>Payment acknowledged</source> - <translation type="unfinished"/> + <translation>Betaling anerkendt</translation> </message> <message> <source>Network request error</source> @@ -1350,7 +1350,7 @@ Adresse: %4 </message> <message> <source>Error: Cannot parse configuration file: %1. Only use key=value syntax.</source> - <translation type="unfinished"/> + <translation>Fejl: Kan ikke fortolke konfigurationsfil: %1. Brug kun syntaksen nøgle=værdi.</translation> </message> <message> <source>Error: Invalid combination of -regtest and -testnet.</source> @@ -1358,7 +1358,7 @@ Adresse: %4 </message> <message> <source>Bitcoin Core didn't yet exit safely...</source> - <translation type="unfinished"/> + <translation>Bitcoin Core blev ikke afsluttet på sikker vis …</translation> </message> <message> <source>Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</source> @@ -1369,11 +1369,11 @@ Adresse: %4 <name>QRImageWidget</name> <message> <source>&Save Image...</source> - <translation>&Gem foto...</translation> + <translation>Gem billede …</translation> </message> <message> <source>&Copy Image</source> - <translation>&Kopiér foto</translation> + <translation>Kopiér foto</translation> </message> <message> <source>Save QR Code</source> @@ -1381,7 +1381,7 @@ Adresse: %4 </message> <message> <source>PNG Image (*.png)</source> - <translation type="unfinished"/> + <translation>PNG-billede (*.png)</translation> </message> </context> <context> @@ -1404,11 +1404,11 @@ Adresse: %4 </message> <message> <source>Debug window</source> - <translation type="unfinished"/> + <translation>Fejlsøgningsvindue</translation> </message> <message> <source>General</source> - <translation type="unfinished"/> + <translation>Generelt</translation> </message> <message> <source>Using OpenSSL version</source> @@ -1456,23 +1456,23 @@ Adresse: %4 </message> <message> <source>&Network Traffic</source> - <translation type="unfinished"/> + <translation>Netværkstrafik</translation> </message> <message> <source>&Clear</source> - <translation type="unfinished"/> + <translation>Ryd</translation> </message> <message> <source>Totals</source> - <translation type="unfinished"/> + <translation>Totaler</translation> </message> <message> <source>In:</source> - <translation type="unfinished"/> + <translation>Indkommende:</translation> </message> <message> <source>Out:</source> - <translation>Ud:</translation> + <translation>Udgående:</translation> </message> <message> <source>Build date</source> @@ -1535,7 +1535,7 @@ Adresse: %4 <name>ReceiveCoinsDialog</name> <message> <source>&Amount:</source> - <translation>&Mængde:</translation> + <translation>Beløb:</translation> </message> <message> <source>&Label:</source> @@ -1543,35 +1543,35 @@ Adresse: %4 </message> <message> <source>&Message:</source> - <translation>&Besked:</translation> + <translation>Besked:</translation> </message> <message> <source>Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before.</source> - <translation type="unfinished"/> + <translation>Genbrug en af de tidligere brugte modtagelsesadresser. Genbrug af adresser har indflydelse på sikkerhed og privatliv. Brug ikke dette med mindre du genskaber en betalingsforespørgsel fra tidligere.</translation> </message> <message> <source>R&euse an existing receiving address (not recommended)</source> - <translation type="unfinished"/> + <translation>Genbrug en eksisterende modtagelsesadresse (anbefales ikke)</translation> </message> <message> <source>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source> - <translation type="unfinished"/> + <translation>En valgfri besked, der føjes til betalingsanmodningen, og som vil vises, når anmodningen åbnes. Bemærk: Beskeden vil ikke sendes med betalingen over Bitcoin-netværket.</translation> </message> <message> <source>An optional label to associate with the new receiving address.</source> - <translation type="unfinished"/> + <translation>Et valgfrit mærkat, der associeres med den nye modtagelsesadresse.</translation> </message> <message> <source>Use this form to request payments. All fields are <b>optional</b>.</source> - <translation type="unfinished"/> + <translation>Brug denne formular for at anmode om betalinger. Alle felter er <b>valgfri</b>.</translation> </message> <message> <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source> - <translation type="unfinished"/> + <translation>Et valgfrit beløb til anmodning. Lad dette felt være tomt eller indeholde nul for at anmode om et ikke-specifikt beløb.</translation> </message> <message> <source>Clear all fields of the form.</source> - <translation>Ryd alle fælter af formen.</translation> + <translation>Ryd alle felter af formen.</translation> </message> <message> <source>Clear</source> @@ -1579,35 +1579,35 @@ Adresse: %4 </message> <message> <source>Requested payments history</source> - <translation type="unfinished"/> + <translation>Historik over betalingsanmodninger</translation> </message> <message> <source>&Request payment</source> - <translation>&Anmod betaling</translation> + <translation>Anmod om betaling</translation> </message> <message> <source>Show the selected request (does the same as double clicking an entry)</source> - <translation type="unfinished"/> + <translation>Vis den valgte forespørgsel (gør det samme som dobbeltklik på en indgang)</translation> </message> <message> <source>Show</source> - <translation type="unfinished"/> + <translation>Vis</translation> </message> <message> <source>Remove the selected entries from the list</source> - <translation type="unfinished"/> + <translation>Fjern de valgte indgange fra listen</translation> </message> <message> <source>Remove</source> - <translation type="unfinished"/> + <translation>Fjern</translation> </message> <message> <source>Copy label</source> - <translation>Kopier mærkat</translation> + <translation>Kopiér mærkat</translation> </message> <message> <source>Copy message</source> - <translation type="unfinished"/> + <translation>Kopiér besked</translation> </message> <message> <source>Copy amount</source> @@ -1618,23 +1618,23 @@ Adresse: %4 <name>ReceiveRequestDialog</name> <message> <source>QR Code</source> - <translation>QR Kode</translation> + <translation>QR-kode</translation> </message> <message> <source>Copy &URI</source> - <translation>Kopiér &URL</translation> + <translation>Kopiér URI</translation> </message> <message> <source>Copy &Address</source> - <translation>Kopiér &Adresse</translation> + <translation>Kopiér adresse</translation> </message> <message> <source>&Save Image...</source> - <translation>&Gem foto...</translation> + <translation>Gem billede …</translation> </message> <message> <source>Request payment to %1</source> - <translation type="unfinished"/> + <translation>Anmod om betaling til %1</translation> </message> <message> <source>Payment information</source> @@ -1666,7 +1666,7 @@ Adresse: %4 </message> <message> <source>Error encoding URI into QR Code.</source> - <translation>Fejl ved kodning fra URI til QR-kode</translation> + <translation>Fejl ved kodning fra URI til QR-kode.</translation> </message> </context> <context> @@ -1693,11 +1693,11 @@ Adresse: %4 </message> <message> <source>(no message)</source> - <translation type="unfinished"/> + <translation>(ingen besked)</translation> </message> <message> <source>(no amount)</source> - <translation type="unfinished"/> + <translation>(intet beløb)</translation> </message> </context> <context> @@ -1708,27 +1708,27 @@ Adresse: %4 </message> <message> <source>Coin Control Features</source> - <translation type="unfinished"/> + <translation>Egenskaber for coin-styring</translation> </message> <message> <source>Inputs...</source> - <translation type="unfinished"/> + <translation>Inputs …</translation> </message> <message> <source>automatically selected</source> - <translation type="unfinished"/> + <translation>valgt automatisk</translation> </message> <message> <source>Insufficient funds!</source> - <translation type="unfinished"/> + <translation>Utilstrækkelige midler!</translation> </message> <message> <source>Quantity:</source> - <translation type="unfinished"/> + <translation>Mængde:</translation> </message> <message> <source>Bytes:</source> - <translation type="unfinished"/> + <translation>Byte:</translation> </message> <message> <source>Amount:</source> @@ -1736,31 +1736,31 @@ Adresse: %4 </message> <message> <source>Priority:</source> - <translation type="unfinished"/> + <translation>Prioritet:</translation> </message> <message> <source>Fee:</source> - <translation type="unfinished"/> + <translation>Gebyr:</translation> </message> <message> <source>Low Output:</source> - <translation type="unfinished"/> + <translation>Lavt output:</translation> </message> <message> <source>After Fee:</source> - <translation type="unfinished"/> + <translation>Efter gebyr:</translation> </message> <message> <source>Change:</source> - <translation type="unfinished"/> + <translation>Byttepenge:</translation> </message> <message> <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source> - <translation type="unfinished"/> + <translation>Hvis dette aktiveres, men byttepengeadressen er tom eller ugyldig, vil byttepenge blive sendt til en nygenereret adresse.</translation> </message> <message> <source>Custom change address</source> - <translation type="unfinished"/> + <translation>Tilpasset byttepengeadresse</translation> </message> <message> <source>Send to multiple recipients at once</source> @@ -1772,7 +1772,7 @@ Adresse: %4 </message> <message> <source>Clear all fields of the form.</source> - <translation>Ryd alle fælter af formen.</translation> + <translation>Ryd alle felter af formen.</translation> </message> <message> <source>Clear &All</source> @@ -1796,11 +1796,11 @@ Adresse: %4 </message> <message> <source>%1 to %2</source> - <translation type="unfinished"/> + <translation>%1 til %2</translation> </message> <message> <source>Copy quantity</source> - <translation type="unfinished"/> + <translation>Kopiér mængde</translation> </message> <message> <source>Copy amount</source> @@ -1808,35 +1808,35 @@ Adresse: %4 </message> <message> <source>Copy fee</source> - <translation type="unfinished"/> + <translation>Kopiér gebyr</translation> </message> <message> <source>Copy after fee</source> - <translation type="unfinished"/> + <translation>Kopiér efter-gebyr</translation> </message> <message> <source>Copy bytes</source> - <translation type="unfinished"/> + <translation>Kopiér byte</translation> </message> <message> <source>Copy priority</source> - <translation type="unfinished"/> + <translation>Kopiér prioritet</translation> </message> <message> <source>Copy low output</source> - <translation type="unfinished"/> + <translation>Kopiér lavt output</translation> </message> <message> <source>Copy change</source> - <translation type="unfinished"/> + <translation>Kopiér byttepenge</translation> </message> <message> <source>Total Amount %1 (= %2)</source> - <translation type="unfinished"/> + <translation>Totalbeløb %1 (= %2)</translation> </message> <message> <source>or</source> - <translation type="unfinished"/> + <translation>eller</translation> </message> <message> <source>The recipient address is not valid, please recheck.</source> @@ -1860,15 +1860,15 @@ Adresse: %4 </message> <message> <source>Transaction creation failed!</source> - <translation type="unfinished"/> + <translation>Oprettelse af transaktion mislykkedes!</translation> </message> <message> <source>The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.</source> - <translation type="unfinished"/> + <translation>Transaktionen blev afvist! Dette kan ske, hvis nogle af dine bitcoins i din tegnebog allerede er brugt, som hvis du brugte en kopi af wallet.dat og dine bitcoins er blevet brugt i kopien, men ikke er markeret som brugt her.</translation> </message> <message> <source>Warning: Invalid Bitcoin address</source> - <translation type="unfinished"/> + <translation>Advarsel: Ugyldig Bitcoin-adresse</translation> </message> <message> <source>(no label)</source> @@ -1876,7 +1876,7 @@ Adresse: %4 </message> <message> <source>Warning: Unknown change address</source> - <translation type="unfinished"/> + <translation>Advarsel: Ukendt byttepengeadresse</translation> </message> <message> <source>Are you sure you want to send?</source> @@ -1892,7 +1892,7 @@ Adresse: %4 </message> <message> <source>Invalid payment address %1</source> - <translation type="unfinished"/> + <translation>Ugyldig betalingsadresse %1</translation> </message> </context> <context> @@ -1919,11 +1919,11 @@ Adresse: %4 </message> <message> <source>Choose previously used address</source> - <translation type="unfinished"/> + <translation>Vælg tidligere brugt adresse</translation> </message> <message> <source>This is a normal payment.</source> - <translation type="unfinished"/> + <translation>Dette er en normal betaling.</translation> </message> <message> <source>Alt+A</source> @@ -1939,7 +1939,7 @@ Adresse: %4 </message> <message> <source>Remove this entry</source> - <translation type="unfinished"/> + <translation>Fjern denne indgang</translation> </message> <message> <source>Message:</source> @@ -1947,38 +1947,38 @@ Adresse: %4 </message> <message> <source>This is a verified payment request.</source> - <translation type="unfinished"/> + <translation>Dette er en verificeret betalingsforespørgsel.</translation> </message> <message> <source>Enter a label for this address to add it to the list of used addresses</source> - <translation type="unfinished"/> + <translation>Indtast et mærkat for denne adresse for at føje den til listen over brugte adresser</translation> </message> <message> <source>A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source> - <translation type="unfinished"/> + <translation>En besked, som blev føjet til "bitcon:"-URI'en, som vil gemmes med transaktionen til din reference. Bemærk: Denne besked vil ikke blive sendt over Bitcoin-netværket.</translation> </message> <message> <source>This is an unverified payment request.</source> - <translation type="unfinished"/> + <translation>Dette er en ikke-verificeret betalingsforespørgsel.</translation> </message> <message> <source>Pay To:</source> - <translation type="unfinished"/> + <translation>Betal til:</translation> </message> <message> <source>Memo:</source> - <translation type="unfinished"/> + <translation>Memo:</translation> </message> </context> <context> <name>ShutdownWindow</name> <message> <source>Bitcoin Core is shutting down...</source> - <translation type="unfinished"/> + <translation>Bitcoin Core lukker ned …</translation> </message> <message> <source>Do not shut down the computer until this window disappears.</source> - <translation type="unfinished"/> + <translation>Luk ikke computeren ned, før dette vindue forsvinder.</translation> </message> </context> <context> @@ -2001,7 +2001,7 @@ Adresse: %4 </message> <message> <source>Choose previously used address</source> - <translation type="unfinished"/> + <translation>Vælg tidligere brugt adresse</translation> </message> <message> <source>Alt+A</source> @@ -2132,7 +2132,7 @@ Adresse: %4 </message> <message> <source>The Bitcoin Core developers</source> - <translation type="unfinished"/> + <translation>Udviklerne af Bitcoin Core</translation> </message> <message> <source>[testnet]</source> @@ -2154,7 +2154,7 @@ Adresse: %4 </message> <message> <source>conflicted</source> - <translation type="unfinished"/> + <translation>konflikt</translation> </message> <message> <source>%1/offline</source> @@ -2242,11 +2242,11 @@ Adresse: %4 </message> <message> <source>Merchant</source> - <translation type="unfinished"/> + <translation>Forretningsdrivende</translation> </message> <message> <source>Generated coins must mature %1 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to "not accepted" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.</source> - <translation type="unfinished"/> + <translation>Udvundne bitcoins skal modne %1 blokke, før de kan bruges. Da du genererede denne blok, blev den udsendt til netværket for at blive føjet til blokkæden. Hvis det ikke lykkes at få den i kæden, vil dens tilstand ændres til "ikke accepteret", og den vil ikke kunne bruges. Dette kan ske nu og da, hvis en anden knude udvinder en blok inden for nogle få sekunder fra din.</translation> </message> <message> <source>Debug information</source> @@ -2316,7 +2316,7 @@ Adresse: %4 </message> <message> <source>Immature (%1 confirmations, will be available after %2)</source> - <translation type="unfinished"/> + <translation>Umoden (%1 bekræftelser; vil være tilgængelig efter %2)</translation> </message> <message numerus="yes"> <source>Open for %n more block(s)</source> @@ -2340,19 +2340,19 @@ Adresse: %4 </message> <message> <source>Offline</source> - <translation type="unfinished"/> + <translation>Offline</translation> </message> <message> <source>Unconfirmed</source> - <translation type="unfinished"/> + <translation>Ubekræftet</translation> </message> <message> <source>Confirming (%1 of %2 recommended confirmations)</source> - <translation type="unfinished"/> + <translation>Bekræfter (%1 af %2 anbefalede bekræftelser)</translation> </message> <message> <source>Conflicted</source> - <translation type="unfinished"/> + <translation>Konflikt</translation> </message> <message> <source>Received with</source> @@ -2483,23 +2483,23 @@ Adresse: %4 </message> <message> <source>Export Transaction History</source> - <translation type="unfinished"/> + <translation>Historik for eksport af transaktioner</translation> </message> <message> <source>Exporting Failed</source> - <translation type="unfinished"/> + <translation>Eksport mislykkedes</translation> </message> <message> <source>There was an error trying to save the transaction history to %1.</source> - <translation type="unfinished"/> + <translation>En fejl opstod under gemning af transaktionshistorik til %1.</translation> </message> <message> <source>Exporting Successful</source> - <translation type="unfinished"/> + <translation>Eksport problemfri</translation> </message> <message> <source>The transaction history was successfully saved to %1.</source> - <translation type="unfinished"/> + <translation>Transaktionshistorikken blev gemt til %1 med succes.</translation> </message> <message> <source>Comma separated file (*.csv)</source> @@ -2546,7 +2546,7 @@ Adresse: %4 <name>WalletFrame</name> <message> <source>No wallet has been loaded.</source> - <translation type="unfinished"/> + <translation>Ingen tegnebog er indlæst.</translation> </message> </context> <context> @@ -2580,11 +2580,11 @@ Adresse: %4 </message> <message> <source>There was an error trying to save the wallet data to %1.</source> - <translation type="unfinished"/> + <translation>Der skete en fejl under gemning af tegnebogsdata til %1.</translation> </message> <message> <source>The wallet data was successfully saved to %1.</source> - <translation type="unfinished"/> + <translation>Tegnebogsdata blev gemt til %1 med succes.</translation> </message> <message> <source>Backup Successful</source> @@ -2659,7 +2659,7 @@ Adresse: %4 </message> <message> <source>Bitcoin Core RPC client version</source> - <translation type="unfinished"/> + <translation>Bitcoin Core RPC-klient-version</translation> </message> <message> <source>Run in the background as a daemon and accept commands</source> @@ -2699,7 +2699,7 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </message> <message> <source>Acceptable ciphers (default: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</source> - <translation type="unfinished"/> + <translation>Accepterede krypteringer (standard: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</translation> </message> <message> <source>An error occurred while setting up the RPC port %u for listening on IPv6, falling back to IPv4: %s</source> @@ -2711,19 +2711,19 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </message> <message> <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:15)</source> - <translation type="unfinished"/> + <translation>Rate-begræns kontinuerligt frie transaktioner til <n>*1000 byte i minuttet (standard:15)</translation> </message> <message> <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly. This is intended for regression testing tools and app development.</source> - <translation type="unfinished"/> + <translation>Start regressionstesttilstand, som bruger en speciel kæde, hvor blokke kan løses med det samme. Dette er tiltænkt til testværktøjer for regression of programudvikling.</translation> </message> <message> <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation type="unfinished"/> + <translation>Start regressionstesttilstand, som bruger en speciel kæde, hvor blokke kan løses med det samme.</translation> </message> <message> <source>Error: Listening for incoming connections failed (listen returned error %d)</source> - <translation type="unfinished"/> + <translation>Fejl: Lytning efter indkommende forbindelser mislykkedes (lytning returnerede fejl %d)</translation> </message> <message> <source>Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.</source> @@ -2739,27 +2739,27 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </message> <message> <source>Fees smaller than this are considered zero fee (for transaction creation) (default:</source> - <translation type="unfinished"/> + <translation>Gebyrer mindre end dette opfattes som nul-gebyr (for oprettelse af transaktioner) (standard:</translation> </message> <message> <source>Flush database activity from memory pool to disk log every <n> megabytes (default: 100)</source> - <translation type="unfinished"/> + <translation>Flyt databaseaktivitet fra hukommelsespulje til disklog hver <n> megabytes (standard: 100)</translation> </message> <message> <source>How thorough the block verification of -checkblocks is (0-4, default: 3)</source> - <translation type="unfinished"/> + <translation>Hvor gennemarbejdet blokverificeringen for -checkblocks er (0-4; standard: 3)</translation> </message> <message> <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation type="unfinished"/> + <translation>I denne tilstand styrer -genproclimit hvor mange blokke, der genereres med det samme.</translation> </message> <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> - <translation type="unfinished"/> + <translation>Sæt antallet af scriptverificeringstråde (%u til %d, 0 = auto, <0 = efterlad det antal kernet fri, standard: %d)</translation> </message> <message> <source>Set the processor limit for when generation is on (-1 = unlimited, default: -1)</source> - <translation type="unfinished"/> + <translation>Sæt processorbegrænsning for når generering er slået til (-1 = ubegrænset, standard: -1)</translation> </message> <message> <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source> @@ -2767,11 +2767,11 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </message> <message> <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source> - <translation type="unfinished"/> + <translation>Ikke i stand til at tildele til %s på denne computer. Bitcoin Core kører sansynligvis allerede.</translation> </message> <message> <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)</source> - <translation type="unfinished"/> + <translation>Brug separat SOCS5-proxy for at nå andre knuder via Tor skjulte tjenester (standard: -proxy)</translation> </message> <message> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> @@ -2799,15 +2799,15 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </message> <message> <source>(default: 1)</source> - <translation type="unfinished"/> + <translation>(standard: 1)</translation> </message> <message> <source>(default: wallet.dat)</source> - <translation type="unfinished"/> + <translation>(standard: wallet.dat)</translation> </message> <message> <source><category> can be:</source> - <translation type="unfinished"/> + <translation><kategori> kan være:</translation> </message> <message> <source>Attempt to recover private keys from a corrupt wallet.dat</source> @@ -2815,7 +2815,7 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </message> <message> <source>Bitcoin Core Daemon</source> - <translation type="unfinished"/> + <translation>Bitcoin Core-tjeneste</translation> </message> <message> <source>Block creation options:</source> @@ -2823,7 +2823,7 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </message> <message> <source>Clear list of wallet transactions (diagnostic tool; implies -rescan)</source> - <translation type="unfinished"/> + <translation>Ryd liste over transaktioner i tegnebog (diagnoseværktøj; medfører -rescan)</translation> </message> <message> <source>Connect only to the specified node(s)</source> @@ -2831,15 +2831,15 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </message> <message> <source>Connect through SOCKS proxy</source> - <translation type="unfinished"/> + <translation>Forbind gennem SOCKS-proxy</translation> </message> <message> <source>Connect to JSON-RPC on <port> (default: 8332 or testnet: 18332)</source> - <translation type="unfinished"/> + <translation>Forbind til JSON-RPC på <port> (standard: 8332 eller testnetværk: 18332)</translation> </message> <message> <source>Connection options:</source> - <translation type="unfinished"/> + <translation>Tilvalg for forbindelser:</translation> </message> <message> <source>Corrupted block database detected</source> @@ -2847,11 +2847,11 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </message> <message> <source>Debugging/Testing options:</source> - <translation type="unfinished"/> + <translation>Tilvalg for fejlfinding/test:</translation> </message> <message> <source>Disable safemode, override a real safe mode event (default: 0)</source> - <translation type="unfinished"/> + <translation>Slå sikker tilstand fra, tilsidesæt hændelser fra sikker tilstand (standard: 0)</translation> </message> <message> <source>Discover own IP address (default: 1 when listening and no -externalip)</source> @@ -2859,7 +2859,7 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </message> <message> <source>Do not load the wallet and disable wallet RPC calls</source> - <translation type="unfinished"/> + <translation>Indlæs ikke tegnebogen og slå tegnebogs-RPC-kald fra</translation> </message> <message> <source>Do you want to rebuild the block database now?</source> @@ -2939,11 +2939,11 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </message> <message> <source>Fee per kB to add to transactions you send</source> - <translation type="unfinished"/> + <translation>Føj gebyr pr. kB til transaktioner, du sender</translation> </message> <message> <source>Fees smaller than this are considered zero fee (for relaying) (default:</source> - <translation type="unfinished"/> + <translation>Gebyrer mindre end dette opfattes som nul-gebyr (for videreførsler) (standard:</translation> </message> <message> <source>Find peers using DNS lookup (default: 1 unless -connect)</source> @@ -2951,7 +2951,7 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </message> <message> <source>Force safe mode (default: 0)</source> - <translation type="unfinished"/> + <translation>Gennemtving sikker tilstand (standard: 0)</translation> </message> <message> <source>Generate coins (default: 0)</source> @@ -2963,11 +2963,11 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </message> <message> <source>If <category> is not supplied, output all debugging information.</source> - <translation type="unfinished"/> + <translation>Hvis <kategori> ikke angives, udskriv al fejlsøgningsinformation.</translation> </message> <message> <source>Importing...</source> - <translation type="unfinished"/> + <translation>Importerer …</translation> </message> <message> <source>Incorrect or no genesis block found. Wrong datadir for network?</source> @@ -2975,7 +2975,7 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </message> <message> <source>Invalid -onion address: '%s'</source> - <translation type="unfinished"/> + <translation>Ugyldig -onion adresse: "%s"</translation> </message> <message> <source>Not enough file descriptors available.</source> @@ -2983,11 +2983,11 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </message> <message> <source>Prepend debug output with timestamp (default: 1)</source> - <translation type="unfinished"/> + <translation>Føj tidsstempel foran fejlsøgningsoutput (standard: 1)</translation> </message> <message> <source>RPC client options:</source> - <translation type="unfinished"/> + <translation>Tilvalg for RPC-klient:</translation> </message> <message> <source>Rebuild block chain index from current blk000??.dat files</source> @@ -2995,15 +2995,15 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </message> <message> <source>Select SOCKS version for -proxy (4 or 5, default: 5)</source> - <translation type="unfinished"/> + <translation>Vælg SOCKS-version for -proxy (4 eller 5, standard: 5)</translation> </message> <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> - <translation type="unfinished"/> + <translation>Sæt cache-størrelse for database i megabytes (%d til %d; standard: %d)</translation> </message> <message> <source>Set maximum block size in bytes (default: %d)</source> - <translation type="unfinished"/> + <translation>Sæt maksimum blokstørrelse i byte (standard: %d)</translation> </message> <message> <source>Set the number of threads to service RPC calls (default: 4)</source> @@ -3015,15 +3015,15 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </message> <message> <source>Spend unconfirmed change when sending transactions (default: 1)</source> - <translation type="unfinished"/> + <translation>Brug ubekræftede byttepenge under afsendelse af transaktioner (standard: 1)</translation> </message> <message> <source>This is intended for regression testing tools and app development.</source> - <translation type="unfinished"/> + <translation>This is intended for regression testing tools and app development.</translation> </message> <message> <source>Usage (deprecated, use bitcoin-cli):</source> - <translation type="unfinished"/> + <translation>Brug (forældet, brug bitcoin-cli):</translation> </message> <message> <source>Verifying blocks...</source> @@ -3035,7 +3035,7 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </message> <message> <source>Wait for RPC server to start</source> - <translation type="unfinished"/> + <translation>Vent på opstart af RPC-server</translation> </message> <message> <source>Wallet %s resides outside data directory %s</source> @@ -3043,11 +3043,11 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </message> <message> <source>Wallet options:</source> - <translation type="unfinished"/> + <translation>Tilvalg for tegnebog:</translation> </message> <message> <source>Warning: Deprecated argument -debugnet ignored, use -debug=net</source> - <translation type="unfinished"/> + <translation>Advarsel: Forældet argument -debugnet ignoreret; brug -debug=net</translation> </message> <message> <source>You need to rebuild the database using -reindex to change -txindex</source> @@ -3059,7 +3059,7 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </message> <message> <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source> - <translation type="unfinished"/> + <translation>Kan ikke opnå en lås på datamappe %s. Bitcoin Core kører sansynligvis allerede.</translation> </message> <message> <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source> @@ -3067,11 +3067,11 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </message> <message> <source>Output debugging information (default: 0, supplying <category> is optional)</source> - <translation type="unfinished"/> + <translation>Udskriv fejlsøgningsinformation (standard: 0, angivelse af <kategori> er valgfri)</translation> </message> <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> - <translation type="unfinished"/> + <translation>Sæt maksimumstørrelse for højprioritet/lavgebyr-transaktioner i byte (standard: %d)</translation> </message> <message> <source>Information</source> @@ -3087,11 +3087,11 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </message> <message> <source>Limit size of signature cache to <n> entries (default: 50000)</source> - <translation type="unfinished"/> + <translation>Begræns størrelsen på signaturcache til <n> indgange (standard: 50000)</translation> </message> <message> <source>Log transaction priority and fee per kB when mining blocks (default: 0)</source> - <translation type="unfinished"/> + <translation>Prioritet for transaktionslog og gebyr pr. kB under udvinding af blokke (standard: 0)</translation> </message> <message> <source>Maintain a full transaction index (default: 0)</source> @@ -3115,31 +3115,31 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </message> <message> <source>Print block on startup, if found in block index</source> - <translation type="unfinished"/> + <translation>Udskriv blok under opstart, hvis den findes i blokindeks</translation> </message> <message> <source>Print block tree on startup (default: 0)</source> - <translation type="unfinished"/> + <translation>Udskriv bloktræ under startop (standard: 0)</translation> </message> <message> <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> - <translation type="unfinished"/> + <translation>Tilvalg for RPC SSL: (se Bitcoin Wiki for instruktioner i SSL-opstart)</translation> </message> <message> <source>RPC server options:</source> - <translation type="unfinished"/> + <translation>Tilvalg for RPC-server:</translation> </message> <message> <source>Randomly drop 1 of every <n> network messages</source> - <translation type="unfinished"/> + <translation>Drop tilfældigt 1 ud af hver <n> netværksbeskeder</translation> </message> <message> <source>Randomly fuzz 1 of every <n> network messages</source> - <translation type="unfinished"/> + <translation>Slør tilfældigt 1 ud af hver <n> netværksbeskeder</translation> </message> <message> <source>Run a thread to flush wallet periodically (default: 1)</source> - <translation type="unfinished"/> + <translation>Kør en tråd for at rydde tegnebog periodisk (standard: 1)</translation> </message> <message> <source>SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> @@ -3147,7 +3147,7 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </message> <message> <source>Send command to Bitcoin Core</source> - <translation type="unfinished"/> + <translation>Send kommando til Bitcoin Core</translation> </message> <message> <source>Send trace/debug info to console instead of debug.log file</source> @@ -3159,15 +3159,15 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </message> <message> <source>Sets the DB_PRIVATE flag in the wallet db environment (default: 1)</source> - <translation type="unfinished"/> + <translation>Sætter DB_PRIVATE-flaget i tegnebogens db-miljø (standard: 1)</translation> </message> <message> <source>Show all debugging options (usage: --help -help-debug)</source> - <translation type="unfinished"/> + <translation>Vis alle tilvalg for fejlsøgning (brug: --help -help-debug)</translation> </message> <message> <source>Show benchmark information (default: 0)</source> - <translation type="unfinished"/> + <translation>Vis information om ydelsesmåling (standard: 0)</translation> </message> <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> @@ -3183,7 +3183,7 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </message> <message> <source>Start Bitcoin Core Daemon</source> - <translation type="unfinished"/> + <translation>Start Bitcoin Core-tjeneste</translation> </message> <message> <source>System error: </source> @@ -3223,11 +3223,11 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </message> <message> <source>Zapping all transactions from wallet...</source> - <translation type="unfinished"/> + <translation>Zapper alle transaktioner fra tegnebog …</translation> </message> <message> <source>on startup</source> - <translation type="unfinished"/> + <translation>under opstart</translation> </message> <message> <source>version</source> diff --git a/src/qt/locale/bitcoin_ko_KR.ts b/src/qt/locale/bitcoin_ko_KR.ts index 8e2b681ba9..ce30a8603d 100644 --- a/src/qt/locale/bitcoin_ko_KR.ts +++ b/src/qt/locale/bitcoin_ko_KR.ts @@ -40,7 +40,7 @@ MIT/X11 프로그램 라이선스에 따라 배포합니다. COPYING 또는 http <name>AddressBookPage</name> <message> <source>Double-click to edit address or label</source> - <translation>주소 또는 표를 편집하기 위해 더블클릭 하시오</translation> + <translation>지갑 주소나 제목을 수정하려면 더블클릭하세요.</translation> </message> <message> <source>Create a new address</source> @@ -755,7 +755,7 @@ Address: %4 </message> <message> <source>This label turns red, if the transaction size is greater than 1000 bytes.</source> - <translation type="unfinished"/> + <translation>만약 거래 양이 1000bytes 보다 크면 제목이 빨간색으로 변합니다</translation> </message> <message> <source>This means a fee of at least %1 per kB is required.</source> @@ -771,11 +771,11 @@ Address: %4 </message> <message> <source>This label turns red, if the priority is smaller than "medium".</source> - <translation type="unfinished"/> + <translation>우선권이 중간보다 작으면 제목이 빨간색으로 변합니다. </translation> </message> <message> <source>This label turns red, if any recipient receives an amount smaller than %1.</source> - <translation type="unfinished"/> + <translation>만약 수령인이 받은 액수가 잔고의 1%보다 작으면 이 제목이 빨간색으로 변합니다.</translation> </message> <message> <source>This means a fee of at least %1 is required.</source> @@ -787,7 +787,7 @@ Address: %4 </message> <message> <source>This label turns red, if the change is smaller than %1.</source> - <translation type="unfinished"/> + <translation>만약 잔돈이 1%보다 작다면 제목이 빨간색으로 변합니다</translation> </message> <message> <source>(no label)</source> @@ -1053,7 +1053,7 @@ Address: %4 </message> <message> <source>Third party transaction URLs</source> - <translation type="unfinished"/> + <translation>제 3자 거래 URLs</translation> </message> <message> <source>Active command-line options that override above options:</source> @@ -1093,7 +1093,7 @@ Address: %4 </message> <message> <source>&Spend unconfirmed change</source> - <translation type="unfinished"/> + <translation>&확인되지 않은 돈을 쓰다</translation> </message> <message> <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source> @@ -1303,7 +1303,7 @@ Address: %4 </message> <message> <source>Payment request file handling</source> - <translation type="unfinished"/> + <translation>지불이 파일 처리를 요청합니다</translation> </message> <message> <source>Payment request file can not be read or processed! This can be caused by an invalid payment request file.</source> @@ -1354,7 +1354,7 @@ Address: %4 </message> <message> <source>Error: Invalid combination of -regtest and -testnet.</source> - <translation type="unfinished"/> + <translation>오류: 잘못된 -regtest 와 -testnet의 조합입니다.</translation> </message> <message> <source>Bitcoin Core didn't yet exit safely...</source> @@ -1460,7 +1460,7 @@ Address: %4 </message> <message> <source>&Clear</source> - <translation type="unfinished"/> + <translation>&지우기</translation> </message> <message> <source>Totals</source> @@ -1712,7 +1712,7 @@ Address: %4 </message> <message> <source>Inputs...</source> - <translation type="unfinished"/> + <translation>입력...</translation> </message> <message> <source>automatically selected</source> @@ -1864,7 +1864,7 @@ Address: %4 </message> <message> <source>The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.</source> - <translation type="unfinished"/> + <translation>거래가 거부되었습니다. 몇몇 코인들이 지갑에서 이미 사용된 경우, 예를 들어 코인을 이미 사용한 wallet.dat를 복사해서 사용한 경우 지금 지갑에 기록이 안되있어 이런 일이 생길 수 있습니다.</translation> </message> <message> <source>Warning: Invalid Bitcoin address</source> @@ -2651,7 +2651,7 @@ Address: %4 </message> <message> <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation type="unfinished"/> + <translation>포트 <port>을 통해 JSON-RPC 연결 (기본값: 8332 또는 testnet: 18332)</translation> </message> <message> <source>Accept command line and JSON-RPC commands</source> @@ -2693,7 +2693,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. </message> <message> <source>An error occurred while setting up the RPC port %u for listening on IPv6, falling back to IPv4: %s</source> - <translation type="unfinished"/> + <translation>IPv6 연결을 위해 RPC port %u 설정 중 오류가 발생했습니다. IPv4: %s 환경으로 돌아갑니다.</translation> </message> <message> <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source> @@ -2717,7 +2717,9 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. </message> <message> <source>Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.</source> - <translation type="unfinished"/> + <translation>에러: 거래가 거부되었습니다! 이런 일이 생길 수 있습니다 만약 몇개의 코인들을 지갑에서 이미 사용했다면요, 예를 들어 만약 당신이 wallet.dat를 복사해서 사용했거나 코인들을 사용 후에 복사했다면 여기선 표시가 안되서 사용할 수 없습니다 + +-번역은 했으나 약간 이상한점이 있어서 수정해야함-</translation> </message> <message> <source>Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!</source> @@ -2725,7 +2727,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. </message> <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> - <translation type="unfinished"/> + <translation>지갑 거래가 바뀌면 명령을 실행합니다.(%s 안의 명령어가 TxID로 바뀝니다)</translation> </message> <message> <source>Fees smaller than this are considered zero fee (for transaction creation) (default:</source> @@ -2841,7 +2843,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. </message> <message> <source>Disable safemode, override a real safe mode event (default: 0)</source> - <translation type="unfinished"/> + <translation>안전 모드를 비활성화하고 안전 모드의 이벤트가 발생하더라도 무시합니다. (기본값: 0, 비활성화)</translation> </message> <message> <source>Discover own IP address (default: 1 when listening and no -externalip)</source> @@ -2861,7 +2863,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. </message> <message> <source>Error initializing wallet database environment %s!</source> - <translation type="unfinished"/> + <translation>지갑 데이터베이스 환경 초기화하는데 오류</translation> </message> <message> <source>Error loading block database</source> @@ -2961,7 +2963,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. </message> <message> <source>Incorrect or no genesis block found. Wrong datadir for network?</source> - <translation type="unfinished"/> + <translation>올바르지 않거나 생성된 블록을 찾을 수 없습니다. 잘못된 네트워크 자료 디렉토리?</translation> </message> <message> <source>Invalid -onion address: '%s'</source> @@ -3053,7 +3055,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. </message> <message> <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source> - <translation type="unfinished"/> + <translation>이 사항과 관련있는 경고가 발생하거나 아주 긴 포크가 발생했을 때 명령어를 실행해 주세요. (cmd 명령어 목록에서 %s는 메시지로 대체됩니다) </translation> </message> <message> <source>Output debugging information (default: 0, supplying <category> is optional)</source> @@ -3061,7 +3063,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. </message> <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> - <translation type="unfinished"/> + <translation>최대 크기를 최우선으로 설정 / 바이트당 최소 수수료로 거래(기본값: %d)</translation> </message> <message> <source>Information</source> @@ -3077,11 +3079,11 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. </message> <message> <source>Limit size of signature cache to <n> entries (default: 50000)</source> - <translation type="unfinished"/> + <translation><n>번 째 순서에서 전자서명 캐쉬의 용량을 제한합니다. (기본값: 50000) </translation> </message> <message> <source>Log transaction priority and fee per kB when mining blocks (default: 0)</source> - <translation type="unfinished"/> + <translation>블럭을 채굴할 때 kB당 거래 우선 순위와 수수료를 로그에 남깁니다. (기본값: 0, 비활성화)</translation> </message> <message> <source>Maintain a full transaction index (default: 0)</source> @@ -3089,11 +3091,11 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. </message> <message> <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)</source> - <translation type="unfinished"/> + <translation>최대 연결마다 1000bytes 버퍼를 받는다. (기본값: 5000)</translation> </message> <message> <source>Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)</source> - <translation type="unfinished"/> + <translation>최대 연결 마다 1000bytes 버퍼를 보낸다.(기본값: 1000) </translation> </message> <message> <source>Only accept block chain matching built-in checkpoints (default: 1)</source> @@ -3101,27 +3103,27 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. </message> <message> <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation type="unfinished"/> + <translation>노드가 있는 네트워크에만 접속 합니다(IPv4, IPv6 또는 Tor)</translation> </message> <message> <source>Print block on startup, if found in block index</source> - <translation type="unfinished"/> + <translation>블럭 색인을 발견하면 구동 시 블럭을 출력합니다.</translation> </message> <message> <source>Print block tree on startup (default: 0)</source> - <translation type="unfinished"/> + <translation>구동 시 블럭 트리를 출력합니다. (기본값: 0, 비활성화)</translation> </message> <message> <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> - <translation type="unfinished"/> + <translation>RPC SSL 옵션: (비트코인 위키의 SSL 설정 설명서 참고)</translation> </message> <message> <source>RPC server options:</source> - <translation type="unfinished"/> + <translation>RPC 서버 설정</translation> </message> <message> <source>Randomly drop 1 of every <n> network messages</source> - <translation type="unfinished"/> + <translation>모든 네트워크 메시지 마다 무작위로 1이 떨어진다</translation> </message> <message> <source>Randomly fuzz 1 of every <n> network messages</source> @@ -3137,7 +3139,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. </message> <message> <source>Send command to Bitcoin Core</source> - <translation type="unfinished"/> + <translation>비트코인 코어로 명령 보내기</translation> </message> <message> <source>Send trace/debug info to console instead of debug.log file</source> @@ -3149,15 +3151,15 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. </message> <message> <source>Sets the DB_PRIVATE flag in the wallet db environment (default: 1)</source> - <translation type="unfinished"/> + <translation>전자지갑 데이터베이스 환경에 DB_PRIVATE 플래그를 설정합니다. (기본값: 1, 활성화)</translation> </message> <message> <source>Show all debugging options (usage: --help -help-debug)</source> - <translation type="unfinished"/> + <translation>모든 디버그 설정 보기(설정: --help -help-debug)</translation> </message> <message> <source>Show benchmark information (default: 0)</source> - <translation type="unfinished"/> + <translation>벤치마크 정보 보기(기본값: 0)</translation> </message> <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> @@ -3217,7 +3219,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. </message> <message> <source>on startup</source> - <translation type="unfinished"/> + <translation>구동 중</translation> </message> <message> <source>version</source> diff --git a/src/qt/locale/bitcoin_nb.ts b/src/qt/locale/bitcoin_nb.ts index 1267ad65b9..9e38c69c60 100644 --- a/src/qt/locale/bitcoin_nb.ts +++ b/src/qt/locale/bitcoin_nb.ts @@ -599,7 +599,7 @@ Adresse: %4 </message> <message> <source>Low Output:</source> - <translation>Lav Utdata:</translation> + <translation>Svake Utdata:</translation> </message> <message> <source>After Fee:</source> @@ -1744,7 +1744,7 @@ Adresse: %4 </message> <message> <source>Low Output:</source> - <translation>Svak Utdata:</translation> + <translation>Svake Utdata:</translation> </message> <message> <source>After Fee:</source> @@ -2730,7 +2730,7 @@ For eksempel: varselmelding=echo %%s | mail -s "Bitcoin Varsel" admin@ </message> <message> <source>Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!</source> - <translation>Feil: Denne transaksjonen trenger en gebyr på minst %s på grunn av beløpet, kompleksiteten eller bruk av allerede mottatte penger!</translation> + <translation>Feil: Denne transaksjonen trenger et gebyr på minst %s på grunn av beløpet, kompleksiteten eller bruk av allerede mottatte penger!</translation> </message> <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> diff --git a/src/qt/locale/bitcoin_zh_CN.ts b/src/qt/locale/bitcoin_zh_CN.ts index ea98c4e4b1..b87d27fe12 100644 --- a/src/qt/locale/bitcoin_zh_CN.ts +++ b/src/qt/locale/bitcoin_zh_CN.ts @@ -917,7 +917,7 @@ Address: %4 </message> <message> <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation type="unfinished"/> + <translation>设置SSL根证书的付款请求(默认:-系统-)</translation> </message> <message> <source>Show splash screen on startup (default: 1)</source> @@ -1050,11 +1050,11 @@ Address: %4 </message> <message> <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> - <translation type="unfinished"/> + <translation>出现在交易的选项卡的上下文菜单项的第三方网址 (例如:区块链接查询) 。 %s的URL被替换为交易哈希。多个的URL需要竖线 | 分隔。</translation> </message> <message> <source>Third party transaction URLs</source> - <translation type="unfinished"/> + <translation>第三方交易网址</translation> </message> <message> <source>Active command-line options that override above options:</source> @@ -1074,7 +1074,7 @@ Address: %4 </message> <message> <source>(0 = auto, <0 = leave that many cores free)</source> - <translation type="unfinished"/> + <translation>(0 = 自动, <0 = 离开很多免费的核心)</translation> </message> <message> <source>W&allet</source> @@ -1086,7 +1086,7 @@ Address: %4 </message> <message> <source>Enable coin &control features</source> - <translation type="unfinished"/> + <translation>启动货币 &控制功能</translation> </message> <message> <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source> @@ -1094,7 +1094,7 @@ Address: %4 </message> <message> <source>&Spend unconfirmed change</source> - <translation type="unfinished"/> + <translation>&选择未经确认的花费</translation> </message> <message> <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source> @@ -1351,7 +1351,7 @@ Address: %4 </message> <message> <source>Error: Cannot parse configuration file: %1. Only use key=value syntax.</source> - <translation type="unfinished"/> + <translation>错误: 无法解析配置文件: %1. 只有钥匙=重要的私匙.</translation> </message> <message> <source>Error: Invalid combination of -regtest and -testnet.</source> @@ -1359,7 +1359,7 @@ Address: %4 </message> <message> <source>Bitcoin Core didn't yet exit safely...</source> - <translation type="unfinished"/> + <translation>比特币核心钱包没有安全退出....</translation> </message> <message> <source>Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</source> @@ -2667,7 +2667,7 @@ Address: %4 </message> <message> <source>Bitcoin Core RPC client version</source> - <translation type="unfinished"/> + <translation>比特币核心钱包RPC客户端版本</translation> </message> <message> <source>Run in the background as a daemon and accept commands</source> @@ -2722,7 +2722,7 @@ rpcpassword=%s </message> <message> <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:15)</source> - <translation type="unfinished"/> + <translation>自由交易不断的速率限制为<n>*1000 字节每分钟(默认值:15)</translation> </message> <message> <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly. This is intended for regression testing tools and app development.</source> @@ -2734,7 +2734,7 @@ rpcpassword=%s </message> <message> <source>Error: Listening for incoming connections failed (listen returned error %d)</source> - <translation type="unfinished"/> + <translation>错误: 监听接收连接失败 (监听错误 %d)</translation> </message> <message> <source>Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.</source> @@ -2750,27 +2750,27 @@ rpcpassword=%s </message> <message> <source>Fees smaller than this are considered zero fee (for transaction creation) (default:</source> - <translation type="unfinished"/> + <translation>比这手续费更小的被认为零手续费 (交易产生) (默认:</translation> </message> <message> <source>Flush database activity from memory pool to disk log every <n> megabytes (default: 100)</source> - <translation type="unfinished"/> + <translation>从缓冲池清理磁盘数据库活动日志每<n>兆字节 (默认值: 100)</translation> </message> <message> <source>How thorough the block verification of -checkblocks is (0-4, default: 3)</source> - <translation type="unfinished"/> + <translation>如何有效的验证checkblocks区块(0-4, 默认值: 3)</translation> </message> <message> <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation type="unfinished"/> + <translation>在-genproclimit这种模式下控制产出多少区块</translation> </message> <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> - <translation type="unfinished"/> + <translation>设置脚本验证的程序 (%u 到 %d, 0 = 自动, <0 = 保留自由的核心, 默认值: %d)</translation> </message> <message> <source>Set the processor limit for when generation is on (-1 = unlimited, default: -1)</source> - <translation type="unfinished"/> + <translation>设置处理器生成的限制 (-1 = 无限, 默认值: -1)</translation> </message> <message> <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source> @@ -2778,7 +2778,7 @@ rpcpassword=%s </message> <message> <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source> - <translation type="unfinished"/> + <translation>无法 %s的绑定到电脑上,比特币核心钱包可能已经在运行。</translation> </message> <message> <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)</source> @@ -2810,11 +2810,11 @@ rpcpassword=%s </message> <message> <source>(default: 1)</source> - <translation type="unfinished"/> + <translation>(默认值: 1)</translation> </message> <message> <source>(default: wallet.dat)</source> - <translation type="unfinished"/> + <translation>(默认: wallet.dat)</translation> </message> <message> <source><category> can be:</source> @@ -2850,7 +2850,7 @@ rpcpassword=%s </message> <message> <source>Connection options:</source> - <translation type="unfinished"/> + <translation>连接选项:</translation> </message> <message> <source>Corrupted block database detected</source> @@ -2858,11 +2858,11 @@ rpcpassword=%s </message> <message> <source>Debugging/Testing options:</source> - <translation type="unfinished"/> + <translation>调试/测试选项:</translation> </message> <message> <source>Disable safemode, override a real safe mode event (default: 0)</source> - <translation type="unfinished"/> + <translation>禁止使用安全模式,重新写入一个真正的安全模式日志(默认值: 0)</translation> </message> <message> <source>Discover own IP address (default: 1 when listening and no -externalip)</source> @@ -2954,7 +2954,7 @@ rpcpassword=%s </message> <message> <source>Fees smaller than this are considered zero fee (for relaying) (default:</source> - <translation type="unfinished"/> + <translation>比这手续费更小的被认为零手续费 (中继) (默认值: </translation> </message> <message> <source>Find peers using DNS lookup (default: 1 unless -connect)</source> @@ -2962,7 +2962,7 @@ rpcpassword=%s </message> <message> <source>Force safe mode (default: 0)</source> - <translation type="unfinished"/> + <translation>强制安全模式(默认值: 0)</translation> </message> <message> <source>Generate coins (default: 0)</source> @@ -3010,7 +3010,7 @@ rpcpassword=%s </message> <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> - <translation type="unfinished"/> + <translation>设置以MB为单位的数据库缓存大小(%d 到 %d, 默认值: %d)</translation> </message> <message> <source>Set maximum block size in bytes (default: %d)</source> @@ -3070,7 +3070,7 @@ rpcpassword=%s </message> <message> <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source> - <translation type="unfinished"/> + <translation>无法获取数据目录的 %s. 比特币核心钱包可能已经在运行.</translation> </message> <message> <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source> @@ -3098,11 +3098,11 @@ rpcpassword=%s </message> <message> <source>Limit size of signature cache to <n> entries (default: 50000)</source> - <translation type="unfinished"/> + <translation>签名缓冲大小限制每<n> 条目 (默认值: 50000)</translation> </message> <message> <source>Log transaction priority and fee per kB when mining blocks (default: 0)</source> - <translation type="unfinished"/> + <translation>开采区块时,日志优先级和手续费每KB (默认值: 0)</translation> </message> <message> <source>Maintain a full transaction index (default: 0)</source> @@ -3126,15 +3126,15 @@ rpcpassword=%s </message> <message> <source>Print block on startup, if found in block index</source> - <translation type="unfinished"/> + <translation>如果在搜索区块中找到,请启动打印区块</translation> </message> <message> <source>Print block tree on startup (default: 0)</source> - <translation>启动时打印块树 (默认: 0)</translation> + <translation>启动时打印区块树 (默认值: 0)</translation> </message> <message> <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> - <translation type="unfinished"/> + <translation>RPC SSL选项:(见有关比特币设置用于SSL说明的维基百科)</translation> </message> <message> <source>RPC server options:</source> @@ -3142,15 +3142,15 @@ rpcpassword=%s </message> <message> <source>Randomly drop 1 of every <n> network messages</source> - <translation type="unfinished"/> + <translation>随机每1个丢失测试<n>网络信息</translation> </message> <message> <source>Randomly fuzz 1 of every <n> network messages</source> - <translation type="unfinished"/> + <translation>随机每1个模拟测试<n>网络信息</translation> </message> <message> <source>Run a thread to flush wallet periodically (default: 1)</source> - <translation type="unfinished"/> + <translation>运行一个程序,定时清理钱包 (默认值:1)</translation> </message> <message> <source>SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> @@ -3158,7 +3158,7 @@ rpcpassword=%s </message> <message> <source>Send command to Bitcoin Core</source> - <translation type="unfinished"/> + <translation>发送指令到比特币核心钱包</translation> </message> <message> <source>Send trace/debug info to console instead of debug.log file</source> @@ -3170,15 +3170,15 @@ rpcpassword=%s </message> <message> <source>Sets the DB_PRIVATE flag in the wallet db environment (default: 1)</source> - <translation type="unfinished"/> + <translation>设置DB_PRIVATE钱包标志DB环境 (默认值: 1)</translation> </message> <message> <source>Show all debugging options (usage: --help -help-debug)</source> - <translation type="unfinished"/> + <translation>显示所有调试选项 (用法: --帮助 -帮助调试)</translation> </message> <message> <source>Show benchmark information (default: 0)</source> - <translation type="unfinished"/> + <translation>显示标准信息 (默认值: 0)</translation> </message> <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> @@ -3194,7 +3194,7 @@ rpcpassword=%s </message> <message> <source>Start Bitcoin Core Daemon</source> - <translation type="unfinished"/> + <translation>开启比特币核心钱包守护进程</translation> </message> <message> <source>System error: </source> @@ -3238,7 +3238,7 @@ rpcpassword=%s </message> <message> <source>on startup</source> - <translation type="unfinished"/> + <translation>启动中</translation> </message> <message> <source>version</source> diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index ca6ae17990..4c45585685 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -178,6 +178,9 @@ void PaymentServer::LoadRootCAs(X509_STORE* _store) // and the items in savedPaymentRequest will be handled // when uiReady() is called. // +// Warning: ipcSendCommandLine() is called early in init, +// so don't use "emit message()", but "QMessageBox::"! +// bool PaymentServer::ipcParseCommandLine(int argc, char* argv[]) { for (int i = 1; i < argc; i++) @@ -411,7 +414,15 @@ void PaymentServer::handleURIOrFile(const QString& s) { SendCoinsRecipient recipient; if (GUIUtil::parseBitcoinURI(s, &recipient)) - emit receivedPaymentRequest(recipient); + { + CBitcoinAddress address(recipient.address.toStdString()); + if (!address.IsValid()) { + emit message(tr("URI handling"), tr("Invalid payment address %1").arg(recipient.address), + CClientUIInterface::MSG_ERROR); + } + else + emit receivedPaymentRequest(recipient); + } else emit message(tr("URI handling"), tr("URI can not be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters."), @@ -425,12 +436,14 @@ void PaymentServer::handleURIOrFile(const QString& s) { PaymentRequestPlus request; SendCoinsRecipient recipient; - if (readPaymentRequest(s, request) && processPaymentRequest(request, recipient)) - emit receivedPaymentRequest(recipient); - else + if (!readPaymentRequest(s, request)) + { emit message(tr("Payment request file handling"), - tr("Payment request file can not be read or processed! This can be caused by an invalid payment request file."), + tr("Payment request file can not be read! This can be caused by an invalid payment request file."), CClientUIInterface::ICON_WARNING); + } + else if (processPaymentRequest(request, recipient)) + emit receivedPaymentRequest(recipient); return; } @@ -482,6 +495,35 @@ bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoins if (!optionsModel) return false; + if (request.IsInitialized()) { + const payments::PaymentDetails& details = request.getDetails(); + + // Payment request network matches client network? + if ((details.network() == "main" && TestNet()) || + (details.network() == "test" && !TestNet())) + { + emit message(tr("Payment request rejected"), tr("Payment request network doesn't match client network."), + CClientUIInterface::MSG_ERROR); + + return false; + } + + // Expired payment request? + if (details.has_expires() && (int64_t)details.expires() < GetTime()) + { + emit message(tr("Payment request rejected"), tr("Payment request has expired."), + CClientUIInterface::MSG_ERROR); + + return false; + } + } + else { + emit message(tr("Payment request error"), tr("Payment request is not initialized."), + CClientUIInterface::MSG_ERROR); + + return false; + } + recipient.paymentRequest = request; recipient.message = GUIUtil::HtmlEscape(request.getDetails().memo()); @@ -497,11 +539,11 @@ bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoins // Append destination address addresses.append(QString::fromStdString(CBitcoinAddress(dest).ToString())); } - else if (!recipient.authenticatedMerchant.isEmpty()){ + else if (!recipient.authenticatedMerchant.isEmpty()) { // Insecure payments to custom bitcoin addresses are not supported // (there is no good way to tell the user where they are paying in a way // they'd have a chance of understanding). - emit message(tr("Payment request error"), + emit message(tr("Payment request rejected"), tr("Unverified payment requests to custom payment scripts are unsupported."), CClientUIInterface::MSG_ERROR); return false; @@ -510,11 +552,10 @@ bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoins // Extract and check amounts CTxOut txOut(sendingTo.second, sendingTo.first); if (txOut.IsDust(CTransaction::nMinRelayTxFee)) { - QString msg = tr("Requested payment amount of %1 is too small (considered dust).") - .arg(BitcoinUnits::formatWithUnit(optionsModel->getDisplayUnit(), sendingTo.second)); + emit message(tr("Payment request error"), tr("Requested payment amount of %1 is too small (considered dust).") + .arg(BitcoinUnits::formatWithUnit(optionsModel->getDisplayUnit(), sendingTo.second)), + CClientUIInterface::MSG_ERROR); - qDebug() << "PaymentServer::processPaymentRequest : " << msg; - emit message(tr("Payment request error"), msg, CClientUIInterface::MSG_ERROR); return false; } @@ -581,8 +622,8 @@ void PaymentServer::fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipien refund_to->set_script(&s[0], s.size()); } else { - // This should never happen, because sending coins should have just unlocked the wallet - // and refilled the keypool + // This should never happen, because sending coins should have + // just unlocked the wallet and refilled the keypool. qDebug() << "PaymentServer::fetchPaymentACK : Error getting refund key, refund_to not set"; } } @@ -594,7 +635,7 @@ void PaymentServer::fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipien netManager->post(netRequest, serData); } else { - // This should never happen, either: + // This should never happen, either. qDebug() << "PaymentServer::fetchPaymentACK : Error serializing payment message"; } } @@ -620,17 +661,15 @@ void PaymentServer::netRequestFinished(QNetworkReply* reply) { PaymentRequestPlus request; SendCoinsRecipient recipient; - if (request.parse(data) && processPaymentRequest(request, recipient)) + if (!request.parse(data)) { - emit receivedPaymentRequest(recipient); - } - else - { - qDebug() << "PaymentServer::netRequestFinished : Error processing payment request"; + qDebug() << "PaymentServer::netRequestFinished : Error parsing payment request"; emit message(tr("Payment request error"), - tr("Payment request can not be parsed or processed!"), + tr("Payment request can not be parsed!"), CClientUIInterface::MSG_ERROR); } + else if (processPaymentRequest(request, recipient)) + emit receivedPaymentRequest(recipient); return; } diff --git a/src/qt/peertablemodel.cpp b/src/qt/peertablemodel.cpp new file mode 100644 index 0000000000..db5ce639b1 --- /dev/null +++ b/src/qt/peertablemodel.cpp @@ -0,0 +1,236 @@ +// Copyright (c) 2011-2013 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "peertablemodel.h" + +#include "clientmodel.h" + +#include "net.h" +#include "sync.h" + +#include <QDebug> +#include <QList> +#include <QTimer> + +bool NodeLessThan::operator()(const CNodeCombinedStats &left, const CNodeCombinedStats &right) const +{ + const CNodeStats *pLeft = &(left.nodestats); + const CNodeStats *pRight = &(right.nodestats); + + if (order == Qt::DescendingOrder) + std::swap(pLeft, pRight); + + switch(column) + { + case PeerTableModel::Address: + return pLeft->addrName.compare(pRight->addrName) < 0; + case PeerTableModel::Subversion: + return pLeft->cleanSubVer.compare(pRight->cleanSubVer) < 0; + case PeerTableModel::Height: + return pLeft->nStartingHeight < pRight->nStartingHeight; + } + + return false; +} + +// private implementation +class PeerTablePriv +{ +public: + /** Local cache of peer information */ + QList<CNodeCombinedStats> cachedNodeStats; + /** Column to sort nodes by */ + int sortColumn; + /** Order (ascending or descending) to sort nodes by */ + Qt::SortOrder sortOrder; + /** Index of rows by node ID */ + std::map<NodeId, int> mapNodeRows; + + /** Pull a full list of peers from vNodes into our cache */ + void refreshPeers() { + TRY_LOCK(cs_vNodes, lockNodes); + { + if (!lockNodes) + { + // skip the refresh if we can't immediately get the lock + return; + } + cachedNodeStats.clear(); +#if QT_VERSION >= 0x040700 + cachedNodeStats.reserve(vNodes.size()); +#endif + BOOST_FOREACH(CNode* pnode, vNodes) + { + CNodeCombinedStats stats; + stats.statestats.nMisbehavior = -1; + pnode->copyStats(stats.nodestats); + cachedNodeStats.append(stats); + } + } + + // if we can, retrieve the CNodeStateStats for each node. + TRY_LOCK(cs_main, lockMain); + { + if (lockMain) + { + BOOST_FOREACH(CNodeCombinedStats &stats, cachedNodeStats) + { + GetNodeStateStats(stats.nodestats.nodeid, stats.statestats); + } + } + } + + if (sortColumn >= 0) + // sort cacheNodeStats (use stable sort to prevent rows jumping around unneceesarily) + qStableSort(cachedNodeStats.begin(), cachedNodeStats.end(), NodeLessThan(sortColumn, sortOrder)); + + // build index map + mapNodeRows.clear(); + int row = 0; + BOOST_FOREACH(CNodeCombinedStats &stats, cachedNodeStats) + { + mapNodeRows.insert(std::pair<NodeId, int>(stats.nodestats.nodeid, row++)); + } + } + + int size() + { + return cachedNodeStats.size(); + } + + CNodeCombinedStats *index(int idx) + { + if(idx >= 0 && idx < cachedNodeStats.size()) { + return &cachedNodeStats[idx]; + } + else + { + return 0; + } + } +}; + +PeerTableModel::PeerTableModel(ClientModel *parent) : + QAbstractTableModel(parent),clientModel(parent),timer(0) +{ + columns << tr("Address") << tr("User Agent") << tr("Start Height"); + priv = new PeerTablePriv(); + // default to unsorted + priv->sortColumn = -1; + + // set up timer for auto refresh + timer = new QTimer(); + connect(timer, SIGNAL(timeout()), SLOT(refresh())); + + // load initial data + refresh(); +} + +void PeerTableModel::startAutoRefresh(int msecs) +{ + timer->setInterval(1000); + timer->start(); +} + +void PeerTableModel::stopAutoRefresh() +{ + timer->stop(); +} + +int PeerTableModel::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return priv->size(); +} + +int PeerTableModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return 3; +} + +QVariant PeerTableModel::data(const QModelIndex &index, int role) const +{ + if(!index.isValid()) + return QVariant(); + + CNodeCombinedStats *rec = static_cast<CNodeCombinedStats*>(index.internalPointer()); + + if(role == Qt::DisplayRole) + { + switch(index.column()) + { + case Address: + return QVariant(rec->nodestats.addrName.c_str()); + case Subversion: + return QVariant(rec->nodestats.cleanSubVer.c_str()); + case Height: + return rec->nodestats.nStartingHeight; + } + } + return QVariant(); +} + +QVariant PeerTableModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(orientation == Qt::Horizontal) + { + if(role == Qt::DisplayRole && section < columns.size()) + { + return columns[section]; + } + } + return QVariant(); +} + +Qt::ItemFlags PeerTableModel::flags(const QModelIndex &index) const +{ + if(!index.isValid()) + return 0; + + Qt::ItemFlags retval = Qt::ItemIsSelectable | Qt::ItemIsEnabled; + return retval; +} + +QModelIndex PeerTableModel::index(int row, int column, const QModelIndex &parent) const +{ + Q_UNUSED(parent); + CNodeCombinedStats *data = priv->index(row); + + if (data) + { + return createIndex(row, column, data); + } + else + { + return QModelIndex(); + } +} + +const CNodeCombinedStats *PeerTableModel::getNodeStats(int idx) { + return priv->index(idx); +} + +void PeerTableModel::refresh() +{ + emit layoutAboutToBeChanged(); + priv->refreshPeers(); + emit layoutChanged(); +} + +int PeerTableModel::getRowByNodeId(NodeId nodeid) +{ + std::map<NodeId, int>::iterator it = priv->mapNodeRows.find(nodeid); + if (it == priv->mapNodeRows.end()) + return -1; + + return it->second; +} + +void PeerTableModel::sort(int column, Qt::SortOrder order) +{ + priv->sortColumn = column; + priv->sortOrder = order; + refresh(); +} diff --git a/src/qt/peertablemodel.h b/src/qt/peertablemodel.h new file mode 100644 index 0000000000..385bf0e0c1 --- /dev/null +++ b/src/qt/peertablemodel.h @@ -0,0 +1,80 @@ +// Copyright (c) 2011-2013 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef PEERTABLEMODEL_H +#define PEERTABLEMODEL_H + +#include "main.h" +#include "net.h" + +#include <QAbstractTableModel> +#include <QStringList> + +class ClientModel; +class PeerTablePriv; + +QT_BEGIN_NAMESPACE +class QTimer; +QT_END_NAMESPACE + +struct CNodeCombinedStats { + CNodeStats nodestats; + CNodeStateStats statestats; +}; + +class NodeLessThan +{ +public: + NodeLessThan(int nColumn, Qt::SortOrder fOrder) : + column(nColumn), order(fOrder) {} + bool operator()(const CNodeCombinedStats &left, const CNodeCombinedStats &right) const; + +private: + int column; + Qt::SortOrder order; +}; + +/** + Qt model providing information about connected peers, similar to the + "getpeerinfo" RPC call. Used by the rpc console UI. + */ +class PeerTableModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + explicit PeerTableModel(ClientModel *parent = 0); + const CNodeCombinedStats *getNodeStats(int idx); + int getRowByNodeId(NodeId nodeid); + void startAutoRefresh(int msecs); + void stopAutoRefresh(); + + enum ColumnIndex { + Address = 0, + Subversion = 1, + Height = 2 + }; + + /** @name Methods overridden from QAbstractTableModel + @{*/ + int rowCount(const QModelIndex &parent) const; + int columnCount(const QModelIndex &parent) const; + QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int section, Qt::Orientation orientation, int role) const; + QModelIndex index(int row, int column, const QModelIndex &parent) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + void sort(int column, Qt::SortOrder order); + /*@}*/ + +public slots: + void refresh(); + +private: + ClientModel *clientModel; + QStringList columns; + PeerTablePriv *priv; + QTimer *timer; +}; + +#endif // PEERTABLEMODEL_H diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp index 062638f2bc..d8dad15c0d 100644 --- a/src/qt/receiverequestdialog.cpp +++ b/src/qt/receiverequestdialog.cpp @@ -13,10 +13,10 @@ #include <QClipboard> #include <QDrag> +#include <QMenu> #include <QMimeData> #include <QMouseEvent> #include <QPixmap> -#include <QMenu> #if QT_VERSION < 0x050000 #include <QUrl> #endif diff --git a/src/qt/receiverequestdialog.h b/src/qt/receiverequestdialog.h index 5614ac635a..9b78e495c3 100644 --- a/src/qt/receiverequestdialog.h +++ b/src/qt/receiverequestdialog.h @@ -11,10 +11,12 @@ #include <QImage> #include <QLabel> +class OptionsModel; + namespace Ui { class ReceiveRequestDialog; } -class OptionsModel; + QT_BEGIN_NAMESPACE class QMenu; QT_END_NAMESPACE diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 0a46a722e4..3b7d37ff39 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -7,9 +7,12 @@ #include "clientmodel.h" #include "guiutil.h" +#include "peertablemodel.h" +#include "main.h" #include "rpcserver.h" #include "rpcclient.h" +#include "util.h" #include "json/json_spirit_value.h" #include <openssl/crypto.h> @@ -195,6 +198,10 @@ RPCConsole::RPCConsole(QWidget *parent) : clientModel(0), historyPtr(0) { + detailNodeStats = CNodeCombinedStats(); + detailNodeStats.nodestats.nodeid = -1; + detailNodeStats.statestats.nMisbehavior = -1; + ui->setupUi(this); GUIUtil::restoreWindowGeometry("nRPCConsoleWindow", this->size(), this); @@ -214,6 +221,7 @@ RPCConsole::RPCConsole(QWidget *parent) : startExecutor(); setTrafficGraphRange(INITIAL_TRAFFIC_GRAPH_MINS); + ui->detailWidget->hide(); clear(); } @@ -277,6 +285,21 @@ void RPCConsole::setClientModel(ClientModel *model) updateTrafficStats(model->getTotalBytesRecv(), model->getTotalBytesSent()); connect(model, SIGNAL(bytesChanged(quint64,quint64)), this, SLOT(updateTrafficStats(quint64, quint64))); + // set up peer table + ui->peerWidget->setModel(model->getPeerTableModel()); + ui->peerWidget->verticalHeader()->hide(); + ui->peerWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); + ui->peerWidget->setSelectionBehavior(QAbstractItemView::SelectRows); + ui->peerWidget->setSelectionMode(QAbstractItemView::SingleSelection); + ui->peerWidget->setColumnWidth(PeerTableModel::Address, ADDRESS_COLUMN_WIDTH); + columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(ui->peerWidget, MINIMUM_COLUMN_WIDTH, MINIMUM_COLUMN_WIDTH); + + // connect the peerWidget's selection model to our peerSelected() handler + QItemSelectionModel *peerSelectModel = ui->peerWidget->selectionModel(); + connect(peerSelectModel, SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)), + this, SLOT(peerSelected(const QItemSelection &, const QItemSelection &))); + connect(model->getPeerTableModel(), SIGNAL(layoutChanged()), this, SLOT(peerLayoutChanged())); + // Provide initial values ui->clientVersion->setText(model->formatFullVersion()); ui->clientName->setText(model->clientName()); @@ -474,17 +497,7 @@ QString RPCConsole::FormatBytes(quint64 bytes) void RPCConsole::setTrafficGraphRange(int mins) { ui->trafficGraph->setGraphRangeMins(mins); - if(mins < 60) { - ui->lblGraphRange->setText(QString(tr("%1 m")).arg(mins)); - } else { - int hours = mins / 60; - int minsLeft = mins % 60; - if(minsLeft == 0) { - ui->lblGraphRange->setText(QString(tr("%1 h")).arg(hours)); - } else { - ui->lblGraphRange->setText(QString(tr("%1 h %2 m")).arg(hours).arg(minsLeft)); - } - } + ui->lblGraphRange->setText(GUIUtil::formatDurationStr(mins * 60)); } void RPCConsole::updateTrafficStats(quint64 totalBytesIn, quint64 totalBytesOut) @@ -492,3 +505,161 @@ void RPCConsole::updateTrafficStats(quint64 totalBytesIn, quint64 totalBytesOut) ui->lblBytesIn->setText(FormatBytes(totalBytesIn)); ui->lblBytesOut->setText(FormatBytes(totalBytesOut)); } + +void RPCConsole::peerSelected(const QItemSelection &selected, const QItemSelection &deselected) +{ + Q_UNUSED(deselected); + + if (selected.indexes().isEmpty()) + return; + + // mark the cached banscore as unknown + detailNodeStats.statestats.nMisbehavior = -1; + + const CNodeCombinedStats *stats = clientModel->getPeerTableModel()->getNodeStats(selected.indexes().first().row()); + + if (stats) + { + detailNodeStats.nodestats.nodeid = stats->nodestats.nodeid; + updateNodeDetail(stats); + ui->detailWidget->show(); + ui->detailWidget->setDisabled(false); + } +} + +void RPCConsole::peerLayoutChanged() +{ + const CNodeCombinedStats *stats = NULL; + bool fUnselect = false, fReselect = false, fDisconnected = false; + + if (detailNodeStats.nodestats.nodeid == -1) + // no node selected yet + return; + + // find the currently selected row + int selectedRow; + QModelIndexList selectedModelIndex = ui->peerWidget->selectionModel()->selectedIndexes(); + if (selectedModelIndex.isEmpty()) + selectedRow = -1; + else + selectedRow = selectedModelIndex.first().row(); + + // 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(detailNodeStats.nodestats.nodeid); + + if (detailNodeRow < 0) + { + // detail node dissapeared from table (node disconnected) + fUnselect = true; + fDisconnected = true; + detailNodeStats.nodestats.nodeid = 0; + } + else + { + if (detailNodeRow != selectedRow) + { + // detail node moved position + fUnselect = true; + fReselect = true; + } + + // get fresh stats on the detail node. + stats = clientModel->getPeerTableModel()->getNodeStats(detailNodeRow); + } + + if (fUnselect && selectedRow >= 0) + { + ui->peerWidget->selectionModel()->select(QItemSelection(selectedModelIndex.first(), selectedModelIndex.last()), + QItemSelectionModel::Deselect); + } + + if (fReselect) + { + ui->peerWidget->selectRow(detailNodeRow); + } + + if (stats) + updateNodeDetail(stats); + + if (fDisconnected) + { + ui->peerHeading->setText(QString(tr("Peer Disconnected"))); + ui->detailWidget->setDisabled(true); + QDateTime dt = QDateTime::fromTime_t(detailNodeStats.nodestats.nLastSend); + if (detailNodeStats.nodestats.nLastSend) + ui->peerLastSend->setText(dt.toString("yyyy-MM-dd hh:mm:ss")); + dt.setTime_t(detailNodeStats.nodestats.nLastRecv); + if (detailNodeStats.nodestats.nLastRecv) + ui->peerLastRecv->setText(dt.toString("yyyy-MM-dd hh:mm:ss")); + dt.setTime_t(detailNodeStats.nodestats.nTimeConnected); + ui->peerConnTime->setText(dt.toString("yyyy-MM-dd hh:mm:ss")); + } +} + +void RPCConsole::updateNodeDetail(const CNodeCombinedStats *combinedStats) +{ + CNodeStats stats = combinedStats->nodestats; + + // keep a copy of timestamps, used to display dates upon disconnect + detailNodeStats.nodestats.nLastSend = stats.nLastSend; + detailNodeStats.nodestats.nLastRecv = stats.nLastRecv; + detailNodeStats.nodestats.nTimeConnected = stats.nTimeConnected; + + // update the detail ui with latest node information + ui->peerHeading->setText(QString("<b>%1</b>").arg(tr("Node Detail"))); + ui->peerAddr->setText(QString(stats.addrName.c_str())); + ui->peerServices->setText(GUIUtil::formatServicesStr(stats.nServices)); + ui->peerLastSend->setText(stats.nLastSend ? GUIUtil::formatDurationStr(GetTime() - stats.nLastSend) : tr("never")); + ui->peerLastRecv->setText(stats.nLastRecv ? GUIUtil::formatDurationStr(GetTime() - stats.nLastRecv) : tr("never")); + ui->peerBytesSent->setText(FormatBytes(stats.nSendBytes)); + ui->peerBytesRecv->setText(FormatBytes(stats.nRecvBytes)); + ui->peerConnTime->setText(GUIUtil::formatDurationStr(GetTime() - stats.nTimeConnected)); + ui->peerPingTime->setText(stats.dPingTime == 0 ? tr("N/A") : QString(tr("%1 secs")).arg(QString::number(stats.dPingTime, 'f', 3))); + ui->peerVersion->setText(QString("%1").arg(stats.nVersion)); + ui->peerSubversion->setText(QString(stats.cleanSubVer.c_str())); + ui->peerDirection->setText(stats.fInbound ? tr("Inbound") : tr("Outbound")); + ui->peerHeight->setText(QString("%1").arg(stats.nStartingHeight)); + ui->peerSyncNode->setText(stats.fSyncNode ? tr("Yes") : tr("No")); + + // if we can, display the peer's ban score + CNodeStateStats statestats = combinedStats->statestats; + if (statestats.nMisbehavior >= 0) + { + // we have a new nMisbehavor value - update the cache + detailNodeStats.statestats.nMisbehavior = statestats.nMisbehavior; + } + + // pull the ban score from cache. -1 means it hasn't been retrieved yet (lock busy). + if (detailNodeStats.statestats.nMisbehavior >= 0) + ui->peerBanScore->setText(QString("%1").arg(detailNodeStats.statestats.nMisbehavior)); + else + ui->peerBanScore->setText(tr("Fetching...")); +} + +// We override the virtual resizeEvent of the QWidget to adjust tables column +// sizes as the tables width is proportional to the dialogs width. +void RPCConsole::resizeEvent(QResizeEvent *event) +{ + QWidget::resizeEvent(event); + columnResizingFixer->stretchColumnWidth(PeerTableModel::Address); +} + +void RPCConsole::showEvent(QShowEvent *event) +{ + QWidget::showEvent(event); + + // peerWidget needs a resize in case the dialog has non-default geometry + columnResizingFixer->stretchColumnWidth(PeerTableModel::Address); + + // start PeerTableModel auto refresh + clientModel->getPeerTableModel()->startAutoRefresh(1000); +} + +void RPCConsole::hideEvent(QHideEvent *event) +{ + QWidget::hideEvent(event); + + // stop PeerTableModel auto refresh + clientModel->getPeerTableModel()->stopAutoRefresh(); +} diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h index 091a6d294f..3fee34d00e 100644 --- a/src/qt/rpcconsole.h +++ b/src/qt/rpcconsole.h @@ -5,9 +5,19 @@ #ifndef RPCCONSOLE_H #define RPCCONSOLE_H +#include "guiutil.h" +#include "peertablemodel.h" + +#include "net.h" + #include <QDialog> class ClientModel; +class CNodeCombinedStats; + +QT_BEGIN_NAMESPACE +class QItemSelection; +QT_END_NAMESPACE namespace Ui { class RPCConsole; @@ -35,6 +45,19 @@ public: protected: virtual bool eventFilter(QObject* obj, QEvent *event); +private: + /** show detailed information on ui about selected node */ + void updateNodeDetail(const CNodeCombinedStats *combinedStats); + + enum ColumnWidths + { + ADDRESS_COLUMN_WIDTH = 250, + MINIMUM_COLUMN_WIDTH = 120 + }; + + /** track the node that we are currently viewing detail on in the peers tab */ + CNodeCombinedStats detailNodeStats; + private slots: void on_lineEdit_returnPressed(); void on_tabWidget_currentChanged(int index); @@ -44,6 +67,9 @@ private slots: void on_sldGraphRange_valueChanged(int value); /** update traffic statistics */ void updateTrafficStats(quint64 totalBytesIn, quint64 totalBytesOut); + void resizeEvent(QResizeEvent *event); + void showEvent(QShowEvent *event); + void hideEvent(QHideEvent *event); public slots: void clear(); @@ -57,6 +83,10 @@ public slots: void browseHistory(int offset); /** Scroll console view to end */ void scrollToEnd(); + /** Handle selection of peer in peers list */ + void peerSelected(const QItemSelection &selected, const QItemSelection &deselected); + /** Handle updated peer information */ + void peerLayoutChanged(); signals: // For RPC command executor @@ -70,6 +100,7 @@ private: Ui::RPCConsole *ui; ClientModel *clientModel; QStringList history; + GUIUtil::TableViewLastColumnResizingFixer *columnResizingFixer; int historyPtr; void startExecutor(); diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 33621e54b0..23b8ef83e2 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -377,26 +377,8 @@ void SendCoinsDialog::pasteEntry(const SendCoinsRecipient &rv) bool SendCoinsDialog::handlePaymentRequest(const SendCoinsRecipient &rv) { - QString strSendCoins = tr("Send Coins"); - if (rv.paymentRequest.IsInitialized()) { - // Expired payment request? - const payments::PaymentDetails& details = rv.paymentRequest.getDetails(); - if (details.has_expires() && (int64_t)details.expires() < GetTime()) - { - emit message(strSendCoins, tr("Payment request expired"), - CClientUIInterface::MSG_WARNING); - return false; - } - } - else { - CBitcoinAddress address(rv.address.toStdString()); - if (!address.IsValid()) { - emit message(strSendCoins, tr("Invalid payment address %1").arg(rv.address), - CClientUIInterface::MSG_WARNING); - return false; - } - } - + // Just paste the entry, all pre-checks + // are done in paymentserver.cpp. pasteEntry(rv); return true; } diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index 7c79b0efd0..1162e2d87f 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -129,6 +129,7 @@ void SplashScreen::subscribeToCoreSignals() { // Connect signals to client uiInterface.InitMessage.connect(boost::bind(InitMessage, this, _1)); + uiInterface.ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2)); #ifdef ENABLE_WALLET uiInterface.LoadWallet.connect(boost::bind(ConnectWallet, this, _1)); #endif @@ -138,6 +139,7 @@ void SplashScreen::unsubscribeFromCoreSignals() { // Disconnect signals from client uiInterface.InitMessage.disconnect(boost::bind(InitMessage, this, _1)); + uiInterface.ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2)); #ifdef ENABLE_WALLET if(pwalletMain) pwalletMain->ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2)); diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index 45fb3d40c2..0cfcb048c8 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -42,7 +42,7 @@ QString TransactionDesc::FormatTxStatus(const CWalletTx& wtx) } } -QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, int vout, int unit) +QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionRecord *rec, int unit) { QString strHTML; @@ -86,26 +86,19 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, int vout, int u if (nNet > 0) { // Credit - BOOST_FOREACH(const CTxOut& txout, wtx.vout) + if (CBitcoinAddress(rec->address).IsValid()) { - if (wallet->IsMine(txout)) + CTxDestination address = CBitcoinAddress(rec->address).Get(); + if (wallet->mapAddressBook.count(address)) { - CTxDestination address; - if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*wallet, address)) - { - if (wallet->mapAddressBook.count(address)) - { - strHTML += "<b>" + tr("From") + ":</b> " + tr("unknown") + "<br>"; - strHTML += "<b>" + tr("To") + ":</b> "; - strHTML += GUIUtil::HtmlEscape(CBitcoinAddress(address).ToString()); - if (!wallet->mapAddressBook[address].name.empty()) - strHTML += " (" + tr("own address") + ", " + tr("label") + ": " + GUIUtil::HtmlEscape(wallet->mapAddressBook[address].name) + ")"; - else - strHTML += " (" + tr("own address") + ")"; - strHTML += "<br>"; - } - } - break; + strHTML += "<b>" + tr("From") + ":</b> " + tr("unknown") + "<br>"; + strHTML += "<b>" + tr("To") + ":</b> "; + strHTML += GUIUtil::HtmlEscape(rec->address); + if (!wallet->mapAddressBook[address].name.empty()) + strHTML += " (" + tr("own address") + ", " + tr("label") + ": " + GUIUtil::HtmlEscape(wallet->mapAddressBook[address].name) + ")"; + else + strHTML += " (" + tr("own address") + ")"; + strHTML += "<br>"; } } } @@ -224,7 +217,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, int vout, int u if (wtx.mapValue.count("comment") && !wtx.mapValue["comment"].empty()) strHTML += "<br><b>" + tr("Comment") + ":</b><br>" + GUIUtil::HtmlEscape(wtx.mapValue["comment"], true) + "<br>"; - strHTML += "<b>" + tr("Transaction ID") + ":</b> " + TransactionRecord::formatSubTxId(wtx.GetHash(), vout) + "<br>"; + strHTML += "<b>" + tr("Transaction ID") + ":</b> " + TransactionRecord::formatSubTxId(wtx.GetHash(), rec->idx) + "<br>"; // Message from normal bitcoin:URI (bitcoin:123...?message=example) foreach (const PAIRTYPE(string, string)& r, wtx.vOrderForm) diff --git a/src/qt/transactiondesc.h b/src/qt/transactiondesc.h index 92d093b3eb..4bd4293210 100644 --- a/src/qt/transactiondesc.h +++ b/src/qt/transactiondesc.h @@ -8,6 +8,8 @@ #include <QObject> #include <QString> +class TransactionRecord; + class CWallet; class CWalletTx; @@ -18,7 +20,7 @@ class TransactionDesc: public QObject Q_OBJECT public: - static QString toHTML(CWallet *wallet, CWalletTx &wtx, int vout, int unit); + static QString toHTML(CWallet *wallet, CWalletTx &wtx, TransactionRecord *rec, int unit); private: TransactionDesc() {} diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index 8cf2b0a1b1..b9fcd0d6b0 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -222,7 +222,7 @@ public: std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(rec->hash); if(mi != wallet->mapWallet.end()) { - return TransactionDesc::toHTML(wallet, mi->second, rec->idx, unit); + return TransactionDesc::toHTML(wallet, mi->second, rec, unit); } } return QString(""); diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index a303b5d3ef..ff5057b526 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -427,7 +427,7 @@ Value verifychain(const Array& params, bool fHelp) if (params.size() > 1) nCheckDepth = params[1].get_int(); - return VerifyDB(nCheckLevel, nCheckDepth); + return CVerifyDB().VerifyDB(nCheckLevel, nCheckDepth); } Value getblockchaininfo(const Array& params, bool fHelp) diff --git a/src/script.cpp b/src/script.cpp index ac6d4b316f..381e84d0b7 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -208,14 +208,13 @@ const char* GetOpName(opcodetype opcode) case OP_NOP9 : return "OP_NOP9"; case OP_NOP10 : return "OP_NOP10"; + case OP_INVALIDOPCODE : return "OP_INVALIDOPCODE"; + // Note: + // The template matching params OP_SMALLDATA/etc are defined in opcodetype enum + // as kind of implementation hack, they are *NOT* real opcodes. If found in real + // Script, just let the default: case deal with them. - // template matching params - case OP_PUBKEYHASH : return "OP_PUBKEYHASH"; - case OP_PUBKEY : return "OP_PUBKEY"; - case OP_SMALLDATA : return "OP_SMALLDATA"; - - case OP_INVALIDOPCODE : return "OP_INVALIDOPCODE"; default: return "OP_UNKNOWN"; } diff --git a/src/test/data/tx_valid.json b/src/test/data/tx_valid.json index 40275cd194..aa8e5ca6c3 100644 --- a/src/test/data/tx_valid.json +++ b/src/test/data/tx_valid.json @@ -16,7 +16,7 @@ ["It is an OP_CHECKMULTISIG with an arbitrary extra byte stuffed into the signature at pos length - 2"], ["The dummy byte is fine however, so the NULLDUMMY flag should be happy"], [[["60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1", 0, "1 0x41 0x04cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4 0x41 0x0461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af 2 OP_CHECKMULTISIG"]], -"0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba260000000004A0048304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2bab01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", "P2SH,NULLDUMMY"], +"0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba260000000004a0048304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2bab01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", "P2SH,NULLDUMMY"], ["The following is a tweaked form of 23b397edccd3740a74adb603c9756370fafcde9bcc4483eb271ecad09a94dd63"], ["It is an OP_CHECKMULTISIG with the dummy value set to something other than an empty string"], diff --git a/src/test/rpc_wallet_tests.cpp b/src/test/rpc_wallet_tests.cpp index eea249b114..1dc2a3d82f 100644 --- a/src/test/rpc_wallet_tests.cpp +++ b/src/test/rpc_wallet_tests.cpp @@ -67,6 +67,31 @@ BOOST_AUTO_TEST_CASE(rpc_wallet) LOCK2(cs_main, pwalletMain->cs_wallet); + CPubKey demoPubkey = pwalletMain->GenerateNewKey(); + CBitcoinAddress demoAddress = CBitcoinAddress(CTxDestination(demoPubkey.GetID())); + Value retValue; + string strAccount = "walletDemoAccount"; + string strPurpose = "receive"; + BOOST_CHECK_NO_THROW({ /*Initialize Wallet with an account */ + CWalletDB walletdb(pwalletMain->strWalletFile); + CAccount account; + account.vchPubKey = demoPubkey; + pwalletMain->SetAddressBook(account.vchPubKey.GetID(), strAccount, strPurpose); + walletdb.WriteAccount(strAccount, account); + }); + + + /********************************* + * setaccount + *********************************/ + BOOST_CHECK_NO_THROW(CallRPC("setaccount 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ nullaccount")); + BOOST_CHECK_THROW(CallRPC("setaccount"), runtime_error); + /* 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4X (33 chars) is an illegal address (should be 34 chars) */ + BOOST_CHECK_THROW(CallRPC("setaccount 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4X nullaccount"), runtime_error); + + /********************************* + * listunspent + *********************************/ BOOST_CHECK_NO_THROW(CallRPC("listunspent")); BOOST_CHECK_THROW(CallRPC("listunspent string"), runtime_error); BOOST_CHECK_THROW(CallRPC("listunspent 0 string"), runtime_error); @@ -75,6 +100,9 @@ BOOST_AUTO_TEST_CASE(rpc_wallet) BOOST_CHECK_NO_THROW(r=CallRPC("listunspent 0 1 []")); BOOST_CHECK(r.get_array().empty()); + /********************************* + * listreceivedbyaddress + *********************************/ BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaddress")); BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaddress 0")); BOOST_CHECK_THROW(CallRPC("listreceivedbyaddress not_int"), runtime_error); @@ -82,12 +110,71 @@ BOOST_AUTO_TEST_CASE(rpc_wallet) BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaddress 0 true")); BOOST_CHECK_THROW(CallRPC("listreceivedbyaddress 0 true extra"), runtime_error); + /********************************* + * listreceivedbyaccount + *********************************/ BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaccount")); BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaccount 0")); BOOST_CHECK_THROW(CallRPC("listreceivedbyaccount not_int"), runtime_error); BOOST_CHECK_THROW(CallRPC("listreceivedbyaccount 0 not_bool"), runtime_error); BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaccount 0 true")); BOOST_CHECK_THROW(CallRPC("listreceivedbyaccount 0 true extra"), runtime_error); + + /********************************* + * getrawchangeaddress + *********************************/ + BOOST_CHECK_NO_THROW(CallRPC("getrawchangeaddress")); + + /********************************* + * getnewaddress + *********************************/ + BOOST_CHECK_NO_THROW(CallRPC("getnewaddress")); + BOOST_CHECK_NO_THROW(CallRPC("getnewaddress getnewaddress_demoaccount")); + + /********************************* + * getaccountaddress + *********************************/ + BOOST_CHECK_NO_THROW(CallRPC("getaccountaddress \"\"")); + BOOST_CHECK_NO_THROW(CallRPC("getaccountaddress accountThatDoesntExists")); // Should generate a new account + BOOST_CHECK_NO_THROW(retValue = CallRPC("getaccountaddress " + strAccount)); + BOOST_CHECK(CBitcoinAddress(retValue.get_str()).Get() == demoAddress.Get()); + + /********************************* + * getaccount + *********************************/ + BOOST_CHECK_THROW(CallRPC("getaccount"), runtime_error); + BOOST_CHECK_NO_THROW(CallRPC("getaccount " + demoAddress.ToString())); + + /********************************* + * signmessage + verifymessage + *********************************/ + BOOST_CHECK_NO_THROW(retValue = CallRPC("signmessage " + demoAddress.ToString() + " mymessage")); + BOOST_CHECK_THROW(CallRPC("signmessage"), runtime_error); + /* Should throw error because this address is not loaded in the wallet */ + BOOST_CHECK_THROW(CallRPC("signmessage 1QFqqMUD55ZV3PJEJZtaKCsQmjLT6JkjvJ mymessage"), runtime_error); + + /* missing arguments */ + BOOST_CHECK_THROW(CallRPC("verifymessage "+ demoAddress.ToString()), runtime_error); + BOOST_CHECK_THROW(CallRPC("verifymessage "+ demoAddress.ToString() + " " + retValue.get_str()), runtime_error); + /* Illegal address */ + BOOST_CHECK_THROW(CallRPC("verifymessage 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4X " + retValue.get_str() + " mymessage"), runtime_error); + /* wrong address */ + BOOST_CHECK(CallRPC("verifymessage 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ " + retValue.get_str() + " mymessage").get_bool() == false); + /* Correct address and signature but wrong message */ + BOOST_CHECK(CallRPC("verifymessage "+ demoAddress.ToString() + " " + retValue.get_str() + " wrongmessage").get_bool() == false); + /* Correct address, message and signature*/ + BOOST_CHECK(CallRPC("verifymessage "+ demoAddress.ToString() + " " + retValue.get_str() + " mymessage").get_bool() == true); + + /********************************* + * getaddressesbyaccount + *********************************/ + BOOST_CHECK_THROW(CallRPC("getaddressesbyaccount"), runtime_error); + BOOST_CHECK_NO_THROW(retValue = CallRPC("getaddressesbyaccount " + strAccount)); + Array arr = retValue.get_array(); + BOOST_CHECK(arr.size() > 0); + BOOST_CHECK(CBitcoinAddress(arr[0].get_str()).Get() == demoAddress.Get()); + } + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/ui_interface.h b/src/ui_interface.h index 7b655ac951..e1a3e04e12 100644 --- a/src/ui_interface.h +++ b/src/ui_interface.h @@ -94,6 +94,9 @@ public: /** A wallet has been loaded. */ boost::signals2::signal<void (CWallet* wallet)> LoadWallet; + + /** Show progress e.g. for verifychain */ + boost::signals2::signal<void (const std::string &title, int nProgress)> ShowProgress; }; extern CClientUIInterface uiInterface; diff --git a/src/wallet.h b/src/wallet.h index 96074151ad..d9d071c2b9 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -151,6 +151,7 @@ public: nOrderPosNext = 0; nNextResend = 0; nLastResend = 0; + nTimeFirstKey = 0; } CWallet(std::string strWalletFileIn) { |